fix: forcing 3 sec for each notification instead of one replacing the other

This commit is contained in:
2026-06-28 19:12:55 +02:00
parent 165f33caa5
commit 76c1e2df60
+18 -4
View File
@@ -490,11 +490,25 @@ export default function App() {
}; };
// Transient success toast (bottom-right, auto-dismiss). Used for things // Transient success toast (bottom-right, auto-dismiss). Used for things
// like "spot sent" where a blocking error banner would be overkill. // like "spot sent" where a blocking error banner would be overkill.
// Toasts are QUEUED so two firing at once don't clobber each other: each shows
// for 3s, then the next takes over (no gap). `toast` is the one on screen now.
const [toast, setToast] = useState(''); const [toast, setToast] = useState('');
const showToast = useCallback((msg: string) => { const toastQueue = useRef<string[]>([]);
setToast(msg); const toastTimer = useRef<number | undefined>(undefined);
window.setTimeout(() => setToast((t) => (t === msg ? '' : t)), 3500); const advanceToast = useCallback(() => {
const next = toastQueue.current.shift();
if (next === undefined) { toastTimer.current = undefined; setToast(''); return; }
setToast(next);
toastTimer.current = window.setTimeout(advanceToast, 3000);
}, []); }, []);
const showToast = useCallback((msg: string) => {
toastQueue.current.push(msg);
if (toastTimer.current === undefined) advanceToast(); // nothing showing → start now
}, [advanceToast]);
const dismissToast = useCallback(() => {
if (toastTimer.current !== undefined) { window.clearTimeout(toastTimer.current); toastTimer.current = undefined; }
advanceToast(); // skip to the next queued toast (or clear if none)
}, [advanceToast]);
// Error banners auto-dismiss after a few seconds (longer than toasts since // Error banners auto-dismiss after a few seconds (longer than toasts since
// they may be multi-line). The X button still closes them immediately. // they may be multi-line). The X button still closes them immediately.
useEffect(() => { useEffect(() => {
@@ -2878,7 +2892,7 @@ export default function App() {
<div className="flex items-center gap-1.5 rounded-md border border-emerald-300 bg-emerald-50 text-emerald-800 px-2.5 py-1 text-xs shadow min-w-0 animate-in fade-in"> <div className="flex items-center gap-1.5 rounded-md border border-emerald-300 bg-emerald-50 text-emerald-800 px-2.5 py-1 text-xs shadow min-w-0 animate-in fade-in">
<Satellite className="size-3.5 shrink-0" /> <Satellite className="size-3.5 shrink-0" />
<span className="truncate" title={toast}>{toast}</span> <span className="truncate" title={toast}>{toast}</span>
<button className="shrink-0 text-emerald-600 hover:text-emerald-800" onClick={() => setToast('')}><X className="size-3" /></button> <button className="shrink-0 text-emerald-600 hover:text-emerald-800" onClick={dismissToast}><X className="size-3" /></button>
</div> </div>
)} )}
</div> </div>