feat: avoid reordering pagination border effects (#877)
This commit is contained in:
parent
f8692ed480
commit
efe406df5b
|
@ -10,6 +10,7 @@ const {
|
|||
keyProp = 'id',
|
||||
virtualScroller = false,
|
||||
eventType = 'update',
|
||||
buffer = 10,
|
||||
preprocess,
|
||||
} = defineProps<{
|
||||
paginator: Paginator<T[], O>
|
||||
|
@ -17,6 +18,10 @@ const {
|
|||
virtualScroller?: boolean
|
||||
stream?: Promise<WsEvents>
|
||||
eventType?: 'notification' | 'update'
|
||||
// When preprocess is used, buffer is the number of items that will be hidden
|
||||
// until the next pagination to avoid border effect between pages when reordering
|
||||
// and grouping items
|
||||
buffer?: number
|
||||
preprocess?: (items: T[]) => any[]
|
||||
}>()
|
||||
|
||||
|
|
|
@ -13,12 +13,13 @@ const showHistory = (edit: mastodon.v1.StatusEdit) => {
|
|||
}
|
||||
const timeAgoOptions = useTimeAgoOptions()
|
||||
|
||||
// TODO: rework, this is only reversing the first page of edits
|
||||
const reverseHistory = (items: mastodon.v1.StatusEdit[]) =>
|
||||
[...items].reverse()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CommonPaginator :paginator="paginator" key-prop="createdAt" :preprocess="reverseHistory">
|
||||
<CommonPaginator :paginator="paginator" key-prop="createdAt" :preprocess="reverseHistory" :buffer="0">
|
||||
<template #default="{ items, item, index }">
|
||||
<CommonDropdownItem
|
||||
px="0.5"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
const paginator = useMasto().v1.timelines.listHome()
|
||||
const paginator = useMasto().v1.timelines.listHome({ limit: 30 })
|
||||
const stream = useMasto().v1.stream.streamUser()
|
||||
onBeforeUnmount(() => stream?.then(s => s.disconnect()))
|
||||
</script>
|
||||
|
|
|
@ -4,12 +4,13 @@ import { DynamicScrollerItem } from 'vue-virtual-scroller'
|
|||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
||||
import type { Paginator, WsEvents, mastodon } from 'masto'
|
||||
|
||||
const { paginator, stream, account } = defineProps<{
|
||||
const { paginator, stream, account, buffer = 10 } = defineProps<{
|
||||
paginator: Paginator<mastodon.v1.Status[], mastodon.v1.ListAccountStatusesParams>
|
||||
stream?: Promise<WsEvents>
|
||||
context?: mastodon.v2.FilterContext
|
||||
account?: mastodon.v1.Account
|
||||
preprocess?: (items: mastodon.v1.Status[]) => mastodon.v1.Status[]
|
||||
buffer?: number
|
||||
}>()
|
||||
|
||||
const { formatNumber } = useHumanReadableNumber()
|
||||
|
@ -21,7 +22,7 @@ const showOriginSite = $computed(() =>
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<CommonPaginator v-bind="{ paginator, stream, preprocess }" :virtual-scroller="virtualScroller">
|
||||
<CommonPaginator v-bind="{ paginator, stream, preprocess, buffer }" :virtual-scroller="virtualScroller">
|
||||
<template #updater="{ number, update }">
|
||||
<button py-4 border="b base" flex="~ col" p-3 w-full text-primary font-bold @click="update">
|
||||
{{ $t('timeline.show_new_items', number, { named: { v: formatNumber(number) } }) }}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
const paginator = useMasto().v1.timelines.listPublic()
|
||||
const paginator = useMasto().v1.timelines.listPublic({ limit: 30 })
|
||||
const stream = useMasto().v1.stream.streamPublicTimeline()
|
||||
onBeforeUnmount(() => stream.then(s => s.disconnect()))
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
const paginator = useMasto().v1.timelines.listPublic({ local: true })
|
||||
const paginator = useMasto().v1.timelines.listPublic({ limit: 30, local: true })
|
||||
const stream = useMasto().v1.stream.streamCommunityTimeline()
|
||||
onBeforeUnmount(() => stream.then(s => s.disconnect()))
|
||||
</script>
|
||||
|
|
|
@ -6,6 +6,7 @@ export function usePaginator<T, P>(
|
|||
stream?: Promise<WsEvents>,
|
||||
eventType: 'notification' | 'update' = 'update',
|
||||
preprocess: (items: T[]) => T[] = (items: T[]) => items,
|
||||
buffer = 10,
|
||||
) {
|
||||
const state = ref<PaginatorState>(isMastoInitialised.value ? 'idle' : 'loading')
|
||||
const items = ref<T[]>([])
|
||||
|
@ -62,8 +63,10 @@ export function usePaginator<T, P>(
|
|||
const result = await paginator.next()
|
||||
|
||||
if (result.value?.length) {
|
||||
nextItems.value = preprocess(result.value) as any
|
||||
items.value.push(...nextItems.value)
|
||||
const preprocessedItems = preprocess([...nextItems.value, ...result.value]) as any
|
||||
const itemsToShowCount = preprocessedItems.length - buffer
|
||||
nextItems.value = preprocessedItems.slice(itemsToShowCount)
|
||||
items.value.push(...preprocessedItems.slice(0, itemsToShowCount))
|
||||
state.value = 'idle'
|
||||
}
|
||||
else {
|
||||
|
@ -108,7 +111,6 @@ export function usePaginator<T, P>(
|
|||
return {
|
||||
items,
|
||||
prevItems,
|
||||
nextItems,
|
||||
update,
|
||||
state,
|
||||
error,
|
||||
|
|
|
@ -8,7 +8,7 @@ const { t } = useI18n()
|
|||
|
||||
const account = await fetchAccountByHandle(handle)
|
||||
|
||||
const paginator = useMasto().v1.accounts.listStatuses(account.id, { excludeReplies: true })
|
||||
const paginator = useMasto().v1.accounts.listStatuses(account.id, { limit: 30, excludeReplies: true })
|
||||
|
||||
if (account) {
|
||||
useHeadFixed({
|
||||
|
|
Loading…
Reference in a new issue