diff --git a/static/admin.js b/static/admin.js
index 1d63382..14685d1 100644
--- a/static/admin.js
+++ b/static/admin.js
@@ -1,159 +1,33 @@
(() => {
- function initDashboardLiveUpdates() {
- // Optional live updates on dashboard
- if (!document.getElementById('tbl-displays')) return;
+ // Optional live updates on dashboard
+ if (!document.getElementById('tbl-displays')) return;
- const socket = io({ transports: ['websocket'], upgrade: false });
- socket.on('connect', () => {
- socket.emit('admin_join');
- });
+ const socket = io({ transports: ['websocket'], upgrade: false });
+ socket.on('connect', () => {
+ socket.emit('admin_join');
+ });
- function updateRow(publicId, patch) {
- const row = document.querySelector(`tr[data-public-id="${publicId}"]`);
- if (!row) return;
- if (patch.is_online !== undefined) row.querySelector('.st').textContent = patch.is_online ? 'online' : 'offline';
- if (patch.last_seen) row.querySelector('.ls').textContent = patch.last_seen;
- if (patch.latency_ms !== undefined) row.querySelector('.lat').textContent = patch.latency_ms ? `${patch.latency_ms.toFixed(1)}ms` : '';
- if (patch.offset_ms !== undefined) row.querySelector('.off').textContent = patch.offset_ms ? `${patch.offset_ms.toFixed(1)}ms` : '';
- }
-
- socket.on('admin_snapshot', (msg) => {
- const live = msg.live || {};
- Object.keys(live).forEach(pid => updateRow(pid, { ...live[pid], is_online: true }));
- });
-
- socket.on('admin_display_update', (msg) => {
- updateRow(msg.public_id, msg);
- });
-
- socket.on('admin_event_triggered', (msg) => {
- const el = document.getElementById('active-event');
- if (!el) return;
- el.innerHTML = `
${msg.event_name} (#${msg.event_id})
Start: ${msg.start_time_ms.toFixed(3)}
`;
- });
+ function updateRow(publicId, patch) {
+ const row = document.querySelector(`tr[data-public-id="${publicId}"]`);
+ if (!row) return;
+ if (patch.is_online !== undefined) row.querySelector('.st').textContent = patch.is_online ? 'online' : 'offline';
+ if (patch.last_seen) row.querySelector('.ls').textContent = patch.last_seen;
+ if (patch.latency_ms !== undefined) row.querySelector('.lat').textContent = patch.latency_ms ? `${patch.latency_ms.toFixed(1)}ms` : '';
+ if (patch.offset_ms !== undefined) row.querySelector('.off').textContent = patch.offset_ms ? `${patch.offset_ms.toFixed(1)}ms` : '';
}
- function initVideoUploadProgress() {
- const form = document.getElementById('video-upload-form');
- if (!form) return;
+ socket.on('admin_snapshot', (msg) => {
+ const live = msg.live || {};
+ Object.keys(live).forEach(pid => updateRow(pid, { ...live[pid], is_online: true }));
+ });
- const fileInput = form.querySelector('input[type="file"][name="file"]');
- const submitBtn = form.querySelector('button[type="submit"]');
- const progressWrap = document.getElementById('upload-progress');
- const progressBar = document.getElementById('upload-progress-bar') || (progressWrap ? progressWrap.querySelector('.progress-bar') : null);
- const statusEl = document.getElementById('upload-status');
+ socket.on('admin_display_update', (msg) => {
+ updateRow(msg.public_id, msg);
+ });
- // Tiny boot indicator so it’s obvious the JS is active on this page.
- setStatus('Ready to upload.', 'form-text mt-2 text-muted');
-
- if (fileInput) {
- fileInput.addEventListener('change', () => {
- if (fileInput.files && fileInput.files.length > 0) {
- showProgress();
- setProgress(0, { indeterminate: false, variant: 'info' });
- setStatus(`Selected: ${fileInput.files[0].name}`, 'form-text mt-2 text-muted');
- }
- });
- }
-
- function setStatus(msg, cls) {
- if (!statusEl) return;
- statusEl.textContent = msg || '';
- statusEl.className = cls ? cls : 'form-text mt-2';
- }
-
- function showProgress() {
- if (!progressWrap) return;
- progressWrap.classList.remove('d-none');
- progressWrap.classList.add('d-block');
- }
-
- function setProgress(percent, opts = {}) {
- if (!progressWrap || !progressBar) return;
- const pct = Math.max(0, Math.min(100, Math.round(percent)));
- progressBar.setAttribute('aria-valuenow', String(pct));
- progressBar.style.width = `${pct}%`;
- progressBar.textContent = `${pct}%`;
- if (opts.indeterminate) {
- progressBar.classList.add('progress-bar-striped', 'progress-bar-animated');
- } else {
- progressBar.classList.remove('progress-bar-animated');
- // keep striped (optional) to make it visible
- progressBar.classList.add('progress-bar-striped');
- }
- if (opts.variant) {
- progressBar.classList.remove('bg-success', 'bg-danger', 'bg-warning', 'bg-info');
- progressBar.classList.add(`bg-${opts.variant}`);
- }
- }
-
- form.addEventListener('submit', (e) => {
- e.preventDefault();
-
- if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
- setStatus('Please select a file to upload.', 'form-text mt-2 text-danger');
- return;
- }
-
- // Reset UI
- showProgress();
- setProgress(0, { indeterminate: true, variant: 'info' });
- setStatus('Uploading…', 'form-text mt-2');
-
- if (submitBtn) submitBtn.disabled = true;
- if (fileInput) fileInput.disabled = true;
-
- const xhr = new XMLHttpRequest();
- const targetUrl = form.getAttribute('action') || window.location.href;
- xhr.open('POST', targetUrl, true);
-
- xhr.upload.addEventListener('progress', (evt) => {
- if (!evt.lengthComputable) {
- setProgress(0, { indeterminate: true, variant: 'info' });
- return;
- }
- const percent = (evt.loaded / evt.total) * 100;
- setProgress(percent, { indeterminate: false, variant: 'info' });
- });
-
- xhr.upload.addEventListener('load', () => {
- // Upload bytes are done; server might still be processing.
- setProgress(100, { indeterminate: true, variant: 'info' });
- setStatus('Processing on server…', 'form-text mt-2');
- });
-
- xhr.addEventListener('load', () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- setProgress(100, { indeterminate: false, variant: 'success' });
- setStatus('Upload complete. Redirecting…', 'form-text mt-2 text-success');
- window.location.assign(xhr.responseURL || targetUrl);
- } else {
- setProgress(100, { indeterminate: false, variant: 'danger' });
- setStatus(`Upload failed (HTTP ${xhr.status}).`, 'form-text mt-2 text-danger');
- if (submitBtn) submitBtn.disabled = false;
- if (fileInput) fileInput.disabled = false;
- }
- });
-
- xhr.addEventListener('error', () => {
- setProgress(100, { indeterminate: false, variant: 'danger' });
- setStatus('Upload failed (network error).', 'form-text mt-2 text-danger');
- if (submitBtn) submitBtn.disabled = false;
- if (fileInput) fileInput.disabled = false;
- });
-
- xhr.addEventListener('abort', () => {
- setProgress(0, { indeterminate: false, variant: 'warning' });
- setStatus('Upload aborted.', 'form-text mt-2 text-warning');
- if (submitBtn) submitBtn.disabled = false;
- if (fileInput) fileInput.disabled = false;
- });
-
- const data = new FormData(form);
- xhr.send(data);
- });
- }
-
- initDashboardLiveUpdates();
- initVideoUploadProgress();
+ socket.on('admin_event_triggered', (msg) => {
+ const el = document.getElementById('active-event');
+ if (!el) return;
+ el.innerHTML = `${msg.event_name} (#${msg.event_id})
Start: ${msg.start_time_ms.toFixed(3)}
`;
+ });
})();
diff --git a/templates/admin/videos_upload.html b/templates/admin/videos_upload.html
index 27e6606..5612096 100644
--- a/templates/admin/videos_upload.html
+++ b/templates/admin/videos_upload.html
@@ -1,25 +1,11 @@
{% extends 'admin/base.html' %}
{% block content %}
Upload Video
-