53 lines
2 KiB
JavaScript
53 lines
2 KiB
JavaScript
// Broadcast banner — polls /api/broadcast/current every 60s (Phase 3/4)
|
|
(function () {
|
|
'use strict';
|
|
const POLL_MS = 60000;
|
|
const DISMISS_KEY = 'jae-broadcast-dismissed';
|
|
|
|
function ready(fn) { if (document.readyState !== 'loading') fn(); else document.addEventListener('DOMContentLoaded', fn); }
|
|
|
|
function renderBanner(data) {
|
|
const dismissed = localStorage.getItem(DISMISS_KEY);
|
|
const fingerprint = (data.created_at || '') + '|' + (data.message || '');
|
|
if (dismissed === fingerprint) return;
|
|
let el = document.getElementById('jaeBroadcastBanner');
|
|
if (!el) {
|
|
el = document.createElement('div');
|
|
el.id = 'jaeBroadcastBanner';
|
|
el.className = 'jae-broadcast';
|
|
document.body.appendChild(el);
|
|
}
|
|
el.innerHTML = `
|
|
<span class="jbb-icon">📣</span>
|
|
<span class="jbb-msg"></span>
|
|
<button type="button" class="jbb-close" aria-label="Dismiss">✕</button>`;
|
|
el.querySelector('.jbb-msg').textContent = data.message || '';
|
|
el.querySelector('.jbb-close').onclick = () => {
|
|
localStorage.setItem(DISMISS_KEY, fingerprint);
|
|
el.remove();
|
|
document.body.classList.remove('has-broadcast');
|
|
};
|
|
document.body.classList.add('has-broadcast');
|
|
}
|
|
|
|
function hideBanner() {
|
|
const el = document.getElementById('jaeBroadcastBanner');
|
|
if (el) el.remove();
|
|
document.body.classList.remove('has-broadcast');
|
|
}
|
|
|
|
async function check() {
|
|
try {
|
|
const res = await fetch('/api/broadcast/current', { cache: 'no-store' });
|
|
if (res.status === 204) { hideBanner(); return; }
|
|
if (!res.ok) return;
|
|
const data = await res.json();
|
|
if (data && data.message) renderBanner(data); else hideBanner();
|
|
} catch (e) { /* offline: ignore */ }
|
|
}
|
|
|
|
ready(function () {
|
|
check();
|
|
setInterval(check, POLL_MS);
|
|
});
|
|
})();
|