Skip to content

Commit

Permalink
リモートクリップ閲覧機能のフロントエンド改善 (yojo-art#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
kozakura913 authored Jul 14, 2024
1 parent b8e2641 commit 85b6460
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 11 deletions.
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkNote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<MkPoll v-if="appearNote.poll" :noteId="appearNote.id" :poll="appearNote.poll" :author="appearNote.user" :emojiUrls="appearNote.emojis" :class="$style.poll" @click.stop/>
<div v-if="isEnabledUrlPreview">
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :host="appearNote.user.host" :class="$style.urlPreview"/>
</div>
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || (appearNote.files && appearNote.files.length > 0 && defaultStore.state.allMediaNoteCollapse)) && collapsed" v-vibrate="defaultStore.state.vibrateSystem ? 5 : []" :class="$style.collapsed" class="_button" @click.stop="collapsed = false">
<span :class="$style.collapsedLabel">
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkNoteDetailed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<MkPoll v-if="appearNote.poll" ref="pollViewer" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll" :author="appearNote.user" :emojiUrls="appearNote.emojis"/>
<div v-if="isEnabledUrlPreview">
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="true" style="margin-top: 6px;"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="true" :host="appearNote.user.host" style="margin-top: 6px;"/>
</div>
<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div>
</div>
Expand Down
16 changes: 12 additions & 4 deletions packages/frontend/src/components/MkUrlPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</template>
<div v-else>
<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url.substring(local.length) : url" rel="nofollow noopener" :target="target" :title="url" @click.stop>
<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url_string.substring(local.length) : url_string" rel="nofollow noopener" :target="target" :title="url_string" @click.stop>
<div v-if="thumbnail && !sensitive" :class="$style.thumbnail" :style="defaultStore.state.dataSaver.urlPreview ? '' : `background-image: url('${thumbnail}')`">
</div>
<article :class="$style.body">
<header :class="$style.header">
<h1 v-if="unknownUrl" :class="$style.title">{{ url }}</h1>
<h1 v-if="unknownUrl" :class="$style.title">{{ url_string }}</h1>
<h1 v-else-if="fetching" :class="$style.title"><MkEllipsis/></h1>
<h1 v-else :class="$style.title" :title="title ?? undefined">{{ title }}</h1>
</header>
Expand Down Expand Up @@ -102,16 +102,24 @@ const props = withDefaults(defineProps<{
detail?: boolean;
compact?: boolean;
showActions?: boolean;
host?: string | null | undefined;
}>(), {
detail: false,
compact: false,
showActions: true,
host: null,
});

const MOBILE_THRESHOLD = 500;
const isMobile = ref(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD);

const self = props.url.startsWith(local);
let self = props.url.startsWith(local);
let requestUrl = new URL(props.url);
if (props.host === requestUrl.host && requestUrl.pathname.startsWith('/clips/')) {
requestUrl = new URL(local + requestUrl.pathname + '@' + props.host);
self = true;
}
const url_string = requestUrl.toString();
const attr = self ? 'to' : 'href';
const target = self ? null : '_blank';
const fetching = ref(true);
Expand All @@ -137,7 +145,7 @@ onDeactivated(() => {
playerEnabled.value = false;
});

const requestUrl = new URL(props.url);
//const requestUrl = new URL(props.url);
if (!['http:', 'https:'].includes(requestUrl.protocol)) throw new Error('invalid url');

if (requestUrl.hostname === 'twitter.com' || requestUrl.hostname === 'mobile.twitter.com' || requestUrl.hostname === 'x.com' || requestUrl.hostname === 'mobile.x.com') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
key: Math.random(),
url: token.props.url,
rel: 'nofollow noopener',
host: props.author?.host,
})];
}

Expand Down
16 changes: 12 additions & 4 deletions packages/frontend/src/components/global/MkUrl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only

<template>
<component
:is="self ? 'MkA' : 'a'" ref="el" :class="$style.root" class="_link" :[attr]="self ? props.url.substring(local.length) : props.url" :rel="rel ?? 'nofollow noopener'" :target="target"
:is="self ? 'MkA' : 'a'" ref="el" :class="$style.root" class="_link" :[attr]="self ? url_string.substring(local.length) : url_string" :rel="rel ?? 'nofollow noopener'" :target="target"
:behavior="props.navigationBehavior"
@click.stop
@contextmenu.stop="() => {}"
Expand Down Expand Up @@ -40,20 +40,27 @@ const props = withDefaults(defineProps<{
rel?: string;
showUrlPreview?: boolean;
navigationBehavior?: MkABehavior;
host: string | null | undefined;
}>(), {
showUrlPreview: true,
});

const self = props.url.startsWith(local);
const url = new URL(props.url);
let self = props.url.startsWith(local);
let url = new URL(props.url);
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url');

if (props.host === url.host && url.pathname.startsWith('/clips/')) {
url = new URL(local + url.pathname + '@' + props.host);
self = true;
}
const url_string = url.toString();
const el = ref();

if (props.showUrlPreview && isEnabledUrlPreview.value) {
useTooltip(el, (showing) => {
os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), {
showing,
url: props.url,
url: url_string,
source: el.value instanceof HTMLElement ? el.value : el.value?.$el,
}, {}, 'closed');
});
Expand All @@ -65,6 +72,7 @@ const port = url.port;
const pathname = safeURIDecode(url.pathname);
const query = safeURIDecode(url.search);
const hash = safeURIDecode(url.hash);

const attr = self ? 'to' : 'href';
const target = self ? null : '_blank';
</script>
Expand Down
13 changes: 12 additions & 1 deletion packages/frontend/src/pages/clip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkStickyContainer>
<template #header><MkPageHeader :actions="headerActions"/></template>
<MkSpacer :contentMax="800">
<MkRemoteCaution v-if="remoteUrl != null" :href="remoteUrl" class="warn" :class="$style.remote_caution"/>
<div v-if="clip" class="_gaps">
<div class="_panel">
<div class="_gaps_s" :class="$style.description">
Expand Down Expand Up @@ -34,6 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
import { computed, watch, provide, ref } from 'vue';
import * as Misskey from 'cherrypick-js';
import MkNotes from '@/components/MkNotes.vue';
import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
import { $i } from '@/account.js';
import { i18n } from '@/i18n.js';
import * as os from '@/os.js';
Expand All @@ -58,7 +60,13 @@ const pagination = {
clipId: props.clipId,
})),
};

const remoteUrl = ref<string | null>(null);
(() => {
let remote_split = props.clipId.split('@');
if (remote_split.length === 2 ) {
remoteUrl.value = 'https://' + remote_split[1] + '/clips/' + remote_split[0];
}
})();
const isOwned = computed<boolean | null>(() => $i && clip.value && ($i.id === clip.value.userId));

watch(() => props.clipId, async () => {
Expand Down Expand Up @@ -169,6 +177,9 @@ definePageMetadata(() => ({
</script>

<style lang="scss" module>
.remote_caution{
margin-bottom: 10px;
}
.description {
padding: 16px;
}
Expand Down

0 comments on commit 85b6460

Please sign in to comment.