From 9350af9589bc90141b4d0abc6767e5b0eae8702f Mon Sep 17 00:00:00 2001 From: rouggy Date: Sat, 29 Aug 2026 01:34:09 +0200 Subject: [PATCH] fix(watchlist): remove actually removes on the second click MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two-click arm compared against the STATE variable, which each click's handler captured at render time — a quick double-click read the pre-arm value twice, so both clicks merely armed: the bin turned red and nothing was ever deleted. The arm lives in a ref now, compared synchronously, and the window grows to three seconds. --- frontend/src/components/WatchlistTab.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/WatchlistTab.tsx b/frontend/src/components/WatchlistTab.tsx index b706d5d..e6f8e53 100644 --- a/frontend/src/components/WatchlistTab.tsx +++ b/frontend/src/components/WatchlistTab.tsx @@ -186,10 +186,23 @@ export function WatchlistTab({ spots, spotStatus, onSpotSelect, onSpotClick }: P } catch (e: any) { flash(String(e?.message ?? e), true); } }; + // Armed through a REF, checked synchronously: the state variable is captured + // at render time, so a quick double-click read the pre-arm value twice and + // both clicks merely armed — the bin turned red and nothing was ever removed. + const removeArmRef = useRef(''); const remove = async (call: string) => { - if (removeArm !== call) { setRemoveArm(call); window.setTimeout(() => setRemoveArm(''), 2500); return; } + if (removeArmRef.current !== call) { + removeArmRef.current = call; + setRemoveArm(call); + window.setTimeout(() => { + if (removeArmRef.current === call) { removeArmRef.current = ''; setRemoveArm(''); } + }, 3000); + return; + } + removeArmRef.current = ''; + setRemoveArm(''); try { await WatchlistRemove(call); await refresh(); } - catch (e: any) { setError(String(e?.message ?? e)); } + catch (e: any) { flash(String(e?.message ?? e), true); } }; const isOnAir = (e: WLEntry): boolean =>