diff --git a/services/web-ui/public/screens-admin.jsx b/services/web-ui/public/screens-admin.jsx index 6b98a5e..558166b 100644 --- a/services/web-ui/public/screens-admin.jsx +++ b/services/web-ui/public/screens-admin.jsx @@ -1235,11 +1235,25 @@ function S3SettingsCard() { React.useEffect(() => { window.ZAMPP_API.fetch('/settings/s3') .then(data => { - setS3({ s3_endpoint: data.s3_endpoint || '', s3_bucket: data.s3_bucket || '', s3_access_key: data.s3_access_key || '', s3_secret_key: '', s3_region: data.s3_region || 'us-east-1' }); + // Diagnostic: previous reports of "endpoint always blank" were + // hard to chase without seeing the raw payload. Log it once on + // load so the next user can verify quickly. + try { console.debug('[settings] /settings/s3 →', data); } catch (_) {} + setS3({ + s3_endpoint: data.s3_endpoint || '', + s3_bucket: data.s3_bucket || '', + s3_access_key: data.s3_access_key || '', + s3_secret_key: '', + s3_region: data.s3_region || 'us-east-1', + }); setSecretExists(!!data.s3_secret_key_exists); setLoading(false); }) - .catch(() => setLoading(false)); + .catch(err => { + console.error('[settings] /settings/s3 failed:', err); + setMsg({ ok: false, text: 'Could not load S3 settings: ' + (err.message || err) }); + setLoading(false); + }); }, []); const save = () => { diff --git a/services/web-ui/public/screens-ingest.jsx b/services/web-ui/public/screens-ingest.jsx index bbe0795..a8008ca 100644 --- a/services/web-ui/public/screens-ingest.jsx +++ b/services/web-ui/public/screens-ingest.jsx @@ -413,7 +413,10 @@ function RecorderRow({ recorder: initialRecorder, onRefresh }) {
Signal
-
{displaySignal}
+
+ + {displaySignal} +
{liveStatus?.currentFps != null && (
diff --git a/services/web-ui/public/styles-fixes.css b/services/web-ui/public/styles-fixes.css index 13d5ffb..9de51b1 100644 --- a/services/web-ui/public/styles-fixes.css +++ b/services/web-ui/public/styles-fixes.css @@ -517,3 +517,27 @@ box-shadow: 0 0 0 3px var(--live-soft); animation: pulse 1.6s ease-in-out infinite; } + +/* ============================================================ + Recorder row — signal indicator with a pulsing dot when + actually receiving frames. Closes part of #2. + ============================================================ */ +.signal-val { + display: inline-flex; + align-items: center; + gap: 6px; +} +.signal-dot { + width: 6px; + height: 6px; + border-radius: 50%; + flex-shrink: 0; + box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.04); +} +.signal-dot.receiving { + animation: signalPulse 1.4s ease-in-out infinite; +} +@keyframes signalPulse { + 0%, 100% { box-shadow: 0 0 0 0 rgba(45, 212, 168, 0.6); } + 50% { box-shadow: 0 0 0 6px rgba(45, 212, 168, 0); } +}