From 175210f4bbf79d3115ca5566aa28890c86a932ae Mon Sep 17 00:00:00 2001 From: weichen Date: Tue, 13 Oct 2026 02:51:07 +0000 Subject: [PATCH] Open processed source versions through the existing preview Why: Source context must remain attached to the bytes being read. Evidence: SELF frontend tests and production build pass. Impact: Carries an optional expected hash and preserves one preview location. Refs: fast-slow-u2-u3 Task 5 source-version acceptance --- src/components/PreviewPane.tsx | 9 +++++---- src/components/Workbench.tsx | 2 +- src/previewtabs.ts | 2 +- src/store.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/PreviewPane.tsx b/src/components/PreviewPane.tsx index c9676a1..be021cc 100644 --- a/src/components/PreviewPane.tsx +++ b/src/components/PreviewPane.tsx @@ -24,6 +24,7 @@ export function PreviewPane() { }) : undefined const art = active ? artifacts.find(a => a.id === active.id) : undefined + const contentUrl=art?api.artifactContentUrl(art.id)+(active?.sourceContext?.expectedHash?`?expectedHash=${encodeURIComponent(active.sourceContext.expectedHash)}`:''):'' const textKind = !!art && isTextKind(art) const [content, setContent] = useState(null) const [editing, setEditing] = useState(false) @@ -35,12 +36,12 @@ export function PreviewPane() { setContent(null) if (!art || !isTextKind(art)) return let cancelled = false - fetch(api.artifactContentUrl(art.id)) - .then(r => r.text()) + fetch(contentUrl) + .then(r => {if(!r.ok)throw new Error('source unavailable');return r.text()}) .then(text => { if (!cancelled) setContent(text) }) .catch(() => { if (!cancelled) setContent('(读取失败)') }) return () => { cancelled = true } - }, [art?.id]) + }, [art?.id,contentUrl]) if (!active) return null if (active.id.startsWith('surface:')) { @@ -120,7 +121,7 @@ export function PreviewPane() { id: art.id, name: art.name, mime: art.mime, - contentUrl: api.artifactContentUrl(art.id), + contentUrl, downloadUrl: api.artifactDownloadUrl(art.id), }} /> ) :
这个文件已不在当前项目里
} diff --git a/src/components/Workbench.tsx b/src/components/Workbench.tsx index f726246..39efbd4 100644 --- a/src/components/Workbench.tsx +++ b/src/components/Workbench.tsx @@ -19,7 +19,7 @@ export const docBridge: DocBridge = { try{const out=await api.taskSource(cardId,source.id) if(context!==store.getState().currentConvId||project!==store.getState().currentProjectId)return if(!out.artifact){store.toast('来源当前不可用,正在核实工作记录');if(context)void store.refreshCards(context);return} - store.requestTaskSourcePreview(out.artifact,{notice:out.versionState==='changed'?'当前文件已更新;下方引用来自任务处理时的版本,不能作为当前文件的结论':'当前文件与处理时来源一致;下方是本项发现引用的片段',quote:out.source.quote??''}) + store.requestTaskSourcePreview(out.artifact,{notice:out.versionState==='changed'?'当前文件已更新;下方引用来自任务处理时的版本,不能作为当前文件的结论':'任务处理时引用的来源版本;下方是本项发现引用的片段',quote:out.source.quote??'',expectedHash:out.versionState==='current'?out.source.contentHash:undefined}) if(out.versionState==='changed'&&context)void store.refreshCards(context) }catch{if(context===store.getState().currentConvId&&project===store.getState().currentProjectId){store.toast('来源当前无法读取,正在核实工作记录');if(context)void store.refreshCards(context)}} }, diff --git a/src/previewtabs.ts b/src/previewtabs.ts index a0628a5..e8b3b89 100644 --- a/src/previewtabs.ts +++ b/src/previewtabs.ts @@ -3,7 +3,7 @@ export interface PreviewTab { id: string name: string - sourceContext?: {notice:string;quote:string} + sourceContext?: {notice:string;quote:string;expectedHash?:string} } export function openPreviewTab(tabs: PreviewTab[], tab: PreviewTab): { tabs: PreviewTab[]; activeId: string } { diff --git a/src/store.ts b/src/store.ts index 209f99b..6506b1a 100644 --- a/src/store.ts +++ b/src/store.ts @@ -1255,7 +1255,7 @@ export const store = { * 工件预览唯一入口:在第三栏「文件」入口打开或激活标签(多文件多标签)。 * 打开第一张自动切到预览子视图;关掉最后一张回到文件列表,并收回展开态。 */ - requestTaskSourcePreview(a:Artifact,sourceContext:{notice:string;quote:string}){ + requestTaskSourcePreview(a:Artifact,sourceContext:{notice:string;quote:string;expectedHash?:string}){ store.requestPreview(a) const conv=previewTabsKey(state.currentConvId) set({previewTabs:{...state.previewTabs,[conv]:(state.previewTabs[conv]??[]).map(tab=>tab.id===a.id?{...tab,sourceContext}:tab)}})