From 038f6bc26c477704d8126d55966dca68624e9327 Mon Sep 17 00:00:00 2001 From: carlobortolan Date: Sat, 25 Jan 2025 21:29:51 +0100 Subject: [PATCH] Refactor viewerjs code into separate ImageActions.tsx component and revert ImageWithFallback.tsx --- src/components/FullscreenButton.tsx | 4 +- src/components/image/ImageActions.tsx | 55 +++++++++ src/components/image/ImageLarge.tsx | 16 ++- src/components/image/ImageWithFallback.tsx | 131 +++++++-------------- 4 files changed, 108 insertions(+), 98 deletions(-) create mode 100644 src/components/image/ImageActions.tsx diff --git a/src/components/FullscreenButton.tsx b/src/components/FullscreenButton.tsx index e5794184..4b6124d7 100644 --- a/src/components/FullscreenButton.tsx +++ b/src/components/FullscreenButton.tsx @@ -11,7 +11,7 @@ export default function FullscreenButton({ imageRef, }: { className?: string; - imageRef: RefObject; + imageRef: RefObject; }) { const { isFullscreen, setIsFullscreen } = useAppState(); @@ -55,7 +55,7 @@ export default function FullscreenButton({ title="Toggle Fullscreen" className={clsx( className, - 'text-medium absolute bottom-2 right-2 bg-white p-2 rounded', + 'text-medium absolute bottom-2 right-2 bg-white p-2 rounded hidden md:block', )} icon={isFullscreen ? : } diff --git a/src/components/image/ImageActions.tsx b/src/components/image/ImageActions.tsx new file mode 100644 index 00000000..1bfe6326 --- /dev/null +++ b/src/components/image/ImageActions.tsx @@ -0,0 +1,55 @@ +import { useEffect, useRef } from 'react'; +import Viewer from 'viewerjs'; +import 'viewerjs/dist/viewer.css'; +import { clsx } from 'clsx/lite'; +import FullscreenButton from '../FullscreenButton'; + +export default function ImageActions({ children, enableImageActions = false, className }: { children: React.ReactNode, enableImageActions?: boolean, className?: string }) { + const containerRef = useRef(null); + const viewerRef = useRef(null); + + useEffect(() => { + if (containerRef.current && enableImageActions) { + viewerRef.current = new Viewer(containerRef.current, { + inline: false, + button: true, + navbar: false, + title: false, + toolbar: { + zoomIn: 1, + zoomOut: 1, + reset: 1, + tooltip: 1, + }, + }); + return () => { + viewerRef.current?.destroy(); + }; + } + }, [enableImageActions]); + + return ( + <> + +
+ {children} + {enableImageActions && } +
+ + ); +} diff --git a/src/components/image/ImageLarge.tsx b/src/components/image/ImageLarge.tsx index 18569d92..e9bcf92d 100644 --- a/src/components/image/ImageLarge.tsx +++ b/src/components/image/ImageLarge.tsx @@ -1,18 +1,22 @@ import { IMAGE_WIDTH_LARGE, ImageProps } from '.'; import ImageWithFallback from './ImageWithFallback'; +import ImageActions from './ImageActions'; export default function ImageLarge(props: ImageProps) { const { aspectRatio, blurCompatibilityMode, + enableImageActions = false, ...rest } = props; return ( - + + + ); }; diff --git a/src/components/image/ImageWithFallback.tsx b/src/components/image/ImageWithFallback.tsx index 7cd60e4a..dbf76af6 100644 --- a/src/components/image/ImageWithFallback.tsx +++ b/src/components/image/ImageWithFallback.tsx @@ -3,18 +3,13 @@ /* eslint-disable jsx-a11y/alt-text */ import { BLUR_ENABLED } from '@/site/config'; import { useAppState } from '@/state/AppState'; -import { clsx } from 'clsx/lite'; +import { clsx} from 'clsx/lite'; import Image, { ImageProps } from 'next/image'; import { useCallback, useEffect, useRef, useState } from 'react'; -import FullscreenButton from '../FullscreenButton'; -import Viewer from 'viewerjs'; -import 'viewerjs/dist/viewer.css'; export default function ImageWithFallback(props: ImageProps & { blurCompatibilityLevel?: 'none' | 'low' | 'high' imgClassName?: string - allowFullscreen?: boolean - enableImageActions?: boolean }) { const { className, @@ -22,7 +17,6 @@ export default function ImageWithFallback(props: ImageProps & { blurDataURL, blurCompatibilityLevel = 'low', imgClassName = 'object-cover h-full', - enableImageActions = false, ...rest } = props; @@ -37,10 +31,7 @@ export default function ImageWithFallback(props: ImageProps & { const [hideFallback, setHideFallback] = useState(false); - const containerRef = useRef(null); - const viewerRef = useRef(null); - const imgRef = useRef(null); - const { isFullscreen } = useAppState(); + const imgRef = useRef(null); useEffect(() => { const timeout = setTimeout( @@ -59,26 +50,6 @@ export default function ImageWithFallback(props: ImageProps & { } }, [isLoading, didError]); - useEffect(() => { - if (containerRef.current && enableImageActions) { - viewerRef.current = new Viewer(containerRef.current, { - inline: false, - button: true, - navbar: false, - title: false, - toolbar: { - zoomIn: 1, - zoomOut: 1, - reset: 1, - tooltip: 1, - }, - }); - return () => { - viewerRef.current?.destroy(); - }; - } - }, [enableImageActions]); - const showFallback = !wasCached && !hideFallback; @@ -94,65 +65,45 @@ export default function ImageWithFallback(props: ImageProps & { }; return ( - <> - -
- {(showFallback || shouldDebugImageFallbacks) && -
- {(BLUR_ENABLED && blurDataURL) - ? - :
} -
} - - {enableImageActions && } +
+ {(showFallback || shouldDebugImageFallbacks) && +
+ {(BLUR_ENABLED && blurDataURL) + ? + :
} +
} +
- ); }