Versie 0.2.0
This commit is contained in:
commit
e77d8fd373
495 files changed
+81026
No files matched your search
@@ -0,0 +1,123 @@
|
||||
// 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') =>
|
||||
`<button type="button" class="btn btn-${soort} btn-sm" ${data}>${tekst}</button>`;
|
||||
|
||||
const knoppen = (...items) => `<div class="cmd-bar-buttons">${items.join('')}</div>`;
|
||||
|
||||
function meldDirect(plek) {
|
||||
const bar = toonBalk(`<span class="cmd-bar-text">${t('commands.movedTo')} <strong>${esc(plek)}</strong></span>`
|
||||
+ 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')} <strong>${esc(plek)}</strong> (${over})`;
|
||||
const bar = toonBalk(`<span class="cmd-bar-text">${tekst()}</span>`
|
||||
+ 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);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user