/** * The popup's wording, kept apart from its DOM so the specs can load it * (test/popup-format.spec.js). Classic script, like the rest of lib/. */ /** * One line of state for a source row, from /api/sources' fields, with the * status class the popup colours it by ('ready' | 'error' | 'no-cookies' for * a warning | '' for plain). The most actionable fact wins: an error before * a running backfill, a backfill before the last-checked time. */ function sourceStatus(src, now = Date.now()) { if (!src.enabled) return { text: 'Disabled', kind: '' }; if (src.last_error) { const first = String(src.last_error).split('\n')[0].trim(); const short = first.length > 90 ? `${first.slice(0, 89)}…` : first; return { text: `Error — ${short}`, kind: 'error' }; } if (src.backfill_state === 'running') { const n = src.backfill_chunks || 0; return { text: n ? `Backfilling — ${n} chunk${n === 1 ? '' : 's'} done` : 'Backfill queued', kind: 'ready' }; } if (src.backfill_state === 'stalled') return { text: 'Backfill stalled', kind: 'no-cookies' }; if (!src.last_checked_at) return { text: 'Not checked yet', kind: '' }; return { text: `Checked ${relativeTime(src.last_checked_at, now)}`, kind: '' }; } // Same buckets and wording as the web UI's canonical formatRelative // (frontend/src/utils/date.js, snippet #3959) — the extension can't import it (classic // scripts, separate package), so it mirrors it: "42s ago", "5m ago", "3h ago", // "2d ago", and "Never" for a missing or unreadable time. function relativeTime(iso, now = Date.now()) { const t = iso ? Date.parse(iso) : NaN; if (Number.isNaN(t)) return 'Never'; const abs = Math.abs(now - t) / 1000; let body; if (abs < 60) body = `${Math.floor(abs)}s`; else if (abs < 3600) body = `${Math.floor(abs / 60)}m`; else if (abs < 86400) body = `${Math.floor(abs / 3600)}h`; else body = `${Math.floor(abs / 86400)}d`; return `${body} ago`; } /** * The popup message after a Discord token export, from FC's verify of the * stored token: {text, kind} with kind 'success' | 'warning' | 'error'. * valid=null is "FC couldn't test it" (no Discord source yet, or a network * hiccup) — a warning with FC's reason, never a failure. */ function tokenExportMessage(verify) { if (!verify) return { text: 'Discord: token exported', kind: 'success' }; if (verify.valid === true) return { text: `Discord: token exported and verified ✓ — ${verify.reason}`, kind: 'success' }; if (verify.valid === false) return { text: `Discord: token exported, but FC's check failed — ${verify.reason}`, kind: 'error' }; return { text: `Discord: token exported (not verified — ${verify.reason})`, kind: 'warning' }; }