From ee57195681beec90d0fb7197b06c30259918ea20 Mon Sep 17 00:00:00 2001 From: Hermes Date: Sat, 1 Aug 2026 12:53:19 +0000 Subject: [PATCH] fix: stabilize handleContentChange callback via ref to prevent NoteEditor re-render stealing focus --- apps/web/src/routes/_app/notes.tsx | 14 +++++++++++--- fix_notes2.py | 13 +++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 fix_notes2.py diff --git a/apps/web/src/routes/_app/notes.tsx b/apps/web/src/routes/_app/notes.tsx index bb8e155..8fbef2c 100644 --- a/apps/web/src/routes/_app/notes.tsx +++ b/apps/web/src/routes/_app/notes.tsx @@ -53,6 +53,7 @@ function NotesPage() { const queryClient = useQueryClient(); const [search, setSearch] = useState(""); const [selectedNote, setSelectedNote] = useState(null); + const [titleDraft, setTitleDraft] = useState(""); const [editorContent, setEditorContent] = useState(""); const saveTimerRef = useRef | null>(null); const [showBacklinks, setShowBacklinks] = useState(false); @@ -93,24 +94,30 @@ function NotesPage() { try { const detail = await api.get("/notes/" + note.id); setSelectedNote(detail); + setTitleDraft(detail.title); setEditorContent(detail.content || ""); } catch { setSelectedNote(note); + setTitleDraft(note.title); setEditorContent(note.content || ""); } setShowBacklinks(false); setShowVersions(false); }; + const selectedNoteRef = useRef(selectedNote); + selectedNoteRef.current = selectedNote; + const handleContentChange = useCallback((html: string) => { setEditorContent(html); if (saveTimerRef.current) clearTimeout(saveTimerRef.current); saveTimerRef.current = setTimeout(() => { - if (selectedNote) { - updateMutation.mutate({ id: selectedNote.id, data: { content: html } }); + const note = selectedNoteRef.current; + if (note) { + updateMutation.mutate({ id: note.id, data: { content: html } }); } }, 500); - }, [selectedNote, updateMutation]); + }, [updateMutation]); return ( @@ -166,6 +173,7 @@ function NotesPage() { e.stopPropagation()} onBlur={(e) => { if (selectedNote && e.target.value !== selectedNote.title) { updateMutation.mutate({ id: selectedNote.id, data: { title: e.target.value } }); diff --git a/fix_notes2.py b/fix_notes2.py new file mode 100644 index 0000000..c9cd9f4 --- /dev/null +++ b/fix_notes2.py @@ -0,0 +1,13 @@ +import sys + +with open(sys.argv[1], 'r') as f: + content = f.read() + +old = ' {' +new = ' e.stopPropagation()}\n onBlur={(e) => {' + +content = content.replace(old, new, 1) + +with open(sys.argv[1], 'w') as f: + f.write(content) +print('Done')