fix(app): 模式切换文本闪烁——epoch 重挂统一弃旧窗格回写,源码模式禁富文本窗格回写(docs/24)
This commit is contained in:
24
src/App.tsx
24
src/App.tsx
@@ -82,6 +82,12 @@ export default function App() {
|
||||
const [sourceMode, setSourceMode] = useState(false)
|
||||
const [paneEpochs, setPaneEpochs] = useState<Record<string, number>>({})
|
||||
const bumpPaneEpoch = useCallback((id: string) => {
|
||||
// 凡是 epoch 重挂(源码退出重建、外部重载),旧窗格卸载时的最终回写必然
|
||||
// 是过期文本(新内容已在状态里),先上闸门丢弃,免得它盖掉新内容——
|
||||
// 源码模式下输的文本曾被空窗格的回写反复盖掉(docs/24)。闸门 1.5 秒
|
||||
// 自清,防止没有卸载发生时长期挂着。
|
||||
suppressFinalWriteRef.current.add(id)
|
||||
window.setTimeout(() => suppressFinalWriteRef.current.delete(id), 1500)
|
||||
setPaneEpochs((prev) => ({ ...prev, [id]: (prev[id] ?? 0) + 1 }))
|
||||
}, [])
|
||||
// 标签编辑器保活:最近用过的标签保持挂载(隐藏而非销毁),切回免去整篇重解析
|
||||
@@ -433,11 +439,7 @@ export default function App() {
|
||||
if (expectedContent !== undefined && current.content !== expectedContent) return
|
||||
if (isDirty(current)) return
|
||||
}
|
||||
// 审计修复(卸载回写覆盖):标签重挂时,旧 EditorPane 的卸载回写会把旧正文
|
||||
// 写回状态、盖掉刚载入的内容——重载前先给该标签的这次最终回写上闸门。
|
||||
// 保活后非活动标签也可能正挂载着,闸门与重挂对所有标签一律生效。
|
||||
suppressFinalWriteRef.current.add(target.id)
|
||||
window.setTimeout(() => suppressFinalWriteRef.current.delete(target.id), 1500)
|
||||
// 卸载回写覆盖的闸门已集中在 bumpPaneEpoch 内(重挂必弃旧回写)。
|
||||
dispatch({
|
||||
type: 'loadContent', id: target.id, content: file.content,
|
||||
encoding: file.encoding, lineEnding: file.lineEnding, hadBom: file.hadBom,
|
||||
@@ -1299,12 +1301,18 @@ export default function App() {
|
||||
key={`${t.id}:${paneEpochs[t.id] ?? 0}`}
|
||||
tabId={t.id}
|
||||
initialMarkdown={t.content}
|
||||
onMarkdown={(id, md) => dispatch({ type: 'updateContent', id, content: md })}
|
||||
onMarkdown={(id, md) => {
|
||||
if (sourceMode && stateRef.current.activeId === id) return // 源码模式中:富文本窗格是旧稿,禁回写
|
||||
dispatch({ type: 'updateContent', id, content: md })
|
||||
}}
|
||||
onFinalMarkdown={(id, md) => {
|
||||
if (suppressFinalWriteRef.current.delete(id)) return // 外部重载的卸载回写,丢弃
|
||||
if (suppressFinalWriteRef.current.delete(id)) return // 重挂时的卸载回写已过期,丢弃
|
||||
dispatch({ type: 'syncEditorContent', id, content: md })
|
||||
}}
|
||||
onSyncInitial={(id, md) => {
|
||||
if (sourceMode && stateRef.current.activeId === id) return // 同上
|
||||
dispatch({ type: 'syncEditorContent', id, content: md })
|
||||
}}
|
||||
onSyncInitial={(id, md) => dispatch({ type: 'syncEditorContent', id, content: md })}
|
||||
onCursor={(c) => { if (stateRef.current.activeId === t.id) setCursor(c) }}
|
||||
focusMode={ui.focusMode}
|
||||
typewriter={ui.typewriter}
|
||||
|
||||
Reference in New Issue
Block a user