Skip to content

Fullscreen poster viewer: pan, zoom clamp, save feedback & error state #21

Description

@NickReisenauer

Spotted during a UI review of the recent media-view changes (commit bb4714f). All in simalytics/Components/FullscreenPosterView.swift.

The fullscreen poster viewer has several UX/correctness gaps:

  • Can't pan while zoomed. scaleEffect scales about center with no offset/DragGesture, so zooming only magnifies the dead center — the edges (credits/artwork) can't be reached, which defeats the point of zooming. Add @State offset/lastOffset, apply .offset(offset), and a DragGesture (via .simultaneousGesture so it composes with the magnify gesture); reset offset when scale returns to 1. Ideally clamp to the scaled image bounds.
  • No maximum zoom. onChanged does scale = lastScale * value with no upper bound and onEnded only clamps the lower bound — you can pinch to arbitrary blur and it stays there. Add a maxScale (~4–5) and clamp on end (respecting reduceMotion like the existing lower-bound branch).
  • "Saved to Photos" is reported before the write finishes. UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) has no completion handler, yet the success alert fires immediately — so it reports success even on failure. Switch to PHPhotoLibrary.shared().performChanges { PHAssetChangeRequest.creationRequestForAsset(from: image) } with a real completion handler and set the alert from the actual result on the MainActor.
  • Blank black screen on load failure. On failure loadImage sets image = nil, isLoading = false, so the body renders neither the spinner nor the image — just Color.black + a lone X button. Add a failure state (icon + "Couldn't load poster", optional Retry).
  • MagnificationGesture is deprecated on the iOS 17 minimum target → migrate to MagnifyGesture (read value.magnification). No availability gate needed; also exposes the pinch anchor for anchored zoom.

Source: multi-agent UI review, 2026-07-02.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions