diff --git a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte index a341b07f..1818b015 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte @@ -154,33 +154,38 @@ $effect(() => { // 2. Auto-Save Debounce $effect(() => { - // Isolate logic from secondary dependencies - const should_save = untrack( - () => has_unsaved_changes && !is_processing && save_status !== 'saving' - ); + // Track content and name directly so this effect re-runs on every keystroke, + // resetting the debounce timer each time (fires 2 s after the LAST change). + // Tracking has_unsaved_changes ensures the effect also wakes up when changes + // are cleared (e.g. after a save) so the status indicator resets correctly. + // All side-effects (save_status writes, $journals_loc reads) stay in untrack + // to avoid creating reactive loops. + void tmp_entry_obj.content; + void tmp_entry_obj.name; + const changed = has_unsaved_changes; - if (should_save) { - if (save_status !== 'saving') save_status = 'unsaved'; + clearTimeout(auto_save_timer); - const auto_save_enabled = untrack(() => $journals_loc.entry.auto_save); - if (auto_save_enabled) { - clearTimeout(auto_save_timer); - auto_save_timer = setTimeout(() => { - if ( - untrack( - () => - has_unsaved_changes && - !is_processing && - save_status !== 'saving' - ) - ) { - update_journal_entry(); - } - }, 2000); - } - } else if (save_status === 'unsaved' && !has_unsaved_changes) { - save_status = 'saved'; + if (!changed) { + untrack(() => { + if (save_status === 'unsaved') save_status = 'saved'; + }); + return; } + + untrack(() => { + if (save_status !== 'saving') save_status = 'unsaved'; + }); + + if (!untrack(() => $journals_loc.entry.auto_save)) return; + + auto_save_timer = setTimeout(() => { + untrack(() => { + if (has_unsaved_changes && !is_processing && save_status !== 'saving') { + update_journal_entry(); + } + }); + }, 2000); }); // 3. Auto-Decryption Workflow