From 8c88c4f1a77b7c9200e50d3289ce666c10f9accb Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Sun, 19 Oct 2025 09:30:51 +0200 Subject: [PATCH] feat: implement double-click zoom and click handling in PhotoswipeReader for improved user interaction --- src/components/reader/PhotoswipeReader.tsx | 40 ++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/components/reader/PhotoswipeReader.tsx b/src/components/reader/PhotoswipeReader.tsx index c6202e5..8f267d4 100644 --- a/src/components/reader/PhotoswipeReader.tsx +++ b/src/components/reader/PhotoswipeReader.tsx @@ -40,6 +40,8 @@ export function PhotoswipeReader({ book, pages, onClose, nextBook }: BookReaderP const touchStartYRef = useRef(null); const isPinchingRef = useRef(false); const currentPageRef = useRef(currentPage); + const lastClickTimeRef = useRef(0); + const clickTimeoutRef = useRef(null); // Garder currentPage à jour dans la ref pour le cleanup useEffect(() => { @@ -399,11 +401,43 @@ export function PhotoswipeReader({ book, pages, onClose, nextBook }: BookReaderP } }, [currentPage, imageBlobUrls, isDoublePage, shouldShowDoublePage, getPageUrl]); + const handleContainerClick = useCallback((e: React.MouseEvent) => { + // Vérifier si c'est un double-clic sur une image + const target = e.target as HTMLElement; + const now = Date.now(); + const timeSinceLastClick = now - lastClickTimeRef.current; + + if (target.tagName === 'IMG' && timeSinceLastClick < 300) { + // Double-clic sur une image + if (clickTimeoutRef.current) { + clearTimeout(clickTimeoutRef.current); + clickTimeoutRef.current = null; + } + e.stopPropagation(); + handleZoom(); + lastClickTimeRef.current = 0; + } else if (target.tagName === 'IMG') { + // Premier clic sur une image - attendre pour voir si c'est un double-clic + lastClickTimeRef.current = now; + if (clickTimeoutRef.current) { + clearTimeout(clickTimeoutRef.current); + } + clickTimeoutRef.current = setTimeout(() => { + setShowControls(prev => !prev); + clickTimeoutRef.current = null; + }, 300); + } else { + // Clic ailleurs - toggle les contrôles immédiatement + setShowControls(!showControls); + lastClickTimeRef.current = 0; + } + }, [showControls, handleZoom]); + return (
setShowControls(!showControls)} + onClick={handleContainerClick} >
{showEndMessage && ( @@ -471,7 +505,7 @@ export function PhotoswipeReader({ book, pages, onClose, nextBook }: BookReaderP src={imageBlobUrls[currentPage] || getPageUrl(currentPage)} alt={`Page ${currentPage}`} className={cn( - "max-h-full max-w-full object-contain transition-opacity", + "max-h-full max-w-full object-contain transition-opacity cursor-pointer", isLoading ? "opacity-0" : "opacity-100" )} loading="eager" @@ -510,7 +544,7 @@ export function PhotoswipeReader({ book, pages, onClose, nextBook }: BookReaderP src={imageBlobUrls[currentPage + 1] || getPageUrl(currentPage + 1)} alt={`Page ${currentPage + 1}`} className={cn( - "max-h-full max-w-full object-contain transition-opacity", + "max-h-full max-w-full object-contain transition-opacity cursor-pointer", secondPageLoading ? "opacity-0" : "opacity-100" )} loading="eager"