Skip to content

fix(detail): mount the zoom viewer when opened via the fullscreen (⛶) button#529

Closed
Zheaoli wants to merge 1 commit into
mainfrom
fix/zoom-lru-mount-gate
Closed

fix(detail): mount the zoom viewer when opened via the fullscreen (⛶) button#529
Zheaoli wants to merge 1 commit into
mainfrom
fix/zoom-lru-mount-gate

Conversation

@Zheaoli

@Zheaoli Zheaoli commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Symptom

Clicking the fullscreen (⛶) button on a photo opened a blank zoom area — "can't load zoom." Happens on every device; it is not a WebGL/GPU issue — the viewer simply was never mounted.

Root cause

The ⛶ button's onClick only set lightboxPhoto = true. It did not add the photo to the zoomed-viewer LRU, unlike the image-click path:

// image click (had the bump):
onShowLightboxChange = (value) => { setLightboxPhoto(value); if (value) bumpZoomLru(photo.id) }
// ⛶ button (missing the bump):
onClick = () => { setLightboxPhoto(true) }   // ← no bumpZoomLru

With the LRU mount-gate added earlier (keepViewerMounted={zoomLru.includes(photo.id)}progressive-image gates the viewer on hasOpenedFullScreen && keepViewerMounted !== false), a photo opened via ⛶ was never in the LRU, so keepViewerMounted was falsefalse !== false → the WebGL viewer <div> never rendered → blank. The two zoom-open paths were asymmetric; the mount-gate was added without updating the ⛶ path.

Fix (both, complementary)

  • A — the ⛶ button now also calls bumpZoomLru(current?.id), mirroring the image-click path. bumpZoomLru now ignores a falsy id defensively.
  • B — the mount-gate also keeps the currently-open photo mounted regardless of which path opened it:
    keepViewerMounted={zoomLru.includes(photo.id) || (isCurrent && lightboxPhoto)}.
    This root-fixes the whole class (any route that sets lightboxPhoto) and does not relax the LRU's ≤3 cap — the current photo should always be mounted; the rest stay LRU-bound.

tsc + eslint clean. The viewer-lifecycle / GL-context LRU behavior is otherwise unchanged. (Verification needs a real GPU browser — the fullscreen WebGL viewer can't be exercised headless; the fix is that the viewer <div> now mounts on the ⛶ path, which is environment-independent.)

The "View fullscreen" (⛶) button only set `lightboxPhoto = true`; it did not add
the photo to the zoomed-viewer LRU like the image-click path does. With the
LRU mount-gate (`keepViewerMounted={zoomLru.includes(photo.id)}`), a photo opened
via ⛶ was never in the LRU, so `keepViewerMounted` was false and the WebGL viewer
`<div>` never mounted — the fullscreen area came up blank ("can't load zoom"),
on every device (not a WebGL/GPU issue: the viewer simply wasn't rendered).

Two complementary fixes:
- The ⛶ button now also calls `bumpZoomLru(current?.id)`, mirroring the
  image-click path (`bumpZoomLru` ignores a falsy id defensively).
- The mount-gate also keeps the currently-open photo mounted regardless of path:
  `keepViewerMounted={zoomLru.includes(photo.id) || (isCurrent && lightboxPhoto)}`,
  so any route that sets `lightboxPhoto` mounts the viewer. This doesn't relax the
  LRU's ≤3 cap — the current photo should always be mounted; the rest stay
  LRU-bound.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
picimpact Ready Ready Preview, Comment Jun 11, 2026 8:44am

@Zheaoli

Zheaoli commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator Author

Duplicate of #528 (same A+B fix), which is already Review-approved. Closing in favor of #528.

@Zheaoli Zheaoli closed this Jun 11, 2026
@Zheaoli Zheaoli deleted the fix/zoom-lru-mount-gate branch June 11, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant