fix: URLプレビューの動作改善+動作設定を可能にする (#13579)

* wip

* support new version

* URLプレビュー無効化時、フロント側も非表示にしてリクエストをしないようにする

* fix lint

* fix lint

* tweak preview request error handles

* fix: CHANGELOG.md

* fix

* fix

---------

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
おさむのひと 2024-03-21 18:46:42 +09:00 committed by GitHub
parent f4838e50b4
commit 831c74a25b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 420 additions and 66 deletions

View file

@ -18,6 +18,7 @@ import { defineAsyncComponent, ref } from 'vue';
import { url as local } from '@/config.js';
import { useTooltip } from '@/scripts/use-tooltip.js';
import * as os from '@/os.js';
import { isEnabledUrlPreview } from '@/instance.js';
const props = withDefaults(defineProps<{
url: string;
@ -31,13 +32,15 @@ const target = self ? null : '_blank';
const el = ref<HTMLElement | { $el: HTMLElement }>();
useTooltip(el, (showing) => {
os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), {
showing,
url: props.url,
source: el.value instanceof HTMLElement ? el.value : el.value?.$el,
}, {}, 'closed');
});
if (isEnabledUrlPreview.value) {
useTooltip(el, (showing) => {
os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), {
showing,
url: props.url,
source: el.value instanceof HTMLElement ? el.value : el.value?.$el,
}, {}, 'closed');
});
}
</script>
<style lang="scss" module>

View file

@ -82,7 +82,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkMediaList :mediaList="appearNote.files"/>
</div>
<MkPoll v-if="appearNote.poll" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview"/>
<div v-if="isEnabledUrlPreview">
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview"/>
</div>
<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div>
<button v-if="isLong && collapsed" :class="$style.collapsed" class="_button" @click="collapsed = false">
<span :class="$style.collapsedLabel">{{ i18n.ts.showMore }}</span>
@ -194,6 +196,7 @@ import { MenuItem } from '@/types/menu.js';
import MkRippleEffect from '@/components/MkRippleEffect.vue';
import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
import { shouldCollapsed } from '@/scripts/collapsed.js';
import { isEnabledUrlPreview } from '@/instance.js';
const props = withDefaults(defineProps<{
note: Misskey.entities.Note;
@ -268,7 +271,7 @@ const renoteCollapsed = ref(
defaultStore.state.collapseRenotes && isRenote && (
($i && ($i.id === note.value.userId || $i.id === appearNote.value.userId)) || // `||` must be `||`! See https://github.com/misskey-dev/misskey/issues/13131
(appearNote.value.myReaction != null)
)
),
);
/* Overload FunctionLint

View file

@ -95,7 +95,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkMediaList :mediaList="appearNote.files"/>
</div>
<MkPoll v-if="appearNote.poll" ref="pollViewer" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="true" style="margin-top: 6px;"/>
<div v-if="isEnabledUrlPreview">
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="true" style="margin-top: 6px;"/>
</div>
<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div>
</div>
<MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA>
@ -229,6 +231,7 @@ import MkUserCardMini from '@/components/MkUserCardMini.vue';
import MkPagination, { type Paging } from '@/components/MkPagination.vue';
import MkReactionIcon from '@/components/MkReactionIcon.vue';
import MkButton from '@/components/MkButton.vue';
import { isEnabledUrlPreview } from '@/instance.js';
const props = defineProps<{
note: Misskey.entities.Note;

View file

@ -110,7 +110,6 @@ const MOBILE_THRESHOLD = 500;
const isMobile = ref(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD);
const self = props.url.startsWith(local);
const attr = self ? 'to' : 'href';
const target = self ? null : '_blank';
const fetching = ref(true);
const title = ref<string | null>(null);
@ -152,15 +151,16 @@ requestUrl.hash = '';
window.fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${versatileLang}`)
.then(res => {
if (!res.ok) {
fetching.value = false;
unknownUrl.value = true;
return;
if (_DEV_) {
console.warn(`[HTTP${res.status}] Failed to fetch url preview`);
}
return null;
}
return res.json();
})
.then((info: SummalyResult) => {
if (info.url == null) {
.then((info: SummalyResult | null) => {
if (!info || info.url == null) {
fetching.value = false;
unknownUrl.value = true;
return;

View file

@ -30,6 +30,7 @@ import { url as local } from '@/config.js';
import * as os from '@/os.js';
import { useTooltip } from '@/scripts/use-tooltip.js';
import { safeURIDecode } from '@/scripts/safe-uri-decode.js';
import { isEnabledUrlPreview } from '@/instance.js';
const props = withDefaults(defineProps<{
url: string;
@ -44,7 +45,7 @@ const url = new URL(props.url);
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url');
const el = ref();
if (props.showUrlPreview) {
if (props.showUrlPreview && isEnabledUrlPreview.value) {
useTooltip(el, (showing) => {
os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), {
showing,

View file

@ -6,7 +6,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div class="_gaps" :class="$style.textRoot">
<Mfm :text="block.text ?? ''" :isNote="false"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url"/>
<div v-if="isEnabledUrlPreview">
<MkUrlPreview v-for="url in urls" :key="url" :url="url"/>
</div>
</div>
</template>
@ -15,6 +17,7 @@ import { defineAsyncComponent } from 'vue';
import * as mfm from 'mfm-js';
import * as Misskey from 'misskey-js';
import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm.js';
import { isEnabledUrlPreview } from '@/instance.js';
const MkUrlPreview = defineAsyncComponent(() => import('@/components/MkUrlPreview.vue'));