From e32942fb3555e44bfcc353d8ea73be078b7375a0 Mon Sep 17 00:00:00 2001 From: James Smith Date: Wed, 18 Mar 2026 23:09:07 +0000 Subject: [PATCH] Refresh embedded satellite dashboard state --- routes/satellite.py | 24 ++++++++++++++---------- templates/index.html | 4 ++++ templates/satellite_dashboard.html | 22 +++++++++++++++------- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/routes/satellite.py b/routes/satellite.py index 88ca2f0..27640a5 100644 --- a/routes/satellite.py +++ b/routes/satellite.py @@ -8,7 +8,7 @@ import urllib.request from datetime import datetime, timedelta import requests -from flask import Blueprint, Response, jsonify, render_template, request +from flask import Blueprint, Response, jsonify, make_response, render_template, request from config import DEFAULT_LATITUDE, DEFAULT_LONGITUDE, SHARED_OBSERVER_LOCATION_ENABLED from utils.sse import sse_stream_fanout @@ -394,15 +394,19 @@ def _fetch_iss_realtime(observer_lat: float | None = None, observer_lon: float | return result -@satellite_bp.route('/dashboard') -def satellite_dashboard(): - """Popout satellite tracking dashboard.""" - embedded = request.args.get('embedded', 'false') == 'true' - return render_template( - 'satellite_dashboard.html', - shared_observer_location=SHARED_OBSERVER_LOCATION_ENABLED, - embedded=embedded, - ) +@satellite_bp.route('/dashboard') +def satellite_dashboard(): + """Popout satellite tracking dashboard.""" + embedded = request.args.get('embedded', 'false') == 'true' + response = make_response(render_template( + 'satellite_dashboard.html', + shared_observer_location=SHARED_OBSERVER_LOCATION_ENABLED, + embedded=embedded, + )) + response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0' + response.headers['Pragma'] = 'no-cache' + response.headers['Expires'] = '0' + return response @satellite_bp.route('/predict', methods=['POST']) diff --git a/templates/index.html b/templates/index.html index 0ebb852..9c58be9 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4574,6 +4574,10 @@ if (btLayoutContainer) btLayoutContainer.classList.toggle('active', mode === 'bluetooth'); if (satelliteVisuals) satelliteVisuals.style.display = mode === 'satellite' ? 'block' : 'none'; const satFrame = document.getElementById('satelliteDashboardFrame'); + if (satFrame && mode === 'satellite') { + const baseSrc = '/satellite/dashboard?embedded=true&v={{ version }}'; + satFrame.src = `${baseSrc}&ts=${Date.now()}`; + } if (satFrame && satFrame.contentWindow) { satFrame.contentWindow.postMessage({type: 'satellite-visibility', visible: mode === 'satellite'}, '*'); } diff --git a/templates/satellite_dashboard.html b/templates/satellite_dashboard.html index 019be32..08b077d 100644 --- a/templates/satellite_dashboard.html +++ b/templates/satellite_dashboard.html @@ -762,12 +762,7 @@ function handleLivePositions(positions) { // Find the selected satellite by name or norad_id - const satName = satellites[selectedSatellite]?.name; - const pos = positions.find(p => - parseInt(p.norad_id) === selectedSatellite || - p.satellite === satName || - p.satellite === satellites[selectedSatellite]?.name - ); + const pos = findSelectedPosition(positions); // Update visible count from all positions const visibleCount = positions.filter(p => p.visible).length; @@ -775,7 +770,6 @@ if (visEl) visEl.textContent = visibleCount; if (!pos) { - clearTelemetry(); return; } @@ -821,6 +815,16 @@ } } + function findSelectedPosition(positions) { + if (!Array.isArray(positions)) return null; + const satName = satellites[selectedSatellite]?.name; + return positions.find(p => + parseInt(p.norad_id) === selectedSatellite || + p.satellite === satName || + p.satellite === satellites[selectedSatellite]?.name + ) || null; + } + function clearTelemetry() { const telLat = document.getElementById('telLat'); const telLon = document.getElementById('telLon'); @@ -855,6 +859,10 @@ if (!response.ok) return; const data = await response.json(); if (data.status !== 'success' || !Array.isArray(data.positions)) return; + if (!findSelectedPosition(data.positions)) { + clearTelemetry(); + return; + } handleLivePositions(data.positions); } catch (_) {} }