Skip to content

Commit

Permalink
feat: stop fetching world records seperately and pagination tweaks (#296
Browse files Browse the repository at this point in the history
)

* feat: stop fetching world records seperately and pagination tweaks

* chore: show indicator on record pages too
  • Loading branch information
wopian authored May 25, 2023
1 parent a586681 commit b204729
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 86 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@unhead/vue": "1.1.27",
"@vueuse/components": "10.1.2",
"@vueuse/schema-org": "2.1.3",
"@zeepkist/gtr-api": "3.5.0",
"@zeepkist/gtr-api": "3.6.0",
"date-fns": "2.30.0",
"date-fns-tz": "2.0.0",
"ky": "0.33.3",
Expand Down
86 changes: 29 additions & 57 deletions src/components/LevelRow.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,19 @@
<script setup lang="ts">
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { getRecords, type Level } from '@zeepkist/gtr-api'
import { addDays } from 'date-fns'
import { useQueryClient } from '@tanstack/vue-query'
import { type Level } from '@zeepkist/gtr-api'
import IconMedalAuthor from '~/assets/medal-author.webp?inline'
import IconTrophy from '~/assets/trophy.webp?inline'
import UserBadge from '~/components/UserBadge.vue'
import { formatResultTime } from '~/utils'
import LoadingIndicator from './LoadingIndicator.vue'
const { level } = defineProps<{
level: Level
recordsCount?: number
}>()
const queryClient = useQueryClient()
const { data: worldRecord, isLoading } = useQuery({
queryKey: ['worldRecord', level.id],
queryFn: async () => {
const { records } = await getRecords({
LevelId: level.id,
Limit: 1,
WorldRecordOnly: true
})
return records.length > 0
? {
time: records[0].time,
date: records[0].dateCreated,
user: records[0].user
}
: // eslint-disable-next-line unicorn/no-null
null
},
enabled: !!level.id,
staleTime: addDays(0, 1).getTime(),
cacheTime: addDays(0, 1).getTime()
})
queryClient.setQueryData(['level', level.id], level)
</script>

Expand All @@ -54,36 +29,33 @@
<div :class="$style.content">
<p :class="$style.levelName">{{ level.name }}</p>
<p :class="$style.levelAuthor">By {{ level.author }}</p>
<p v-if="isLoading"><loading-indicator :class="$style.loading" /></p>
<template v-else>
<div v-if="worldRecord" :class="$style.worldRecord">
<img :src="IconTrophy" alt="" />
<router-link
:to="{
name: 'user',
params: { steamId: worldRecord.user.steamId }
}">
<user-badge
:username="worldRecord.user.steamName"
:class="$style.worldRecordAuthor" />
<div>{{ formatResultTime(worldRecord.time) }}</div>
</router-link>
<p
v-if="recordsCount"
:class="$style.recordsCount"
:title="`${recordsCount} total unique play sessions`">
{{ recordsCount }} plays
</p>
<p v-else :class="$style.recordsCount">{{ level.points ?? 0 }} ➤</p>
</div>
<div v-else :class="$style.worldRecord">
<p>
<img :src="IconMedalAuthor" alt="" />
{{ formatResultTime(level.timeAuthor) }}
</p>
<p :class="$style.recordsCount">No times</p>
</div>
</template>
<div v-if="level.worldRecord" :class="$style.worldRecord">
<img :src="IconTrophy" alt="" />
<router-link
:to="{
name: 'user',
params: { steamId: level.worldRecord.user.steamId }
}">
<user-badge
:username="level.worldRecord.user.steamName"
:class="$style.worldRecordAuthor" />
<div>{{ formatResultTime(level.worldRecord.time) }}</div>
</router-link>
<p
v-if="recordsCount"
:class="$style.recordsCount"
:title="`${recordsCount} total unique play sessions`">
{{ recordsCount }} plays
</p>
<p v-else :class="$style.recordsCount">{{ level.points ?? 0 }} ➤</p>
</div>
<div v-else :class="$style.worldRecord">
<p>
<img :src="IconMedalAuthor" alt="" />
{{ formatResultTime(level.timeAuthor) }}
</p>
<p :class="$style.recordsCount">No times</p>
</div>
</div>
</router-link>
</template>
Expand Down
17 changes: 16 additions & 1 deletion src/components/LoadingIndicator.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<script setup lang="ts">
const { inline = false } = defineProps<{
inline?: boolean
}>()
</script>

<template>
<div :class="$style.ellipsis">
<div :class="[$style.ellipsis, { [$style.inline]: inline }]">
<div></div>
<div></div>
<div></div>
Expand All @@ -25,6 +31,15 @@
animation-timing-function: cubic-bezier(0, 1, 1, 0);
}
&.inline {
height: unset;
top: 0.6rem;
div {
top: 0;
}
}
div:nth-child(1) {
left: 8px;
animation: lds-ellipsis1 0.6s infinite;
Expand Down
17 changes: 12 additions & 5 deletions src/components/PaginatedComponent.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
<script setup lang="ts">
import { ref } from 'vue'
import LoadingIndicator from '~/components/LoadingIndicator.vue'
const {
totalItems,
currentPage = 1,
itemsPerPage = 10
itemsPerPage = 10,
disabledPagination = false,
isLoading = false
} = defineProps<{
currentPage?: number
totalItems: number
itemsPerPage?: number
disabledPagination?: boolean
isLoading?: boolean
}>()
const totalPages = ref(Math.ceil(totalItems / itemsPerPage))
Expand All @@ -23,26 +29,27 @@
<div v-if="totalItems > itemsPerPage" class="pagination">
<span>Page {{ currentPage }} of {{ totalPages }}</span>
<div class="pagination-actions">
<loading-indicator v-if="isLoading" inline />
<button
:disabled="currentPage == 1"
:disabled="disabledPagination || currentPage == 1"
title="First"
@click="emit('page-changed', 1)">
</button>
<button
:disabled="currentPage === 1"
:disabled="disabledPagination || currentPage === 1"
title="Previous"
@click="emit('page-changed', currentPage - 1)">
</button>
<button
:disabled="currentPage === totalPages"
:disabled="disabledPagination || currentPage === totalPages"
title="Next"
@click="emit('page-changed', currentPage + 1)">
</button>
<button
:disabled="currentPage === totalPages"
:disabled="disabledPagination || currentPage === totalPages"
title="Last"
@click="emit('page-changed', totalPages)">
Expand Down
9 changes: 6 additions & 3 deletions src/components/layouts/DashboardLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
const levelsPerPage = 18
const levelsPage = ref(1)
const { data: levels, isPreviousData: isPreviousLevelsData } = useQuery({
queryKey: ['levels', levelsPage],
queryKey: ['recentLevels', levelsPage],
queryFn: async () =>
await getLevels({
Limit: levelsPerPage,
Expand Down Expand Up @@ -145,6 +145,7 @@
:current-page="worldRecordsPage"
:items-per-page="limit"
:total-items="worldRecords.totalAmount"
:is-loading="isPreviousWorldRecordsData"
@page-changed="page => handlePageChanged('worldRecord', page)">
<record-list
header="World Records"
Expand All @@ -160,6 +161,7 @@
:current-page="recentRecordsPage"
:items-per-page="limit"
:total-items="recentRecords.totalAmount"
:is-loading="isPreviousRecentRecordsData"
@page-changed="page => handlePageChanged('recent', page)">
<record-list
header="Recent Times"
Expand Down Expand Up @@ -194,12 +196,13 @@
</paginated-component>
</content-sheet>

<content-sheet>
<content-sheet v-if="levels">
<paginated-component
v-if="levels"
:current-page="levelsPage"
:items-per-page="levelsPerPage"
:total-items="levels.totalAmount"
:disabled-pagination="isPreviousLevelsData"
:is-loading="isPreviousLevelsData"
@page-changed="page => handlePageChanged('level', page)">
<level-list header="New Levels" :levels="levels.levels" />
</paginated-component>
Expand Down
22 changes: 14 additions & 8 deletions src/components/layouts/LevelsLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
const currentPage = ref(1)
const sort = ref<Sort>(workshopId ? 'name' : '-id')
const { data } = useQuery({
const { data, isPreviousData } = useQuery({
queryKey: ['levels', currentPage, workshopId, sort],
queryFn: async () => {
const levels = await getLevels({
Expand All @@ -35,13 +35,17 @@
currentPage.value,
workshopId,
sort
]) as LevelsResponse,
keepPreviousData: false
]) as LevelsResponse
})
const handlePageChanged = async (page: number) => {
currentPage.value = page
}
const handleSortChanged = (newSort: Sort) => {
currentPage.value = 1
sort.value = newSort
}
</script>

<template>
Expand All @@ -51,27 +55,27 @@
<div :class="$style.filter">
<button
:class="{ [$style.selected]: sort === 'name' }"
@click="sort = 'name'">
@click="handleSortChanged('name')">
A-Z
</button>
<button
:class="{ [$style.selected]: sort === '-name' }"
@click="sort = '-name'">
@click="handleSortChanged('-name')">
Z-A
</button>
<button
:class="{ [$style.selected]: sort === '-id' }"
@click="sort = '-id'">
@click="handleSortChanged('-id')">
Newest First
</button>
<button
:class="{ [$style.selected]: sort === 'id' }"
@click="sort = 'id'">
@click="handleSortChanged('id')">
Oldest First
</button>
<button
:class="{ [$style.selected]: sort === 'rank' }"
@click="sort = 'rank'">
@click="handleSortChanged('rank')">
Popularity
</button>
</div>
Expand All @@ -80,6 +84,8 @@
:current-page="currentPage"
:items-per-page="itemsPerPage"
:total-items="data.totalAmount"
:disabled-pagination="isPreviousData"
:is-loading="isPreviousData"
@page-changed="handlePageChanged">
<level-list :levels="data.levels" />
</paginated-component>
Expand Down
9 changes: 3 additions & 6 deletions src/components/layouts/UserLayout.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { getRecords, getUserRanking, type User } from '@zeepkist/gtr-api'
import { getRecords, type User } from '@zeepkist/gtr-api'
import { ref } from 'vue'
import ColumnLayout from '~/components/ColumnLayout.vue'
Expand Down Expand Up @@ -95,7 +95,6 @@
const worldRecords = ref(await getPaginatedRecords('worldRecord'))
const recentRecords = ref(await getPaginatedRecords('recent'))
const invalidRecords = ref(await getPaginatedRecords('invalid'))
const userRanking = ref(await getUserRanking(user.id))
const pages = ref({
best: 1,
Expand All @@ -115,10 +114,8 @@
{{ invalidRecords.totalAmount }} any% attempts.
</p>
<p>
They are ranked {{ formatOrdinal(userRanking.position) }} with
<span :title="`${userRanking.score} points`">
{{ userRanking.score }} ➤
</span>
They are ranked {{ formatOrdinal(user.position) }} with
<span :title="`${user.score} points`"> {{ user.score }} ➤ </span>
and hold {{ worldRecords.totalAmount }} world records
</p>
<column-layout>
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1627,16 +1627,16 @@ __metadata:
languageName: node
linkType: hard

"@zeepkist/gtr-api@npm:3.5.0":
version: 3.5.0
resolution: "@zeepkist/gtr-api@npm:3.5.0"
"@zeepkist/gtr-api@npm:3.6.0":
version: 3.6.0
resolution: "@zeepkist/gtr-api@npm:3.6.0"
dependencies:
ky: ~0.33.2
ky-universal: ~0.11.0
dependenciesMeta:
esbuild:
built: true
checksum: 7c521981f4c9f62bd64518439e421beaf941dbbad81b5dfda24bafde1005e725484b6f21729ffb67aa48f6715ecce22c9e8530ee9b9f72975963f5da6ffde622
checksum: d9e0bd56ba97389aa70a5ed8eab489283c2d1488e4f85c761422c432308a3f2158385e9ab64c1b201a374d51af4300c7937ee21820a14b12f3551f502075c333
languageName: node
linkType: hard

Expand Down Expand Up @@ -9397,7 +9397,7 @@ __metadata:
"@vue/tsconfig": 0.4.0
"@vueuse/components": 10.1.2
"@vueuse/schema-org": 2.1.3
"@zeepkist/gtr-api": 3.5.0
"@zeepkist/gtr-api": 3.6.0
cypress: 12.13.0
date-fns: 2.30.0
date-fns-tz: 2.0.0
Expand Down

0 comments on commit b204729

Please sign in to comment.