Skip to content

fix(preview): step through the list the gallery is actually showing - #151

Open
lstein wants to merge 1 commit into
mainfrom
fix/preview-navigation-follows-gallery-order
Open

fix(preview): step through the list the gallery is actually showing#151
lstein wants to merge 1 commit into
mainfrom
fix/preview-navigation-follows-gallery-order

Conversation

@lstein

@lstein lstein commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Pressing next/prev in Preview while a similarity search is active walked the board listing in date order instead of the ranked results on screen, so the arrows jumped to images that were not in the result set at all. The filmstrip and the successor selected after a deletion read the same list, so they were wrong the same way.

Reproducible on main today without any new feature: run a text search with the sparkle button (or drop an image onto the search field), click a result, then press >.

Why

Preview rebuilds its list from selectedImageQuery — the record of which list this selection was made in: board, view, sort, page, search term. It had no field for a similarity search, so Preview could only ever reconstruct a board listing, while the grid was showing a ranked one.

The fix

Preview now reads the gallery's current search rather than a copy stamped onto the selection.

That distinction matters. Stamping was the obvious fix and it is wrong in both directions: the stamp keeps walking a ranked set after the chip is cleared, and it carries a ranked set onto selections made outside it — an upload, an image-map click, stepping off the live progress tile — where the cursor lands outside the list and both arrows go dead with no gesture short of clicking the grid to recover. The chip is a view mode: the grid shows ranked results while it is set and the board listing once it is cleared, so Preview follows it live and cannot go stale.

Under a ranked list Preview also stops doing three things the grid already does not do, each of which would otherwise reorder the list or add members that are not on screen:

  • re-sorting by date (relevance order is the list),
  • overlaying local generations (the grid overlays none into a ranked set),
  • splicing in the generating placeholder (a ranking has no chronological insertion point).

The one deliberate exception is the selected item itself, kept at the head when the ranking does not contain it, so the cursor always has somewhere to stand and one arrow press moves into the visible results.

A ranked list also mirrors the grid's paging rather than the stamped board context. A stamped page indexes the board listing; applied to a ranking it lands on an unrelated slice, or — past the end of a ranking shorter than the board — on an empty one. For the same reason a ranked window's page params are never written back into selectedImageQuery.page, which every other consumer reads as a board page.

Live-follow is suppressed while a search is active, matching the grid, which hides pending items there entirely.

Behaviour change

"Next" now means next most similar rather than next chronologically. That is the point — the arrows match the order the grid is showing. A reference that no longer resolves after a reload (dropped files, and image-map clusters once #149 lands, both live in an in-memory registry) reads as the board listing, the same fallback the gallery's own search chip already takes.

Scope

Frontend only. Based on main, so it covers the search kinds that exist there today (text, gallery image, web URL, dropped file). The image-map cluster kind in #149 inherits the fix automatically when that merges — a cluster is just another reference kind — so the two PRs need no coordination.

Testing

pnpm run lint (format, oxlint, typecheck, architecture check), the performance budget gate, 6,399 unit tests and 833 browser tests all pass. New coverage for the ranked merge: relevance order preserved, and a selection outside the ranking anchored rather than dropped.

Two rounds of fresh-context adversarial review were run against the diff; the first is what rejected the stamped design, and the second found the paginated-anchor and live-follow interactions fixed above. Every finding was verified against the code before acting on it.

Pressing next/prev in Preview while a similarity search was active walked
the board listing in chronological order instead of the ranked results on
screen, so the arrows jumped to images that were not in the result set at
all. The filmstrip and the successor picked after a deletion read the
same list, so they were wrong in the same way.

Preview rebuilds its list from `selectedImageQuery` — a record of the
board, view, sort, page and search term the selection was made in — which
had no notion of a similarity search, so it could only ever reconstruct a
board listing.

Rather than stamp the search into that record, Preview now reads the
gallery's CURRENT search directly. The chip is a view mode: the grid
shows ranked results while it is set and the board listing once it is
cleared, and Preview has to follow that the moment it changes. A stamped
copy would go stale in both directions — kept walking a ranked set after
the chip was cleared, and carried a ranked set onto selections made
outside it (an upload, an image-map click, stepping off the live tile),
where the cursor would land outside the list and both arrows would go
dead.

Under a ranked list Preview also stops re-sorting by date, stops
overlaying local generations, and stops splicing in the generating
placeholder — three things the grid already does not do for a ranked set,
each of which would otherwise reorder the list or add members the user
cannot see. The one exception is the selected item itself, which is kept
at the head when the ranking does not contain it, so the cursor always
has somewhere to stand and one arrow press moves into the visible list.

"Next" now means next most similar rather than next chronologically,
which is the point: the arrows match the grid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y3qLymWvCN3BcYpTAhLSR1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant