diff --git a/src/main/resources/static/js/copyright-notices.js b/src/main/resources/static/js/copyright-notices.js new file mode 100644 index 0000000..ac189ba --- /dev/null +++ b/src/main/resources/static/js/copyright-notices.js @@ -0,0 +1,137 @@ +/** + * Copyright notices panel for the broadcaster dashboard. + * + * On load: fetches any pending (NOTIFIED) copyright notices and renders them. + * Dismiss button: acknowledges the notice via API (→ RESOLVED) and removes it. + * WebSocket: subscribes to the channel topic and refreshes on COPYRIGHT_WARNING. + */ +(function () { + const panel = document.getElementById("copyright-notices-panel"); + const list = document.getElementById("copyright-notices-list"); + + if (!panel || !list || typeof broadcaster === "undefined") return; + + // ── Helpers ─────────────────────────────────────────────────────────────── + function csrfHeaders() { + const token = document.querySelector("meta[name='_csrf']")?.content ?? ""; + const header = document.querySelector("meta[name='_csrf_header']")?.content ?? "X-XSRF-TOKEN"; + return { [header]: token }; + } + + function escHtml(str) { + if (!str) return ""; + return String(str) + .replace(/&/g, "&").replace(//g, ">").replace(/"/g, """); + } + + function formatDate(iso) { + if (!iso) return ""; + try { return new Date(iso).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric" }); } + catch { return iso; } + } + + // ── Render ──────────────────────────────────────────────────────────────── + function renderNotices(notices) { + if (!notices || notices.length === 0) { + panel.classList.add("hidden"); + return; + } + panel.classList.remove("hidden"); + list.innerHTML = ""; + for (const notice of notices) { + list.appendChild(buildNoticeItem(notice)); + } + } + + function buildNoticeItem(notice) { + const li = document.createElement("li"); + li.className = "copyright-notice-item"; + li.dataset.reportId = notice.id; + li.innerHTML = ` +
Received ${escHtml(formatDate(notice.updatedAt))}
+