diff --git a/app/pages/leaderboard/likes.vue b/app/pages/leaderboard/likes.vue index 63208cfbce..60e309c294 100644 --- a/app/pages/leaderboard/likes.vue +++ b/app/pages/leaderboard/likes.vue @@ -12,34 +12,18 @@ useSeoMeta({ const compactNumberFormatter = useCompactNumberFormatter() -const { data: leaderboardEntries, status: leaderboardStatus } = useFetch( - '/api/leaderboard/likes', - { - default: () => [], - server: false, - }, -) - -const hasResolvedLeaderboardRequest = shallowRef(false) - -// Only show the skeleton for the first unresolved request. If this fetch runs -// again after content is already on screen, keep the current UI to avoid -// collapsing back to placeholders and causing layout shift. -watchEffect(() => { - if (leaderboardStatus.value === 'success' || leaderboardStatus.value === 'error') { - hasResolvedLeaderboardRequest.value = true - } +const { data: leaderboardEntries } = useFetch('/api/leaderboard/likes', { + default: () => [], }) -const isLoadingLeaderboard = computed( - () => - !hasResolvedLeaderboardRequest.value && - (leaderboardStatus.value === 'pending' || leaderboardStatus.value === 'idle'), -) - +const shouldAnimateEntries = ref(false) const highlightedEntries = computed(() => leaderboardEntries.value.slice(0, 3)) const remainingEntries = computed(() => leaderboardEntries.value.slice(3)) +onMounted(() => { + shouldAnimateEntries.value = true +}) + function getPreviewFallbackClass(rank: number): string { switch (rank) { case 1: @@ -79,6 +63,15 @@ function getPodiumItemClass(rank: number): string { } } +function getResponsivePodiumItemClass(rank: number): string { + switch (rank) { + case 1: + return 'md:col-span-2' + default: + return 'md:max-w-none' + } +} + function getPodiumCardClass(rank: number): string { switch (rank) { case 1: @@ -92,6 +85,12 @@ function formatCompactStat(value: number | null): string | null { if (value == null) return null return compactNumberFormatter.value.format(value) } + +function getEntryAnimationStyle(index: number): Record { + return { + animationDelay: `${Math.min(index * 100, 600)}ms`, + } +} + + diff --git a/nuxt.config.ts b/nuxt.config.ts index 13b4bbeb4a..17ac34033f 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -141,10 +141,10 @@ export default defineNuxtConfig({ '/oauth-client-metadata.json': { prerender: true }, '/.well-known/jwks.json': { prerender: true }, '/.well-known/site.standard.publication': { prerender: true }, + '/api/leaderboard/likes': { isr: 900 }, // never cache '/api/auth/**': { isr: false, cache: false }, '/api/social/**': { isr: false, cache: false }, - '/api/leaderboard/likes': { isr: false, cache: false }, '/api/atproto/bluesky-comments': { isr: { expiration: 60 * 60 /* one hour */,