Auto-on live preview when recount starts (all recounting templates)
This commit is contained in:
1 parent
6043197d72
commit
6be017c4f0
5 files changed
+82
-20
No files matched your search
@@ -159,6 +159,7 @@ V18: .env missing → scripts fail at import (os.getenv falls back to defaults,
|
||||
V19: stream reconnect → reset motion detection state (prev_gray = None)
|
||||
V20: reset → delete STATE_FILE + touch {SHM_DIR}/.reset; batch_store._check_reset_signal() watches marker & clears in-memory state before next crossing
|
||||
V21: upload filename batch_XX_YYYYMMDD_HHmmSS.mp4 → batch# + date parsed; batch-result queries /api/day-detail/<YYYY-MM-DD> on live API
|
||||
V22: preview auto-on when recount running — enablePreview() on START RECOUNT + applyState streaming branch; manual toggle overrides; img.onerror retries cache-busted src while streaming
|
||||
```
|
||||
|
||||
## §T — Tasks
|
||||
@@ -181,6 +182,7 @@ T13|x|add template system — DASHBOARD_TEMPLATE env var selects dashboard.html|
|
||||
T14|x|harden reset API — separate SHM marker creation from state file cleanup; return 500 on SHM failure|V20
|
||||
T15|x|add upload recounting dashboard — MP4 upload, progress bar, RECOUNT_CMD replay|V21
|
||||
T16|x|add cross-dashboard header links — UPLOAD_DASHBOARD_URL (live→upload) & LIVE_DASHBOARD_URL (upload→live)|I.config
|
||||
T17|x|auto-on live preview when recount running — enablePreview() on START + applyState; onerror retry while streaming|V22
|
||||
```
|
||||
|
||||
## §B — Bugs
|
||||
|
||||
@@ -483,6 +483,7 @@ function applyState(data) {
|
||||
document.getElementById('video-status').innerHTML =
|
||||
'<span style="width:6px;height:6px;border-radius:50%;background:var(--accent4);box-shadow:0 0 6px var(--accent4);animation:blink 1.5s ease-in-out infinite;"></span> streaming ' + (data.file_name || '');
|
||||
document.getElementById('video-status').className = 'video-status connected';
|
||||
enablePreview();
|
||||
|
||||
loadBatchResult(data.file);
|
||||
} else if (data.file && selectedFile === data.file) {
|
||||
@@ -669,6 +670,7 @@ async function startRecount() {
|
||||
document.getElementById('video-status').innerHTML =
|
||||
'<span style="width:6px;height:6px;border-radius:50%;background:var(--accent4);box-shadow:0 0 6px var(--accent4);animation:blink 1.5s ease-in-out infinite;"></span> streaming ' + data.file;
|
||||
document.getElementById('video-status').className = 'video-status connected';
|
||||
enablePreview();
|
||||
} catch (err) {
|
||||
alert('Error: ' + err.message);
|
||||
btnStart.disabled = false;
|
||||
@@ -732,11 +734,7 @@ function togglePreview() {
|
||||
btn.textContent = 'STREAM OFF';
|
||||
btn.classList.remove('active');
|
||||
} else {
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
btn.textContent = 'STREAM ON';
|
||||
btn.classList.add('active');
|
||||
enablePreview();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -751,6 +749,23 @@ function resetVideoToggle() {
|
||||
btn.classList.remove('active');
|
||||
}
|
||||
|
||||
function enablePreview() {
|
||||
const btn = document.getElementById('videoToggle');
|
||||
const img = document.getElementById('stream-img');
|
||||
const placeholder = document.getElementById('video-placeholder');
|
||||
if (!streamUrl) return;
|
||||
img.onerror = function() {
|
||||
if (streaming && streamUrl) {
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
}
|
||||
};
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
btn.textContent = 'STREAM ON';
|
||||
btn.classList.add('active');
|
||||
}
|
||||
|
||||
let lastRecountCount = null;
|
||||
let lastRecountTime = null;
|
||||
|
||||
|
||||
@@ -405,6 +405,7 @@ function applyState(data) {
|
||||
document.getElementById('video-status').innerHTML =
|
||||
'<span style="width:5px;height:5px;background:var(--success);display:inline-block;"></span> streaming ' + (data.file_name || '');
|
||||
document.getElementById('video-status').className = 'video-status connected';
|
||||
enablePreview();
|
||||
|
||||
loadBatchResult(data.file);
|
||||
} else if (data.file && selectedFile === data.file) {
|
||||
@@ -595,6 +596,7 @@ async function startRecount() {
|
||||
document.getElementById('video-status').innerHTML =
|
||||
'<span style="width:5px;height:5px;background:var(--success);display:inline-block;"></span> streaming ' + data.file;
|
||||
document.getElementById('video-status').className = 'video-status connected';
|
||||
enablePreview();
|
||||
} catch (err) {
|
||||
alert('Error: ' + err.message);
|
||||
btnStart.disabled = false;
|
||||
@@ -655,11 +657,7 @@ function togglePreview() {
|
||||
btn.textContent = 'STREAM OFF';
|
||||
btn.classList.remove('active');
|
||||
} else {
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
btn.textContent = 'STREAM ON';
|
||||
btn.classList.add('active');
|
||||
enablePreview();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,6 +672,23 @@ function resetVideoToggle() {
|
||||
btn.classList.remove('active');
|
||||
}
|
||||
|
||||
function enablePreview() {
|
||||
const btn = document.getElementById('videoToggle');
|
||||
const img = document.getElementById('stream-img');
|
||||
const placeholder = document.getElementById('video-placeholder');
|
||||
if (!streamUrl) return;
|
||||
img.onerror = function() {
|
||||
if (streaming && streamUrl) {
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
}
|
||||
};
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
btn.textContent = 'STREAM ON';
|
||||
btn.classList.add('active');
|
||||
}
|
||||
|
||||
// --- Recount counter ---
|
||||
|
||||
let lastRecountCount = null;
|
||||
|
||||
@@ -782,6 +782,7 @@ async function startRecount() {
|
||||
document.getElementById('video-status').innerHTML =
|
||||
'<span style="width:6px;height:6px;border-radius:50%;background:var(--accent4);box-shadow:0 0 6px var(--accent4);animation:blink 1.5s ease-in-out infinite;"></span> streaming ' + data.file;
|
||||
document.getElementById('video-status').className = 'video-status connected';
|
||||
enablePreview();
|
||||
} catch (err) {
|
||||
alert('Error: ' + err.message);
|
||||
btnStart.disabled = false;
|
||||
@@ -845,11 +846,7 @@ function togglePreview() {
|
||||
btn.textContent = 'STREAM OFF';
|
||||
btn.classList.remove('active');
|
||||
} else {
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
btn.textContent = 'STREAM ON';
|
||||
btn.classList.add('active');
|
||||
enablePreview();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -864,6 +861,23 @@ function resetVideoToggle() {
|
||||
btn.classList.remove('active');
|
||||
}
|
||||
|
||||
function enablePreview() {
|
||||
var btn = document.getElementById('videoToggle');
|
||||
var img = document.getElementById('stream-img');
|
||||
var placeholder = document.getElementById('video-placeholder');
|
||||
if (!streamUrl) return;
|
||||
img.onerror = function() {
|
||||
if (streaming && streamUrl) {
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
}
|
||||
};
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
btn.textContent = 'STREAM ON';
|
||||
btn.classList.add('active');
|
||||
}
|
||||
|
||||
async function syncState() {
|
||||
try {
|
||||
var res = await fetch('/api/state');
|
||||
@@ -888,6 +902,7 @@ function applyState(data) {
|
||||
document.getElementById('video-status').innerHTML =
|
||||
'<span style="width:6px;height:6px;border-radius:50%;background:var(--accent4);box-shadow:0 0 6px var(--accent4);animation:blink 1.5s ease-in-out infinite;"></span> streaming ' + (data.file_name || '');
|
||||
document.getElementById('video-status').className = 'video-status connected';
|
||||
enablePreview();
|
||||
|
||||
loadBatchResult(data.file);
|
||||
} else if (data.file && selectedFile === data.file) {
|
||||
|
||||
@@ -661,6 +661,7 @@ async function startRecount() {
|
||||
document.getElementById('video-status').innerHTML =
|
||||
'<span style="width:5px;height:5px;background:var(--success);display:inline-block;"></span> streaming ' + data.file;
|
||||
document.getElementById('video-status').className = 'video-status connected';
|
||||
enablePreview();
|
||||
} catch (err) {
|
||||
alert('Error: ' + err.message);
|
||||
btnStart.disabled = false;
|
||||
@@ -724,11 +725,7 @@ function togglePreview() {
|
||||
btn.textContent = 'STREAM OFF';
|
||||
btn.classList.remove('active');
|
||||
} else {
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
btn.textContent = 'STREAM ON';
|
||||
btn.classList.add('active');
|
||||
enablePreview();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,6 +740,23 @@ function resetVideoToggle() {
|
||||
btn.classList.remove('active');
|
||||
}
|
||||
|
||||
function enablePreview() {
|
||||
var btn = document.getElementById('videoToggle');
|
||||
var img = document.getElementById('stream-img');
|
||||
var placeholder = document.getElementById('video-placeholder');
|
||||
if (!streamUrl) return;
|
||||
img.onerror = function() {
|
||||
if (streaming && streamUrl) {
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
}
|
||||
};
|
||||
img.src = streamUrl + '?' + Date.now();
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
btn.textContent = 'STREAM ON';
|
||||
btn.classList.add('active');
|
||||
}
|
||||
|
||||
async function syncState() {
|
||||
try {
|
||||
var res = await fetch('/api/state');
|
||||
@@ -767,6 +781,7 @@ function applyState(data) {
|
||||
document.getElementById('video-status').innerHTML =
|
||||
'<span style="width:5px;height:5px;background:var(--success);display:inline-block;"></span> streaming ' + (data.file_name || '');
|
||||
document.getElementById('video-status').className = 'video-status connected';
|
||||
enablePreview();
|
||||
|
||||
loadBatchResult(data.file);
|
||||
} else if (data.file && selectedFile === data.file) {
|
||||
|
||||
Reference in new issue
Block a user