Fix dashboard startup regressions and mode utilities

This commit is contained in:
James Smith
2026-03-19 10:37:21 +00:00
parent 5f34d20287
commit 18b442eb21
15 changed files with 283 additions and 96 deletions

View File

@@ -25,7 +25,7 @@
<script defer src="{{ url_for('static', filename='vendor/leaflet/leaflet.js') }}"></script>
<script defer src="{{ url_for('static', filename='js/core/observer-location.js') }}"></script>
</head>
<body>
<body data-mode="adsb">
<div class="radar-bg"></div>
<div class="scanline"></div>
@@ -422,6 +422,7 @@
let eventSource = null;
let agentPollTimer = null; // Polling fallback for agent mode
let isTracking = false;
let isTrackingStarting = false;
let currentFilter = 'all';
// ICAO -> { emergency: bool, watchlist: bool, military: bool }
let alertedAircraft = {};
@@ -2367,6 +2368,10 @@ sudo make install</code>
const btn = document.getElementById('startBtn');
const useAgent = typeof adsbCurrentAgent !== 'undefined' && adsbCurrentAgent !== 'local';
if (isTrackingStarting) {
return;
}
if (!isTracking) {
// Check for remote dump1090 config (only for local mode)
const remoteConfig = !useAgent ? getRemoteDump1090Config() : null;
@@ -2444,6 +2449,10 @@ sudo make install</code>
requestBody.remote_sbs_host = remoteConfig.host;
requestBody.remote_sbs_port = remoteConfig.port;
}
isTrackingStarting = true;
btn.disabled = true;
btn.textContent = 'STARTING...';
updateTrackingStatusDisplay();
try {
// Route through agent proxy if using remote agent
const url = useAgent
@@ -2470,10 +2479,12 @@ sudo make install</code>
drawRangeRings();
startSessionTimer();
isTracking = true;
isTrackingStarting = false;
adsbActiveDevice = adsbDevice; // Track which device is being used
adsbTrackingSource = useAgent ? adsbCurrentAgent : 'local'; // Track which source started tracking
btn.textContent = 'STOP';
btn.classList.add('active');
btn.disabled = false;
document.getElementById('trackingDot').classList.remove('inactive');
updateTrackingStatusDisplay();
// Disable ADS-B device selector while tracking
@@ -2493,6 +2504,14 @@ sudo make install</code>
}
} catch (err) {
alert('Error: ' + err.message);
} finally {
if (!isTracking) {
isTrackingStarting = false;
btn.disabled = false;
btn.textContent = 'START';
btn.classList.remove('active');
updateTrackingStatusDisplay();
}
}
} else {
try {
@@ -5697,10 +5716,14 @@ sudo make install</code>
{% include 'partials/help-modal.html' %}
<script src="{{ url_for('static', filename='js/core/voice-alerts.js') }}?v={{ version }}&r=adsbvoice1"></script>
<script src="{{ url_for('static', filename='js/core/keyboard-shortcuts.js') }}"></script>
<script src="{{ url_for('static', filename='js/core/cheat-sheets.js') }}"></script>
{% include 'partials/nav-utility-modals.html' %}
<script src="{{ url_for('static', filename='js/core/settings-manager.js') }}?v={{ version }}&r=maptheme17"></script>
<script>
window.addEventListener('DOMContentLoaded', () => {
if (typeof VoiceAlerts !== 'undefined') VoiceAlerts.init();
if (typeof KeyboardShortcuts !== 'undefined') KeyboardShortcuts.init();
});
</script>
@@ -5738,7 +5761,10 @@ sudo make install</code>
const statusEl = document.getElementById('trackingStatus');
if (!statusEl) return;
if (!isTracking) {
if (isTrackingStarting && !isTracking) {
statusEl.textContent = 'INITIALIZING';
statusEl.title = 'Starting ADS-B receiver';
} else if (!isTracking) {
statusEl.textContent = 'STANDBY';
statusEl.title = 'Select source and click START';
} else {

View File

@@ -24,7 +24,7 @@
<script defer src="{{ url_for('static', filename='vendor/leaflet/leaflet.js') }}"></script>
<script defer src="{{ url_for('static', filename='js/core/observer-location.js') }}"></script>
</head>
<body>
<body data-mode="ais">
<!-- Radar background effects -->
<div class="radar-bg"></div>
<div class="scanline"></div>
@@ -1632,7 +1632,20 @@
<!-- Help Modal -->
{% include 'partials/help-modal.html' %}
<script src="{{ url_for('static', filename='js/core/voice-alerts.js') }}?v={{ version }}&r=voicefix2"></script>
<script src="{{ url_for('static', filename='js/core/keyboard-shortcuts.js') }}"></script>
<script src="{{ url_for('static', filename='js/core/cheat-sheets.js') }}"></script>
{% include 'partials/nav-utility-modals.html' %}
<script src="{{ url_for('static', filename='js/core/settings-manager.js') }}?v={{ version }}&r=maptheme17"></script>
<script>
window.addEventListener('DOMContentLoaded', () => {
if (typeof VoiceAlerts !== 'undefined') {
VoiceAlerts.init({ startStreams: false });
VoiceAlerts.scheduleStreamStart(20000);
}
if (typeof KeyboardShortcuts !== 'undefined') KeyboardShortcuts.init();
});
</script>
<!-- Agent Manager -->
<script src="{{ url_for('static', filename='js/core/agents.js') }}"></script>

View File

@@ -518,7 +518,7 @@
}
</style>
</head>
<body>
<body data-mode="controller_monitor">
<header class="header">
<div class="logo">
NETWORK MONITOR
@@ -1117,7 +1117,20 @@
<!-- Help Modal -->
{% include 'partials/help-modal.html' %}
<script src="{{ url_for('static', filename='js/core/voice-alerts.js') }}?v={{ version }}&r=voicefix2"></script>
<script src="{{ url_for('static', filename='js/core/keyboard-shortcuts.js') }}"></script>
<script src="{{ url_for('static', filename='js/core/cheat-sheets.js') }}"></script>
{% include 'partials/nav-utility-modals.html' %}
<script src="{{ url_for('static', filename='js/core/settings-manager.js') }}?v={{ version }}&r=maptheme17"></script>
<script src="{{ url_for('static', filename='js/core/global-nav.js') }}"></script>
<script>
window.addEventListener('DOMContentLoaded', () => {
if (typeof VoiceAlerts !== 'undefined') {
VoiceAlerts.init({ startStreams: false });
VoiceAlerts.scheduleStreamStart(20000);
}
if (typeof KeyboardShortcuts !== 'undefined') KeyboardShortcuts.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,26 @@
<!-- Cheat Sheet Modal -->
<div id="cheatSheetModal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.7); z-index:10000; align-items:center; justify-content:center; padding:20px;" onclick="if(event.target===this)CheatSheets.hide()">
<div style="background:var(--bg-card, #1a1f2e); border:1px solid rgba(255,255,255,0.15); border-radius:12px; max-width:480px; width:100%; max-height:80vh; overflow-y:auto; padding:20px; position:relative;">
<button onclick="CheatSheets.hide()" style="position:absolute; top:12px; right:12px; background:none; border:none; color:var(--text-dim); cursor:pointer; font-size:18px; line-height:1;"></button>
<div id="cheatSheetContent"></div>
</div>
</div>
<!-- Keyboard Shortcuts Modal -->
<div id="kbShortcutsModal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.7); z-index:10000; align-items:center; justify-content:center; padding:20px;" onclick="if(event.target===this)KeyboardShortcuts.hideHelp()">
<div style="background:var(--bg-card, #1a1f2e); border:1px solid rgba(255,255,255,0.15); border-radius:12px; max-width:520px; width:100%; max-height:80vh; overflow-y:auto; padding:20px; position:relative;">
<button onclick="KeyboardShortcuts.hideHelp()" style="position:absolute; top:12px; right:12px; background:none; border:none; color:var(--text-dim); cursor:pointer; font-size:18px; line-height:1;"></button>
<h2 style="margin:0 0 16px; font-size:16px; color:var(--accent-cyan, #4aa3ff); font-family:var(--font-mono);">Keyboard Shortcuts</h2>
<table style="width:100%; border-collapse:collapse; font-family:var(--font-mono); font-size:12px;">
<tbody>
<tr style="border-bottom:1px solid rgba(255,255,255,0.06);"><td style="padding:6px 8px; color:var(--accent-cyan);">Alt+W</td><td style="padding:6px 8px; color:var(--text-secondary);">Switch to Waterfall</td></tr>
<tr style="border-bottom:1px solid rgba(255,255,255,0.06);"><td style="padding:6px 8px; color:var(--accent-cyan);">Alt+M</td><td style="padding:6px 8px; color:var(--text-secondary);">Toggle voice mute</td></tr>
<tr style="border-bottom:1px solid rgba(255,255,255,0.06);"><td style="padding:6px 8px; color:var(--accent-cyan);">Alt+S</td><td style="padding:6px 8px; color:var(--text-secondary);">Toggle sidebar</td></tr>
<tr style="border-bottom:1px solid rgba(255,255,255,0.06);"><td style="padding:6px 8px; color:var(--accent-cyan);">Alt+K / ?</td><td style="padding:6px 8px; color:var(--text-secondary);">Show keyboard shortcuts</td></tr>
<tr style="border-bottom:1px solid rgba(255,255,255,0.06);"><td style="padding:6px 8px; color:var(--accent-cyan);">Alt+C</td><td style="padding:6px 8px; color:var(--text-secondary);">Show cheat sheet for current mode</td></tr>
<tr style="border-bottom:1px solid rgba(255,255,255,0.06);"><td style="padding:6px 8px; color:var(--accent-cyan);">Alt+1..9</td><td style="padding:6px 8px; color:var(--text-secondary);">Switch to Nth mode in current group</td></tr>
<tr><td style="padding:6px 8px; color:var(--accent-cyan);">Escape</td><td style="padding:6px 8px; color:var(--text-secondary);">Close modal</td></tr>
</tbody>
</table>
</div>
</div>

View File

@@ -21,7 +21,7 @@
</script>
<script src="{{ url_for('static', filename='js/core/observer-location.js') }}"></script>
</head>
<body>
<body data-mode="satellite">
<div class="grid-bg"></div>
<div class="scanline"></div>
@@ -1830,9 +1830,22 @@
<!-- Help Modal -->
{% include 'partials/help-modal.html' %}
<script src="{{ url_for('static', filename='js/core/voice-alerts.js') }}?v={{ version }}&r=voicefix2"></script>
<script src="{{ url_for('static', filename='js/core/keyboard-shortcuts.js') }}"></script>
<script src="{{ url_for('static', filename='js/core/cheat-sheets.js') }}"></script>
{% include 'partials/nav-utility-modals.html' %}
<script src="{{ url_for('static', filename='js/core/settings-manager.js') }}?v={{ version }}&r=maptheme17"></script>
<script src="{{ url_for('static', filename='js/core/global-nav.js') }}"></script>
<script src="{{ url_for('static', filename='js/modes/ground_station_waterfall.js') }}"></script>
<script>
window.addEventListener('DOMContentLoaded', () => {
if (typeof VoiceAlerts !== 'undefined') {
VoiceAlerts.init({ startStreams: false });
VoiceAlerts.scheduleStreamStart(20000);
}
if (typeof KeyboardShortcuts !== 'undefined') KeyboardShortcuts.init();
});
</script>
<script>
// -------------------------------------------------------------------------