diff --git a/memento-note/components/notes-tabs-view.tsx b/memento-note/components/notes-tabs-view.tsx index 6f6ab25..4e94d3a 100644 --- a/memento-note/components/notes-tabs-view.tsx +++ b/memento-note/components/notes-tabs-view.tsx @@ -643,46 +643,50 @@ export function NotesTabsView({ const prevNotesRef = useRef(notes) - if (notes !== prevNotesRef.current) { - const prevIds = items.map((n) => n.id).join(',') - const incomingIds = notes.map((n) => n.id).join(',') - - const merge = (fresh: Note, local: Note, oldFresh?: Note) => { - const labelsChanged = JSON.stringify(fresh.labels?.sort()) !== JSON.stringify(local.labels?.sort()) - - const contentChangedOnServer = oldFresh && oldFresh.content !== fresh.content - const titleChangedOnServer = oldFresh && oldFresh.title !== fresh.title - const checkItemsChangedOnServer = oldFresh && JSON.stringify(oldFresh.checkItems) !== JSON.stringify(fresh.checkItems) + useEffect(() => { + setItems((prev) => { + const prevIds = prev.map((n) => n.id).join(',') + const incomingIds = notes.map((n) => n.id).join(',') - return { - ...fresh, - title: titleChangedOnServer ? fresh.title : (local.title || fresh.title), - content: contentChangedOnServer ? fresh.content : local.content, - checkItems: checkItemsChangedOnServer ? fresh.checkItems : local.checkItems, - labels: labelsChanged ? fresh.labels : local.labels + const merge = (fresh: Note, local: Note) => { + // Detect if the server explicitly changed content since last sync + const prevServer = prevNotesRef.current.find((n) => n.id === fresh.id) + const serverContentChanged = prevServer ? prevServer.content !== fresh.content : false + const serverTitleChanged = prevServer ? prevServer.title !== fresh.title : false + const serverCheckItemsChanged = prevServer + ? JSON.stringify(prevServer.checkItems) !== JSON.stringify(fresh.checkItems) + : false + const labelsChanged = + JSON.stringify(fresh.labels?.slice().sort()) !== + JSON.stringify(local.labels?.slice().sort()) + + return { + ...fresh, + title: serverTitleChanged ? fresh.title : local.title || fresh.title, + content: serverContentChanged ? fresh.content : local.content, + checkItems: serverCheckItemsChanged ? fresh.checkItems : local.checkItems, + labels: labelsChanged ? fresh.labels : local.labels, + } } - } - - let newItems: Note[] - if (prevIds === incomingIds) { - newItems = items.map((local) => { - const fresh = notes.find((n) => n.id === local.id) - if (!fresh) return local - const oldFresh = prevNotesRef.current.find((n) => n.id === local.id) - return merge(fresh, local, oldFresh) - }) - } else { - newItems = notes.map((fresh) => { - const local = items.find((p) => p.id === fresh.id) - if (!local) return fresh - const oldFresh = prevNotesRef.current.find((n) => n.id === fresh.id) - return merge(fresh, local, oldFresh) - }) - } - - setItems(newItems) + + let result: Note[] + if (prevIds === incomingIds) { + result = prev.map((local) => { + const fresh = notes.find((n) => n.id === local.id) + return fresh ? merge(fresh, local) : local + }) + } else { + result = notes.map((fresh) => { + const local = prev.find((p) => p.id === fresh.id) + return local ? merge(fresh, local) : fresh + }) + } + + return result + }) + prevNotesRef.current = notes - } + }, [notes]) useEffect(() => { if (items.length === 0) {