'use strict'; // ---- Boot (async () => { try { cfg = { ...cfg, ...(await (await fetch('/api/config')).json()) }; } catch {} const loadedBuild = cfg.build; // When a new version is deployed, an open page keeps running the old one. Tell the person, and offer a reload. const checkForUpdate = async () => { try { const c = await (await fetch('/api/config', { cache: 'no-store' })).json(); if (c.build && loadedBuild && c.build !== loadedBuild && !document.getElementById('upd')) { const b = document.createElement('div'); b.id = 'upd'; b.innerHTML = 'A new version of NE Hub is available. '; document.body.appendChild(b); document.getElementById('updgo').onclick = () => location.reload(); } } catch {} }; document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') checkForUpdate(); }); setInterval(checkForUpdate, 10 * 60e3); await loadMe(); await loadSettings(); sgStart(); addEventListener('hashchange', route); restorePlayer(); route(); shareCheck(); // Unread mail and tasks due (the badge): checked on a timer only while the app is on screen, and again the moment you come back to it. const badgePoll = () => { mailPoll(); taskPoll(); }; let lastBadge = Date.now(); badgePoll(); setInterval(() => { if (document.visibilityState === 'visible') { lastBadge = Date.now(); badgePoll(); } }, 2 * 60e3); document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible' && Date.now() - lastBadge > 30e3) { lastBadge = Date.now(); badgePoll(); } }); if ('serviceWorker' in navigator) navigator.serviceWorker.register('/sw.js').catch(() => {}); })(); // Keyboard (desktop): space play/pause, arrows seek, N/P next/previous. addEventListener('keydown', e => { const tag = e.target.tagName || '', k = e.key; if (e.metaKey || e.ctrlKey || e.altKey || !cur() || document.body.classList.contains('onvideo') || /^(INPUT|TEXTAREA|SELECT)$/.test(tag) || (k === ' ' && /^(BUTTON|A)$/.test(tag))) return; if (k === ' ') { e.preventDefault(); toggle(); } else if (k === 'ArrowRight') pl.a.currentTime += 10; else if (k === 'ArrowLeft') pl.a.currentTime = Math.max(0, pl.a.currentTime - 10); else if (k === 'n' || k === 'N') next(); else if (k === 'p' || k === 'P') prev(); });