fix(recorders): kill the timer/status flap by computing live values inline + skipping unchanged DOM rebuilds
This commit is contained in:
parent
57116dde42
commit
230944fc4b
1 changed files with 12 additions and 3 deletions
|
|
@ -421,6 +421,15 @@
|
||||||
}
|
}
|
||||||
empty.style.display = 'none';
|
empty.style.display = 'none';
|
||||||
|
|
||||||
|
// Skip full DOM rebuild if structure is unchanged — the per-second timer
|
||||||
|
// and the signal poll will update the dynamic fields in place. Rebuilding
|
||||||
|
// every 5s was tearing down the live <video> element and the timer span.
|
||||||
|
const sig = pState.recorders.map(r => r.id + ':' + r.status + ':' + (r.live_asset_id || '') + ':' + (r.started_at || '')).join('|');
|
||||||
|
if (sig === pState._lastRenderSig && grid.children.length === pState.recorders.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pState._lastRenderSig = sig;
|
||||||
|
|
||||||
grid.innerHTML = pState.recorders.map(rec => {
|
grid.innerHTML = pState.recorders.map(rec => {
|
||||||
const isRecording = rec.status === 'recording';
|
const isRecording = rec.status === 'recording';
|
||||||
const cfg = rec.source_config || {};
|
const cfg = rec.source_config || {};
|
||||||
|
|
@ -480,11 +489,11 @@
|
||||||
<div class="recorder-status-row">
|
<div class="recorder-status-row">
|
||||||
<span class="status-dot ${statusDotClass}" id="statusDot-${rec.id}"></span>
|
<span class="status-dot ${statusDotClass}" id="statusDot-${rec.id}"></span>
|
||||||
<span class="text-sm" id="statusText-${rec.id}" style="color:${isRecording ? 'var(--accent)' : rec.status === 'error' ? 'var(--status-red)' : 'var(--text-secondary)'}">
|
<span class="text-sm" id="statusText-${rec.id}" style="color:${isRecording ? 'var(--accent)' : rec.status === 'error' ? 'var(--status-red)' : 'var(--text-secondary)'}">
|
||||||
${isRecording ? 'Connecting...' : rec.status === 'error' ? 'Error' : 'Idle'}
|
${(() => { if (rec.status === 'error') return 'Error'; if (!isRecording) return 'Idle'; const sg = (pState.signals[rec.id]||{}).signal; if (sg === 'lost') return 'Signal lost'; if (sg === 'error') return 'Connection error'; if (sg === 'connecting') return 'Connecting...'; return 'Recording'; })()}
|
||||||
</span>
|
</span>
|
||||||
${isRecording ? `<span class="recorder-timer" id="timer-${rec.id}">00:00:00</span>` : ''}
|
${isRecording ? `<span class="recorder-timer" id="timer-${rec.id}">${rec.started_at ? formatDur(Math.max(0, Math.floor((Date.now() - new Date(rec.started_at).getTime())/1000))) : "00:00:00"}</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
${isRecording ? `<div class="signal-strip" id="signalStrip-${rec.id}"><div class="signal-strip-fill"></div></div><div class="recorder-status-row" style="font-size:var(--text-xs);"><span id="signal-${rec.id}" style="color:var(--text-tertiary);font-family:var(--font-mono);letter-spacing:0.02em">Connecting…</span></div>` : ''}
|
${isRecording ? `<div class="signal-strip" id="signalStrip-${rec.id}"><div class="signal-strip-fill"></div></div><div class="recorder-status-row" style="font-size:var(--text-xs);"><span id="signal-${rec.id}" style="color:var(--text-tertiary);font-family:var(--font-mono);letter-spacing:0.02em">${(pState.signals[rec.id]||{}).signal === "lost" ? "No signal — stream dropped" : (pState.signals[rec.id]||{}).signal === "error" ? "Capture error" : "Receiving stream"}</span></div>` : ''}
|
||||||
${isRecording && rec.live_asset_id ? `<div class="recorder-preview"><video id="livevideo-${rec.id}" data-live-id="${rec.live_asset_id}" muted playsinline autoplay></video><div class="recorder-preview-stamp"><span class="recorder-preview-dot"></span>LIVE</div></div>` : ''}
|
${isRecording && rec.live_asset_id ? `<div class="recorder-preview"><video id="livevideo-${rec.id}" data-live-id="${rec.live_asset_id}" muted playsinline autoplay></video><div class="recorder-preview-stamp"><span class="recorder-preview-dot"></span>LIVE</div></div>` : ''}
|
||||||
|
|
||||||
<div class="recorder-source">
|
<div class="recorder-source">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue