From 362499318921a485e30bbec506bc70725c88bf69 Mon Sep 17 00:00:00 2001 From: dsutanto Date: Mon, 10 Aug 2026 10:56:50 +0700 Subject: [PATCH] Add LOAD MP4 button flow before START RECOUNT in upload templates --- templates/recounting_upload.html | 129 +++++++++++++------ templates/recounting_upload_lamborghini.html | 129 +++++++++++++------ 2 files changed, 180 insertions(+), 78 deletions(-) diff --git a/templates/recounting_upload.html b/templates/recounting_upload.html index 8ee5863..92589b6 100644 --- a/templates/recounting_upload.html +++ b/templates/recounting_upload.html @@ -484,7 +484,7 @@
▶
-
Upload an MP4 and start recount
+
Upload an MP4, then LOAD and START recount
Preview via recount node live feed
@@ -525,6 +525,9 @@
+ @@ -548,6 +551,8 @@ let selectedFile = null; let streaming = false; let streamUrl = ''; +let loaded = false; +let started = false; let pendingUploadFile = null; let batchResultLoaded = false; @@ -639,9 +644,7 @@ function uploadFile() { } showUploadStatus('Upload complete: ' + data.name, 'success'); selectedFile = data.path; - document.getElementById('btn-start').disabled = false; - document.getElementById('btn-download').disabled = false; - document.getElementById('btn-delete').disabled = false; + renderButtons(); document.getElementById('pending-filename').textContent = 'no file chosen'; document.getElementById('pending-filename').classList.remove('has-file'); pendingUploadFile = null; @@ -677,9 +680,7 @@ function selectFile(path, name) { if (selectedFile === path) { selectedFile = null; batchResultLoaded = false; - document.getElementById('btn-start').disabled = true; - document.getElementById('btn-download').disabled = true; - document.getElementById('btn-delete').disabled = true; + renderButtons(); document.getElementById('live-title').innerHTML = '◉ Live Counter'; document.getElementById('live-count').textContent = '--'; document.getElementById('live-label').textContent = 'Objects Counted'; @@ -691,9 +692,7 @@ function selectFile(path, name) { return; } selectedFile = path; - document.getElementById('btn-start').disabled = false; - document.getElementById('btn-download').disabled = false; - document.getElementById('btn-delete').disabled = false; + renderButtons(); updateFileSelection(); loadBatchResult(path); } @@ -746,8 +745,69 @@ function formatSize(bytes) { return (bytes / 1073741824).toFixed(1) + ' GB'; } -async function startRecount() { +function renderButtons() { + var btnLoad = document.getElementById('btn-load'); + var btnStart = document.getElementById('btn-start'); + var btnStop = document.getElementById('btn-stop'); + var btnDownload = document.getElementById('btn-download'); + var btnDelete = document.getElementById('btn-delete'); + + btnLoad.disabled = !(selectedFile && !loaded); + + if (loaded && !started) { + btnStart.disabled = false; + btnStart.textContent = '\u25b6 START RECOUNT'; + btnStart.classList.remove('btn-ghost'); + } else if (started) { + btnStart.disabled = true; + btnStart.textContent = 'STREAMING'; + btnStart.classList.add('btn-ghost'); + } else { + btnStart.disabled = true; + btnStart.textContent = '\u25b6 START RECOUNT'; + btnStart.classList.remove('btn-ghost'); + } + + btnStop.disabled = !streaming; + btnDownload.disabled = !selectedFile; + btnDelete.disabled = !selectedFile; +} + +async function loadMp4() { if (!selectedFile) return; + var btnLoad = document.getElementById('btn-load'); + btnLoad.disabled = true; + btnLoad.textContent = 'LOADING...'; + try { + var res = await fetch('/api/load-mp4', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ path: selectedFile }) + }); + var data = await res.json(); + if (!data.success) { + alert('Failed: ' + (data.error || 'unknown')); + renderButtons(); + return; + } + streamUrl = data.stream_url; + selectedFile = data.path; + streaming = true; + loaded = true; + started = false; + showUploadStatus('LOADED ' + data.file + ' \u2014 press START RECOUNT', 'success'); + renderButtons(); + syncState(); + } catch (err) { + alert('Error: ' + err.message); + renderButtons(); + } finally { + btnLoad.textContent = '\u25b6 LOAD MP4'; + } +} + +async function startRecount() { + if (!selectedFile || !loaded) return; var btnStart = document.getElementById('btn-start'); btnStart.disabled = true; btnStart.textContent = 'CONNECTING...'; @@ -761,32 +821,28 @@ async function startRecount() { try { var res = await fetch('/api/start-recount', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ path: selectedFile }) + method: 'POST' }); var data = await res.json(); if (!data.success) { alert('Failed: ' + (data.error || 'unknown')); - btnStart.disabled = false; - btnStart.textContent = '\u25b6 START RECOUNT'; + renderButtons(); return; } streamUrl = data.stream_url; streaming = true; selectedFile = data.path; + loaded = true; + started = true; - document.getElementById('btn-stop').disabled = false; - btnStart.textContent = 'STREAMING'; - btnStart.classList.add('btn-ghost'); + renderButtons(); document.getElementById('video-status').innerHTML = ' streaming ' + data.file; document.getElementById('video-status').className = 'video-status connected'; enablePreview(); } catch (err) { alert('Error: ' + err.message); - btnStart.disabled = false; - btnStart.textContent = '\u25b6 START RECOUNT'; + renderButtons(); } } @@ -800,6 +856,8 @@ async function stopRecount() { streaming = false; streamUrl = ''; selectedFile = null; + loaded = false; + started = false; batchResultLoaded = false; var img = document.getElementById('stream-img'); @@ -808,15 +866,7 @@ async function stopRecount() { img.style.display = 'none'; if (placeholder) placeholder.style.display = ''; - var btnStart = document.getElementById('btn-start'); - var btnStop = document.getElementById('btn-stop'); - btnStart.disabled = true; - btnStart.textContent = '\u25b6 START RECOUNT'; - btnStart.classList.remove('btn-ghost'); - btnStop.disabled = true; - - document.getElementById('btn-download').disabled = true; - document.getElementById('btn-delete').disabled = true; + renderButtons(); document.getElementById('video-status').innerHTML = ' stopped'; @@ -893,12 +943,8 @@ function applyState(data) { streaming = true; streamUrl = data.stream_url; selectedFile = data.file; - document.getElementById('btn-stop').disabled = false; - document.getElementById('btn-start').disabled = true; - document.getElementById('btn-download').disabled = false; - document.getElementById('btn-delete').disabled = false; - document.getElementById('btn-start').textContent = 'STREAMING'; - document.getElementById('btn-start').classList.add('btn-ghost'); + loaded = true; + renderButtons(); document.getElementById('video-status').innerHTML = ' streaming ' + (data.file_name || ''); document.getElementById('video-status').className = 'video-status connected'; @@ -906,7 +952,14 @@ function applyState(data) { loadBatchResult(data.file); } else if (data.file && selectedFile === data.file) { + loaded = false; + started = false; + renderButtons(); loadBatchResult(data.file); + } else if (!data.streaming) { + loaded = false; + started = false; + renderButtons(); } } @@ -969,9 +1022,7 @@ async function deleteUploadRecord(fpath) { if (selectedFile === fpath) { selectedFile = null; batchResultLoaded = false; - document.getElementById('btn-start').disabled = true; - document.getElementById('btn-download').disabled = true; - document.getElementById('btn-delete').disabled = true; + renderButtons(); document.getElementById('live-title').innerHTML = '◉ Live Counter'; document.getElementById('live-count').textContent = '--'; document.getElementById('live-label').textContent = 'Objects Counted'; diff --git a/templates/recounting_upload_lamborghini.html b/templates/recounting_upload_lamborghini.html index bbdee5d..92624d4 100644 --- a/templates/recounting_upload_lamborghini.html +++ b/templates/recounting_upload_lamborghini.html @@ -363,7 +363,7 @@
▶
-
Upload an MP4 and start recount
+
Upload an MP4, then LOAD and START recount
Preview via recount node live feed
@@ -404,6 +404,9 @@
+ @@ -427,6 +430,8 @@ let selectedFile = null; let streaming = false; let streamUrl = ''; +let loaded = false; +let started = false; let pendingUploadFile = null; let batchResultLoaded = false; @@ -518,9 +523,7 @@ function uploadFile() { } showUploadStatus('Upload complete: ' + data.name, 'success'); selectedFile = data.path; - document.getElementById('btn-start').disabled = false; - document.getElementById('btn-download').disabled = false; - document.getElementById('btn-delete').disabled = false; + renderButtons(); document.getElementById('pending-filename').textContent = 'no file chosen'; document.getElementById('pending-filename').classList.remove('has-file'); pendingUploadFile = null; @@ -556,9 +559,7 @@ function selectFile(path, name) { if (selectedFile === path) { selectedFile = null; batchResultLoaded = false; - document.getElementById('btn-start').disabled = true; - document.getElementById('btn-download').disabled = true; - document.getElementById('btn-delete').disabled = true; + renderButtons(); document.getElementById('live-title').innerHTML = 'Live Counter'; document.getElementById('live-count').textContent = '--'; document.getElementById('live-label').textContent = 'Objects Counted'; @@ -570,9 +571,7 @@ function selectFile(path, name) { return; } selectedFile = path; - document.getElementById('btn-start').disabled = false; - document.getElementById('btn-download').disabled = false; - document.getElementById('btn-delete').disabled = false; + renderButtons(); updateFileSelection(); loadBatchResult(path); } @@ -625,8 +624,69 @@ function formatSize(bytes) { return (bytes / 1073741824).toFixed(1) + ' GB'; } -async function startRecount() { +function renderButtons() { + var btnLoad = document.getElementById('btn-load'); + var btnStart = document.getElementById('btn-start'); + var btnStop = document.getElementById('btn-stop'); + var btnDownload = document.getElementById('btn-download'); + var btnDelete = document.getElementById('btn-delete'); + + btnLoad.disabled = !(selectedFile && !loaded); + + if (loaded && !started) { + btnStart.disabled = false; + btnStart.textContent = '\u25b6 START RECOUNT'; + btnStart.classList.remove('btn-ghost'); + } else if (started) { + btnStart.disabled = true; + btnStart.textContent = 'STREAMING'; + btnStart.classList.add('btn-ghost'); + } else { + btnStart.disabled = true; + btnStart.textContent = '\u25b6 START RECOUNT'; + btnStart.classList.remove('btn-ghost'); + } + + btnStop.disabled = !streaming; + btnDownload.disabled = !selectedFile; + btnDelete.disabled = !selectedFile; +} + +async function loadMp4() { if (!selectedFile) return; + var btnLoad = document.getElementById('btn-load'); + btnLoad.disabled = true; + btnLoad.textContent = 'LOADING...'; + try { + var res = await fetch('/api/load-mp4', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ path: selectedFile }) + }); + var data = await res.json(); + if (!data.success) { + alert('Failed: ' + (data.error || 'unknown')); + renderButtons(); + return; + } + streamUrl = data.stream_url; + selectedFile = data.path; + streaming = true; + loaded = true; + started = false; + showUploadStatus('LOADED ' + data.file + ' \u2014 press START RECOUNT', 'success'); + renderButtons(); + syncState(); + } catch (err) { + alert('Error: ' + err.message); + renderButtons(); + } finally { + btnLoad.textContent = '\u25b6 LOAD MP4'; + } +} + +async function startRecount() { + if (!selectedFile || !loaded) return; var btnStart = document.getElementById('btn-start'); btnStart.disabled = true; btnStart.textContent = 'CONNECTING...'; @@ -640,32 +700,28 @@ async function startRecount() { try { var res = await fetch('/api/start-recount', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ path: selectedFile }) + method: 'POST' }); var data = await res.json(); if (!data.success) { alert('Failed: ' + (data.error || 'unknown')); - btnStart.disabled = false; - btnStart.textContent = '\u25b6 START RECOUNT'; + renderButtons(); return; } streamUrl = data.stream_url; streaming = true; selectedFile = data.path; + loaded = true; + started = true; - document.getElementById('btn-stop').disabled = false; - btnStart.textContent = 'STREAMING'; - btnStart.classList.add('btn-ghost'); + renderButtons(); document.getElementById('video-status').innerHTML = ' streaming ' + data.file; document.getElementById('video-status').className = 'video-status connected'; enablePreview(); } catch (err) { alert('Error: ' + err.message); - btnStart.disabled = false; - btnStart.textContent = '\u25b6 START RECOUNT'; + renderButtons(); } } @@ -679,6 +735,8 @@ async function stopRecount() { streaming = false; streamUrl = ''; selectedFile = null; + loaded = false; + started = false; batchResultLoaded = false; var img = document.getElementById('stream-img'); @@ -687,15 +745,7 @@ async function stopRecount() { img.style.display = 'none'; if (placeholder) placeholder.style.display = ''; - var btnStart = document.getElementById('btn-start'); - var btnStop = document.getElementById('btn-stop'); - btnStart.disabled = true; - btnStart.textContent = '\u25b6 START RECOUNT'; - btnStart.classList.remove('btn-ghost'); - btnStop.disabled = true; - - document.getElementById('btn-download').disabled = true; - document.getElementById('btn-delete').disabled = true; + renderButtons(); document.getElementById('video-status').innerHTML = ' stopped'; @@ -772,12 +822,8 @@ function applyState(data) { streaming = true; streamUrl = data.stream_url; selectedFile = data.file; - document.getElementById('btn-stop').disabled = false; - document.getElementById('btn-start').disabled = true; - document.getElementById('btn-download').disabled = false; - document.getElementById('btn-delete').disabled = false; - document.getElementById('btn-start').textContent = 'STREAMING'; - document.getElementById('btn-start').classList.add('btn-ghost'); + loaded = true; + renderButtons(); document.getElementById('video-status').innerHTML = ' streaming ' + (data.file_name || ''); document.getElementById('video-status').className = 'video-status connected'; @@ -785,7 +831,14 @@ function applyState(data) { loadBatchResult(data.file); } else if (data.file && selectedFile === data.file) { + loaded = false; + started = false; + renderButtons(); loadBatchResult(data.file); + } else if (!data.streaming) { + loaded = false; + started = false; + renderButtons(); } } @@ -848,9 +901,7 @@ async function deleteUploadRecord(fpath) { if (selectedFile === fpath) { selectedFile = null; batchResultLoaded = false; - document.getElementById('btn-start').disabled = true; - document.getElementById('btn-download').disabled = true; - document.getElementById('btn-delete').disabled = true; + renderButtons(); document.getElementById('live-title').innerHTML = 'Live Counter'; document.getElementById('live-count').textContent = '--'; document.getElementById('live-label').textContent = 'Objects Counted';