// Generated, do not edit. sha256:a469a46a90e6bcc2ab27a831978cd788d57e02abb6e3347f99750cb9fb53c286 import { claimNextCommand, resolveCommand } from './data/commands.js'; import { CONFIG, PLACE_LABELS, hashFromLocation, commandTooLate } from '../shared/config.js'; import { t } from './i18n/index.js'; import { esc } from './ui/escape.js'; const TAB = (globalThis.crypto?.randomUUID?.() || `tab-${Date.now()}-${Math.random()}`).slice(0, 40); const KAN = Object.freeze(['navigate', 'locate']); let bezig = false; export function initCommands() { document.addEventListener('commands-changed', () => { pakOp(); }); pakOp(); } export async function pakOp() { if (bezig) return; bezig = true; try { const opdracht = await claimNextCommand(TAB, KAN); if (opdracht) await voerUit(opdracht); } catch { } finally { bezig = false; } } async function voerUit(opdracht) { if (opdracht.kind === 'locate') { await resolveCommand(opdracht.id, TAB, 'done', hashFromLocation(location.hash)); return; } if (opdracht.kind !== 'navigate') { await resolveCommand(opdracht.id, TAB, 'rejected', t('commands.unknownKind')); return; } const hash = opdracht.payload && typeof opdracht.payload.hash === 'string' ? opdracht.payload.hash : ''; if (!hash.startsWith('#/')) { await resolveCommand(opdracht.id, TAB, 'rejected', t('commands.badTarget')); return; } if (commandTooLate(opdracht.expiresAt)) { await resolveCommand(opdracht.id, TAB, 'expired', t('commands.tooLate')); return; } const doorgaan = await aftellen(plekNaam(opdracht.payload)); if (!doorgaan) { await resolveCommand(opdracht.id, TAB, 'rejected', t('commands.stopped')); return; } location.hash = hash; await resolveCommand(opdracht.id, TAB, 'done'); } function plekNaam({ route, tab, sub }) { const label = (id) => { try { return t(PLACE_LABELS[id] || `nav.${id}`); } catch { return id; } }; return [label(route), tab && label(tab), sub && label(sub)].filter(Boolean).join(' → '); } let directVoortaan = false; function toonBalk(inhoud) { const bar = document.createElement('div'); bar.className = 'cmd-bar'; bar.setAttribute('role', 'alert'); bar.innerHTML = inhoud; document.body.appendChild(bar); return bar; } const knop = (data, tekst, soort = 'secondary') => ``; const knoppen = (...items) => `
`; function meldDirect(plek) { const bar = toonBalk(`` + knoppen(knop('data-countdown-back', t('commands.countdownBack')))); const weg = setTimeout(() => bar.remove(), CONFIG.COMMANDS.NOTICE_SECONDS * 1000); bar.querySelector('[data-countdown-back]').addEventListener('click', () => { directVoortaan = false; clearTimeout(weg); bar.remove(); }); } function aftellen(plek) { if (directVoortaan) { meldDirect(plek); return Promise.resolve(true); } const seconden = CONFIG.COMMANDS.COUNTDOWN_SECONDS; return new Promise((klaar) => { let over = seconden; const tekst = () => `${t('commands.goingTo')} ${esc(plek)} (${over})`; const bar = toonBalk(`` + knoppen( knop('data-now', t('commands.goNow'), 'primary'), knop('data-always', t('commands.goAlways')), knop('data-stop', t('commands.stop')), )); const op = (doorgaan) => { clearInterval(tik); document.removeEventListener('keydown', opEscape); bar.remove(); klaar(doorgaan); }; const opEscape = (e) => { if (e.key === 'Escape') op(false); }; bar.querySelector('[data-stop]').addEventListener('click', () => op(false)); const nu = bar.querySelector('[data-now]'); nu.addEventListener('click', () => op(true)); nu.focus(); bar.querySelector('[data-always]').addEventListener('click', () => { directVoortaan = true; op(true); }); document.addEventListener('keydown', opEscape); const tik = setInterval(() => { over -= 1; if (over <= 0) { op(true); return; } bar.querySelector('.cmd-bar-text').innerHTML = tekst(); }, 1000); }); }