Appearance
useGalleryPreviewPager Composable ​
File Information ​
- Path:
app/composables/core/components/dialogs/useGalleryPreviewPager.ts - Purpose: Loads gallery pages on demand, from the front (head) and from the end (tail)
- Type: Core Composable
- Added: PR #137 (RIV-1266), 2026-10-28
Overview ​
useGalleryPreviewPager(options: GalleryPagerOptions) takes the assets the page already has and a GalleryPagination contract, and exposes one merged list plus the flags navigation needs. It keeps two fetched lists so the gallery can wrap from the first asset to the last one without loading every page in between:
- head:
baseAssets+ pagesloadedPages,loadedPages + 1, ... (nextPageis the next page to fetch) - tail: the last page, then the page before it, ... (
tailFirstPageis the lowest tail page loaded)
All lists are merged by String(id); an id seen earlier wins, so overlapping pages never duplicate an asset.
Features ​
State and derived flags ​
| Name | Rule |
|---|---|
items | head items, then tail items, de-duplicated |
hasTail | tail has items |
merged | tailFirstPage !== null && nextPage >= tailFirstPage (head reached the tail) |
hasGap | hasTail && !merged |
headLength | head length while there is a gap, else items.length |
canLoadForward | pagination set, head not exhausted, nextPage <= tailFirstPage - 1 (or <= lastPage without a tail) |
canLoadBackward | pagination set and tailFirstPage - 1 >= nextPage |
canLoadLast | pagination set, no tail yet, lastPage finite and >= nextPage |
total | items.length once nothing can load; otherwise max(items.length, serverTotal) |
canAutoLoad | false after a failed load, until the next load starts |
Loading ​
loadNext()fetchesnextPage; if the page adds no new asset it keeps fetching whilecanLoadForward. The head is exhausted whennextPage > lastPage, or, with an unknown last page, when a page comes back empty.loadLast()fetcheslastPageinto the tail; if that adds nothing it walks backwards.loadPrevious()fetchestailFirstPage - 1, repeating while nothing new is added.- Each response may update
lastPageandserverTotal. - Only one load runs at a time (
loading). Each load gets a token; a response whose token is no longer current (dialog closed or reset) is dropped. - On error:
paused = trueandsnackbar.showError(getErrorMessage(error)).
Reset ​
On open, and whenever pagination changes while open: fetched lists are cleared, nextPage = max(loadedPages, 1), lastPage = pagination.lastPage, else ceil(total / pageSize), else infinity; serverTotal = pagination.total. Closing invalidates in-flight requests. Without pagination the pager only exposes baseAssets.
Note that nextPage starts at loadedPages (the page the grid already loaded), so the first forward fetch re-requests that page; de-duplication drops the repeated rows.
Return Type ​
items, headLength, hasGap, hasTail, total, canLoadForward, canLoadBackward, canLoadLast, canAutoLoad, loading (readonly), loadNext, loadLast, loadPrevious.
Parameters ​
GalleryPagerOptions: baseAssets: () => any[], pagination: () => GalleryPagination | null | undefined, open: () => boolean.
Usage Example ​
typescript
const pager = useGalleryPreviewPager({
baseAssets: () => props.assets,
pagination: () => props.pagination,
open: () => modalDialog.value,
});