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
This commit is contained in:
@@ -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<string | null>(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),
|
||||
}} />
|
||||
) : <div className="empty-note" style={{ padding: 14 }}>这个文件已不在当前项目里</div>}
|
||||
|
||||
@@ -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)}}
|
||||
},
|
||||
|
||||
+1
-1
@@ -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 } {
|
||||
|
||||
+1
-1
@@ -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)}})
|
||||
|
||||
Reference in New Issue
Block a user