explodorama / files / src / ui / toast.ts
toast.ts
b89399da 2026-11-01 Pavel Safronov | 1 | /** |
| 2 | * A toast (user request, 2026-11-01): a short note over the board that fades by itself, for what | |
| 3 | * the player got when no dialog explains it (a charge picked up for the second time in a run; the | |
| 4 | * icons in the top bar are small). One at a time; a new one replaces the one showing. | |
| 5 | */ | |
| 6 | const SHOW_MS = 2200 | |
| 7 | ||
| 8 | let el: HTMLElement | null = null | |
| 9 | let timer = 0 | |
| 10 | ||
| 11 | /** | |
| 12 | * What a charge pickup says: `n` picked up, and the total held when that is more (2 held and 3 | |
| 13 | * picked up: "Picked up 3 × Nuke", "5 charges in all"; user request, 2026-11-01). | |
| 14 | */ | |
| 15 | export function chargeToast(name: string, n: number, total: number): { title: string; text: string } { | |
| 16 | return { title: n > 1 ? `Picked up ${n} × ${name}` : `Picked up ${name}`, text: total > n ? `${total} charges in all` : '' } | |
| 17 | } | |
| 18 | ||
| 19 | export function showToast(icon: string, title: string, text: string): void { | |
| 20 | if (!el) { | |
| 21 | el = document.createElement('div') | |
| 22 | el.id = 'toast' | |
| 23 | el.setAttribute('role', 'status') | |
| 24 | // In the top layer, so it also shows over a dialog (the almanac's samples). | |
| 25 | el.popover = 'manual' | |
| 26 | document.body.append(el) | |
| 27 | } | |
| 28 | el.innerHTML = `<img src="${icon}" alt="" draggable="false"><div><strong>${title}</strong>${text ? `<span>${text}</span>` : ''}</div>` | |
| 29 | el.classList.remove('show') | |
| 30 | if (!el.matches(':popover-open')) el.showPopover?.() | |
| 31 | // Restarts the fade when one replaces another. | |
| 32 | void el.offsetWidth | |
| 33 | el.classList.add('show') | |
| 34 | window.clearTimeout(timer) | |
| 35 | timer = window.setTimeout(() => { | |
| 36 | el?.classList.remove('show') | |
| 37 | // Hidden once the fade is done. | |
| 38 | window.setTimeout(() => !el?.classList.contains('show') && el?.hidePopover?.(), 300) | |
| 39 | }, SHOW_MS) | |
| 40 | } |