diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-08-26 13:58:57 +0900 |
|---|---|---|
| committer | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-08-26 13:58:57 +0900 |
| commit | 05cc8047fae2d827ed3d98e735d19cd704f6126d (patch) | |
| tree | daf4f611430b0e06798f1f02c5a7346e3023878c /packages/frontend | |
| parent | refactor (diff) | |
| download | misskey-05cc8047fae2d827ed3d98e735d19cd704f6126d.tar.gz misskey-05cc8047fae2d827ed3d98e735d19cd704f6126d.tar.bz2 misskey-05cc8047fae2d827ed3d98e735d19cd704f6126d.zip | |
refactor
Diffstat (limited to 'packages/frontend')
6 files changed, 50 insertions, 29 deletions
diff --git a/packages/frontend/src/components/MkStreamingNotesTimeline.vue b/packages/frontend/src/components/MkStreamingNotesTimeline.vue index 9ace0b32d5..bc6ebf0918 100644 --- a/packages/frontend/src/components/MkStreamingNotesTimeline.vue +++ b/packages/frontend/src/components/MkStreamingNotesTimeline.vue @@ -297,76 +297,97 @@ function prepend(note: Misskey.entities.Note & MisskeyEntity) { } } -let connection: Misskey.IChannelConnection | null = null; -let connection2: Misskey.IChannelConnection | null = null; - const stream = store.s.realtimeMode ? useStream() : null; +const connections = { + antenna: null as Misskey.IChannelConnection<Misskey.Channels['antenna']> | null, + homeTimeline: null as Misskey.IChannelConnection<Misskey.Channels['homeTimeline']> | null, + localTimeline: null as Misskey.IChannelConnection<Misskey.Channels['localTimeline']> | null, + hybridTimeline: null as Misskey.IChannelConnection<Misskey.Channels['hybridTimeline']> | null, + globalTimeline: null as Misskey.IChannelConnection<Misskey.Channels['globalTimeline']> | null, + main: null as Misskey.IChannelConnection<Misskey.Channels['main']> | null, + userList: null as Misskey.IChannelConnection<Misskey.Channels['userList']> | null, + channel: null as Misskey.IChannelConnection<Misskey.Channels['channel']> | null, + roleTimeline: null as Misskey.IChannelConnection<Misskey.Channels['roleTimeline']> | null, +}; + function connectChannel() { if (stream == null) return; if (props.src === 'antenna') { if (props.antenna == null) return; - connection = stream.useChannel('antenna', { + connections.antenna = stream.useChannel('antenna', { antennaId: props.antenna, }); + connections.antenna.on('note', prepend); } else if (props.src === 'home') { - connection = stream.useChannel('homeTimeline', { + connections.homeTimeline = stream.useChannel('homeTimeline', { withRenotes: props.withRenotes, withFiles: props.onlyFiles ? true : undefined, }); - connection2 = stream.useChannel('main'); + connections.main = stream.useChannel('main'); + connections.homeTimeline.on('note', prepend); } else if (props.src === 'local') { - connection = stream.useChannel('localTimeline', { + connections.localTimeline = stream.useChannel('localTimeline', { withRenotes: props.withRenotes, withReplies: props.withReplies, withFiles: props.onlyFiles ? true : undefined, }); + connections.localTimeline.on('note', prepend); } else if (props.src === 'social') { - connection = stream.useChannel('hybridTimeline', { + connections.hybridTimeline = stream.useChannel('hybridTimeline', { withRenotes: props.withRenotes, withReplies: props.withReplies, withFiles: props.onlyFiles ? true : undefined, }); + connections.hybridTimeline.on('note', prepend); } else if (props.src === 'global') { - connection = stream.useChannel('globalTimeline', { + connections.globalTimeline = stream.useChannel('globalTimeline', { withRenotes: props.withRenotes, withFiles: props.onlyFiles ? true : undefined, }); + connections.globalTimeline.on('note', prepend); } else if (props.src === 'mentions') { - connection = stream.useChannel('main'); - connection.on('mention', prepend); + connections.main = stream.useChannel('main'); + connections.main.on('mention', prepend); } else if (props.src === 'directs') { const onNote = note => { if (note.visibility === 'specified') { prepend(note); } }; - connection = stream.useChannel('main'); - connection.on('mention', onNote); + connections.main = stream.useChannel('main'); + connections.main.on('mention', onNote); } else if (props.src === 'list') { if (props.list == null) return; - connection = stream.useChannel('userList', { + connections.userList = stream.useChannel('userList', { withRenotes: props.withRenotes, withFiles: props.onlyFiles ? true : undefined, listId: props.list, }); + connections.userList.on('note', prepend); } else if (props.src === 'channel') { if (props.channel == null) return; - connection = stream.useChannel('channel', { + connections.channel = stream.useChannel('channel', { channelId: props.channel, }); + connections.channel.on('note', prepend); } else if (props.src === 'role') { if (props.role == null) return; - connection = stream.useChannel('roleTimeline', { + connections.roleTimeline = stream.useChannel('roleTimeline', { roleId: props.role, }); + connections.roleTimeline.on('note', prepend); } - if (props.src !== 'directs' && props.src !== 'mentions') connection?.on('note', prepend); } function disconnectChannel() { - if (connection) connection.dispose(); - if (connection2) connection2.dispose(); + for (const key in connections) { + const conn = connections[key as keyof typeof connections]; + if (conn != null) { + conn.dispose(); + connections[key as keyof typeof connections] = null; + } + } } if (store.s.realtimeMode) { diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index e10c44960a..6933d64214 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -54,7 +54,7 @@ SPDX-License-Identifier: AGPL-3.0-only </MkFukidashi> </div> <div v-if="user.roles.length > 0" class="roles"> - <span v-for="role in user.roles" :key="role.id" v-tooltip="role.description" class="role" :style="{ '--color': role.color }"> + <span v-for="role in user.roles" :key="role.id" v-tooltip="role.description" class="role" :style="{ '--color': role.color ?? '' }"> <MkA v-adaptive-bg :to="`/roles/${role.id}`"> <img v-if="role.iconUrl" style="height: 1.3em; vertical-align: -22%;" :src="role.iconUrl"/> {{ role.name }} @@ -249,7 +249,7 @@ const style = computed(() => { }); const age = computed(() => { - return calcAge(props.user.birthday); + return props.user.birthday ? calcAge(props.user.birthday) : NaN; }); function menu(ev: MouseEvent) { diff --git a/packages/frontend/src/ui/_common_/navbar.vue b/packages/frontend/src/ui/_common_/navbar.vue index 28913a54ab..4c43bf2b3b 100644 --- a/packages/frontend/src/ui/_common_/navbar.vue +++ b/packages/frontend/src/ui/_common_/navbar.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.body"> <div :class="$style.top"> <button v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu"> - <img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon" style="viewTransitionName: navbar-serverIcon;"/> + <img :src="instance.iconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon" style="viewTransitionName: navbar-serverIcon;"/> </button> <button v-if="!iconOnly" v-tooltip.noDelay.right="i18n.ts.realtimeMode" class="_button" :class="[$style.realtimeMode, store.r.realtimeMode.value ? $style.on : null]" @click="toggleRealtimeMode"> <i class="ti ti-bolt ti-fw"></i> diff --git a/packages/frontend/src/ui/_common_/statusbar-federation.vue b/packages/frontend/src/ui/_common_/statusbar-federation.vue index 7248e8826b..c79f690cff 100644 --- a/packages/frontend/src/ui/_common_/statusbar-federation.vue +++ b/packages/frontend/src/ui/_common_/statusbar-federation.vue @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only mode="default" > <MkMarqueeText :key="key" :duration="marqueeDuration" :reverse="marqueeReverse"> - <span v-for="instance in instances" :key="instance.id" :class="[$style.item, { [$style.colored]: colored }]" :style="{ background: colored ? instance.themeColor : null }"> + <span v-for="instance in instances" :key="instance.id" :class="[$style.item, { [$style.colored]: colored }]" :style="{ background: colored ? instance.themeColor : '' }"> <img :class="$style.icon" :src="getInstanceIcon(instance)" alt=""/> <MkA :to="`/instance-info/${instance.host}`" :class="$style.host" class="_monospace"> {{ instance.host }} @@ -33,9 +33,9 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref } from 'vue'; import * as Misskey from 'misskey-js'; +import { useInterval } from '@@/js/use-interval.js'; import MkMarqueeText from '@/components/MkMarqueeText.vue'; import { misskeyApi } from '@/utility/misskey-api.js'; -import { useInterval } from '@@/js/use-interval.js'; import { getProxiedImageUrlNullable } from '@/utility/media-proxy.js'; const props = defineProps<{ @@ -44,7 +44,7 @@ const props = defineProps<{ marqueeDuration?: number; marqueeReverse?: boolean; oneByOneInterval?: number; - refreshIntervalSec?: number; + refreshIntervalSec: number; }>(); const instances = ref<Misskey.entities.FederationInstance[]>([]); diff --git a/packages/frontend/src/ui/_common_/statusbar-user-list.vue b/packages/frontend/src/ui/_common_/statusbar-user-list.vue index 13139a1064..8a754e6e64 100644 --- a/packages/frontend/src/ui/_common_/statusbar-user-list.vue +++ b/packages/frontend/src/ui/_common_/statusbar-user-list.vue @@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only > <MkMarqueeText :key="key" :duration="marqueeDuration" :reverse="marqueeReverse"> <span v-for="note in notes" :key="note.id" :class="$style.item"> - <img :class="$style.avatar" :src="note.user.avatarUrl" decoding="async"/> + <img v-if="note.user.avatarUrl" :class="$style.avatar" :src="note.user.avatarUrl" decoding="async"/> <MkA :class="$style.text" :to="notePage(note)"> <Mfm :text="getNoteSummary(note)" :plain="true" :nowrap="true"/> </MkA> @@ -33,9 +33,9 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, watch } from 'vue'; import * as Misskey from 'misskey-js'; +import { useInterval } from '@@/js/use-interval.js'; import MkMarqueeText from '@/components/MkMarqueeText.vue'; import { misskeyApi } from '@/utility/misskey-api.js'; -import { useInterval } from '@@/js/use-interval.js'; import { getNoteSummary } from '@/utility/get-note-summary.js'; import { notePage } from '@/filters/note.js'; @@ -45,7 +45,7 @@ const props = defineProps<{ marqueeDuration?: number; marqueeReverse?: boolean; oneByOneInterval?: number; - refreshIntervalSec?: number; + refreshIntervalSec: number; }>(); const notes = ref<Misskey.entities.Note[]>([]); diff --git a/packages/frontend/src/ui/_common_/titlebar.vue b/packages/frontend/src/ui/_common_/titlebar.vue index c62b13b73a..1b9d47ec40 100644 --- a/packages/frontend/src/ui/_common_/titlebar.vue +++ b/packages/frontend/src/ui/_common_/titlebar.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <div :class="$style.root"> <div :class="$style.title"> - <img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon"/> + <img :src="instance.iconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon"/> <span :class="$style.instanceTitle">{{ instance.name ?? host }}</span> </div> <div :class="$style.controls"> |