Skip to content

Commit e5d1638

Browse files
committed
fix(ui): SSR likes data and add skeleton placeholders to prevent layout shift
1 parent 91b24a9 commit e5d1638

2 files changed

Lines changed: 12 additions & 32 deletions

File tree

app/composables/atproto/useProfileLikes.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,12 @@ export type LikesResult = {
88

99
export function useProfileLikes(handle: MaybeRefOrGetter<string>) {
1010
const cachedFetch = useCachedFetch()
11-
const asyncData = useLazyAsyncData(
12-
`profile:${toValue(handle)}:likes`,
13-
async (_nuxtApp, { signal }) => {
14-
const { data: likes, isStale } = await cachedFetch<LikesResult>(
15-
`/api/social/profile/${toValue(handle)}/likes`,
16-
{ signal },
17-
)
11+
return useLazyAsyncData(`profile:${toValue(handle)}:likes`, async (_nuxtApp, { signal }) => {
12+
const { data: likes, isStale } = await cachedFetch<LikesResult>(
13+
`/api/social/profile/${toValue(handle)}/likes`,
14+
{ signal },
15+
)
1816

19-
return { likes, isStale }
20-
},
21-
)
22-
23-
if (import.meta.client) {
24-
onMounted(() => {
25-
asyncData.refresh()
26-
})
27-
}
28-
29-
return asyncData
17+
return { likes, isStale }
18+
})
3019
}

app/pages/profile/[handle]/index.vue

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,11 @@ import { updateProfile as updateProfileUtil } from '~/utils/atproto/profile'
44
const route = useRoute('profile-handle')
55
const handle = computed(() => route.params.handle)
66
7-
const {
8-
data: profile,
9-
status: profileStatus,
10-
error: profileError,
11-
} = await useFetch<NPMXProfile>(() => `/api/social/profile/${handle.value}`, {
7+
const { data: profile } = await useFetch<NPMXProfile>(() => `/api/social/profile/${handle.value}`, {
128
default: () => ({ displayName: handle.value, description: '', website: '' }),
139
})
1410
15-
if (
16-
profileStatus.value === 'error' &&
17-
profileError.value?.statusCode &&
18-
profileError.value.statusCode >= 400 &&
19-
profileError.value.statusCode < 500
20-
) {
11+
if (!profile.value) {
2112
throw createError({
2213
statusCode: 404,
2314
statusMessage: $t('profile.not_found'),
@@ -77,7 +68,7 @@ async function updateProfile() {
7768
}
7869
}
7970
80-
const { data: likesData, status } = await useProfileLikes(handle)
71+
const { data: likesData, status } = useProfileLikes(handle)
8172
8273
useSeoMeta({
8374
title: () => $t('profile.seo_title', { handle: handle.value }),
@@ -178,8 +169,8 @@ defineOgImageComponent('Default', {
178169
{{ $t('profile.likes') }}
179170
<span v-if="likesData">({{ likesData.likes?.records?.length ?? 0 }})</span>
180171
</h2>
181-
<div v-if="status === 'pending'">
182-
<p>{{ $t('common.loading') }}</p>
172+
<div v-if="status === 'pending'" class="grid grid-cols-1 lg:grid-cols-2 gap-4">
173+
<SkeletonBlock v-for="i in 4" :key="i" class="h-16 rounded-lg" />
183174
</div>
184175
<div v-else-if="status === 'error'">
185176
<p>{{ $t('common.error') }}</p>

0 commit comments

Comments
 (0)