'use strict'; // ---- Notifications: a bell with the count of things you have not seen yet (chat, reminders, announcements); tapping it opens the list. let inboxN = 0; const inboxBell = () => ``; function inboxWire() { const b = document.getElementById('inboxbtn'); if (b) b.onclick = inboxOpen; inboxPaint(); inboxCount(); } function inboxPaint() { const n = document.getElementById('inboxn'); if (n) { n.hidden = !inboxN; n.textContent = inboxN > 99 ? '99+' : inboxN; } } async function inboxCount() { try { const r = await jfetch('/api/inbox'); inboxN = r.unread; inboxPaint(); } catch {} } setInterval(() => { if (!document.hidden && typeof ME !== 'undefined' && ME && document.getElementById('inboxbtn')) inboxCount(); }, 45000); const inboxAgo = t => { const m = Math.round((Date.now() - t) / 6e4); return m < 1 ? 'now' : m < 60 ? m + ' min ago' : m < 1440 ? Math.round(m / 60) + ' h ago' : new Date(t).toLocaleDateString(undefined, { month: 'short', day: 'numeric' }); }; const INBOX_ICON = { chat: ['chat', '#2aa6a0'], remind: ['bell', '#e0742b'], announce: ['bell', '#5b8def'] }; async function inboxOpen() { const el = openSheet('Notifications', '', '

Loading…

'); let items = []; const draw = () => { const l = el.querySelector('#inboxl'); if (!l) return; el.querySelector('#inboxbar').hidden = !items.length; l.innerHTML = items.length ? `
${items.map(i => { const [ic, col] = INBOX_ICON[i.kind] || ['bell', '#6a7280']; return `${icon(ic)}${esc(i.title)}${i.count > 1 ? ` (${i.count})` : ''}${esc(i.body)}${inboxAgo(i.at)}${i.read ? '' : ''}`; }).join('')}
` : '

Nothing yet. Messages, reminders and announcements will show up here.

'; l.querySelectorAll('a.row').forEach(a => a.addEventListener('click', () => { const id = a.dataset.id; jfetch('/api/inbox/read', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id }) }).then(r => { inboxN = r.unread; inboxPaint(); }).catch(() => {}); closeSheet(); })); }; try { const r = await jfetch('/api/inbox'); items = r.items; inboxN = r.unread; inboxPaint(); } catch (e) { toast(e.message); } draw(); const post = (p, b) => jfetch('/api/inbox/' + p, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(b || {}) }); el.querySelector('#inboxall').onclick = async () => { try { const r = await post('read', { all: true }); items.forEach(i => i.read = true); inboxN = r.unread; inboxPaint(); draw(); } catch (e) { toast(e.message); } }; el.querySelector('#inboxclr').onclick = async () => { try { await post('clear'); items = []; inboxN = 0; inboxPaint(); draw(); } catch (e) { toast(e.message); } }; }