Add cursor-based pagination to the media lightbox (fix 12-photo ceiling) - #42
Open
TomProkop wants to merge 1 commit into
Open
Add cursor-based pagination to the media lightbox (fix 12-photo ceiling)#42TomProkop wants to merge 1 commit into
TomProkop wants to merge 1 commit into
Conversation
Fixes a hard ceiling on browsing past the grid's preview/fetch page:
the lightbox previously could only ever navigate within whichever
posts useMediaPosts() had already fetched (first page, capped at
MAX_LIMIT), so a trip archive with hundreds of photos would silently
wrap back to the start once you scrolled past that.
- api/media.ts: support ?before=<ISO capturedAt> cursor, filtered after
the existing full-partition sort; response shape changes from a bare
array to { posts, hasMore }.
- useMediaPosts.ts: unwrap the new response shape; external hook
signature (MediaPost[]) unchanged, so grid/map/day-stats consumers
need no changes.
- MediaLightbox.tsx: new opt-in enablePagination prop. When on,
goNext() fetches the next page on demand once the loaded set is
exhausted (appends, then advances) instead of wrapping, until the
backend reports hasMore: false. Counter omits "/ total" while more
could still be loaded. Off by default, so MediaMarkers.tsx's
intentionally-scoped cluster/nearby-radius lightboxes keep wrapping
within just their subset.
- PhotoStream.tsx / PhotoStreamTile.tsx: pass the full (unsliced)
posts list + enablePagination to the lightbox; grid/tile previews
keep their existing small caps (12 / 6).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
After PR #37 (server-side display resize + 12-post grid cap + capturedAt sort), the live photo grid and map-side photo tile both trapped lightbox navigation to only the posts they'd already loaded — 12 for the grid preview, or (before that) whatever
useMediaPosts()'s first API page happened to contain. With hundreds of trip photos, browsing "next" would silently wrap back to the start well before reaching the archive's end.Raising the fetch limit was rejected as a real fix since it just moves the ceiling (e.g. to 500) instead of removing it.
Fix: on-demand cursor pagination
api/src/functions/media.ts: new optional?before=<ISO capturedAt>query param. Filters the already-sorted (bycapturedAtdesc) result to strictly-older-than-before. Response shape changes from a bare array to{ posts, hasMore }— the only frontend caller of this endpoint (useMediaPosts.ts) is updated accordingly;mediaMine.ts/mediaDisplay.tsare separate endpoints, unaffected.src/hooks/useMediaPosts.ts: unwraps the new response shape internally; external return type (MediaPost[]) is unchanged, so the grid, map pins, and day-stats consumers of this hook need no changes.src/components/MediaLightbox.tsx: new opt-inenablePaginationprop (default off). When enabled,goNext()fetches the next page from/api/media?before=...once the currently-loaded posts are exhausted, appends, and advances — only wrapping to the start once the backend reportshasMore: false. The bottom counter shows just the position (no "/ total") while more could still be loaded, since the real total isn't known yet.src/components/PhotoStream.tsx/src/components/RouteMap/PhotoStreamTile.tsx: pass the full (unsliced)useMediaPosts()result +enablePaginationto the lightbox. Grid/tile previews keep their existing small caps (12 / 6) — only the lightbox's browsing scope changes.MediaMarkers.tsxis untouched — its cluster/nearby-radius lightbox opens are intentionally scoped subsets, not "browse the whole archive," so pagination doesn't apply there.Verification
npx tsc -b(frontend) — cleancd api && npm run build— cleannpx oxlinton changed files — no new warnings (one pre-existing exhaustive-deps warning, confirmed present onmainbefore this change too)