2024-07-15 14:28:08 +00:00
|
|
|
import { JSX, Show, createSignal, onMount } from 'solid-js'
|
|
|
|
import { Button } from '~/components/_shared/Button'
|
|
|
|
import { useLocalize } from '~/context/localize'
|
|
|
|
import { Author, Reaction, Shout } from '~/graphql/schema/core.gen'
|
|
|
|
import { restoreScrollPosition, saveScrollPosition } from '~/utils/scroll'
|
|
|
|
|
2024-07-15 20:35:33 +00:00
|
|
|
export type LoadMoreItems = Shout[] | Author[] | Reaction[]
|
|
|
|
|
2024-07-15 14:28:08 +00:00
|
|
|
type LoadMoreProps = {
|
2024-07-15 20:35:33 +00:00
|
|
|
loadFunction: (offset?: number) => Promise<LoadMoreItems>
|
2024-07-15 14:28:08 +00:00
|
|
|
pageSize: number
|
2024-07-16 00:14:08 +00:00
|
|
|
hidden?: boolean
|
2024-07-15 14:28:08 +00:00
|
|
|
children: JSX.Element
|
|
|
|
}
|
|
|
|
|
|
|
|
export const LoadMoreWrapper = (props: LoadMoreProps) => {
|
|
|
|
const { t } = useLocalize()
|
2024-07-15 20:35:33 +00:00
|
|
|
const [items, setItems] = createSignal<LoadMoreItems>([])
|
2024-07-15 14:28:08 +00:00
|
|
|
const [offset, setOffset] = createSignal(0)
|
|
|
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(true)
|
|
|
|
const [isLoading, setIsLoading] = createSignal(false)
|
|
|
|
|
|
|
|
const loadItems = async () => {
|
|
|
|
setIsLoading(true)
|
|
|
|
saveScrollPosition()
|
|
|
|
const newItems = await props.loadFunction(offset())
|
|
|
|
if (!Array.isArray(newItems)) return
|
2024-07-15 16:51:52 +00:00
|
|
|
console.debug('[_share] load more items', newItems)
|
2024-07-15 20:35:33 +00:00
|
|
|
setItems((prev) => [...prev, ...newItems] as LoadMoreItems)
|
2024-07-15 14:28:08 +00:00
|
|
|
setOffset((prev) => prev + props.pageSize)
|
2024-07-15 16:51:52 +00:00
|
|
|
setIsLoadMoreButtonVisible(newItems.length >= props.pageSize - 1)
|
2024-07-15 14:28:08 +00:00
|
|
|
setIsLoading(false)
|
|
|
|
restoreScrollPosition()
|
|
|
|
}
|
|
|
|
|
|
|
|
onMount(loadItems)
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{props.children}
|
2024-07-16 00:14:08 +00:00
|
|
|
<Show when={isLoadMoreButtonVisible() && !props.hidden}>
|
2024-07-15 14:28:08 +00:00
|
|
|
<div class="load-more-container">
|
|
|
|
<Button
|
|
|
|
onClick={loadItems}
|
|
|
|
disabled={isLoading()}
|
|
|
|
value={t('Load more')}
|
|
|
|
title={`${items().length} ${t('loaded')}`}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</Show>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|