kopia lustrzana https://github.com/cloudflare/wildebeest
63 wiersze
1.9 KiB
TypeScript
63 wiersze
1.9 KiB
TypeScript
import { $, component$, useClientEffect$, useSignal, type QRL } from '@builder.io/qwik'
|
|
import { type MastodonStatus } from '~/types'
|
|
import Status from '../Status'
|
|
|
|
type Props = {
|
|
initialStatuses: MastodonStatus[]
|
|
fetchMoreStatuses: QRL<(numOfCurrentStatuses: number) => Promise<MastodonStatus[]>>
|
|
}
|
|
|
|
export const StatusesPanel = component$(({ initialStatuses, fetchMoreStatuses: fetchMoreStatusesFn }: Props) => {
|
|
const fetchingMoreStatuses = useSignal(false)
|
|
const noMoreStatusesAvailable = useSignal(false)
|
|
const lastStatusRef = useSignal<HTMLDivElement>()
|
|
const statuses = useSignal<MastodonStatus[]>(initialStatuses)
|
|
|
|
const fetchMoreStatuses = $(async () => {
|
|
if (fetchingMoreStatuses.value || noMoreStatusesAvailable.value) {
|
|
return
|
|
}
|
|
fetchingMoreStatuses.value = true
|
|
const newStatuses = await fetchMoreStatusesFn(statuses.value.length)
|
|
fetchingMoreStatuses.value = false
|
|
noMoreStatusesAvailable.value = newStatuses.length === 0
|
|
statuses.value = [...statuses.value, ...newStatuses]
|
|
})
|
|
|
|
useClientEffect$(({ track }) => {
|
|
track(() => lastStatusRef.value)
|
|
if (lastStatusRef.value) {
|
|
const observer = new IntersectionObserver(
|
|
async ([lastStatus]) => {
|
|
if (lastStatus.isIntersecting) {
|
|
await fetchMoreStatuses()
|
|
observer.disconnect()
|
|
}
|
|
},
|
|
{ rootMargin: '250px' }
|
|
)
|
|
observer.observe(lastStatusRef.value)
|
|
}
|
|
})
|
|
|
|
return (
|
|
<>
|
|
{statuses.value.length > 0 ? (
|
|
statuses.value.map((status, i) => {
|
|
const isLastStatus = i === statuses.value.length - 1
|
|
const divProps = isLastStatus ? { ref: lastStatusRef } : {}
|
|
return (
|
|
<div key={status.id} {...divProps}>
|
|
<Status status={status} accountSubText="username" showInfoTray={false} contentClickable={true} />
|
|
</div>
|
|
)
|
|
})
|
|
) : (
|
|
<div class="flex-1 grid place-items-center bg-wildebeest-600 text-center p-5 mt-8">
|
|
<p>Nothing to see right now. Check back later!</p>
|
|
</div>
|
|
)}
|
|
</>
|
|
)
|
|
})
|