Skip to content

Commit cbe145e

Browse files
committed
fix: fetch likes leaderboard from client only
This defers this very optional fetch to later and avoids caching degraded/failed responses.
1 parent ed7fd0e commit cbe145e

5 files changed

Lines changed: 37 additions & 11 deletions

File tree

app/components/Package/Likes.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ const likeAction = async () => {
115115
? {
116116
...previousLikesState,
117117
...result.data,
118-
topLikedRank: result.data.topLikedRank ?? previousLikesState.topLikedRank,
119118
}
120119
: previousLikesState
121120
} catch {

app/pages/leaderboard/likes.vue

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ useSeoMeta({
1212
1313
const compactNumberFormatter = useCompactNumberFormatter()
1414
15-
const { data: leaderboardEntries } = await useFetch<LikesLeaderboardEntry[]>(
15+
const { data: leaderboardEntries, status: leaderboardStatus } = useFetch<LikesLeaderboardEntry[]>(
1616
'/api/leaderboard/likes',
1717
{
1818
default: () => [],
19+
server: false,
1920
},
2021
)
22+
23+
const isLoadingLeaderboard = computed(
24+
() => leaderboardStatus.value === 'pending' || leaderboardStatus.value === 'idle',
25+
)
2126
</script>
2227

2328
<template>
@@ -36,7 +41,16 @@ const { data: leaderboardEntries } = await useFetch<LikesLeaderboardEntry[]>(
3641
</header>
3742

3843
<BaseCard
39-
v-if="leaderboardEntries.length === 0"
44+
v-if="isLoadingLeaderboard"
45+
class="cursor-default hover:(border-border bg-bg-subtle)"
46+
>
47+
<p class="text-fg-muted">
48+
{{ $t('common.loading') }}
49+
</p>
50+
</BaseCard>
51+
52+
<BaseCard
53+
v-else-if="leaderboardEntries.length === 0"
4054
class="cursor-default hover:(border-border bg-bg-subtle)"
4155
>
4256
<h2 class="font-mono text-lg mb-2">

nuxt.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ export default defineNuxtConfig({
143143
// never cache
144144
'/api/auth/**': { isr: false, cache: false },
145145
'/api/social/**': { isr: false, cache: false },
146+
'/api/leaderboard/likes': { isr: false, cache: false },
146147
'/api/atproto/bluesky-comments': {
147148
isr: {
148149
expiration: 60 * 60 /* one hour */,

test/nuxt/a11y.spec.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,11 @@ describe('component accessibility audits', () => {
730730
route: '/leaderboard/likes',
731731
})
732732

733-
expect(component.text()).toContain('Likes Leaderboard')
734-
expect(component.text()).toContain('vue')
733+
await vi.waitFor(() => {
734+
expect(component.text()).toContain('Likes Leaderboard')
735+
expect(component.text()).toContain('vue')
736+
})
737+
735738
const results = await runAxe(component)
736739
expect(results.violations).toEqual([])
737740
})
@@ -744,7 +747,10 @@ describe('component accessibility audits', () => {
744747
route: '/leaderboard/likes',
745748
})
746749

747-
expect(component.text()).toContain('No likes leaderboard yet')
750+
await vi.waitFor(() => {
751+
expect(component.text()).toContain('No likes leaderboard yet')
752+
})
753+
748754
const results = await runAxe(component)
749755
expect(results.violations).toEqual([])
750756
})

test/nuxt/pages/LikesLeaderboardPage.spec.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
1+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
22
import { mountSuspended, registerEndpoint } from '@nuxt/test-utils/runtime'
33
import type { VueWrapper } from '@vue/test-utils'
44
import LikesLeaderboardPage from '~/pages/leaderboard/likes.vue'
@@ -36,9 +36,12 @@ describe('likes leaderboard page', () => {
3636
route: '/leaderboard/likes',
3737
})
3838

39-
expect(wrapper.text()).toContain('Likes Leaderboard')
40-
expect(wrapper.text()).toContain('vue')
41-
expect(wrapper.text()).toContain('@nuxt/kit')
39+
await vi.waitFor(() => {
40+
expect(wrapper?.text()).toContain('Likes Leaderboard')
41+
expect(wrapper?.text()).toContain('vue')
42+
expect(wrapper?.text()).toContain('@nuxt/kit')
43+
})
44+
4245
expect(wrapper.text()).toContain('#1')
4346
expect(wrapper.find('a[href="/package/vue"]').exists()).toBe(true)
4447
})
@@ -50,7 +53,10 @@ describe('likes leaderboard page', () => {
5053
route: '/leaderboard/likes',
5154
})
5255

53-
expect(wrapper.text()).toContain('No likes leaderboard yet')
56+
await vi.waitFor(() => {
57+
expect(wrapper?.text()).toContain('No likes leaderboard yet')
58+
})
59+
5460
expect(wrapper.text()).toContain("We don't have a likes leaderboard to show right now.")
5561
})
5662
})

0 commit comments

Comments
 (0)