video dashboard: Library card is a live scan tool (parity with music)
The Refresh/Deep Scan buttons already fired a scan, but the card gave no feedback so it looked dead. Now it mirrors music's dashboard library card: - a progress section (phase + bar + detail) appears during a scan, driven by the shared scan events (real percent); - buttons disable while scanning; - the card hydrates on load/return — if a scan is already running, video-scan.js re-emits progress and the card shows it; - stats refresh when the scan finishes. Reuses music's .library-status-progress classes. 84 tests green.
This commit is contained in:
parent
68582af374
commit
be141d0073
3 changed files with 45 additions and 3 deletions
|
|
@ -184,6 +184,8 @@ def test_dashboard_library_card_has_refresh_and_deep_buttons():
|
|||
assert 'data-video-scan-mode="full"' in block # Refresh
|
||||
assert 'data-video-scan-mode="deep"' in block # Deep Scan
|
||||
assert "library-status-actions" in block
|
||||
# The card shows live scan progress (parity with the music dashboard).
|
||||
assert "data-video-dash-progress" in block and "data-video-dash-bar" in block
|
||||
|
||||
|
||||
def test_scan_module_referenced_and_isolated():
|
||||
|
|
|
|||
|
|
@ -608,6 +608,11 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="library-status-progress hidden" data-video-dash-progress>
|
||||
<div class="library-status-phase" data-video-dash-phase>Scanning…</div>
|
||||
<div class="library-status-bar"><div class="library-status-bar-fill" data-video-dash-bar style="width: 0%;"></div></div>
|
||||
<div class="library-status-progress-detail" data-video-dash-detail>0 movies, 0 shows</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
|
|
|||
|
|
@ -117,8 +117,43 @@
|
|||
loadStats();
|
||||
}
|
||||
|
||||
// ── Library card: live scan progress (parity with the music dashboard) ──
|
||||
// The scan buttons (data-video-scan-mode) are wired by video-scan.js; here
|
||||
// we reflect progress on the card and hydrate if a scan is already running
|
||||
// (video-scan.js re-emits the progress event on load).
|
||||
function dashButtons() {
|
||||
return document.querySelectorAll(
|
||||
'.video-subpage[data-video-subpage="video-dashboard"] [data-video-scan-mode]');
|
||||
}
|
||||
|
||||
function onDashScanProgress(e) {
|
||||
var s = e.detail || {};
|
||||
if (s.state !== 'scanning') return;
|
||||
var prog = document.querySelector('[data-video-dash-progress]');
|
||||
if (prog) prog.classList.remove('hidden');
|
||||
var phase = (s.phase || 'scanning');
|
||||
var phaseEl = document.querySelector('[data-video-dash-phase]');
|
||||
if (phaseEl) phaseEl.textContent = phase.charAt(0).toUpperCase() + phase.slice(1);
|
||||
var bar = document.querySelector('[data-video-dash-bar]');
|
||||
if (bar) bar.style.width = (s.percent != null ? s.percent : 100) + '%';
|
||||
var detail = document.querySelector('[data-video-dash-detail]');
|
||||
if (detail) {
|
||||
detail.textContent = (s.movies || 0) + ' movies, ' + (s.shows || 0) + ' shows'
|
||||
+ (s.percent != null ? ' · ' + s.percent + '%' : '');
|
||||
}
|
||||
var btns = dashButtons();
|
||||
for (var i = 0; i < btns.length; i++) btns[i].disabled = true;
|
||||
}
|
||||
|
||||
function onDashScanDone() {
|
||||
var prog = document.querySelector('[data-video-dash-progress]');
|
||||
if (prog) prog.classList.add('hidden');
|
||||
var btns = dashButtons();
|
||||
for (var i = 0; i < btns.length; i++) btns[i].disabled = false;
|
||||
loadStats();
|
||||
}
|
||||
|
||||
document.addEventListener('soulsync:video-page-shown', onPageShown);
|
||||
// Dashboard scan buttons (data-video-scan-mode) are wired by video-scan.js;
|
||||
// refresh the live counts whenever any scan finishes.
|
||||
document.addEventListener('soulsync:video-scan-done', function () { loadStats(); });
|
||||
document.addEventListener('soulsync:video-scan-progress', onDashScanProgress);
|
||||
document.addEventListener('soulsync:video-scan-done', onDashScanDone);
|
||||
})();
|
||||
|
|
|
|||
Loading…
Reference in a new issue