const RecordingUI = (function() { 'use strict'; let recordings = []; let active = []; function init() { refresh(); } function refresh() { fetch('/recordings') .then(r => r.json()) .then(data => { if (data.status !== 'success') return; recordings = data.recordings || []; active = data.active || []; renderActive(); renderRecordings(); }) .catch(err => console.error('[Recording] Load failed', err)); } function start() { const modeSelect = document.getElementById('recordingModeSelect'); const labelInput = document.getElementById('recordingLabelInput'); const mode = modeSelect ? modeSelect.value : ''; const label = labelInput ? labelInput.value : ''; if (!mode) return; fetch('/recordings/start', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ mode, label }) }) .then(r => r.json()) .then(() => { refresh(); }) .catch(err => console.error('[Recording] Start failed', err)); } function stop() { const modeSelect = document.getElementById('recordingModeSelect'); const mode = modeSelect ? modeSelect.value : ''; if (!mode) return; fetch('/recordings/stop', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ mode }) }) .then(r => r.json()) .then(() => refresh()) .catch(err => console.error('[Recording] Stop failed', err)); } function stopById(sessionId) { fetch('/recordings/stop', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: sessionId }) }).then(() => refresh()); } function renderActive() { const container = document.getElementById('recordingActiveList'); if (!container) return; if (!active.length) { container.innerHTML = '
No active recordings
'; return; } container.innerHTML = active.map(session => { return `
${escapeHtml(session.mode)}
Started: ${new Date(session.started_at).toLocaleString()}
Events: ${session.event_count || 0}
`; }).join(''); } function renderRecordings() { const container = document.getElementById('recordingList'); if (!container) return; if (!recordings.length) { container.innerHTML = '
No recordings yet
'; return; } container.innerHTML = recordings.map(rec => { return `
${escapeHtml(rec.mode)}${rec.label ? ` • ${escapeHtml(rec.label)}` : ''}
${new Date(rec.started_at).toLocaleString()}${rec.stopped_at ? ` → ${new Date(rec.stopped_at).toLocaleString()}` : ''}
Events: ${rec.event_count || 0} • ${(rec.size_bytes || 0) / 1024.0 > 0 ? (rec.size_bytes / 1024).toFixed(1) + ' KB' : '0 KB'}
`; }).join(''); } function download(sessionId) { window.open(`/recordings/${sessionId}/download`, '_blank'); } function openReplay(sessionId) { if (!sessionId) return; window.open(`/recordings/${sessionId}/download`, '_blank'); } function escapeHtml(str) { if (!str) return ''; return String(str) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } return { init, refresh, start, stop, stopById, download, openReplay, }; })();