From 475e4127c24681a0d9cb8bd1bef5d79141fbf9fd Mon Sep 17 00:00:00 2001 From: Nexmoe <16796652+nexmoe@users.noreply.github.com> Date: Sat, 10 Jan 2026 18:39:00 +0800 Subject: [PATCH] fix(remote-image): add load timeout (#72) --- .../src/components/ui/remote-image.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/renderer/src/components/ui/remote-image.tsx b/src/renderer/src/components/ui/remote-image.tsx index e3e525b..dc2e603 100644 --- a/src/renderer/src/components/ui/remote-image.tsx +++ b/src/renderer/src/components/ui/remote-image.tsx @@ -67,6 +67,8 @@ interface RemoteImageProps { * /> * ``` */ +const IMAGE_LOAD_TIMEOUT_MS = 30000 + export function RemoteImage({ src, alt, @@ -91,8 +93,10 @@ export function RemoteImage({ const imageSrc = shouldUseCache ? cachedSrc : (src ?? undefined) const [isImageLoading, setIsImageLoading] = useState(true) + const [timedOutSrc, setTimedOutSrc] = useState(null) const isCacheLoading = shouldUseCache && src && cachedSrc === undefined - const isLoading = isCacheLoading || isImageLoading + const hasTimedOut = Boolean(src) && timedOutSrc === src + const isLoading = !hasTimedOut && (isCacheLoading || isImageLoading) useEffect(() => { if (imageSrc) { @@ -102,6 +106,19 @@ export function RemoteImage({ } }, [imageSrc]) + useEffect(() => { + if (!src || hasTimedOut || !isLoading) return + + const timeoutId = window.setTimeout(() => { + setTimedOutSrc(src) + setIsImageLoading(false) + }, IMAGE_LOAD_TIMEOUT_MS) + + return () => { + window.clearTimeout(timeoutId) + } + }, [src, hasTimedOut, isLoading]) + useEffect(() => { onLoadingChange?.(isLoading) }, [isLoading, onLoadingChange])