@hadoku/watchparty-ui 0.45.5 → 0.45.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import { jsxs as n, jsx as t } from "react/jsx-runtime";
2
- import { h as M, aM as R, $ as E } from "./index-lPWsskGR.js";
2
+ import { h as M, aM as R, $ as E } from "./index-CAgGwvLq.js";
3
3
  import { useState as f, useRef as $, useCallback as A, useEffect as F } from "react";
4
- import { l as I, a as w, m as P, n as B, r as T, o as D, p as C } from "./submissionsApi-CvdxT0zS.js";
5
- import { c as O, B as U } from "./Room-DMSh2z9X.js";
4
+ import { l as I, a as w, m as P, n as B, r as T, o as D, p as C } from "./submissionsApi-jhq3K3jW.js";
5
+ import { c as O, B as U } from "./Room-BqE-eDH3.js";
6
6
  const H = 5e3, q = 8e3;
7
7
  function K() {
8
8
  const [s, r] = f(null), [d, m] = f(null), [c, a] = f({}), [i, p] = f(null), [x, b] = f(null), [v, h] = f(""), [y, L] = f(() => Date.now()), g = $(!0), _ = A(async () => {
@@ -224,4 +224,4 @@ function z({ client: s, initial: r }) {
224
224
  export {
225
225
  Z as default
226
226
  };
227
- //# sourceMappingURL=AdminPanel-B5HNXwP1.js.map
227
+ //# sourceMappingURL=AdminPanel-CugvCe_J.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminPanel-B5HNXwP1.js","sources":["../../src/components/SubmissionQueue.tsx","../../src/components/AdminPanel.tsx"],"sourcesContent":["/**\n * The operator's moderation queue — every `pending` submission, with approve\n * and reject per row. Service tier only (the routes are `serviceAuth`; the\n * caller gates rendering on `isPrivileged()`, and a refusal is shown rather\n * than hidden if the gate and the server ever disagree).\n *\n * A row the server says has already moved (409, or 404 once it is gone) is not\n * an error in the click — a stale queue page is the ordinary way to meet it —\n * so it stays in place carrying the outcome, then drops off after\n * `NOTE_LINGER_MS`. Dropping it at once would make the click look like it did\n * nothing.\n *\n * Buttons carry real classes (`.drawer-btn`): the unlayered `button` reset\n * discards every Tailwind colour/font utility on a `<button>`.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { TSubmission } from '@watchparty/shared';\n/** `TSubmission` plus the `series` field the shared schema gains for magnets\n * (packages/shared/src/submissions.ts) — a cast rather than a schema edit,\n * since this file does not own that schema; harmless once the real field\n * lands, since the shapes agree. */\ntype SubmissionWithSeries = TSubmission & { series?: string };\nimport {\n approveSubmission,\n decisionFailureLabel,\n decisionMeansRowMoved,\n fetchPendingSubmissions,\n formatSubmissionAge,\n rejectSubmission,\n submissionFailureLabel,\n type SubmissionFailure,\n} from '../lib/submissionsApi';\n\nconst POLL_MS = 5000;\nconst NOTE_LINGER_MS = 8000;\n\ninterface Note { row: TSubmission; message: string; tone: 'info' | 'error' }\n\nexport default function SubmissionQueue() {\n const [rows, setRows] = useState<TSubmission[] | null>(null);\n const [listFailure, setListFailure] = useState<SubmissionFailure | null>(null);\n const [notes, setNotes] = useState<Record<string, Note>>({});\n const [busyId, setBusyId] = useState<string | null>(null);\n const [rejectingId, setRejectingId] = useState<string | null>(null);\n const [reason, setReason] = useState('');\n const [now, setNow] = useState(() => Date.now());\n const liveRef = useRef(true);\n\n const refresh = useCallback(async () => {\n const res = await fetchPendingSubmissions();\n if (!liveRef.current) return;\n setNow(Date.now());\n if (res.ok) { setRows(res.value); setListFailure(null); }\n else { setListFailure(res.failure); }\n }, []);\n\n useEffect(() => {\n liveRef.current = true;\n // Deferred a tick: the first read is a subscription callback, not a\n // synchronous setState in the effect body.\n const first = setTimeout(() => { void refresh(); }, 0);\n const timer = setInterval(() => { void refresh(); }, POLL_MS);\n return () => { liveRef.current = false; clearTimeout(first); clearInterval(timer); };\n }, [refresh]);\n\n function leaveNote(row: TSubmission, message: string, tone: Note['tone']) {\n setNotes(prev => ({ ...prev, [row.id]: { row, message, tone } }));\n setTimeout(() => {\n if (!liveRef.current) return;\n setNotes(prev => Object.fromEntries(Object.entries(prev).filter(([id]) => id !== row.id)));\n }, NOTE_LINGER_MS);\n }\n\n async function decide(row: TSubmission, verb: 'approve' | 'reject') {\n if (busyId) return;\n setBusyId(row.id);\n const res = verb === 'approve'\n ? await approveSubmission(row.id)\n : await rejectSubmission(row.id, reason);\n setBusyId(null);\n if (!liveRef.current) return;\n if (res.ok) {\n setRejectingId(null);\n setReason('');\n setRows(prev => (prev ?? []).filter(r => r.id !== row.id));\n leaveNote(row, res.value.state, 'info');\n } else if (decisionMeansRowMoved(res.failure)) {\n setRejectingId(null);\n setRows(prev => (prev ?? []).filter(r => r.id !== row.id));\n leaveNote(row, decisionFailureLabel(res.failure), 'error');\n } else {\n leaveNote(row, decisionFailureLabel(res.failure), 'error');\n }\n void refresh();\n }\n\n const shown = [\n ...(rows ?? []).map(r => ({ row: r, note: notes[r.id] })),\n ...Object.values(notes)\n .filter(n => !(rows ?? []).some(r => r.id === n.row.id))\n .map(n => ({ row: n.row, note: n })),\n ];\n\n // Nothing to moderate is shown as nothing — no header, no \"(none)\". A list\n // failure still renders, since that IS state the leader needs to see.\n if (!listFailure && shown.length === 0) return null;\n\n return (\n <section className=\"border-t border-border pt-2\" data-testid=\"submission-queue\">\n <div className=\"flex items-center px-1 pb-1\">\n <span className=\"text-[10px] uppercase tracking-wider text-text-muted\">Submissions</span>\n <span className=\"ml-1 text-[10px] text-text-muted\" data-testid=\"submission-queue-count\">\n {rows?.length ?? 0}\n </span>\n </div>\n {listFailure && (\n <div className=\"px-2 py-1 text-[11px] bg-danger-bg text-on-danger-bg rounded\">{submissionFailureLabel(listFailure)}</div>\n )}\n <ul className=\"list-none m-0 p-0\">\n {shown.map(({ row, note }) => {\n const decided = note && !(rows ?? []).some(r => r.id === row.id);\n return (\n <li\n key={row.id}\n className=\"px-1 py-1.5 border-b border-border/50 flex flex-col gap-1\"\n data-submission-id={row.id}\n data-submission-state={decided ? 'decided' : row.state}\n data-submission-kind={row.kind}\n data-submission-series={(row as SubmissionWithSeries).series ?? ''}\n >\n <div className=\"flex items-center gap-2 text-[11px] min-w-0\">\n <span className=\"text-[10px] uppercase tracking-wider text-text-muted shrink-0\">{row.kind}</span>\n <span className=\"text-text truncate flex-1\" title={row.source}>\n {(row as SubmissionWithSeries).series\n ? `${(row as SubmissionWithSeries).series} — ${row.title || row.source}`\n : (row.title || row.source)}\n </span>\n <span className=\"text-text-muted shrink-0\">{formatSubmissionAge(row.createdAt, now)}</span>\n </div>\n <div className=\"text-[10px] text-text-muted truncate\" title={row.ownerUserId}>{row.ownerUserId}</div>\n {note && (\n <div\n data-testid=\"submission-decision-note\"\n className={`text-[11px] px-1.5 py-0.5 rounded ${note.tone === 'error' ? 'bg-danger-bg text-on-danger-bg' : 'bg-success-bg text-on-success-bg'}`}\n >\n {note.message}\n </div>\n )}\n {!decided && rejectingId === row.id ? (\n <div className=\"flex items-center gap-1\">\n <input\n value={reason}\n onChange={e => setReason(e.target.value)}\n onKeyDown={e => { if (e.key === 'Enter') void decide(row, 'reject'); }}\n aria-label=\"Reject reason\"\n placeholder=\"reason\"\n className=\"flex-1 min-w-0 bg-bg-alt border border-border outline-none px-2 py-0.5 rounded text-[11px]\"\n />\n <button\n className=\"drawer-btn drawer-btn-danger\"\n aria-label=\"Confirm reject\"\n disabled={busyId === row.id}\n onClick={() => { void decide(row, 'reject'); }}\n >\n Reject\n </button>\n <button\n className=\"drawer-btn\"\n aria-label=\"Cancel reject\"\n onClick={() => { setRejectingId(null); setReason(''); }}\n >\n Cancel\n </button>\n </div>\n ) : !decided && (\n <div className=\"flex items-center gap-1\">\n <button\n className=\"drawer-btn drawer-btn-primary\"\n aria-label=\"Approve submission\"\n disabled={busyId === row.id}\n onClick={() => { void decide(row, 'approve'); }}\n >\n Approve\n </button>\n <button\n className=\"drawer-btn\"\n aria-label=\"Reject submission\"\n disabled={busyId === row.id}\n onClick={() => { setRejectingId(row.id); setReason(''); }}\n >\n Reject\n </button>\n </div>\n )}\n </li>\n );\n })}\n </ul>\n </section>\n );\n}\n","import { useAppStore } from '../lib/store';\nimport { BUFFER_AHEAD_MS, type TClientHealth } from '@watchparty/shared';\nimport { isPrivileged } from '../lib/auth';\nimport SubmissionQueue from './SubmissionQueue';\nimport { bufferHealthLevel, BUFFER_HEALTH_LABEL } from './bufferHealth';\n\n/**\n * Health monitor panel — renders as sidebar content (replaces chat when active).\n * Shows a card per connected client with live health metrics.\n */\nexport default function AdminPanel() {\n const healthSnapshot = useAppStore(s => s.healthSnapshot);\n\n const clients = healthSnapshot?.clients ?? [];\n // Slowest download first — easiest to spot struggling clients\n const sorted = [...clients].sort((a, b) => a.avg_download_rate_bps - b.avg_download_rate_bps);\n\n const initials = computeInitials(sorted);\n // Moderation is service tier, like the routes behind it.\n const queue = isPrivileged() ? <SubmissionQueue /> : null;\n\n if (clients.length === 0) {\n return (\n <div className=\"flex-1 overflow-y-auto p-2 flex flex-col\">\n <div className=\"flex-1 flex items-center justify-center p-4\">\n <p className=\"text-text-muted text-xs text-center\">\n No health data yet.<br />Clients report once media is loaded.\n </p>\n </div>\n {queue}\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 overflow-y-auto p-2 space-y-2\">\n {sorted.map(c => <ClientCard key={c.client_id} client={c} initial={initials[c.client_id]} />)}\n {queue}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n\nfunction formatTime(ms: number): string {\n const totalSecs = Math.floor(ms / 1000);\n const mins = Math.floor(totalSecs / 60);\n const secs = totalSecs % 60;\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n\n// Initials are first alphanumeric of display name; on conflict, advance to next\n// unused alphanumeric letter in the same name. Stable across renders via client_id sort.\nfunction computeInitials(clients: TClientHealth[]): Record<string, string> {\n const out: Record<string, string> = {};\n const taken = new Set<string>();\n const ordered = [...clients].sort((a, b) => a.client_id.localeCompare(b.client_id));\n for (const c of ordered) {\n const name = c.name ?? '';\n let chosen = '?';\n for (const ch of name) {\n if (!/[\\p{L}\\p{N}]/u.test(ch)) continue;\n const up = ch.toUpperCase();\n if (!taken.has(up)) { chosen = up; taken.add(up); break; }\n }\n out[c.client_id] = chosen;\n }\n return out;\n}\n\nfunction ClientCard({ client, initial }: { client: TClientHealth; initial: string }) {\n const dlKbps = Math.round(client.avg_download_rate_bps / 1024);\n const dlMbps = (dlKbps / 1024).toFixed(1);\n const bufferS = (client.buffered_ahead_ms / 1000).toFixed(1);\n const rtt = Math.round(client.rtt_ms);\n\n // Idle: not playing, no meaningful position — don't alarm about \"Critical\".\n // Near end-of-stream is exempt from the buffered-ahead thresholds (see\n // bufferHealth.ts) so the final seconds of every episode don't false-Critical.\n const level = bufferHealthLevel(client);\n // A connected client whose reports stopped arriving: the figures below are\n // its last known state, and the silence itself is the status.\n const silent = client.stale_ms !== undefined;\n const statusLabel = silent ? `Silent ${Math.round(client.stale_ms! / 1000)}s` : BUFFER_HEALTH_LABEL[level];\n const isRed = silent || level === 'critical' || level === 'buffering';\n const statusClasses = isRed\n ? 'text-danger bg-danger/10'\n : level === 'idle'\n ? 'text-text-muted bg-bg-alt/40'\n : level === 'warning'\n ? 'text-on-neutral-bg bg-neutral/10'\n : 'text-success bg-success/10';\n\n const barColor = isRed ? 'bg-danger' : level === 'warning' ? 'bg-neutral-bg' : 'bg-success';\n const barPct = Math.min(100, (client.buffered_ahead_ms / BUFFER_AHEAD_MS) * 100);\n\n return (\n <div className=\"rounded-lg border border-border/50 bg-bg-alt/20 p-2.5\" data-silent={silent || undefined}>\n {/* Row 1: Name + Status */}\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <div className=\"w-5 h-5 rounded-full bg-bg-alt flex items-center justify-center text-[9px] font-semibold shrink-0\">\n {initial}\n </div>\n <span className=\"text-sm font-medium text-text truncate\">{client.name}</span>\n </div>\n <span className={`inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium shrink-0 ${statusClasses}`}>\n {statusLabel}\n </span>\n </div>\n\n {/* Row 2: Stats grid */}\n <div className={`grid grid-cols-3 gap-x-2 gap-y-1 text-[11px] ${silent ? 'opacity-50' : ''}`}>\n <div>\n <span className=\"text-text-muted\">DL</span>\n <span className=\"ml-1 font-mono text-text\">{dlMbps}</span>\n <span className=\"text-text-muted ml-0.5\">Mbps</span>\n </div>\n <div>\n <span className=\"text-text-muted\">Ping</span>\n <span className=\"ml-1 font-mono text-text\">{rtt}</span>\n <span className=\"text-text-muted ml-0.5\">ms</span>\n </div>\n <div>\n <span className=\"text-text-muted\">Pos</span>\n <span className=\"ml-1 font-mono text-text-secondary\">{formatTime(client.playhead_ms)}</span>\n </div>\n\n {/* Buffer row spans full width */}\n <div className=\"col-span-2 flex items-center gap-1.5\">\n <span className=\"text-text-muted\">Buf</span>\n <span className=\"font-mono text-text\">{bufferS}s</span>\n <div className=\"flex-1 h-1 bg-bg-alt rounded-full overflow-hidden\">\n <div className={`h-full rounded-full transition-all ${barColor}`} style={{ width: `${barPct}%` }} />\n </div>\n </div>\n <div className=\"flex gap-1 font-mono justify-end\">\n <span className=\"bg-success-bg text-on-success-bg px-1 rounded\">{client.fragments_loaded}L</span>\n <span className=\"text-text-muted\">{client.fragments_pending}P</span>\n {client.fragments_error > 0 && <span className=\"bg-danger-bg text-on-danger-bg px-1 rounded\">{client.fragments_error}E</span>}\n </div>\n </div>\n </div>\n );\n}\n"],"names":["POLL_MS","NOTE_LINGER_MS","SubmissionQueue","rows","setRows","useState","listFailure","setListFailure","notes","setNotes","busyId","setBusyId","rejectingId","setRejectingId","reason","setReason","now","setNow","liveRef","useRef","refresh","useCallback","res","fetchPendingSubmissions","useEffect","first","timer","leaveNote","row","message","tone","prev","id","decide","verb","approveSubmission","rejectSubmission","r","decisionMeansRowMoved","decisionFailureLabel","shown","n","jsxs","jsx","submissionFailureLabel","note","decided","e","AdminPanel","clients","useAppStore","s","sorted","b","initials","computeInitials","queue","isPrivileged","c","ClientCard","formatTime","ms","totalSecs","mins","secs","out","taken","ordered","a","name","chosen","ch","up","client","initial","dlMbps","bufferS","rtt","level","bufferHealthLevel","silent","statusLabel","BUFFER_HEALTH_LABEL","isRed","statusClasses","barColor","barPct","BUFFER_AHEAD_MS"],"mappings":"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"}
1
+ {"version":3,"file":"AdminPanel-CugvCe_J.js","sources":["../../src/components/SubmissionQueue.tsx","../../src/components/AdminPanel.tsx"],"sourcesContent":["/**\n * The operator's moderation queue — every `pending` submission, with approve\n * and reject per row. Service tier only (the routes are `serviceAuth`; the\n * caller gates rendering on `isPrivileged()`, and a refusal is shown rather\n * than hidden if the gate and the server ever disagree).\n *\n * A row the server says has already moved (409, or 404 once it is gone) is not\n * an error in the click — a stale queue page is the ordinary way to meet it —\n * so it stays in place carrying the outcome, then drops off after\n * `NOTE_LINGER_MS`. Dropping it at once would make the click look like it did\n * nothing.\n *\n * Buttons carry real classes (`.drawer-btn`): the unlayered `button` reset\n * discards every Tailwind colour/font utility on a `<button>`.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { TSubmission } from '@watchparty/shared';\n/** `TSubmission` plus the `series` field the shared schema gains for magnets\n * (packages/shared/src/submissions.ts) — a cast rather than a schema edit,\n * since this file does not own that schema; harmless once the real field\n * lands, since the shapes agree. */\ntype SubmissionWithSeries = TSubmission & { series?: string };\nimport {\n approveSubmission,\n decisionFailureLabel,\n decisionMeansRowMoved,\n fetchPendingSubmissions,\n formatSubmissionAge,\n rejectSubmission,\n submissionFailureLabel,\n type SubmissionFailure,\n} from '../lib/submissionsApi';\n\nconst POLL_MS = 5000;\nconst NOTE_LINGER_MS = 8000;\n\ninterface Note { row: TSubmission; message: string; tone: 'info' | 'error' }\n\nexport default function SubmissionQueue() {\n const [rows, setRows] = useState<TSubmission[] | null>(null);\n const [listFailure, setListFailure] = useState<SubmissionFailure | null>(null);\n const [notes, setNotes] = useState<Record<string, Note>>({});\n const [busyId, setBusyId] = useState<string | null>(null);\n const [rejectingId, setRejectingId] = useState<string | null>(null);\n const [reason, setReason] = useState('');\n const [now, setNow] = useState(() => Date.now());\n const liveRef = useRef(true);\n\n const refresh = useCallback(async () => {\n const res = await fetchPendingSubmissions();\n if (!liveRef.current) return;\n setNow(Date.now());\n if (res.ok) { setRows(res.value); setListFailure(null); }\n else { setListFailure(res.failure); }\n }, []);\n\n useEffect(() => {\n liveRef.current = true;\n // Deferred a tick: the first read is a subscription callback, not a\n // synchronous setState in the effect body.\n const first = setTimeout(() => { void refresh(); }, 0);\n const timer = setInterval(() => { void refresh(); }, POLL_MS);\n return () => { liveRef.current = false; clearTimeout(first); clearInterval(timer); };\n }, [refresh]);\n\n function leaveNote(row: TSubmission, message: string, tone: Note['tone']) {\n setNotes(prev => ({ ...prev, [row.id]: { row, message, tone } }));\n setTimeout(() => {\n if (!liveRef.current) return;\n setNotes(prev => Object.fromEntries(Object.entries(prev).filter(([id]) => id !== row.id)));\n }, NOTE_LINGER_MS);\n }\n\n async function decide(row: TSubmission, verb: 'approve' | 'reject') {\n if (busyId) return;\n setBusyId(row.id);\n const res = verb === 'approve'\n ? await approveSubmission(row.id)\n : await rejectSubmission(row.id, reason);\n setBusyId(null);\n if (!liveRef.current) return;\n if (res.ok) {\n setRejectingId(null);\n setReason('');\n setRows(prev => (prev ?? []).filter(r => r.id !== row.id));\n leaveNote(row, res.value.state, 'info');\n } else if (decisionMeansRowMoved(res.failure)) {\n setRejectingId(null);\n setRows(prev => (prev ?? []).filter(r => r.id !== row.id));\n leaveNote(row, decisionFailureLabel(res.failure), 'error');\n } else {\n leaveNote(row, decisionFailureLabel(res.failure), 'error');\n }\n void refresh();\n }\n\n const shown = [\n ...(rows ?? []).map(r => ({ row: r, note: notes[r.id] })),\n ...Object.values(notes)\n .filter(n => !(rows ?? []).some(r => r.id === n.row.id))\n .map(n => ({ row: n.row, note: n })),\n ];\n\n // Nothing to moderate is shown as nothing — no header, no \"(none)\". A list\n // failure still renders, since that IS state the leader needs to see.\n if (!listFailure && shown.length === 0) return null;\n\n return (\n <section className=\"border-t border-border pt-2\" data-testid=\"submission-queue\">\n <div className=\"flex items-center px-1 pb-1\">\n <span className=\"text-[10px] uppercase tracking-wider text-text-muted\">Submissions</span>\n <span className=\"ml-1 text-[10px] text-text-muted\" data-testid=\"submission-queue-count\">\n {rows?.length ?? 0}\n </span>\n </div>\n {listFailure && (\n <div className=\"px-2 py-1 text-[11px] bg-danger-bg text-on-danger-bg rounded\">{submissionFailureLabel(listFailure)}</div>\n )}\n <ul className=\"list-none m-0 p-0\">\n {shown.map(({ row, note }) => {\n const decided = note && !(rows ?? []).some(r => r.id === row.id);\n return (\n <li\n key={row.id}\n className=\"px-1 py-1.5 border-b border-border/50 flex flex-col gap-1\"\n data-submission-id={row.id}\n data-submission-state={decided ? 'decided' : row.state}\n data-submission-kind={row.kind}\n data-submission-series={(row as SubmissionWithSeries).series ?? ''}\n >\n <div className=\"flex items-center gap-2 text-[11px] min-w-0\">\n <span className=\"text-[10px] uppercase tracking-wider text-text-muted shrink-0\">{row.kind}</span>\n <span className=\"text-text truncate flex-1\" title={row.source}>\n {(row as SubmissionWithSeries).series\n ? `${(row as SubmissionWithSeries).series} — ${row.title || row.source}`\n : (row.title || row.source)}\n </span>\n <span className=\"text-text-muted shrink-0\">{formatSubmissionAge(row.createdAt, now)}</span>\n </div>\n <div className=\"text-[10px] text-text-muted truncate\" title={row.ownerUserId}>{row.ownerUserId}</div>\n {note && (\n <div\n data-testid=\"submission-decision-note\"\n className={`text-[11px] px-1.5 py-0.5 rounded ${note.tone === 'error' ? 'bg-danger-bg text-on-danger-bg' : 'bg-success-bg text-on-success-bg'}`}\n >\n {note.message}\n </div>\n )}\n {!decided && rejectingId === row.id ? (\n <div className=\"flex items-center gap-1\">\n <input\n value={reason}\n onChange={e => setReason(e.target.value)}\n onKeyDown={e => { if (e.key === 'Enter') void decide(row, 'reject'); }}\n aria-label=\"Reject reason\"\n placeholder=\"reason\"\n className=\"flex-1 min-w-0 bg-bg-alt border border-border outline-none px-2 py-0.5 rounded text-[11px]\"\n />\n <button\n className=\"drawer-btn drawer-btn-danger\"\n aria-label=\"Confirm reject\"\n disabled={busyId === row.id}\n onClick={() => { void decide(row, 'reject'); }}\n >\n Reject\n </button>\n <button\n className=\"drawer-btn\"\n aria-label=\"Cancel reject\"\n onClick={() => { setRejectingId(null); setReason(''); }}\n >\n Cancel\n </button>\n </div>\n ) : !decided && (\n <div className=\"flex items-center gap-1\">\n <button\n className=\"drawer-btn drawer-btn-primary\"\n aria-label=\"Approve submission\"\n disabled={busyId === row.id}\n onClick={() => { void decide(row, 'approve'); }}\n >\n Approve\n </button>\n <button\n className=\"drawer-btn\"\n aria-label=\"Reject submission\"\n disabled={busyId === row.id}\n onClick={() => { setRejectingId(row.id); setReason(''); }}\n >\n Reject\n </button>\n </div>\n )}\n </li>\n );\n })}\n </ul>\n </section>\n );\n}\n","import { useAppStore } from '../lib/store';\nimport { BUFFER_AHEAD_MS, type TClientHealth } from '@watchparty/shared';\nimport { isPrivileged } from '../lib/auth';\nimport SubmissionQueue from './SubmissionQueue';\nimport { bufferHealthLevel, BUFFER_HEALTH_LABEL } from './bufferHealth';\n\n/**\n * Health monitor panel — renders as sidebar content (replaces chat when active).\n * Shows a card per connected client with live health metrics.\n */\nexport default function AdminPanel() {\n const healthSnapshot = useAppStore(s => s.healthSnapshot);\n\n const clients = healthSnapshot?.clients ?? [];\n // Slowest download first — easiest to spot struggling clients\n const sorted = [...clients].sort((a, b) => a.avg_download_rate_bps - b.avg_download_rate_bps);\n\n const initials = computeInitials(sorted);\n // Moderation is service tier, like the routes behind it.\n const queue = isPrivileged() ? <SubmissionQueue /> : null;\n\n if (clients.length === 0) {\n return (\n <div className=\"flex-1 overflow-y-auto p-2 flex flex-col\">\n <div className=\"flex-1 flex items-center justify-center p-4\">\n <p className=\"text-text-muted text-xs text-center\">\n No health data yet.<br />Clients report once media is loaded.\n </p>\n </div>\n {queue}\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 overflow-y-auto p-2 space-y-2\">\n {sorted.map(c => <ClientCard key={c.client_id} client={c} initial={initials[c.client_id]} />)}\n {queue}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n\nfunction formatTime(ms: number): string {\n const totalSecs = Math.floor(ms / 1000);\n const mins = Math.floor(totalSecs / 60);\n const secs = totalSecs % 60;\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n\n// Initials are first alphanumeric of display name; on conflict, advance to next\n// unused alphanumeric letter in the same name. Stable across renders via client_id sort.\nfunction computeInitials(clients: TClientHealth[]): Record<string, string> {\n const out: Record<string, string> = {};\n const taken = new Set<string>();\n const ordered = [...clients].sort((a, b) => a.client_id.localeCompare(b.client_id));\n for (const c of ordered) {\n const name = c.name ?? '';\n let chosen = '?';\n for (const ch of name) {\n if (!/[\\p{L}\\p{N}]/u.test(ch)) continue;\n const up = ch.toUpperCase();\n if (!taken.has(up)) { chosen = up; taken.add(up); break; }\n }\n out[c.client_id] = chosen;\n }\n return out;\n}\n\nfunction ClientCard({ client, initial }: { client: TClientHealth; initial: string }) {\n const dlKbps = Math.round(client.avg_download_rate_bps / 1024);\n const dlMbps = (dlKbps / 1024).toFixed(1);\n const bufferS = (client.buffered_ahead_ms / 1000).toFixed(1);\n const rtt = Math.round(client.rtt_ms);\n\n // Idle: not playing, no meaningful position — don't alarm about \"Critical\".\n // Near end-of-stream is exempt from the buffered-ahead thresholds (see\n // bufferHealth.ts) so the final seconds of every episode don't false-Critical.\n const level = bufferHealthLevel(client);\n // A connected client whose reports stopped arriving: the figures below are\n // its last known state, and the silence itself is the status.\n const silent = client.stale_ms !== undefined;\n const statusLabel = silent ? `Silent ${Math.round(client.stale_ms! / 1000)}s` : BUFFER_HEALTH_LABEL[level];\n const isRed = silent || level === 'critical' || level === 'buffering';\n const statusClasses = isRed\n ? 'text-danger bg-danger/10'\n : level === 'idle'\n ? 'text-text-muted bg-bg-alt/40'\n : level === 'warning'\n ? 'text-on-neutral-bg bg-neutral/10'\n : 'text-success bg-success/10';\n\n const barColor = isRed ? 'bg-danger' : level === 'warning' ? 'bg-neutral-bg' : 'bg-success';\n const barPct = Math.min(100, (client.buffered_ahead_ms / BUFFER_AHEAD_MS) * 100);\n\n return (\n <div className=\"rounded-lg border border-border/50 bg-bg-alt/20 p-2.5\" data-silent={silent || undefined}>\n {/* Row 1: Name + Status */}\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <div className=\"w-5 h-5 rounded-full bg-bg-alt flex items-center justify-center text-[9px] font-semibold shrink-0\">\n {initial}\n </div>\n <span className=\"text-sm font-medium text-text truncate\">{client.name}</span>\n </div>\n <span className={`inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium shrink-0 ${statusClasses}`}>\n {statusLabel}\n </span>\n </div>\n\n {/* Row 2: Stats grid */}\n <div className={`grid grid-cols-3 gap-x-2 gap-y-1 text-[11px] ${silent ? 'opacity-50' : ''}`}>\n <div>\n <span className=\"text-text-muted\">DL</span>\n <span className=\"ml-1 font-mono text-text\">{dlMbps}</span>\n <span className=\"text-text-muted ml-0.5\">Mbps</span>\n </div>\n <div>\n <span className=\"text-text-muted\">Ping</span>\n <span className=\"ml-1 font-mono text-text\">{rtt}</span>\n <span className=\"text-text-muted ml-0.5\">ms</span>\n </div>\n <div>\n <span className=\"text-text-muted\">Pos</span>\n <span className=\"ml-1 font-mono text-text-secondary\">{formatTime(client.playhead_ms)}</span>\n </div>\n\n {/* Buffer row spans full width */}\n <div className=\"col-span-2 flex items-center gap-1.5\">\n <span className=\"text-text-muted\">Buf</span>\n <span className=\"font-mono text-text\">{bufferS}s</span>\n <div className=\"flex-1 h-1 bg-bg-alt rounded-full overflow-hidden\">\n <div className={`h-full rounded-full transition-all ${barColor}`} style={{ width: `${barPct}%` }} />\n </div>\n </div>\n <div className=\"flex gap-1 font-mono justify-end\">\n <span className=\"bg-success-bg text-on-success-bg px-1 rounded\">{client.fragments_loaded}L</span>\n <span className=\"text-text-muted\">{client.fragments_pending}P</span>\n {client.fragments_error > 0 && <span className=\"bg-danger-bg text-on-danger-bg px-1 rounded\">{client.fragments_error}E</span>}\n </div>\n </div>\n </div>\n );\n}\n"],"names":["POLL_MS","NOTE_LINGER_MS","SubmissionQueue","rows","setRows","useState","listFailure","setListFailure","notes","setNotes","busyId","setBusyId","rejectingId","setRejectingId","reason","setReason","now","setNow","liveRef","useRef","refresh","useCallback","res","fetchPendingSubmissions","useEffect","first","timer","leaveNote","row","message","tone","prev","id","decide","verb","approveSubmission","rejectSubmission","r","decisionMeansRowMoved","decisionFailureLabel","shown","n","jsxs","jsx","submissionFailureLabel","note","decided","e","AdminPanel","clients","useAppStore","s","sorted","b","initials","computeInitials","queue","isPrivileged","c","ClientCard","formatTime","ms","totalSecs","mins","secs","out","taken","ordered","a","name","chosen","ch","up","client","initial","dlMbps","bufferS","rtt","level","bufferHealthLevel","silent","statusLabel","BUFFER_HEALTH_LABEL","isRed","statusClasses","barColor","barPct","BUFFER_AHEAD_MS"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { jsx as A, jsxs as o } from "react/jsx-runtime";
2
2
  import { useState as b, useEffect as v, useMemo as G, useRef as F } from "react";
3
- import { d as h, w as j, j as W, O as Oe, s as ce, h as R, aC as Ze, aD as Ge, Z as De, aE as N, _ as Ce, aF as xe, G as se, aG as ye, aH as Ne, aI as Le, aJ as Me, aK as Ke, g as Re, aL as Je } from "./index-lPWsskGR.js";
3
+ import { d as h, w as j, j as W, O as Oe, s as ce, h as R, aC as Ze, aD as Ge, Z as De, aE as N, _ as Ce, aF as xe, G as se, aG as ye, aH as Ne, aI as Le, aJ as Me, aK as Ke, g as Re, aL as Je } from "./index-CAgGwvLq.js";
4
4
  import { b as He } from "./cover-AUIrlUMF.js";
5
5
  import { createPortal as We } from "react-dom";
6
- import { S as Xe } from "./Room-DMSh2z9X.js";
6
+ import { S as Xe } from "./Room-BqE-eDH3.js";
7
7
  import { Icon as Ye } from "@wolffm/themes";
8
8
  const Ve = "data:image/png;base64,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", Fe = 700, je = -1, _e = -2, $e = { endMatch: !1, rejectedStale: !1 };
9
9
  function eA(e, n, r) {
@@ -788,7 +788,7 @@ function Qe() {
788
788
  }
789
789
  function gA() {
790
790
  const e = `${Re()}/game/`, n = e.includes("?") ? "&" : "?";
791
- return `${e}${n}net=1&v=${encodeURIComponent("0.45.5")}`;
791
+ return `${e}${n}net=1&v=${encodeURIComponent("0.45.7")}`;
792
792
  }
793
793
  function hA() {
794
794
  const { snapshot: e, me: n } = R.getState();
@@ -1509,4 +1509,4 @@ function kA() {
1509
1509
  export {
1510
1510
  kA as default
1511
1511
  };
1512
- //# sourceMappingURL=GameModule-BAH3ZhRG.js.map
1512
+ //# sourceMappingURL=GameModule-BDk8hldc.js.map