mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
Harden APRS mode teardown and map fallback
This commit is contained in:
@@ -4218,7 +4218,14 @@
|
|||||||
acars: () => { if (acarsMainEventSource) { acarsMainEventSource.close(); acarsMainEventSource = null; } },
|
acars: () => { if (acarsMainEventSource) { acarsMainEventSource.close(); acarsMainEventSource = null; } },
|
||||||
vdl2: () => { if (vdl2MainEventSource) { vdl2MainEventSource.close(); vdl2MainEventSource = null; } },
|
vdl2: () => { if (vdl2MainEventSource) { vdl2MainEventSource.close(); vdl2MainEventSource = null; } },
|
||||||
radiosonde: () => { if (radiosondeEventSource) { radiosondeEventSource.close(); radiosondeEventSource = null; } },
|
radiosonde: () => { if (radiosondeEventSource) { radiosondeEventSource.close(); radiosondeEventSource = null; } },
|
||||||
aprs: () => { if (aprsEventSource) { aprsEventSource.close(); aprsEventSource = null; } },
|
aprs: () => {
|
||||||
|
if (typeof destroyAprsMode === 'function') {
|
||||||
|
destroyAprsMode();
|
||||||
|
} else if (aprsEventSource) {
|
||||||
|
aprsEventSource.close();
|
||||||
|
aprsEventSource = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
tscm: () => { if (tscmEventSource) { tscmEventSource.close(); tscmEventSource = null; } },
|
tscm: () => { if (tscmEventSource) { tscmEventSource.close(); tscmEventSource = null; } },
|
||||||
meteor: () => typeof MeteorScatter !== 'undefined' && MeteorScatter.destroy?.(),
|
meteor: () => typeof MeteorScatter !== 'undefined' && MeteorScatter.destroy?.(),
|
||||||
ook: () => typeof OokMode !== 'undefined' && OokMode.destroy?.(),
|
ook: () => typeof OokMode !== 'undefined' && OokMode.destroy?.(),
|
||||||
@@ -9880,6 +9887,7 @@
|
|||||||
let aprsStationCount = 0;
|
let aprsStationCount = 0;
|
||||||
let aprsMeterLastUpdate = 0;
|
let aprsMeterLastUpdate = 0;
|
||||||
let aprsMeterCheckInterval = null;
|
let aprsMeterCheckInterval = null;
|
||||||
|
let aprsClockInterval = null;
|
||||||
const APRS_METER_TIMEOUT = 5000; // 5 seconds for "no signal" state
|
const APRS_METER_TIMEOUT = 5000; // 5 seconds for "no signal" state
|
||||||
|
|
||||||
// APRS user location (from GPS or shared observer location)
|
// APRS user location (from GPS or shared observer location)
|
||||||
@@ -10023,6 +10031,47 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createAprsFallbackGridLayer() {
|
||||||
|
const layer = L.gridLayer({
|
||||||
|
tileSize: 256,
|
||||||
|
updateWhenIdle: true,
|
||||||
|
attribution: 'Local fallback grid'
|
||||||
|
});
|
||||||
|
layer.createTile = function(coords) {
|
||||||
|
const tile = document.createElement('canvas');
|
||||||
|
tile.width = 256;
|
||||||
|
tile.height = 256;
|
||||||
|
const ctx = tile.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#08121c';
|
||||||
|
ctx.fillRect(0, 0, 256, 256);
|
||||||
|
|
||||||
|
ctx.strokeStyle = 'rgba(0, 212, 255, 0.12)';
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0, 0);
|
||||||
|
ctx.lineTo(256, 0);
|
||||||
|
ctx.moveTo(0, 0);
|
||||||
|
ctx.lineTo(0, 256);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
ctx.strokeStyle = 'rgba(255, 255, 255, 0.06)';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(128, 0);
|
||||||
|
ctx.lineTo(128, 256);
|
||||||
|
ctx.moveTo(0, 128);
|
||||||
|
ctx.lineTo(256, 128);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
ctx.fillStyle = 'rgba(160, 220, 255, 0.28)';
|
||||||
|
ctx.font = '11px "JetBrains Mono", monospace';
|
||||||
|
ctx.fillText(`Z${coords.z} X${coords.x} Y${coords.y}`, 12, 22);
|
||||||
|
|
||||||
|
return tile;
|
||||||
|
};
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
async function initAprsMap() {
|
async function initAprsMap() {
|
||||||
if (aprsMap) return;
|
if (aprsMap) return;
|
||||||
|
|
||||||
@@ -10054,13 +10103,8 @@
|
|||||||
aprsMap = L.map('aprsMap').setView([initialLat, initialLon], initialZoom);
|
aprsMap = L.map('aprsMap').setView([initialLat, initialLon], initialZoom);
|
||||||
window.aprsMap = aprsMap;
|
window.aprsMap = aprsMap;
|
||||||
|
|
||||||
// Add fallback tiles immediately so the map is visible instantly
|
// Zero-network fallback so mode switches never block on external tiles.
|
||||||
const fallbackTiles = L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', {
|
const fallbackTiles = createAprsFallbackGridLayer().addTo(aprsMap);
|
||||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OSM</a> © <a href="https://carto.com/">CARTO</a>',
|
|
||||||
maxZoom: 19,
|
|
||||||
subdomains: 'abcd',
|
|
||||||
className: 'tile-layer-cyan'
|
|
||||||
}).addTo(aprsMap);
|
|
||||||
|
|
||||||
// Upgrade tiles in background via Settings (with timeout fallback)
|
// Upgrade tiles in background via Settings (with timeout fallback)
|
||||||
if (typeof Settings !== 'undefined') {
|
if (typeof Settings !== 'undefined') {
|
||||||
@@ -10084,7 +10128,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update time display (both map header and function bar)
|
// Update time display (both map header and function bar)
|
||||||
setInterval(() => {
|
if (aprsClockInterval) clearInterval(aprsClockInterval);
|
||||||
|
aprsClockInterval = setInterval(() => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const timeStr = now.toLocaleTimeString('en-US', { hour12: false });
|
const timeStr = now.toLocaleTimeString('en-US', { hour12: false });
|
||||||
const utcStr = now.toUTCString().slice(17, 25) + ' UTC';
|
const utcStr = now.toUTCString().slice(17, 25) + ' UTC';
|
||||||
@@ -10097,6 +10142,31 @@
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function destroyAprsMode() {
|
||||||
|
stopAprsMeterCheck();
|
||||||
|
if (aprsEventSource) {
|
||||||
|
aprsEventSource.close();
|
||||||
|
aprsEventSource = null;
|
||||||
|
}
|
||||||
|
if (aprsPollTimer) {
|
||||||
|
clearInterval(aprsPollTimer);
|
||||||
|
aprsPollTimer = null;
|
||||||
|
}
|
||||||
|
if (aprsClockInterval) {
|
||||||
|
clearInterval(aprsClockInterval);
|
||||||
|
aprsClockInterval = null;
|
||||||
|
}
|
||||||
|
if (aprsMap) {
|
||||||
|
try {
|
||||||
|
aprsMap.remove();
|
||||||
|
} catch (_) {}
|
||||||
|
aprsMap = null;
|
||||||
|
window.aprsMap = null;
|
||||||
|
}
|
||||||
|
aprsMarkers = {};
|
||||||
|
aprsUserMarker = null;
|
||||||
|
}
|
||||||
|
|
||||||
function updateAprsStatus(state, freq) {
|
function updateAprsStatus(state, freq) {
|
||||||
// Update function bar status
|
// Update function bar status
|
||||||
const stripDot = document.getElementById('aprsStripDot');
|
const stripDot = document.getElementById('aprsStripDot');
|
||||||
|
|||||||
Reference in New Issue
Block a user