Stabilize satellite dashboard sidebar panels

This commit is contained in:
James Smith
2026-03-18 23:17:02 +00:00
parent e32942fb35
commit 96146a2e2c
2 changed files with 45 additions and 5 deletions

View File

@@ -602,6 +602,7 @@
let _txRequestId = 0;
let _telemetryPollTimer = null;
let _passRequestId = 0;
const DASHBOARD_FETCH_TIMEOUT_MS = 10000;
const BUILTIN_TX_FALLBACK = {
25544: [
{ description: 'APRS digipeater', downlink_low: 145.825, downlink_high: 145.825, uplink_low: null, uplink_high: null, mode: 'FM AX.25', baud: 1200, status: 'active', type: 'beacon', service: 'Packet' },
@@ -630,7 +631,7 @@
void btn.offsetWidth; // force reflow to restart animation
btn.classList.add('spinning');
}
fetch('/satellite/tracked?enabled=true')
fetch('/satellite/tracked?enabled=true', { credentials: 'same-origin' })
.then(r => r.json())
.then(data => {
const prevSelected = selectedSatellite;
@@ -846,9 +847,13 @@
if (!Number.isFinite(lat) || !Number.isFinite(lon) || !selectedSatellite) return;
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), DASHBOARD_FETCH_TIMEOUT_MS);
const response = await fetch('/satellite/position', {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
signal: controller.signal,
body: JSON.stringify({
latitude: lat,
longitude: lon,
@@ -856,7 +861,10 @@
includeTrack: false
})
});
clearTimeout(timeout);
if (!response.ok) return;
const contentType = response.headers.get('Content-Type') || '';
if (!contentType.includes('application/json')) return;
const data = await response.json();
if (data.status !== 'success' || !Array.isArray(data.positions)) return;
if (!findSelectedPosition(data.positions)) {
@@ -1124,9 +1132,13 @@
}
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), DASHBOARD_FETCH_TIMEOUT_MS);
const response = await fetch('/satellite/predict', {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
signal: controller.signal,
body: JSON.stringify({
latitude: lat,
longitude: lon,
@@ -1135,7 +1147,12 @@
satellites: [selectedSatellite]
})
});
clearTimeout(timeout);
const contentType = response.headers.get('Content-Type') || '';
if (!contentType.includes('application/json')) {
throw new Error('Unexpected response while calculating passes');
}
const data = await response.json();
if (requestId !== _passRequestId) return;
if (data.status === 'success') {
@@ -1156,12 +1173,20 @@
renderPassList();
document.getElementById('trackingStatus').textContent = 'ERROR';
document.getElementById('trackingDot').style.background = 'var(--accent-red)';
if (container) {
container.innerHTML = `<div style="text-align:center;color:var(--text-secondary);padding:20px;">${data.message || 'Failed to calculate passes'}</div>`;
}
}
} catch (err) {
if (requestId !== _passRequestId) return;
console.error('Pass calculation error:', err);
passes = [];
renderPassList();
if (container) {
const timedOut = err && (err.name === 'AbortError' || String(err).includes('AbortError'));
container.innerHTML = `<div style="text-align:center;color:var(--text-secondary);padding:20px;">${timedOut ? 'Timed out calculating passes' : 'Failed to calculate passes'}</div>`;
} else {
renderPassList();
}
document.getElementById('trackingStatus').textContent = 'OFFLINE';
document.getElementById('trackingDot').style.background = 'var(--accent-red)';
} finally {
@@ -1651,7 +1676,10 @@
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 7000);
const r = await fetch(`/satellite/transmitters/${noradId}`, { signal: controller.signal });
const r = await fetch(`/satellite/transmitters/${noradId}`, {
signal: controller.signal,
credentials: 'same-origin'
});
clearTimeout(timeout);
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const data = await r.json();