Skip to content

Open element photos full screen with pinch-to-zoom - #64

Merged
dfalling merged 1 commit into
mainfrom
allow-photo-zoominga
Jul 27, 2026
Merged

Open element photos full screen with pinch-to-zoom#64
dfalling merged 1 commit into
mainfrom
allow-photo-zoominga

Conversation

@dfalling

Copy link
Copy Markdown
Owner

Summary

Photos on the element detail screen were only ever visible as 200×140 thumbnails. They're now tappable and open a full-screen viewer:

  • Pinch to zoom (1×–4×), anchored on the fingers so the photo doesn't drift while zooming
  • Drag to pan while zoomed, clamped to the photo's edges
  • Double tap to toggle 2.5×, centered on the tapped point
  • Swipe the photo away in any direction to close — it tracks the finger and fades, with a fling threshold so a quick flick counts
  • × button at the top-left, plus hardware back

Notes

  • Gestures are hand-rolled on PanResponder + Animated rather than adding react-native-gesture-handler + react-native-reanimated. ScrollView's pinch-zoom props are iOS-only, so there was no built-in path, and two native modules for one screen's zoom seemed like the worse trade. The transform geometry lives in src/photos/photoZoom.ts as pure functions (same split as placeZoom.ts) with 12 tests; the component only translates touches into it. If the dependency is preferred later, the component is the only thing that changes.
  • The viewer is an absolute overlay, not a Modal, for the reason already documented in Sheet.tsx: Modal gets its own window and doesn't reliably draw under Android 15's system bars, so a "full-screen" viewer would stop short of them.
  • It renders photo.regular — the same URL as the thumbnail — so opening it fetches nothing new. Photo also has a full field that would look sharper at 3–4×, but wiring it up needs a codegen run against the uncommitted schema plus the Apollo v4 fixups; left for a follow-up.
  • Black in both themes rather than themed, on the grounds that a photo viewer should let the image set the mood. Commented in the file.

Testing

bunx tsc --noEmit, bun run lint, and bun run test all pass.

Not run on a device — no emulator or handset was attached — so the gesture feel (spring stiffness, dismiss threshold, double-tap window) is untested in the hand and may want tuning.

The detail screen's photo strip was the only place a photo could be seen,
and at 200x140 that's too small to make out anything in it. Tapping a
thumbnail now opens it full screen where it can be zoomed and panned.

Gestures are hand-rolled on PanResponder + Animated. ScrollView's
pinch-zoom props are iOS-only so there was no built-in path, and pulling
in gesture-handler + reanimated — two native modules — for one screen's
zoom is a worse trade than ~150 lines of touch handling. The transform
geometry is split into photoZoom.ts so it can be tested without a
renderer, leaving the component to only translate touches into it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dfalling
dfalling merged commit 3719715 into main Jul 27, 2026
2 checks passed
@dfalling
dfalling deleted the allow-photo-zoominga branch July 27, 2026 13:11
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