diff --git a/pages/[[server]]/@[account]/[status].vue b/pages/[[server]]/@[account]/[status].vue index 2e330b24..e25df22d 100644 --- a/pages/[[server]]/@[account]/[status].vue +++ b/pages/[[server]]/@[account]/[status].vue @@ -1,4 +1,6 @@ <script setup lang="ts"> +// @ts-expect-error missing types +import { DynamicScroller, DynamicScrollerItem } from 'vue-virtual-scroller' import type { ComponentPublicInstance } from 'vue' definePageMeta({ @@ -17,13 +19,13 @@ const publishWidget = ref() const { data: status, pending, refresh: refreshStatus } = useAsyncData( `status:${id}`, () => fetchStatus(id), - { watch: [isHydrated], immediate: isHydrated.value }, + { watch: [isHydrated], immediate: isHydrated.value, default: () => shallowRef() }, ) const { client } = $(useMasto()) const { data: context, pending: pendingContext, refresh: refreshContext } = useAsyncData( `context:${id}`, async () => client.v1.statuses.fetchContext(id), - { watch: [isHydrated], immediate: isHydrated.value }, + { watch: [isHydrated], immediate: isHydrated.value, lazy: true, default: () => shallowRef() }, ) const replyDraft = $computed(() => status.value ? getReplyDraft(status.value) : null) @@ -90,16 +92,25 @@ onReactivated(() => { @published="refreshContext()" /> - <template v-for="(comment, di) of context?.descendants" :key="comment.id"> - <StatusCard - :status="comment" - context="account" - :older="context?.descendants[di + 1]" - :newer="context?.descendants[di - 1]" - :has-newer="di === 0" - :main="status" - /> - </template> + <TimelineSkeleton v-if="pendingContext" /> + <DynamicScroller + v-slot="{ item, index, active }" + :items="context?.descendants || []" + :min-item-size="200" + key-field="id" + page-mode + > + <DynamicScrollerItem :item="item" :active="active"> + <StatusCard + :status="item" + context="account" + :older="context?.descendants[index + 1]" + :newer="context?.descendants[index - 1]" + :has-newer="index === 0" + :main="status" + /> + </DynamicScrollerItem> + </DynamicScroller> </div> <StatusNotFound v-else :account="route.params.account as string" :status="id" /> diff --git a/pages/[[server]]/@[account]/index.vue b/pages/[[server]]/@[account]/index.vue index 34a0f9c8..027ac8f5 100644 --- a/pages/[[server]]/@[account]/index.vue +++ b/pages/[[server]]/@[account]/index.vue @@ -8,7 +8,7 @@ const accountName = $(computedEager(() => toShortHandle(params.account as string const { t } = useI18n() -const { data: account, pending, refresh } = $(await useAsyncData(() => fetchAccountByHandle(accountName).catch(() => null), { immediate: process.client })) +const { data: account, pending, refresh } = $(await useAsyncData(() => fetchAccountByHandle(accountName).catch(() => null), { immediate: process.client, default: () => shallowRef() })) const relationship = $computed(() => account ? useRelationship(account).value : undefined) onReactivated(() => { diff --git a/pages/[[server]]/tags/[tag].vue b/pages/[[server]]/tags/[tag].vue index e673005f..3df97c80 100644 --- a/pages/[[server]]/tags/[tag].vue +++ b/pages/[[server]]/tags/[tag].vue @@ -7,7 +7,7 @@ const params = useRoute().params const tagName = $(computedEager(() => params.tag as string)) const { client } = $(useMasto()) -const { data: tag, refresh } = $(await useAsyncData(() => client.v1.tags.fetch(tagName))) +const { data: tag, refresh } = $(await useAsyncData(() => client.v1.tags.fetch(tagName), { default: () => shallowRef() })) const paginator = client.v1.timelines.listHashtag(tagName) const stream = useStreaming(client => client.v1.stream.streamTagTimeline(tagName))