From 8959bfa1c0b558888aa7da207f8166092c51a353 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Tue, 6 May 2025 14:41:31 +0900 Subject: [PATCH] =?UTF-8?q?refactor(frontend):=20=E7=A9=BA/=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E7=B5=90=E6=9E=9C=E8=A1=A8=E7=A4=BA=E3=82=92?= =?UTF-8?q?=E3=82=B3=E3=83=B3=E3=83=9D=E3=83=BC=E3=83=8D=E3=83=B3=E3=83=88?= =?UTF-8?q?=E5=8C=96=20(#15963)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip * wip * wip * wip * wip * Update MkResult.vue * Add storybook story for MkResult (#15964) * Update MkResult.vue --------- Co-authored-by: taichan <40626578+tai-cha@users.noreply.github.com> --- .../frontend-embed/src/pages/not-found.vue | 4 -- packages/frontend-embed/src/style.scss | 7 --- packages/frontend-shared/js/const.ts | 4 -- .../frontend/src/components/MkChannelList.vue | 8 +-- .../src/components/MkChatHistories.vue | 4 +- .../frontend/src/components/MkFormDialog.vue | 6 +- packages/frontend/src/components/MkNotes.vue | 8 +-- .../src/components/MkNotification.vue | 2 - .../src/components/MkNotifications.vue | 8 +-- .../frontend/src/components/MkPagination.vue | 8 +-- .../frontend/src/components/MkTimeline.vue | 8 +-- .../frontend/src/components/MkUserList.vue | 8 +-- .../src/components/global/MkError.vue | 4 +- .../global/MkResult.stories.impl.ts | 57 +++++++++++++++++++ .../src/components/global/MkResult.vue | 44 ++++++++++++++ packages/frontend/src/components/index.ts | 3 + packages/frontend/src/instance.ts | 7 --- packages/frontend/src/pages/_error_.vue | 4 +- .../frontend/src/pages/admin/roles.role.vue | 8 +-- .../src/pages/chat/home.invitations.vue | 4 +- .../src/pages/chat/home.joiningRooms.vue | 4 +- .../src/pages/chat/home.ownedRooms.vue | 4 +- .../frontend/src/pages/chat/room.search.vue | 6 +- .../frontend/src/pages/drive.file.info.vue | 6 +- packages/frontend/src/pages/favorites.vue | 8 +-- .../frontend/src/pages/follow-requests.vue | 8 +-- packages/frontend/src/pages/invite.vue | 30 +--------- packages/frontend/src/pages/list.vue | 9 +-- .../frontend/src/pages/my-antennas/index.vue | 8 +-- .../frontend/src/pages/my-lists/index.vue | 8 +-- packages/frontend/src/pages/not-found.vue | 6 +- packages/frontend/src/pages/role.vue | 41 +------------ packages/frontend/src/pages/settings/apps.vue | 8 +-- .../src/pages/settings/mute-block.vue | 23 ++------ packages/frontend/src/style.scss | 12 ---- .../src/widgets/WidgetBirthdayFollowings.vue | 12 +--- packages/frontend/src/widgets/WidgetRss.vue | 6 +- 37 files changed, 140 insertions(+), 265 deletions(-) create mode 100644 packages/frontend/src/components/global/MkResult.stories.impl.ts create mode 100644 packages/frontend/src/components/global/MkResult.vue diff --git a/packages/frontend-embed/src/pages/not-found.vue b/packages/frontend-embed/src/pages/not-found.vue index 061254a39a..68897ca7e1 100644 --- a/packages/frontend-embed/src/pages/not-found.vue +++ b/packages/frontend-embed/src/pages/not-found.vue @@ -6,7 +6,6 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <div> <div class="_fullinfo"> - <img :src="notFoundImageUrl" draggable="false"/> <div>{{ i18n.ts.notFoundDescription }}</div> </div> </div> @@ -14,11 +13,8 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { inject, computed } from 'vue'; -import { DEFAULT_NOT_FOUND_IMAGE_URL } from '@@/js/const.js'; import { DI } from '@/di.js'; import { i18n } from '@/i18n.js'; const serverMetadata = inject(DI.serverMetadata)!; - -const notFoundImageUrl = computed(() => serverMetadata.notFoundImageUrl ?? DEFAULT_NOT_FOUND_IMAGE_URL); </script> diff --git a/packages/frontend-embed/src/style.scss b/packages/frontend-embed/src/style.scss index b67f929933..035d687ee4 100644 --- a/packages/frontend-embed/src/style.scss +++ b/packages/frontend-embed/src/style.scss @@ -286,13 +286,6 @@ rt { ._fullinfo { padding: 64px 32px; text-align: center; - - > img { - vertical-align: bottom; - height: 128px; - margin-bottom: 16px; - border-radius: 16px; - } } ._link { diff --git a/packages/frontend-shared/js/const.ts b/packages/frontend-shared/js/const.ts index 84b5afe78f..8c49b41f4d 100644 --- a/packages/frontend-shared/js/const.ts +++ b/packages/frontend-shared/js/const.ts @@ -112,10 +112,6 @@ export const ROLE_POLICIES = [ 'chatAvailability', ] as const; -export const DEFAULT_SERVER_ERROR_IMAGE_URL = 'https://xn--931a.moe/assets/error.jpg'; -export const DEFAULT_NOT_FOUND_IMAGE_URL = 'https://xn--931a.moe/assets/not-found.jpg'; -export const DEFAULT_INFO_IMAGE_URL = 'https://xn--931a.moe/assets/info.jpg'; - export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime']; export const MFM_PARAMS: Record<typeof MFM_TAGS[number], string[]> = { tada: ['speed=', 'delay='], diff --git a/packages/frontend/src/components/MkChannelList.vue b/packages/frontend/src/components/MkChannelList.vue index fdb7d2a1c4..d0b50f04f2 100644 --- a/packages/frontend/src/components/MkChannelList.vue +++ b/packages/frontend/src/components/MkChannelList.vue @@ -5,12 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <MkPagination :pagination="pagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.notFound }}</div> - </div> - </template> + <template #empty><MkResult type="empty"/></template> <template #default="{ items }"> <MkChannelPreview v-for="item in items" :key="item.id" class="_margin" :channel="extractor(item)"/> @@ -23,7 +18,6 @@ import type { Paging } from '@/components/MkPagination.vue'; import MkChannelPreview from '@/components/MkChannelPreview.vue'; import MkPagination from '@/components/MkPagination.vue'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; const props = withDefaults(defineProps<{ pagination: Paging; diff --git a/packages/frontend/src/components/MkChatHistories.vue b/packages/frontend/src/components/MkChatHistories.vue index c508ea8451..b33ed428c7 100644 --- a/packages/frontend/src/components/MkChatHistories.vue +++ b/packages/frontend/src/components/MkChatHistories.vue @@ -28,9 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </MkA> </div> -<div v-if="!initializing && history.length == 0" class="_fullinfo"> - <div>{{ i18n.ts._chat.noHistory }}</div> -</div> +<MkResult v-if="!initializing && history.length == 0" type="empty" :text="i18n.ts._chat.noHistory"/> <MkLoading v-if="initializing"/> </template> diff --git a/packages/frontend/src/components/MkFormDialog.vue b/packages/frontend/src/components/MkFormDialog.vue index 0884cdc016..6ac4441cac 100644 --- a/packages/frontend/src/components/MkFormDialog.vue +++ b/packages/frontend/src/components/MkFormDialog.vue @@ -62,10 +62,7 @@ SPDX-License-Identifier: AGPL-3.0-only /> </template> </div> - <div v-else class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> + <MkResult v-else type="empty"/> </div> </MkModalWindow> </template> @@ -83,7 +80,6 @@ import XFile from './MkFormDialog.file.vue'; import type { Form } from '@/utility/form.js'; import MkModalWindow from '@/components/MkModalWindow.vue'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; const props = defineProps<{ title: string; diff --git a/packages/frontend/src/components/MkNotes.vue b/packages/frontend/src/components/MkNotes.vue index 9d862a4eac..509099e0b9 100644 --- a/packages/frontend/src/components/MkNotes.vue +++ b/packages/frontend/src/components/MkNotes.vue @@ -5,12 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <MkPagination ref="pagingComponent" :pagination="pagination" :disableAutoLoad="disableAutoLoad"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noNotes }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noNotes"/></template> <template #default="{ items: notes }"> <div :class="[$style.root, { [$style.noGap]: noGap, '_gaps': !noGap, [$style.reverse]: pagination.reversed }]"> @@ -34,7 +29,6 @@ import type { Paging } from '@/components/MkPagination.vue'; import MkNote from '@/components/MkNote.vue'; import MkPagination from '@/components/MkPagination.vue'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; const props = defineProps<{ pagination: Paging; diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue index 9672efca0a..21104b41df 100644 --- a/packages/frontend/src/components/MkNotification.vue +++ b/packages/frontend/src/components/MkNotification.vue @@ -11,7 +11,6 @@ SPDX-License-Identifier: AGPL-3.0-only <div v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'" :class="[$style.icon, $style.icon_reactionGroupHeart]"><i class="ti ti-heart" style="line-height: 1;"></i></div> <div v-else-if="notification.type === 'reaction:grouped'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ti ti-plus" style="line-height: 1;"></i></div> <div v-else-if="notification.type === 'renote:grouped'" :class="[$style.icon, $style.icon_renoteGroup]"><i class="ti ti-repeat" style="line-height: 1;"></i></div> - <img v-else-if="notification.type === 'test'" :class="$style.icon" :src="infoImageUrl"/> <MkAvatar v-else-if="'user' in notification" :class="$style.icon" :user="notification.user" link preview/> <img v-else-if="'icon' in notification && notification.icon != null" :class="[$style.icon, $style.icon_app]" :src="notification.icon" alt=""/> <div @@ -176,7 +175,6 @@ import { userPage } from '@/filters/user.js'; import { i18n } from '@/i18n.js'; import { misskeyApi } from '@/utility/misskey-api.js'; import { ensureSignin } from '@/i.js'; -import { infoImageUrl } from '@/instance.js'; const $i = ensureSignin(); diff --git a/packages/frontend/src/components/MkNotifications.vue b/packages/frontend/src/components/MkNotifications.vue index 308a077bd9..3c88b8af0d 100644 --- a/packages/frontend/src/components/MkNotifications.vue +++ b/packages/frontend/src/components/MkNotifications.vue @@ -6,12 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <component :is="prefer.s.enablePullToRefresh ? MkPullToRefresh : 'div'" :refresher="() => reload()"> <MkPagination ref="pagingComponent" :pagination="pagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noNotifications }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noNotifications"/></template> <template #default="{ items: notifications }"> <component @@ -42,7 +37,6 @@ import XNotification from '@/components/MkNotification.vue'; import MkNote from '@/components/MkNote.vue'; import { useStream } from '@/stream.js'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; import MkPullToRefresh from '@/components/MkPullToRefresh.vue'; import { prefer } from '@/preferences.js'; diff --git a/packages/frontend/src/components/MkPagination.vue b/packages/frontend/src/components/MkPagination.vue index 9adc3d98da..54da5a889d 100644 --- a/packages/frontend/src/components/MkPagination.vue +++ b/packages/frontend/src/components/MkPagination.vue @@ -16,12 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only <MkError v-else-if="error" @retry="init()"/> <div v-else-if="empty" key="_empty_"> - <slot name="empty"> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> - </slot> + <slot name="empty"><MkResult type="empty"/></slot> </div> <div v-else ref="rootEl" class="_gaps"> @@ -88,7 +83,6 @@ function concatMapWithArray(map: MisskeyEntityMap, entities: MisskeyEntity[]): M </script> <script lang="ts" setup> -import { infoImageUrl } from '@/instance.js'; import MkButton from '@/components/MkButton.vue'; const props = withDefaults(defineProps<{ diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue index e2c261787b..6a265aa836 100644 --- a/packages/frontend/src/components/MkTimeline.vue +++ b/packages/frontend/src/components/MkTimeline.vue @@ -6,12 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <component :is="prefer.s.enablePullToRefresh ? MkPullToRefresh : 'div'" :refresher="() => reloadTimeline()"> <MkPagination v-if="paginationQuery" ref="pagingComponent" :pagination="paginationQuery" @queue="emit('queue', $event)"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noNotes }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noNotes"/></template> <template #default="{ items: notes }"> <component @@ -53,7 +48,6 @@ import { prefer } from '@/preferences.js'; import MkNote from '@/components/MkNote.vue'; import MkPagination from '@/components/MkPagination.vue'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; const props = withDefaults(defineProps<{ src: BasicTimelineType | 'mentions' | 'directs' | 'list' | 'antenna' | 'channel' | 'role'; diff --git a/packages/frontend/src/components/MkUserList.vue b/packages/frontend/src/components/MkUserList.vue index 0d1ffd715f..90087cb000 100644 --- a/packages/frontend/src/components/MkUserList.vue +++ b/packages/frontend/src/components/MkUserList.vue @@ -5,12 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <MkPagination :pagination="pagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noUsers }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noUsers"/></template> <template #default="{ items }"> <div :class="$style.root"> @@ -25,7 +20,6 @@ import type { Paging } from '@/components/MkPagination.vue'; import MkUserInfo from '@/components/MkUserInfo.vue'; import MkPagination from '@/components/MkPagination.vue'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; const props = withDefaults(defineProps<{ pagination: Paging; diff --git a/packages/frontend/src/components/global/MkError.vue b/packages/frontend/src/components/global/MkError.vue index 95ed255189..bc3a282e40 100644 --- a/packages/frontend/src/components/global/MkError.vue +++ b/packages/frontend/src/components/global/MkError.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <Transition :name="prefer.s.animation ? '_transition_zoom' : ''" appear> <div :class="$style.root"> - <img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/> + <img v-if="instance.serverErrorImageUrl" :class="$style.img" :src="instance.serverErrorImageUrl" draggable="false"/> <p :class="$style.text"><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</p> <MkButton :class="$style.button" @click="() => emit('retry')">{{ i18n.ts.retry }}</MkButton> </div> @@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only import MkButton from '@/components/MkButton.vue'; import { i18n } from '@/i18n.js'; import { prefer } from '@/preferences.js'; -import { serverErrorImageUrl } from '@/instance.js'; +import { instance } from '@/instance.js'; const emit = defineEmits<{ (ev: 'retry'): void; diff --git a/packages/frontend/src/components/global/MkResult.stories.impl.ts b/packages/frontend/src/components/global/MkResult.stories.impl.ts new file mode 100644 index 0000000000..05f8c9069b --- /dev/null +++ b/packages/frontend/src/components/global/MkResult.stories.impl.ts @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import MkResult from './MkResult.vue'; +import type { StoryObj } from '@storybook/vue3'; +export const Default = { + render(args) { + return { + components: { + MkResult, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + }, + template: '<MkResult v-bind="props" />', + }; + }, + args: { + type: 'empty', + text: 'Lorem Ipsum', + }, + parameters: { + layout: 'centered', + }, +} satisfies StoryObj<typeof MkResult>; +export const emptyWithNoText = { + ...Default, + args: { + ...Default.args, + text: undefined, + }, +} satisfies StoryObj<typeof MkResult>; +export const notFound = { + ...Default, + args: { + ...Default.args, + type: 'notFound', + }, +} satisfies StoryObj<typeof MkResult>; +export const errorType = { + ...Default, + args: { + ...Default.args, + type: 'error', + }, +} satisfies StoryObj<typeof MkResult>; diff --git a/packages/frontend/src/components/global/MkResult.vue b/packages/frontend/src/components/global/MkResult.vue new file mode 100644 index 0000000000..51cf8a860a --- /dev/null +++ b/packages/frontend/src/components/global/MkResult.vue @@ -0,0 +1,44 @@ +<!-- +SPDX-FileCopyrightText: syuilo and misskey-project +SPDX-License-Identifier: AGPL-3.0-only +--> + +<template> +<div :class="[$style.root]" class="_gaps"> + <img v-if="type === 'empty' && instance.infoImageUrl" :src="instance.infoImageUrl" draggable="false" :class="$style.img"/> + <i v-else-if="type === 'empty'" class="ti ti-info-circle" :class="$style.icon"></i> + <div>{{ props.text ?? (type === 'empty' ? i18n.ts.nothing : type === 'notFound' ? i18n.ts.notFound : null) }}</div> + <slot></slot> +</div> +</template> + +<script lang="ts" setup> +import {} from 'vue'; +import { instance } from '@/instance.js'; +import { i18n } from '@/i18n.js'; + +const props = defineProps<{ + type: 'empty' | 'notFound' | 'error'; + text?: string; +}>(); +</script> + +<style lang="scss" module> +.root { + position: relative; + text-align: center; + padding: 32px; +} + +.img { + vertical-align: bottom; + height: 128px; + margin-bottom: 16px; + border-radius: 16px; +} + +.icon { + font-size: 24px; + margin: 0 auto; +} +</style> diff --git a/packages/frontend/src/components/index.ts b/packages/frontend/src/components/index.ts index ec6ea7c569..33d3532c1d 100644 --- a/packages/frontend/src/components/index.ts +++ b/packages/frontend/src/components/index.ts @@ -24,6 +24,7 @@ import MkAd from './global/MkAd.vue'; import MkPageHeader from './global/MkPageHeader.vue'; import MkStickyContainer from './global/MkStickyContainer.vue'; import MkLazy from './global/MkLazy.vue'; +import MkResult from './global/MkResult.vue'; import PageWithHeader from './global/PageWithHeader.vue'; import PageWithAnimBg from './global/PageWithAnimBg.vue'; import SearchMarker from './global/SearchMarker.vue'; @@ -61,6 +62,7 @@ export const components = { MkPageHeader: MkPageHeader, MkStickyContainer: MkStickyContainer, MkLazy: MkLazy, + MkResult: MkResult, PageWithHeader: PageWithHeader, PageWithAnimBg: PageWithAnimBg, SearchMarker: SearchMarker, @@ -92,6 +94,7 @@ declare module '@vue/runtime-core' { MkPageHeader: typeof MkPageHeader; MkStickyContainer: typeof MkStickyContainer; MkLazy: typeof MkLazy; + MkResult: typeof MkResult; PageWithHeader: typeof PageWithHeader; PageWithAnimBg: typeof PageWithAnimBg; SearchMarker: typeof SearchMarker; diff --git a/packages/frontend/src/instance.ts b/packages/frontend/src/instance.ts index e75e3dfd34..2943e60e43 100644 --- a/packages/frontend/src/instance.ts +++ b/packages/frontend/src/instance.ts @@ -7,7 +7,6 @@ import { computed, reactive } from 'vue'; import * as Misskey from 'misskey-js'; import { misskeyApi } from '@/utility/misskey-api.js'; import { miLocalStorage } from '@/local-storage.js'; -import { DEFAULT_INFO_IMAGE_URL, DEFAULT_NOT_FOUND_IMAGE_URL, DEFAULT_SERVER_ERROR_IMAGE_URL } from '@@/js/const.js'; // TODO: 他のタブと永続化されたstateを同期 @@ -30,12 +29,6 @@ if (providedAt > cachedAt) { export const instance: Misskey.entities.MetaDetailed = reactive(cachedMeta ?? {}); -export const serverErrorImageUrl = computed(() => instance.serverErrorImageUrl ?? DEFAULT_SERVER_ERROR_IMAGE_URL); - -export const infoImageUrl = computed(() => instance.infoImageUrl ?? DEFAULT_INFO_IMAGE_URL); - -export const notFoundImageUrl = computed(() => instance.notFoundImageUrl ?? DEFAULT_NOT_FOUND_IMAGE_URL); - export const isEnabledUrlPreview = computed(() => instance.enableUrlPreview ?? true); export async function fetchInstance(force = false): Promise<Misskey.entities.MetaDetailed> { diff --git a/packages/frontend/src/pages/_error_.vue b/packages/frontend/src/pages/_error_.vue index 791267f5ca..d656f93fa3 100644 --- a/packages/frontend/src/pages/_error_.vue +++ b/packages/frontend/src/pages/_error_.vue @@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only <MkLoading v-if="!loaded"/> <Transition :name="prefer.s.animation ? '_transition_zoom' : ''" appear> <div v-show="loaded" :class="$style.root"> - <img :src="serverErrorImageUrl" draggable="false" :class="$style.img"/> + <img v-if="instance.serverErrorImageUrl" :src="instance.serverErrorImageUrl" draggable="false" :class="$style.img"/> <div class="_gaps"> <div><b><i class="ti ti-alert-triangle"></i> {{ i18n.ts.pageLoadError }}</b></div> <div v-if="meta && (version === meta.version)">{{ i18n.ts.pageLoadErrorDescription }}</div> @@ -36,7 +36,7 @@ import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { miLocalStorage } from '@/local-storage.js'; import { prefer } from '@/preferences.js'; -import { serverErrorImageUrl } from '@/instance.js'; +import { instance } from '@/instance.js'; const props = withDefaults(defineProps<{ error?: Error; diff --git a/packages/frontend/src/pages/admin/roles.role.vue b/packages/frontend/src/pages/admin/roles.role.vue index 69645957bf..61d72777b8 100644 --- a/packages/frontend/src/pages/admin/roles.role.vue +++ b/packages/frontend/src/pages/admin/roles.role.vue @@ -24,12 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only <MkButton primary rounded @click="assign"><i class="ti ti-plus"></i> {{ i18n.ts.assign }}</MkButton> <MkPagination :pagination="usersPagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noUsers }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noUsers"/></template> <template #default="{ items }"> <div class="_gaps_s"> @@ -70,7 +65,6 @@ import MkButton from '@/components/MkButton.vue'; import MkUserCardMini from '@/components/MkUserCardMini.vue'; import MkInfo from '@/components/MkInfo.vue'; import MkPagination from '@/components/MkPagination.vue'; -import { infoImageUrl } from '@/instance.js'; import { useRouter } from '@/router.js'; const router = useRouter(); diff --git a/packages/frontend/src/pages/chat/home.invitations.vue b/packages/frontend/src/pages/chat/home.invitations.vue index 82b22ea9dd..3cbe186e9d 100644 --- a/packages/frontend/src/pages/chat/home.invitations.vue +++ b/packages/frontend/src/pages/chat/home.invitations.vue @@ -27,9 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </MkFolder> </div> - <div v-if="!fetching && invitations.length == 0" class="_fullinfo"> - <div>{{ i18n.ts._chat.noInvitations }}</div> - </div> + <MkResult v-if="!fetching && invitations.length == 0" type="empty" :text="i18n.ts._chat.noInvitations"/> <MkLoading v-if="fetching"/> </div> </template> diff --git a/packages/frontend/src/pages/chat/home.joiningRooms.vue b/packages/frontend/src/pages/chat/home.joiningRooms.vue index f9fd6bfd55..8887aec3d5 100644 --- a/packages/frontend/src/pages/chat/home.joiningRooms.vue +++ b/packages/frontend/src/pages/chat/home.joiningRooms.vue @@ -8,9 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div v-if="memberships.length > 0" class="_gaps_s"> <XRoom v-for="membership in memberships" :key="membership.id" :room="membership.room!"/> </div> - <div v-if="!fetching && memberships.length == 0" class="_fullinfo"> - <div>{{ i18n.ts._chat.noRooms }}</div> - </div> + <MkResult v-if="!fetching && memberships.length == 0" type="empty" :text="i18n.ts._chat.noRooms"/> <MkLoading v-if="fetching"/> </div> </template> diff --git a/packages/frontend/src/pages/chat/home.ownedRooms.vue b/packages/frontend/src/pages/chat/home.ownedRooms.vue index ce7da15563..9a7ae5dd72 100644 --- a/packages/frontend/src/pages/chat/home.ownedRooms.vue +++ b/packages/frontend/src/pages/chat/home.ownedRooms.vue @@ -8,9 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div v-if="rooms.length > 0" class="_gaps_s"> <XRoom v-for="room in rooms" :key="room.id" :room="room"/> </div> - <div v-if="!fetching && rooms.length == 0" class="_fullinfo"> - <div>{{ i18n.ts._chat.noRooms }}</div> - </div> + <MkResult v-if="!fetching && rooms.length == 0" type="empty" :text="i18n.ts._chat.noRooms"/> <MkLoading v-if="fetching"/> </div> </template> diff --git a/packages/frontend/src/pages/chat/room.search.vue b/packages/frontend/src/pages/chat/room.search.vue index 20b6e22a46..1e4eaf5639 100644 --- a/packages/frontend/src/pages/chat/room.search.vue +++ b/packages/frontend/src/pages/chat/room.search.vue @@ -24,10 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only <XMessage :message="message" :user="message.fromUser" :isSearchResult="true"/> </div> </div> - <div v-else class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.notFound }}</div> - </div> + <MkResult v-else type="notFound"/> </MkFoldableSection> </div> </template> @@ -38,7 +35,6 @@ import * as Misskey from 'misskey-js'; import XMessage from './XMessage.vue'; import MkButton from '@/components/MkButton.vue'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; import { misskeyApi } from '@/utility/misskey-api.js'; import MkInput from '@/components/MkInput.vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; diff --git a/packages/frontend/src/pages/drive.file.info.vue b/packages/frontend/src/pages/drive.file.info.vue index 5390a48be5..21be0b18a9 100644 --- a/packages/frontend/src/pages/drive.file.info.vue +++ b/packages/frontend/src/pages/drive.file.info.vue @@ -68,10 +68,7 @@ SPDX-License-Identifier: AGPL-3.0-only </MkKeyValue> </div> </div> - <div v-else class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> + <MkResult v-else type="empty"/> </div> </template> @@ -82,7 +79,6 @@ import MkInfo from '@/components/MkInfo.vue'; import MkMediaList from '@/components/MkMediaList.vue'; import MkKeyValue from '@/components/MkKeyValue.vue'; import bytes from '@/filters/bytes.js'; -import { infoImageUrl } from '@/instance.js'; import { i18n } from '@/i18n.js'; import * as os from '@/os.js'; import { misskeyApi } from '@/utility/misskey-api.js'; diff --git a/packages/frontend/src/pages/favorites.vue b/packages/frontend/src/pages/favorites.vue index 4f57c1209e..b0a18987b4 100644 --- a/packages/frontend/src/pages/favorites.vue +++ b/packages/frontend/src/pages/favorites.vue @@ -7,12 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only <PageWithHeader> <div class="_spacer" style="--MI_SPACER-w: 800px;"> <MkPagination :pagination="pagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noNotes }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noNotes"/></template> <template #default="{ items }"> <MkDateSeparatedList v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false"> @@ -30,7 +25,6 @@ import MkNote from '@/components/MkNote.vue'; import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; -import { infoImageUrl } from '@/instance.js'; const pagination = { endpoint: 'i/favorites' as const, diff --git a/packages/frontend/src/pages/follow-requests.vue b/packages/frontend/src/pages/follow-requests.vue index 8ea385a74f..9b4e3faaef 100644 --- a/packages/frontend/src/pages/follow-requests.vue +++ b/packages/frontend/src/pages/follow-requests.vue @@ -7,12 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only <PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs" :swipable="true"> <div class="_spacer" style="--MI_SPACER-w: 800px;"> <MkPagination ref="paginationComponent" :pagination="pagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noFollowRequests }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noFollowRequests"/></template> <template #default="{items}"> <div class="mk-follow-requests _gaps"> <div v-for="req in items" :key="req.id" class="user _panel"> @@ -48,7 +43,6 @@ import { userPage, acct } from '@/filters/user.js'; import * as os from '@/os.js'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; -import { infoImageUrl } from '@/instance.js'; import { $i } from '@/i.js'; const paginationComponent = useTemplateRef('paginationComponent'); diff --git a/packages/frontend/src/pages/invite.vue b/packages/frontend/src/pages/invite.vue index cc114ae9b3..406c08bcf2 100644 --- a/packages/frontend/src/pages/invite.vue +++ b/packages/frontend/src/pages/invite.vue @@ -6,13 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <PageWithHeader> <div v-if="!instance.disableRegistration || !($i && ($i.isAdmin || $i.policies.canInvite))" class="_spacer" style="--MI_SPACER-w: 1200px;"> - <div :class="$style.root"> - <img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/> - <div :class="$style.text"> - <i class="ti ti-alert-triangle"></i> - {{ i18n.ts.nothing }} - </div> - </div> + <MkResult type="empty"/> </div> <div v-else class="_spacer" style="--MI_SPACER-w: 800px;"> <div class="_gaps_m" style="text-align: center;"> @@ -43,7 +37,7 @@ import MkButton from '@/components/MkButton.vue'; import MkPagination from '@/components/MkPagination.vue'; import MkInviteCode from '@/components/MkInviteCode.vue'; import { definePage } from '@/page.js'; -import { serverErrorImageUrl, instance } from '@/instance.js'; +import { instance } from '@/instance.js'; import { $i } from '@/i.js'; const pagingComponent = useTemplateRef('pagingComponent'); @@ -96,23 +90,3 @@ definePage(() => ({ icon: 'ti ti-user-plus', })); </script> - -<style lang="scss" module> -.root { - padding: 32px; - text-align: center; - align-items: center; -} - -.text { - margin: 0 0 8px 0; -} - -.img { - vertical-align: bottom; - width: 128px; - height: 128px; - margin-bottom: 16px; - border-radius: 16px; -} -</style> diff --git a/packages/frontend/src/pages/list.vue b/packages/frontend/src/pages/list.vue index e9e3c79be5..4368aff8be 100644 --- a/packages/frontend/src/pages/list.vue +++ b/packages/frontend/src/pages/list.vue @@ -6,13 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <PageWithHeader :actions="headerActions" :tabs="headerTabs"> <div v-if="error != null" class="_spacer" style="--MI_SPACER-w: 1200px;"> - <div :class="$style.root"> - <img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/> - <p :class="$style.text"> - <i class="ti ti-alert-triangle"></i> - {{ i18n.ts.nothing }} - </p> - </div> + <MkResult type="error"/> </div> <div v-else-if="list" class="_spacer" style="--MI_SPACER-w: 700px;"> <div v-if="list" class="members _margin"> @@ -42,7 +36,6 @@ import { i18n } from '@/i18n.js'; import MkUserCardMini from '@/components/MkUserCardMini.vue'; import MkButton from '@/components/MkButton.vue'; import { definePage } from '@/page.js'; -import { serverErrorImageUrl } from '@/instance.js'; const props = defineProps<{ listId: string; diff --git a/packages/frontend/src/pages/my-antennas/index.vue b/packages/frontend/src/pages/my-antennas/index.vue index 6f623abb64..95a3108e3a 100644 --- a/packages/frontend/src/pages/my-antennas/index.vue +++ b/packages/frontend/src/pages/my-antennas/index.vue @@ -7,12 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only <PageWithHeader :actions="headerActions" :tabs="headerTabs"> <div class="_spacer" style="--MI_SPACER-w: 700px;"> <div> - <div v-if="antennas.length === 0" class="empty"> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> - </div> + <MkResult v-if="antennas.length === 0" type="empty"/> <MkButton :link="true" to="/my/antennas/create" primary :class="$style.add"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton> @@ -32,7 +27,6 @@ import MkButton from '@/components/MkButton.vue'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { antennasCache } from '@/cache.js'; -import { infoImageUrl } from '@/instance.js'; const antennas = computed(() => antennasCache.value.value ?? []); diff --git a/packages/frontend/src/pages/my-lists/index.vue b/packages/frontend/src/pages/my-lists/index.vue index c974f3afc7..41afabff99 100644 --- a/packages/frontend/src/pages/my-lists/index.vue +++ b/packages/frontend/src/pages/my-lists/index.vue @@ -7,12 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only <PageWithHeader :actions="headerActions" :tabs="headerTabs"> <div class="_spacer" style="--MI_SPACER-w: 700px;"> <div class="_gaps"> - <div v-if="items.length === 0" class="empty"> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> - </div> + <MkResult v-if="items.length === 0" type="empty"/> <MkButton primary rounded style="margin: 0 auto;" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.createList }}</MkButton> @@ -35,7 +30,6 @@ import * as os from '@/os.js'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { userListsCache } from '@/cache.js'; -import { infoImageUrl } from '@/instance.js'; import { ensureSignin } from '@/i.js'; const $i = ensureSignin(); diff --git a/packages/frontend/src/pages/not-found.vue b/packages/frontend/src/pages/not-found.vue index 684a3bb5bd..305518f64a 100644 --- a/packages/frontend/src/pages/not-found.vue +++ b/packages/frontend/src/pages/not-found.vue @@ -5,10 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <div> - <div class="_fullinfo"> - <img :src="notFoundImageUrl" draggable="false"/> - <div>{{ i18n.ts.notFoundDescription }}</div> - </div> + <MkResult type="notFound" :text="i18n.ts.notFoundDescription"/> </div> </template> @@ -17,7 +14,6 @@ import { computed } from 'vue'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { pleaseLogin } from '@/utility/please-login.js'; -import { notFoundImageUrl } from '@/instance.js'; const props = defineProps<{ showLoginPopup?: boolean; diff --git a/packages/frontend/src/pages/role.vue b/packages/frontend/src/pages/role.vue index 82e5999406..9d01edb255 100644 --- a/packages/frontend/src/pages/role.vue +++ b/packages/frontend/src/pages/role.vue @@ -6,30 +6,18 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <PageWithHeader v-model:tab="tab" :tabs="headerTabs"> <div v-if="error != null" class="_spacer" style="--MI_SPACER-w: 1200px;"> - <div :class="$style.root"> - <img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/> - <p :class="$style.text"> - <i class="ti ti-alert-triangle"></i> - {{ error }} - </p> - </div> + <MkResult type="error" :text="error"/> </div> <div v-else-if="tab === 'users'" class="_spacer" style="--MI_SPACER-w: 1200px;"> <div class="_gaps_s"> <div v-if="role">{{ role.description }}</div> <MkUserList v-if="visible" :pagination="users" :extractor="(item) => item.user"/> - <div v-else-if="!visible" class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> + <MkResult v-else-if="!visible" type="empty" :text="i18n.ts.nothing"/> </div> </div> <div v-else-if="tab === 'timeline'" class="_spacer" style="--MI_SPACER-w: 700px;"> <MkTimeline v-if="visible" ref="timeline" src="role" :role="props.roleId"/> - <div v-else-if="!visible" class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> + <MkResult v-else-if="!visible" type="empty" :text="i18n.ts.nothing"/> </div> </PageWithHeader> </template> @@ -37,13 +25,11 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, watch, ref } from 'vue'; import * as Misskey from 'misskey-js'; -import { instanceName } from '@@/js/config.js'; import { misskeyApi } from '@/utility/misskey-api.js'; import MkUserList from '@/components/MkUserList.vue'; import { definePage } from '@/page.js'; import { i18n } from '@/i18n.js'; import MkTimeline from '@/components/MkTimeline.vue'; -import { serverErrorImageUrl, infoImageUrl } from '@/instance.js'; const props = withDefaults(defineProps<{ roleId: string; @@ -97,24 +83,3 @@ definePage(() => ({ icon: 'ti ti-badge', })); </script> - -<style lang="scss" module> -.root { - padding: 32px; - text-align: center; - align-items: center; -} - -.text { - margin: 0 0 8px 0; -} - -.img { - vertical-align: bottom; - width: 128px; - height: 128px; - margin-bottom: 16px; - border-radius: 16px; -} -</style> - diff --git a/packages/frontend/src/pages/settings/apps.vue b/packages/frontend/src/pages/settings/apps.vue index c72179b9a1..33c17e5d7f 100644 --- a/packages/frontend/src/pages/settings/apps.vue +++ b/packages/frontend/src/pages/settings/apps.vue @@ -6,12 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <div class="_gaps_m"> <FormPagination ref="list" :pagination="pagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> - </template> + <template #empty><MkResult type="empty"/></template> <template #default="{items}"> <div class="_gaps"> <MkFolder v-for="token in items" :key="token.id" :defaultOpen="true"> @@ -63,7 +58,6 @@ import { definePage } from '@/page.js'; import MkKeyValue from '@/components/MkKeyValue.vue'; import MkButton from '@/components/MkButton.vue'; import MkFolder from '@/components/MkFolder.vue'; -import { infoImageUrl } from '@/instance.js'; const list = ref<InstanceType<typeof FormPagination>>(); diff --git a/packages/frontend/src/pages/settings/mute-block.vue b/packages/frontend/src/pages/settings/mute-block.vue index fc9cd8f892..7c2376249e 100644 --- a/packages/frontend/src/pages/settings/mute-block.vue +++ b/packages/frontend/src/pages/settings/mute-block.vue @@ -69,12 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template #label><SearchLabel>{{ i18n.ts.mutedUsers }} ({{ i18n.ts.renote }})</SearchLabel></template> <MkPagination :pagination="renoteMutingPagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noUsers }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noUsers"/></template> <template #default="{ items }"> <div class="_gaps_s"> @@ -105,12 +100,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template #label>{{ i18n.ts.mutedUsers }}</template> <MkPagination :pagination="mutingPagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noUsers }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noUsers"/></template> <template #default="{ items }"> <div class="_gaps_s"> @@ -143,12 +133,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template #label>{{ i18n.ts.blockedUsers }}</template> <MkPagination :pagination="blockingPagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.noUsers }}</div> - </div> - </template> + <template #empty><MkResult type="empty" :text="i18n.ts.noUsers"/></template> <template #default="{ items }"> <div class="_gaps_s"> @@ -186,7 +171,7 @@ import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import MkUserCardMini from '@/components/MkUserCardMini.vue'; import * as os from '@/os.js'; -import { instance, infoImageUrl } from '@/instance.js'; +import { instance } from '@/instance.js'; import { ensureSignin } from '@/i.js'; import MkInfo from '@/components/MkInfo.vue'; import MkFolder from '@/components/MkFolder.vue'; diff --git a/packages/frontend/src/style.scss b/packages/frontend/src/style.scss index b7ca0cfd01..341f5cb621 100644 --- a/packages/frontend/src/style.scss +++ b/packages/frontend/src/style.scss @@ -486,18 +486,6 @@ rt { } } -._fullinfo { - padding: 64px 32px; - text-align: center; - - > img { - vertical-align: bottom; - height: 128px; - margin-bottom: 16px; - border-radius: 16px; - } -} - ._link { color: var(--MI_THEME-link); } diff --git a/packages/frontend/src/widgets/WidgetBirthdayFollowings.vue b/packages/frontend/src/widgets/WidgetBirthdayFollowings.vue index 6fe743aed2..4790f143cb 100644 --- a/packages/frontend/src/widgets/WidgetBirthdayFollowings.vue +++ b/packages/frontend/src/widgets/WidgetBirthdayFollowings.vue @@ -15,8 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only <MkAvatar v-for="user in users" :key="user.id" :user="user.followee" link preview></MkAvatar> </div> <div v-else :class="$style.bdayFFallback"> - <img :src="infoImageUrl" draggable="false" :class="$style.bdayFFallbackImage"/> - <div>{{ i18n.ts.nothing }}</div> + <MkResult type="empty"/> </div> </div> </MkContainer> @@ -32,7 +31,6 @@ import type { GetFormResultType } from '@/utility/form.js'; import MkContainer from '@/components/MkContainer.vue'; import { misskeyApi } from '@/utility/misskey-api.js'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; import { $i } from '@/i.js'; const name = i18n.ts._widgets.birthdayFollowings; @@ -134,12 +132,4 @@ defineExpose<WidgetComponentExpose>({ justify-content: center; align-items: center; } - -.bdayFFallbackImage { - height: 96px; - width: auto; - max-width: 90%; - margin-bottom: 8px; - border-radius: var(--MI-radius); -} </style> diff --git a/packages/frontend/src/widgets/WidgetRss.vue b/packages/frontend/src/widgets/WidgetRss.vue index 132eb0a629..2594262df1 100644 --- a/packages/frontend/src/widgets/WidgetRss.vue +++ b/packages/frontend/src/widgets/WidgetRss.vue @@ -11,10 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="ekmkgxbj"> <MkLoading v-if="fetching"/> - <div v-else-if="(!items || items.length === 0) && widgetProps.showHeader" class="_fullinfo"> - <img :src="infoImageUrl" draggable="false"/> - <div>{{ i18n.ts.nothing }}</div> - </div> + <MkResult v-else-if="(!items || items.length === 0) && widgetProps.showHeader" type="empty"/> <div v-else :class="$style.feed"> <a v-for="item in items" :key="item.link" :class="$style.item" :href="item.link" rel="nofollow noopener" target="_blank" :title="item.title">{{ item.title }}</a> </div> @@ -32,7 +29,6 @@ import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps import type { GetFormResultType } from '@/utility/form.js'; import MkContainer from '@/components/MkContainer.vue'; import { i18n } from '@/i18n.js'; -import { infoImageUrl } from '@/instance.js'; const name = 'rss';