Unified · Split
| @@ -45,17 +45,20 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ · 44 unmodified lines | |||
| 45 | preview, | 45 | preview, |
| 46 | onClose, | 46 | onClose, |
| 47 | }: ExpandedImageDialogProps) { | 47 | }: ExpandedImageDialogProps) { |
| 48 | const [activeIndex, setActiveIndex] = useState(preview.index); | 48 | const [navigationOffset, setNavigationOffset] = useState(0); |
| 49 | const imageCount = preview.images.length; | ||
| 50 | const activeIndex = | ||
| 51 | imageCount > 0 ? (preview.index + navigationOffset + imageCount) % imageCount : preview.index; | ||
| 49 | 52 | ||
| 50 | const navigateImage = useCallback((direction: -1 | 1) => { | 53 | const navigateImage = useCallback((direction: -1 | 1) => { |
| 51 | setActiveIndex((existingIndex) => { | 54 | setNavigationOffset((offset) => { |
| 52 | if (preview.images.length <= 1) return existingIndex; | 55 | if (imageCount <= 1) return offset; |
| 53 | return (existingIndex + direction + preview.images.length) % preview.images.length; | 56 | return offset + direction; |
| 54 | }); | 57 | }); |
| 55 | }, [preview.images.length]); | 58 | }, [imageCount]); |
| 56 | 59 | ||
| 57 | useExpandedImageDialogKeyboardShortcuts({ | 60 | useExpandedImageDialogKeyboardShortcuts({ |
| 58 | imageCount: preview.images.length, | 61 | imageCount, |
| 59 | onClose, | 62 | onClose, |
| 60 | onNavigate: navigateImage, | 63 | onNavigate: navigateImage, |
| 61 | }); | 64 | }); |
| @@ -76,7 +79,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ · 14 unmodified lines | |||
| 76 | aria-label="Close image preview" | 79 | aria-label="Close image preview" |
| 77 | onClick={onClose} | 80 | onClick={onClose} |
| 78 | /> | 81 | /> |
| 79 | {preview.images.length > 1 && ( | 82 | {imageCount > 1 && ( |
| 80 | <Button | 83 | <Button |
| 81 | type="button" | 84 | type="button" |
| 82 | size="icon" | 85 | size="icon" |
| @@ -107,10 +110,10 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ · 24 unmodified lines | |||
| 107 | /> | 110 | /> |
| 108 | <p className="mt-2 max-w-[92vw] truncate text-center text-xs text-muted-foreground/80"> | 111 | <p className="mt-2 max-w-[92vw] truncate text-center text-xs text-muted-foreground/80"> |
| 109 | {item.name} | 112 | {item.name} |
| 110 | {preview.images.length > 1 ? ` (${activeIndex + 1}/${preview.images.length})` : ""} | 113 | {imageCount > 1 ? ` (${activeIndex + 1}/${imageCount})` : ""} |
| 111 | </p> | 114 | </p> |
| 112 | </div> | 115 | </div> |
| 113 | {preview.images.length > 1 && ( | 116 | {imageCount > 1 && ( |
| 114 | <Button | 117 | <Button |
| 115 | type="button" | 118 | type="button" |
| 116 | size="icon" | 119 | size="icon" |