优化动漫数据源图片降级策略

This commit is contained in:
mtvpls
2026-07-21 16:13:00 +08:00
parent d54cf65927
commit 08c2ff36f9
3 changed files with 173 additions and 49 deletions
+12 -12
View File
@@ -4,6 +4,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
import {
clearBangumiImageFallbackCacheIfFailed,
ensureBangumiImagePrimaryProbed,
processImageUrl,
tryApplyBangumiImageFallback,
tryApplyDoubanImageFallback,
@@ -38,22 +39,21 @@ const ProxyImage: React.FC<ProxyImageProps> = ({
setCurrentSrc(initialSrc);
}, [initialSrc]);
// 主源图片域主页探测:失败则 sticky 走备源(替代原 5s complete 误判)
useEffect(() => {
if (displaySrc) return;
const timer = window.setTimeout(() => {
const img = imgRef.current;
if (!img || img.complete || img.dataset.bangumiBackupTried === 'true') {
return;
}
let cancelled = false;
void (async () => {
const reachable = await ensureBangumiImagePrimaryProbed();
if (cancelled || reachable) return;
setCurrentSrc(processImageUrl(originalSrc));
})();
if (tryApplyBangumiImageFallback(img, originalSrc)) {
setCurrentSrc(img.src);
}
}, 5000);
return () => window.clearTimeout(timer);
}, [currentSrc, displaySrc, originalSrc]);
return () => {
cancelled = true;
};
}, [displaySrc, originalSrc]);
const handleError = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {
const img = e.currentTarget;
+13 -37
View File
@@ -38,9 +38,9 @@ import { isNetdiskSource } from '@/lib/netdisk/source';
import {
base58Decode,
clearBangumiImageFallbackCacheIfFailed,
ensureBangumiImagePrimaryProbed,
getBangumiImageFallbackUrl,
getDoubanImageFallbackUrl,
markBangumiImageFallbackActive,
processImageUrl,
tryApplyBangumiImageFallback,
tryApplyDoubanImageFallback,
@@ -226,44 +226,24 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(
setDisplayPoster(processedPoster);
}, [processedPoster]);
const bangumiImageTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(
null
);
// 主源图片域主页探测:失败写 sticky 后切备源海报(替代原 5s 强制降级)
useEffect(() => {
if (bangumiImageTimeoutRef.current) {
clearTimeout(bangumiImageTimeoutRef.current);
bangumiImageTimeoutRef.current = null;
}
if (!actualPoster) return;
const bangumiFallbackPoster = getBangumiImageFallbackUrl(actualPoster);
if (!bangumiFallbackPoster || displayPoster === bangumiFallbackPoster) {
return;
}
bangumiImageTimeoutRef.current = setTimeout(() => {
markBangumiImageFallbackActive();
setDisplayPoster((current) =>
current === bangumiFallbackPoster ? current : bangumiFallbackPoster
);
}, 5000);
let cancelled = false;
void (async () => {
const reachable = await ensureBangumiImagePrimaryProbed();
if (cancelled || reachable) return;
const bangumiFallbackPoster = getBangumiImageFallbackUrl(actualPoster);
if (bangumiFallbackPoster) {
setDisplayPoster(bangumiFallbackPoster);
}
})();
return () => {
if (bangumiImageTimeoutRef.current) {
clearTimeout(bangumiImageTimeoutRef.current);
bangumiImageTimeoutRef.current = null;
}
cancelled = true;
};
}, [actualPoster, displayPoster]);
const clearBangumiImageTimeout = useCallback(() => {
if (bangumiImageTimeoutRef.current) {
clearTimeout(bangumiImageTimeoutRef.current);
bangumiImageTimeoutRef.current = null;
}
}, []);
}, [actualPoster]);
useImperativeHandle(ref, () => ({
setEpisodes: (eps?: number) => setDynamicEpisodes(eps),
@@ -1017,7 +997,6 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(
loading='lazy'
onLoadingComplete={() => {
setIsLoading(true);
clearBangumiImageTimeout();
}}
onClick={(e) => {
e.stopPropagation();
@@ -1031,7 +1010,6 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(
doubanFallbackPoster &&
tryApplyDoubanImageFallback(img, actualPoster)
) {
clearBangumiImageTimeout();
setDisplayPoster(doubanFallbackPoster);
return;
}
@@ -1042,7 +1020,6 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(
bangumiFallbackPoster &&
tryApplyBangumiImageFallback(img, actualPoster)
) {
clearBangumiImageTimeout();
setDisplayPoster(bangumiFallbackPoster);
return;
}
@@ -1050,7 +1027,6 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(
if (
clearBangumiImageFallbackCacheIfFailed(img, actualPoster)
) {
clearBangumiImageTimeout();
setDisplayPoster(processedPoster);
return;
}