fix(mobile): full-screen media viewers + touch-pan for zoomed images (M3)
Mobile-audit batch 3. All changes mobile-gated (@media <=750px) so desktop is unchanged. - ModalWide: fill the phone screen (100vw/100vh, no radius) at <=750px instead of floating as an 85vw card. This also full-screens the file/PDF viewer and the avatar-crop editor on mobile (they share ModalWide) — intended. - UserHero avatar viewer: new mobile-only ModalMobileFull class (no desktop effect) so it goes edge-to-edge on phones like the timeline lightbox. - usePan: add touch support (single-finger drag, cleaned up on touchend/cancel/unmount) alongside the unchanged mouse path, so a zoomed image can be panned on a phone. Wired into ImageViewer and the MediaGallery lightbox. Two review passes: mouse path byte-for-byte unchanged; desktop provably unaffected; touch is gated to zoom!=1 so a non-zoomed image never hijacks swipe/scroll. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,7 @@ function LightboxMedia({
|
||||
pan,
|
||||
cursor,
|
||||
onMouseDown,
|
||||
onTouchStart,
|
||||
onImageDoubleClick,
|
||||
}: {
|
||||
item: LightboxItem;
|
||||
@@ -198,6 +199,7 @@ function LightboxMedia({
|
||||
pan: Pan;
|
||||
cursor: string;
|
||||
onMouseDown: React.MouseEventHandler<HTMLElement>;
|
||||
onTouchStart: React.TouchEventHandler<HTMLElement>;
|
||||
onImageDoubleClick: () => void;
|
||||
}) {
|
||||
const mx = useMatrixClient();
|
||||
@@ -253,6 +255,7 @@ function LightboxMedia({
|
||||
alt={item.body}
|
||||
draggable={false}
|
||||
onMouseDown={onMouseDown}
|
||||
onTouchStart={onTouchStart}
|
||||
onDoubleClick={onImageDoubleClick}
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
@@ -297,7 +300,7 @@ function Lightbox({
|
||||
const { zoom, zoomIn, zoomOut, setZoom } = useZoom(0.2);
|
||||
// Pan is only active for a zoomed-in image; usePan resets its offset when this
|
||||
// flips false (i.e. back to 1x, on navigation, or on a video).
|
||||
const { pan, cursor, onMouseDown } = usePan(isImage && zoom !== 1);
|
||||
const { pan, cursor, onMouseDown, onTouchStart } = usePan(isImage && zoom !== 1);
|
||||
const toggleZoom = useCallback(() => setZoom((z) => (z === 1 ? 2 : 1)), [setZoom]);
|
||||
|
||||
// Reset zoom when navigating to another item (and thus pan, via usePan).
|
||||
@@ -512,6 +515,7 @@ function Lightbox({
|
||||
pan={pan}
|
||||
cursor={cursor}
|
||||
onMouseDown={onMouseDown}
|
||||
onTouchStart={onTouchStart}
|
||||
onImageDoubleClick={toggleZoom}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user