diff --git a/client/src/pages/VisionLab.tsx b/client/src/pages/VisionLab.tsx index 1156c95..dc18360 100644 --- a/client/src/pages/VisionLab.tsx +++ b/client/src/pages/VisionLab.tsx @@ -47,6 +47,67 @@ type VisionRun = { updatedAt: Date; }; +const COMMONS_SPECIAL_FILE_PATH = "/wiki/Special:FilePath/"; +const COMMONS_FILE_PAGE_PATH = "/wiki/File:"; + +function getCompressedVisionImageUrl(imageUrl: string, width = 960) { + try { + const url = new URL(imageUrl); + if (url.hostname !== "commons.wikimedia.org") { + return imageUrl; + } + + let fileName: string | null = null; + if (url.pathname.startsWith(COMMONS_SPECIAL_FILE_PATH)) { + fileName = url.pathname.slice(COMMONS_SPECIAL_FILE_PATH.length); + } else if (url.pathname.startsWith(COMMONS_FILE_PAGE_PATH)) { + fileName = url.pathname.slice(COMMONS_FILE_PAGE_PATH.length); + } + + if (!fileName) { + return imageUrl; + } + + const decodedFileName = decodeURIComponent(fileName); + return `https://commons.wikimedia.org/wiki/Special:Redirect/file/${encodeURIComponent(decodedFileName)}?width=${width}`; + } catch { + return imageUrl; + } +} + +function VisionPreviewImage({ + src, + alt, + className, + width = 960, +}: { + src: string; + alt: string; + className: string; + width?: number; +}) { + const [displaySrc, setDisplaySrc] = useState(() => getCompressedVisionImageUrl(src, width)); + + useEffect(() => { + setDisplaySrc(getCompressedVisionImageUrl(src, width)); + }, [src, width]); + + return ( + {alt} { + if (displaySrc !== src) { + setDisplaySrc(src); + } + }} + /> + ); +} + function statusBadge(run: VisionRun) { if (run.status === "failed" || run.visionStatus === "failed") { return 失败; @@ -212,12 +273,11 @@ export default function VisionLab() { {references.map((reference) => (
- {reference.title}
@@ -272,59 +332,79 @@ export default function VisionLab() { {runs.map((run) => ( -
-
-
-

{run.title}

- {statusBadge(run)} - {run.exerciseType} +
+ +
+
-

- {new Date(run.createdAt).toLocaleString("zh-CN")} - {user?.role === "admin" && run.userName ? ` · 提交人:${run.userName}` : ""} -

+
+ +
+
+
+
+

{run.title}

+ {statusBadge(run)} + {run.exerciseType} +
+

+ {new Date(run.createdAt).toLocaleString("zh-CN")} + {user?.role === "admin" && run.userName ? ` · 提交人:${run.userName}` : ""} +

+
+ {run.configuredModel ? ( + {run.configuredModel} + ) : null} +
+ + {run.summary ?

{run.summary}

: null} + {run.warning ? ( +

降级说明:{run.warning}

+ ) : null} + {run.error ? ( +

错误:{run.error}

+ ) : null} + + {(run.visionStatus === "fallback" || run.status === "failed") ? ( +
+ +
+ ) : null} + + {run.expectedFocus?.length ? ( +
+ {run.expectedFocus.map((item) => ( + {item} + ))} +
+ ) : null} + + {run.corrections ? ( +
+ {run.corrections} +
+ ) : null}
- {run.configuredModel ? ( - {run.configuredModel} - ) : null}
- - {run.summary ?

{run.summary}

: null} - {run.warning ? ( -

降级说明:{run.warning}

- ) : null} - {run.error ? ( -

错误:{run.error}

- ) : null} - - {(run.visionStatus === "fallback" || run.status === "failed") ? ( -
- -
- ) : null} - - {run.expectedFocus?.length ? ( -
- {run.expectedFocus.map((item) => ( - {item} - ))} -
- ) : null} - - {run.corrections ? ( -
- {run.corrections} -
- ) : null} ))}