From 9a19c85b4b2aab4777741e0c6ff55f92ac39d31b Mon Sep 17 00:00:00 2001 From: Irfan Fadilah Date: Tue, 20 Oct 2026 20:19:02 +0700 Subject: [PATCH] Fix Stale Attachments in Note Editor --- app/components/note/ListView.vue | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/app/components/note/ListView.vue b/app/components/note/ListView.vue index 8482574..0c77ffd 100644 --- a/app/components/note/ListView.vue +++ b/app/components/note/ListView.vue @@ -37,7 +37,7 @@ :notes="displayedNotes" :status="status" :empty-message="emptyMessage" - @open="editingNote = $event" + @open="openEditor" @archive="(n) => archiveNote(n.id)" @unarchive="(n) => unarchiveNote(n.id)" @trash="(n) => trashNote(n.id)" @@ -54,7 +54,7 @@ v-if="editingNote" :note="editingNote" :readonly="!!status" - @close="editingNote = null" + @close="closeEditor" @unarchive="(n) => unarchiveNote(n.id)" @trash="(n) => trashNote(n.id)" @restore="(n) => restoreNote(n.id)" @@ -116,7 +116,26 @@ const listParams = computed(() => ({ // useNotesList/useSearch expose readonly views of their state; list components never mutate their props const displayedNotes = computed(() => (searchResults.value ?? notes.value) as Note[]) -const editingNote = ref(null) + +// Track the open note by id: attachment changes replace the note object in the list, and the +// editor must show the latest version. The snapshot keeps the editor open if the note drops out +// of the list (e.g. trashed on another device) while it is being edited. +const editingId = ref(null) +const editingSnapshot = ref(null) +const editingNote = computed(() => { + if (!editingId.value) return null + return displayedNotes.value.find((n) => n.id === editingId.value) ?? editingSnapshot.value +}) +watch(editingNote, (note) => { if (note) editingSnapshot.value = note }) + +const openEditor = (note: Note) => { + editingSnapshot.value = note + editingId.value = note.id +} +const closeEditor = () => { + editingId.value = null + editingSnapshot.value = null +} const { sentinel } = useInfiniteScroll(() => { if (searchQuery.value.trim()) {