diff --git a/frontend/src/components/gallery/PhotoLightbox.tsx b/frontend/src/components/gallery/PhotoLightbox.tsx index 77735202..4276af9c 100644 --- a/frontend/src/components/gallery/PhotoLightbox.tsx +++ b/frontend/src/components/gallery/PhotoLightbox.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useRef } from 'react'; import { useDevToolsProtection } from '../../hooks/useDevToolsProtection'; -import { X, ChevronLeft, ChevronRight, Download, ZoomIn, ZoomOut, MessageSquare, Heart, Star } from 'lucide-react'; +import { X, ChevronLeft, ChevronRight, Download, ZoomIn, ZoomOut, Minimize2, MessageSquare, Heart, Star } from 'lucide-react'; import type { Photo } from '../../types'; import { useSavePhotoToDevice } from '../../hooks/useGallery'; import { AuthenticatedImage } from '../common'; @@ -407,6 +407,14 @@ export const PhotoLightbox: React.FC = ({ setIsDragging(false); }; + // Double-click returns a zoomed image to fit-to-screen (#886). At zoom 1 + // it does nothing. + const handleDoubleClick = () => { + if (zoom > 1) { + resetZoom(); + } + }; + // Touch event handlers: pinch-to-zoom (2 fingers) + single-finger // carousel-style swipe nav. Swipe is suppressed while zoomed in so the // user can pan instead. The carousel is also disabled mid-animation. @@ -696,7 +704,18 @@ export const PhotoLightbox: React.FC = ({ > - + {/* One-click return from zoomed to fit-to-screen (#886). + Double-clicking the image does the same. */} + +
{photoAllowsDownload && ( @@ -907,6 +926,7 @@ export const PhotoLightbox: React.FC = ({