From 8cc15994343be42e87bab2a40702c13e965c80b8 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Sun, 12 Jul 2026 23:57:43 +0100 Subject: [PATCH] fix(slideover): double-click on Save no longer creates a duplicate entry soSave had no re-entrancy guard: a second click while the first run awaited encryption/POST ran the whole save again -> two POSTs, two entries. Wrapped in a soSaving latch (same class as the sync-button guard); body moved to soSaveInner so every early validation return releases the latch via finally. Co-Authored-By: Claude Opus 4.8 --- js/app.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/js/app.js b/js/app.js index a18b30f..53171d6 100644 --- a/js/app.js +++ b/js/app.js @@ -4713,7 +4713,17 @@ function soDirtyCheck() { if (btn) btn.style.display = isSoDirty() ? '' : 'none'; } +// Re-entrancy latch: a double-click on Save (or Enter+click) while the first +// run awaits encryption/POST would fire a SECOND full save → duplicate entry. +// Same async-race class as the sync-button guard. +let soSaving = false; async function soSave() { + if (soSaving) return; + soSaving = true; + try { await soSaveInner(); } finally { soSaving = false; } +} + +async function soSaveInner() { if (!soState) return; // Flush any uncommitted tag text — user may have typed in the chip // input without pressing Enter / comma before clicking Save.