From e61f909f313ea043b835c1e655300351d64d2450 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 16 Nov 2022 17:11:08 +0100 Subject: [PATCH] feat: common paginator component (#9) --- components/account/AccountPaginator.client.vue | 18 +++++++----------- components/common/CommonPaginator.vue | 17 +++++++++++++++++ .../NotificationPaginator.client.vue | 18 +++++++----------- .../timeline/TimelinePaginator.client.vue | 18 +++++++----------- composables/paginator.ts | 18 +++++++++--------- types/index.ts | 2 ++ 6 files changed, 49 insertions(+), 42 deletions(-) create mode 100644 components/common/CommonPaginator.vue diff --git a/components/account/AccountPaginator.client.vue b/components/account/AccountPaginator.client.vue index e82fc1ee..91d8b668 100644 --- a/components/account/AccountPaginator.client.vue +++ b/components/account/AccountPaginator.client.vue @@ -5,18 +5,14 @@ const { paginator } = defineProps<{ paginator: Paginator }>() -const { items: accounts, isLoading, isDone, endAnchor } = usePaginator(paginator) +const { items: accounts, state, endAnchor } = usePaginator(paginator) diff --git a/components/common/CommonPaginator.vue b/components/common/CommonPaginator.vue new file mode 100644 index 00000000..96127a8d --- /dev/null +++ b/components/common/CommonPaginator.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/notification/NotificationPaginator.client.vue b/components/notification/NotificationPaginator.client.vue index 8f7674ea..3dcce353 100644 --- a/components/notification/NotificationPaginator.client.vue +++ b/components/notification/NotificationPaginator.client.vue @@ -5,18 +5,14 @@ const { paginator } = defineProps<{ paginator: Paginator }>() -const { items: notifications, isLoading, isDone, endAnchor } = usePaginator(paginator) +const { items: notifications, state, endAnchor } = usePaginator(paginator) diff --git a/components/timeline/TimelinePaginator.client.vue b/components/timeline/TimelinePaginator.client.vue index 61fdaef4..dc50598f 100644 --- a/components/timeline/TimelinePaginator.client.vue +++ b/components/timeline/TimelinePaginator.client.vue @@ -5,18 +5,14 @@ const { paginator } = defineProps<{ paginator: Paginator }>() -const { items: statuses, isLoading, isDone, endAnchor } = usePaginator(paginator) +const { items: statuses, state, endAnchor } = usePaginator(paginator) diff --git a/composables/paginator.ts b/composables/paginator.ts index 82233b22..4c3055ed 100644 --- a/composables/paginator.ts +++ b/composables/paginator.ts @@ -1,8 +1,8 @@ import type { Paginator } from 'masto' +import type { PaginatorState } from '~/types' export function usePaginator(paginator: Paginator) { - let isLoading = $ref(false) - let isDone = $ref(false) + let state = $ref('ready' as PaginatorState) const items = $ref([]) const endAnchor = ref() @@ -10,16 +10,16 @@ export function usePaginator(paginator: Paginator) { const isInScreen = $computed(() => bound.top < window.innerHeight * 2) async function loadNext() { - if (isLoading || isDone) + if (state === 'loading' || state === 'done') return - isLoading = true + state = 'loading' const result = await paginator.next() - if (result.done) - isDone = true + state = result.done ? 'done' : 'ready' + if (result.value?.length) items.push(...result.value) - isLoading = false + await nextTick() bound.update() } @@ -31,11 +31,11 @@ export function usePaginator(paginator: Paginator) { watch( () => isInScreen, () => { - if (isInScreen && !isLoading) + if (isInScreen && state !== 'loading') loadNext() }, { immediate: true }, ) - return { items, isLoading, isDone, endAnchor } + return { items, state, endAnchor } } diff --git a/types/index.ts b/types/index.ts index 1a2dc8d2..61485d41 100644 --- a/types/index.ts +++ b/types/index.ts @@ -15,3 +15,5 @@ export interface UserLogin { token: string account?: AccountCredentials } + +export type PaginatorState = 'ready' | 'loading' | 'done'