@@ -128,6 +128,9 @@ export function NoteDetailEditor({ noteId }: NoteDetailEditorProps) {
128128 const targetQueryInputRef = useRef < HTMLInputElement | null > ( null ) ;
129129 const editorSurfaceRef = useRef < HTMLDivElement | null > ( null ) ;
130130 const normalizingMathRef = useRef ( false ) ;
131+ const loadingSeqRef = useRef ( 0 ) ;
132+ const hydratingContentRef = useRef ( false ) ;
133+ const pendingDirtyWhileSavingRef = useRef ( false ) ;
131134
132135 const refreshContext = useCallback ( async ( ) => {
133136 if ( ! noteId ) {
@@ -236,6 +239,10 @@ export function NoteDetailEditor({ noteId }: NoteDetailEditorProps) {
236239 } ,
237240 } ,
238241 onUpdate : ( { editor : activeEditor } ) => {
242+ if ( hydratingContentRef . current ) {
243+ hydratingContentRef . current = false ;
244+ return ;
245+ }
239246 if ( ! normalizingMathRef . current ) {
240247 const normalized = normalizeDisplayMathParagraphs ( activeEditor ) ;
241248 if ( normalized ) {
@@ -250,7 +257,13 @@ export function NoteDetailEditor({ noteId }: NoteDetailEditorProps) {
250257 return ;
251258 }
252259
253- setSaveState ( ( current ) => ( current === "saving" ? current : "dirty" ) ) ;
260+ setSaveState ( ( current ) => {
261+ if ( current === "saving" ) {
262+ pendingDirtyWhileSavingRef . current = true ;
263+ return current ;
264+ }
265+ return "dirty" ;
266+ } ) ;
254267 syncSlashTrigger ( activeEditor ) ;
255268 } ,
256269 onSelectionUpdate : ( { editor : activeEditor } ) => {
@@ -331,6 +344,7 @@ export function NoteDetailEditor({ noteId }: NoteDetailEditorProps) {
331344 if ( ! editor || ! noteId || ! loaded ) {
332345 return ;
333346 }
347+ pendingDirtyWhileSavingRef . current = false ;
334348 setSaveState ( "saving" ) ;
335349 setError ( null ) ;
336350 setNotice ( null ) ;
@@ -342,9 +356,11 @@ export function NoteDetailEditor({ noteId }: NoteDetailEditorProps) {
342356 links : extractNoteLinks ( json ) ,
343357 } ) ;
344358 setTitle ( response . title ) ;
345- setSaveState ( "saved" ) ;
359+ setSaveState ( pendingDirtyWhileSavingRef . current ? "dirty" : "saved" ) ;
360+ pendingDirtyWhileSavingRef . current = false ;
346361 await refreshContext ( ) ;
347362 } catch ( saveError ) {
363+ pendingDirtyWhileSavingRef . current = false ;
348364 setSaveState ( "failed" ) ;
349365 setError (
350366 saveError instanceof Error ? saveError . message : String ( saveError ) ,
@@ -356,22 +372,40 @@ export function NoteDetailEditor({ noteId }: NoteDetailEditorProps) {
356372 if ( ! editor || ! noteId ) {
357373 return ;
358374 }
375+ const currentLoadSeq = loadingSeqRef . current + 1 ;
376+ loadingSeqRef . current = currentLoadSeq ;
377+ setLoaded ( false ) ;
378+ setSaveState ( "saved" ) ;
379+ setError ( null ) ;
380+ setTitle ( "" ) ;
359381 void ( async ( ) => {
360382 try {
361383 const detail = await getNoteDetail ( noteId ) ;
384+ if ( loadingSeqRef . current !== currentLoadSeq ) {
385+ return ;
386+ }
362387 setTitle ( detail . title ) ;
363388 const parsed = safeJsonParse ( detail . content ) as JSONContent ;
364389 const normalized = normalizeLegacyMathNodes ( parsed ) [ 0 ] ?? parsed ;
390+ hydratingContentRef . current = true ;
365391 editor . commands . setContent ( normalized ) ;
392+ if ( loadingSeqRef . current !== currentLoadSeq ) {
393+ return ;
394+ }
366395 setLoaded ( true ) ;
367396 setSaveState ( "saved" ) ;
368397 setError ( null ) ;
369398 } catch ( loadError ) {
399+ if ( loadingSeqRef . current !== currentLoadSeq ) {
400+ return ;
401+ }
370402 setError (
371403 loadError instanceof Error ? loadError . message : String ( loadError ) ,
372404 ) ;
373405 }
374- await refreshContext ( ) ;
406+ if ( loadingSeqRef . current === currentLoadSeq ) {
407+ await refreshContext ( ) ;
408+ }
375409 } ) ( ) ;
376410 } , [ editor , noteId , refreshContext ] ) ;
377411
@@ -676,7 +710,9 @@ export function NoteDetailEditor({ noteId }: NoteDetailEditorProps) {
676710 value = { title }
677711 onChange = { ( event ) => {
678712 setTitle ( event . target . value ) ;
679- setSaveState ( "dirty" ) ;
713+ if ( loaded ) {
714+ setSaveState ( "dirty" ) ;
715+ }
680716 } }
681717 placeholder = "笔记标题"
682718 className = "w-full rounded-2xl border border-[#243651] bg-[#0f1724] px-4 py-3 text-xl font-semibold text-[#e5ecff] shadow-[0_10px_26px_rgba(0,0,0,0.25)] outline-none transition-colors focus:border-[#4f7dff]"
0 commit comments