forked from Mirrors/elk
feat: timeline paginator
This commit is contained in:
parent
f3dd3fe8a5
commit
cf22ca25bf
5 changed files with 64 additions and 7 deletions
|
@ -13,7 +13,7 @@ const createdAt = $computed(() => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div flex flex-col>
|
<div flex flex-col>
|
||||||
<div>
|
<div border="b border">
|
||||||
<img h-50 w-full object-cover :src="account.header">
|
<img h-50 w-full object-cover :src="account.header">
|
||||||
</div>
|
</div>
|
||||||
<div p3 style="margin-top:-3.5rem;" flex flex-col gap-6>
|
<div p3 style="margin-top:-3.5rem;" flex flex-col gap-6>
|
||||||
|
|
57
components/timeline/TimelinePaginator.client.vue
Normal file
57
components/timeline/TimelinePaginator.client.vue
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Paginator, Status } from 'masto'
|
||||||
|
|
||||||
|
const { paginator } = defineProps<{
|
||||||
|
paginator: Paginator<any, Status[]>
|
||||||
|
}>()
|
||||||
|
|
||||||
|
let isLoading = $ref(false)
|
||||||
|
let isDone = $ref(false)
|
||||||
|
const statuses = $ref<Status[]>([])
|
||||||
|
|
||||||
|
const endAnchor = ref<HTMLDivElement>()
|
||||||
|
const bound = reactive(useElementBounding(endAnchor))
|
||||||
|
const isInScreen = $computed(() => bound.top < window.innerHeight * 2)
|
||||||
|
|
||||||
|
async function loadNext() {
|
||||||
|
if (isLoading || isDone)
|
||||||
|
return
|
||||||
|
|
||||||
|
// console.log('REQUEST')
|
||||||
|
isLoading = true
|
||||||
|
const result = await paginator.next()
|
||||||
|
if (result.done)
|
||||||
|
isDone = true
|
||||||
|
if (result.value?.length)
|
||||||
|
statuses.push(...result.value)
|
||||||
|
isLoading = false
|
||||||
|
await nextTick()
|
||||||
|
bound.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
useIntervalFn(() => {
|
||||||
|
bound.update()
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => isInScreen,
|
||||||
|
() => {
|
||||||
|
if (isInScreen && !isLoading)
|
||||||
|
loadNext()
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<template v-for="status of statuses" :key="status.id">
|
||||||
|
<StatusCard :status="status" border="t border" pt-4 />
|
||||||
|
</template>
|
||||||
|
<div ref="endAnchor" />
|
||||||
|
<div v-if="isLoading">
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
<div v-if="isDone">
|
||||||
|
End of list
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -7,12 +7,12 @@ const params = useRoute().params
|
||||||
const user = $computed(() => params.user as string)
|
const user = $computed(() => params.user as string)
|
||||||
const masto = await useMasto()
|
const masto = await useMasto()
|
||||||
const { data: account } = await useAsyncData(`${user}:info`, () => masto.accounts.lookup({ acct: user }))
|
const { data: account } = await useAsyncData(`${user}:info`, () => masto.accounts.lookup({ acct: user }))
|
||||||
const { data: status } = await useAsyncData(`${user}:status`, () => masto.accounts.fetchStatuses(account.value!.id!))
|
const paginator = masto.accounts.getStatusesIterable(account.value!.id!, {})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<AccountHeader :account="account" />
|
<AccountHeader :account="account" />
|
||||||
</div>
|
</div>
|
||||||
<TimelineList :timelines="status?.value" />
|
<TimelinePaginator :paginator="paginator" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -6,9 +6,9 @@ if (!token.value)
|
||||||
router.replace('/public')
|
router.replace('/public')
|
||||||
|
|
||||||
const masto = await useMasto()
|
const masto = await useMasto()
|
||||||
const { data: timelines } = await useAsyncData('timelines-home', () => masto.timelines.fetchHome().then(r => r.value))
|
const paginator = masto.timelines.getHomeIterable()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<TimelineList :timelines="timelines" />
|
<TimelinePaginator :paginator="paginator" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const masto = await useMasto()
|
const masto = await useMasto()
|
||||||
const { data: timelines } = await useAsyncData('timelines-public', () => masto.timelines.fetchPublic().then(r => r.value))
|
const paginator = masto.timelines.getPublicIterable()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<TimelineList :timelines="timelines" />
|
<TimelinePaginator :paginator="paginator" />
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in a new issue