From be70d2e43b7c07a51e7c198fbd7d7e0423168c7e Mon Sep 17 00:00:00 2001 From: Smittix Date: Mon, 2 Mar 2026 16:58:16 +0000 Subject: [PATCH] feat: move radiosonde status display to main pane stats strip Move tracking state, balloon count, last update, and waveform from the sidebar into a stats strip above the map, matching the APRS strip pattern. Co-Authored-By: Claude Opus 4.6 --- static/css/modes/radiosonde.css | 80 ++++++++++++++++++++++++ templates/index.html | 19 ++++++ templates/partials/modes/radiosonde.html | 37 +++++++++-- 3 files changed, 131 insertions(+), 5 deletions(-) diff --git a/static/css/modes/radiosonde.css b/static/css/modes/radiosonde.css index 9cb503a..7b7570b 100644 --- a/static/css/modes/radiosonde.css +++ b/static/css/modes/radiosonde.css @@ -139,6 +139,86 @@ border-radius: 2px; } +/* Stats strip above map */ +.radiosonde-strip { + background: linear-gradient(180deg, var(--bg-panel) 0%, var(--bg-dark) 100%); + border: 1px solid var(--border-color); + border-radius: 6px; + padding: 6px 12px; + margin-bottom: 10px; + overflow-x: auto; +} +.radiosonde-strip-inner { + display: flex; + align-items: center; + gap: 8px; + min-width: max-content; +} +.radiosonde-strip .strip-stat { + display: flex; + flex-direction: column; + align-items: center; + padding: 4px 10px; + background: rgba(0, 229, 255, 0.05); + border: 1px solid rgba(0, 229, 255, 0.15); + border-radius: 4px; + min-width: 55px; +} +.radiosonde-strip .strip-stat:hover { + background: rgba(0, 229, 255, 0.1); + border-color: rgba(0, 229, 255, 0.3); +} +.radiosonde-strip .strip-value { + font-family: var(--font-mono); + font-size: 14px; + font-weight: 600; + color: var(--accent-cyan); + line-height: 1.2; +} +.radiosonde-strip .strip-label { + font-size: 8px; + font-weight: 600; + color: var(--text-dim); + text-transform: uppercase; + letter-spacing: 0.5px; + margin-top: 1px; +} +.radiosonde-strip .strip-divider { + width: 1px; + height: 28px; + background: var(--border-color); + margin: 0 4px; +} +.radiosonde-strip .strip-status { + display: flex; + align-items: center; + gap: 6px; + padding: 4px 8px; + background: rgba(0, 0, 0, 0.2); + border-radius: 4px; + font-size: 10px; + font-weight: 600; + color: var(--text-secondary); +} +.radiosonde-strip .status-dot { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--text-muted); +} +.radiosonde-strip .status-dot.tracking { + background: var(--accent-green); + animation: radiosonde-strip-pulse 1.5s ease-in-out infinite; +} +@keyframes radiosonde-strip-pulse { + 0%, 100% { opacity: 1; box-shadow: 0 0 4px 2px currentColor; } + 50% { opacity: 0.6; box-shadow: none; } +} +.radiosonde-strip .strip-waveform { + display: flex; + align-items: center; +} + /* Responsive: stack cards on narrow screens */ @media (max-width: 600px) { .radiosonde-card { diff --git a/templates/index.html b/templates/index.html index 6edad8d..e100781 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3137,6 +3137,25 @@ diff --git a/templates/partials/modes/radiosonde.html b/templates/partials/modes/radiosonde.html index cad99f0..7726989 100644 --- a/templates/partials/modes/radiosonde.html +++ b/templates/partials/modes/radiosonde.html @@ -35,7 +35,7 @@

Status

-
+

Status: Standby

Balloons: 0

@@ -115,7 +115,7 @@ function initRadiosondeWaveform() { if (radiosondeWaveform) return; if (typeof SignalWaveform === 'undefined') return; - const el = document.getElementById('radiosondeWaveformContainer'); + const el = document.getElementById('radiosondeStripWaveform'); if (el) { radiosondeWaveform = new SignalWaveform.Live(el, { width: 200, @@ -183,6 +183,10 @@ document.getElementById('stopRadiosondeBtn').style.display = 'block'; document.getElementById('radiosondeStatusText').textContent = 'Tracking'; document.getElementById('radiosondeStatusText').style.color = 'var(--accent-green)'; + const stripDot = document.getElementById('radiosondeStripDot'); + if (stripDot) stripDot.className = 'status-dot tracking'; + const stripStatus = document.getElementById('radiosondeStripStatus'); + if (stripStatus) stripStatus.textContent = 'TRACKING'; startRadiosondeSSE(); } else { alert(data.message || 'Failed to start radiosonde tracking'); @@ -210,6 +214,14 @@ document.getElementById('radiosondeStatusText').textContent = 'Standby'; document.getElementById('radiosondeBalloonCount').textContent = '0'; document.getElementById('radiosondeLastUpdate').textContent = '\u2014'; + const stripDot = document.getElementById('radiosondeStripDot'); + if (stripDot) stripDot.className = 'status-dot'; + const stripStatus = document.getElementById('radiosondeStripStatus'); + if (stripStatus) stripStatus.textContent = 'STANDBY'; + const stripBalloons = document.getElementById('radiosondeStripBalloons'); + if (stripBalloons) stripBalloons.textContent = '0'; + const stripUpdate = document.getElementById('radiosondeStripUpdate'); + if (stripUpdate) stripUpdate.textContent = '--:--:--'; radiosondeBalloons = {}; // Clear map markers if (typeof radiosondeMap !== 'undefined' && radiosondeMap) { @@ -221,6 +233,10 @@ }) .catch(() => { document.getElementById('radiosondeStatusText').textContent = 'Standby'; + const stripDot = document.getElementById('radiosondeStripDot'); + if (stripDot) stripDot.className = 'status-dot'; + const stripStatus = document.getElementById('radiosondeStripStatus'); + if (stripStatus) stripStatus.textContent = 'STANDBY'; }); } @@ -234,10 +250,15 @@ if (data.type === 'balloon') { if (radiosondeWaveform) radiosondeWaveform.ping(); radiosondeBalloons[data.id] = data; - document.getElementById('radiosondeBalloonCount').textContent = Object.keys(radiosondeBalloons).length; + const balloonCount = Object.keys(radiosondeBalloons).length; + document.getElementById('radiosondeBalloonCount').textContent = balloonCount; + const stripBalloons = document.getElementById('radiosondeStripBalloons'); + if (stripBalloons) stripBalloons.textContent = balloonCount; const now = new Date(); - document.getElementById('radiosondeLastUpdate').textContent = - now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' }); + const timeStr = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' }); + document.getElementById('radiosondeLastUpdate').textContent = timeStr; + const stripUpdate = document.getElementById('radiosondeStripUpdate'); + if (stripUpdate) stripUpdate.textContent = timeStr; updateRadiosondeMap(data); updateRadiosondeCards(); } @@ -477,6 +498,12 @@ document.getElementById('radiosondeStatusText').textContent = 'Tracking'; document.getElementById('radiosondeStatusText').style.color = 'var(--accent-green)'; document.getElementById('radiosondeBalloonCount').textContent = data.balloon_count || 0; + const stripDot = document.getElementById('radiosondeStripDot'); + if (stripDot) stripDot.className = 'status-dot tracking'; + const stripStatus = document.getElementById('radiosondeStripStatus'); + if (stripStatus) stripStatus.textContent = 'TRACKING'; + const stripBalloons = document.getElementById('radiosondeStripBalloons'); + if (stripBalloons) stripBalloons.textContent = data.balloon_count || 0; startRadiosondeSSE(); } })