MCPcopy
hub / github.com/usememos/memos / PreviewImageDialog

Function PreviewImageDialog

web/src/components/PreviewImageDialog.tsx:26–280  ·  view source on GitHub ↗
({ open, onOpenChange, imgUrls = [], items, initialIndex = 0 }: Props)

Source from the content-addressed store, hash-verified

24const clampZoom = (scale: number) => Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, scale));
25
26function PreviewImageDialog({ open, onOpenChange, imgUrls = [], items, initialIndex = 0 }: Props) {
27 const sm = useMediaQuery("sm");
28 const [currentIndex, setCurrentIndex] = useState(initialIndex);
29 const [zoomScale, setZoomScale] = useState(MIN_ZOOM);
30 const previewItems = useMemo(
31 () => items ?? imgUrls.map((url) => ({ id: url, kind: "image" as const, sourceUrl: url, posterUrl: url, filename: "Image" })),
32 [imgUrls, items],
33 );
34
35 useEffect(() => {
36 if (open) {
37 setCurrentIndex(initialIndex);
38 }
39 }, [initialIndex, open]);
40
41 const itemCount = previewItems.length;
42 const safeIndex = Math.max(0, Math.min(currentIndex, itemCount - 1));
43 const currentItem = previewItems[safeIndex];
44 const hasMultiple = itemCount > 1;
45 const isImagePreview = currentItem?.kind === "image";
46 const canGoPrevious = safeIndex > 0;
47 const canGoNext = safeIndex < itemCount - 1;
48 const zoomPercent = Math.round(zoomScale * 100);
49 const isZoomed = zoomScale > MIN_ZOOM;
50
51 useEffect(() => {
52 const handleKeyDown = (event: KeyboardEvent) => {
53 if (!open) {
54 return;
55 }
56
57 if (event.key === "Escape") {
58 onOpenChange(false);
59 return;
60 }
61
62 if (event.key === "ArrowLeft") {
63 setCurrentIndex((prev) => Math.max(prev - 1, 0));
64 return;
65 }
66
67 if (event.key === "ArrowRight") {
68 setCurrentIndex((prev) => Math.min(prev + 1, itemCount - 1));
69 }
70 };
71
72 document.addEventListener("keydown", handleKeyDown);
73 return () => document.removeEventListener("keydown", handleKeyDown);
74 }, [itemCount, onOpenChange, open]);
75
76 useEffect(() => {
77 setZoomScale(MIN_ZOOM);
78 }, [currentItem?.id, open]);
79
80 const handleClose = () => onOpenChange(false);
81 const handlePrevious = () => {
82 setCurrentIndex((prev) => Math.max(prev - 1, 0));
83 };

Callers

nothing calls this directly

Calls 6

cnFunction · 0.90
useMediaQueryFunction · 0.85
useMemoFunction · 0.85
handleCloseFunction · 0.85
addEventListenerMethod · 0.80
removeEventListenerMethod · 0.80

Tested by

no test coverage detected