fix(watchlist): remove on a single click, like the bell and trophy beside it

The two-click arm goes: removing an entry is cheap to undo (type it again), so
it does not earn a confirmation its neighbours do not have. The bin reddens on
hover and the green line confirms the removal.
This commit is contained in:
2026-08-29 01:36:06 +02:00
parent 9350af9589
commit 107c6fccf6
2 changed files with 8 additions and 19 deletions
+6 -17
View File
@@ -94,7 +94,7 @@ export function WatchlistTab({ spots, spotStatus, onSpotSelect, onSpotClick }: P
setNotice(isError ? '' : msg);
noticeTimer.current = window.setTimeout(() => { setError(''); setNotice(''); }, 4000) as unknown as number;
};
const [removeArm, setRemoveArm] = useState('');
// worked answer per "call|band|modeclass|contest" key.
const [worked, setWorked] = useState<Record<string, boolean>>({});
@@ -186,22 +186,11 @@ 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('');
// One click, like the bell and the trophy beside it: removing a watchlist
// entry is cheap to undo (type it again), so it does not earn a confirmation
// the other two buttons do not have.
const remove = async (call: string) => {
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(); }
try { await WatchlistRemove(call); flash(t('wl.removed', { call }), false); await refresh(); }
catch (e: any) { flash(String(e?.message ?? e), true); }
};
@@ -376,7 +365,7 @@ export function WatchlistTab({ spots, spotStatus, onSpotSelect, onSpotClick }: P
</button>
<button type="button" title={t('wl.remove')}
onClick={() => void remove(e.callsign)}
className={cn('p-1 rounded hover:bg-muted', removeArm === e.callsign ? 'text-danger' : 'text-muted-foreground/40')}>
className="p-1 rounded hover:bg-muted text-muted-foreground/40 hover:text-danger">
<Trash2 className="size-3.5" />
</button>
</div>