From 7410ca229afdb6fafb01f5ebe370d01dc33a4500 Mon Sep 17 00:00:00 2001 From: Innei Date: Fri, 6 Sep 2024 22:05:14 +0800 Subject: [PATCH] fix: preview image fallback Signed-off-by: Innei --- src/renderer/src/components/ui/media.tsx | 6 ++- .../src/components/ui/media/hooks.tsx | 4 +- .../src/components/ui/media/preview-media.tsx | 50 +++++++++++++++---- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/renderer/src/components/ui/media.tsx b/src/renderer/src/components/ui/media.tsx index b386687ce..fdabde655 100644 --- a/src/renderer/src/components/ui/media.tsx +++ b/src/renderer/src/components/ui/media.tsx @@ -86,6 +86,7 @@ const MediaImpl: FC = ({ { url: src, type, + fallbackUrl: imgSrc, }, ], 0, @@ -206,7 +207,10 @@ const MediaImpl: FC = ({ return } return ( - + {InnerContent} ) diff --git a/src/renderer/src/components/ui/media/hooks.tsx b/src/renderer/src/components/ui/media/hooks.tsx index 1ca029f09..0611d9bb9 100644 --- a/src/renderer/src/components/ui/media/hooks.tsx +++ b/src/renderer/src/components/ui/media/hooks.tsx @@ -1,14 +1,14 @@ import { useCallback } from "react" -import type { MediaModel } from "src/hono" import { useModalStack } from "../modal/stacked/hooks" import { NoopChildren } from "../modal/stacked/utils" +import type { PreviewMediaProps } from "./preview-media" import { PreviewMediaContent } from "./preview-media" export const usePreviewMedia = () => { const { present } = useModalStack() return useCallback( - (media: MediaModel[], initialIndex = 0) => { + (media: PreviewMediaProps[], initialIndex = 0) => { present({ content: () => (
diff --git a/src/renderer/src/components/ui/media/preview-media.tsx b/src/renderer/src/components/ui/media/preview-media.tsx index f6c35da63..1a908e891 100644 --- a/src/renderer/src/components/ui/media/preview-media.tsx +++ b/src/renderer/src/components/ui/media/preview-media.tsx @@ -74,8 +74,12 @@ const Wrapper: Component<{
) } + +export interface PreviewMediaProps extends MediaModel { + fallbackUrl?: string +} export const PreviewMediaContent: FC<{ - media: MediaModel[] + media: PreviewMediaProps[] initialIndex?: number }> = ({ media, initialIndex = 0 }) => { const [currentMedia, setCurrentMedia] = useState(media[initialIndex]) @@ -143,6 +147,7 @@ export const PreviewMediaContent: FC<{ /> ) : ( ) : ( handleContextMenu(med.url, e)} className="size-full object-contain" alt="cover" @@ -258,23 +264,47 @@ export const PreviewMediaContent: FC<{ const FallbackableImage: FC< Omit, "src"> & { src: string + fallbackUrl?: string } -> = ({ src, onError, ...props }) => { +> = ({ src, onError, fallbackUrl, ...props }) => { const [currentSrc, setCurrentSrc] = useState(() => replaceImgUrlIfNeed(src)) - const [isAllError, setIsAllError] = useState(false) + const [currentState, setCurrentState] = useState< + "proxy" | "origin" | "fallback" + >(() => (currentSrc === src ? "origin" : "proxy")) + const handleError = useCallback( - (e) => { - if (currentSrc !== src) { - setCurrentSrc(src) - } else { - onError?.(e as any) - setIsAllError(true) + () => { + switch (currentState) { + case "proxy": { + if (currentSrc !== src) { + setCurrentSrc(src) + setCurrentState("origin") + } else { + if (fallbackUrl) { + setCurrentSrc(fallbackUrl) + setCurrentState("fallback") + } + } + + break + } + case "origin": { + if (fallbackUrl) { + setCurrentSrc(fallbackUrl) + setCurrentState("fallback") + } + break + } + case "fallback": { + setIsAllError(true) + } } }, - [currentSrc, onError, src], + [currentSrc, currentState, fallbackUrl, src], ) + return ( {!isAllError && }