mirror of
https://github.com/smittix/intercept.git
synced 2026-07-18 22:38:10 -07:00
Revert "Stage dashboard startup requests"
This reverts commit af7b29b6b0.
This commit is contained in:
+128
-139
@@ -628,33 +628,6 @@
|
|||||||
const defaultLon = window.INTERCEPT_DEFAULT_LON || -0.1278;
|
const defaultLon = window.INTERCEPT_DEFAULT_LON || -0.1278;
|
||||||
return { lat: defaultLat, lon: defaultLon };
|
return { lat: defaultLat, lon: defaultLon };
|
||||||
})();
|
})();
|
||||||
const ADSB_FETCH_TIMEOUT_MS = 8000;
|
|
||||||
function scheduleAuxDashboardInit(fn, delay = 1200) {
|
|
||||||
const run = () => setTimeout(fn, delay);
|
|
||||||
if (typeof window.requestIdleCallback === 'function') {
|
|
||||||
window.requestIdleCallback(run, { timeout: delay + 1200 });
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async function fetchJsonWithTimeout(url, options = {}, timeoutMs = ADSB_FETCH_TIMEOUT_MS) {
|
|
||||||
const controller = new AbortController();
|
|
||||||
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
||||||
try {
|
|
||||||
const response = await fetch(url, {
|
|
||||||
credentials: 'same-origin',
|
|
||||||
...options,
|
|
||||||
signal: controller.signal,
|
|
||||||
});
|
|
||||||
const contentType = response.headers.get('Content-Type') || '';
|
|
||||||
if (!contentType.includes('application/json')) {
|
|
||||||
throw new Error(`Unexpected response from ${url}`);
|
|
||||||
}
|
|
||||||
return await response.json();
|
|
||||||
} finally {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let rangeRingsLayer = null;
|
let rangeRingsLayer = null;
|
||||||
let observerMarker = null;
|
let observerMarker = null;
|
||||||
|
|
||||||
@@ -1612,7 +1585,8 @@ ACARS: ${r.statistics.acarsMessages} messages`;
|
|||||||
// ============================================
|
// ============================================
|
||||||
async function autoConnectGps() {
|
async function autoConnectGps() {
|
||||||
try {
|
try {
|
||||||
const data = await fetchJsonWithTimeout('/gps/auto-connect', { method: 'POST' });
|
const response = await fetch('/gps/auto-connect', { method: 'POST' });
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.status === 'connected') {
|
if (data.status === 'connected') {
|
||||||
gpsConnected = true;
|
gpsConnected = true;
|
||||||
@@ -1763,14 +1737,15 @@ ACARS: ${r.statistics.acarsMessages} messages`;
|
|||||||
updateClock();
|
updateClock();
|
||||||
setInterval(updateClock, 1000);
|
setInterval(updateClock, 1000);
|
||||||
setInterval(cleanupOldAircraft, 10000);
|
setInterval(cleanupOldAircraft, 10000);
|
||||||
|
checkAdsbTools();
|
||||||
|
checkAircraftDatabase();
|
||||||
|
checkDvbDriverConflict();
|
||||||
|
|
||||||
|
// Auto-connect to gpsd if available
|
||||||
|
autoConnectGps();
|
||||||
|
|
||||||
// Sync tracking state if ADS-B already running
|
// Sync tracking state if ADS-B already running
|
||||||
syncTrackingStatus();
|
syncTrackingStatus();
|
||||||
|
|
||||||
scheduleAuxDashboardInit(() => checkAdsbTools(), 500);
|
|
||||||
scheduleAuxDashboardInit(() => checkAircraftDatabase(), 800);
|
|
||||||
scheduleAuxDashboardInit(() => checkDvbDriverConflict(), 1100);
|
|
||||||
scheduleAuxDashboardInit(() => autoConnectGps(), 1400);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Track which device is being used for ADS-B tracking
|
// Track which device is being used for ADS-B tracking
|
||||||
@@ -1778,7 +1753,8 @@ ACARS: ${r.statistics.acarsMessages} messages`;
|
|||||||
|
|
||||||
function initDeviceSelectors() {
|
function initDeviceSelectors() {
|
||||||
// Populate both ADS-B and airband device selectors
|
// Populate both ADS-B and airband device selectors
|
||||||
fetchJsonWithTimeout('/devices')
|
fetch('/devices')
|
||||||
|
.then(r => r.json())
|
||||||
.then(devices => {
|
.then(devices => {
|
||||||
const adsbSelect = document.getElementById('adsbDeviceSelect');
|
const adsbSelect = document.getElementById('adsbDeviceSelect');
|
||||||
const airbandSelect = document.getElementById('airbandDeviceSelect');
|
const airbandSelect = document.getElementById('airbandDeviceSelect');
|
||||||
@@ -2429,7 +2405,18 @@ sudo make install</code>
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await fetchJsonWithTimeout('/adsb/session');
|
const response = await fetch('/adsb/session');
|
||||||
|
if (!response.ok) {
|
||||||
|
// No session info - only auto-start if enabled
|
||||||
|
if (window.INTERCEPT_ADSB_AUTO_START) {
|
||||||
|
console.log('[ADS-B] No session found, attempting auto-start...');
|
||||||
|
await tryAutoStartLocal();
|
||||||
|
} else {
|
||||||
|
console.log('[ADS-B] No session found; auto-start disabled');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.tracking_active) {
|
if (data.tracking_active) {
|
||||||
// Session is running - auto-connect to stream
|
// Session is running - auto-connect to stream
|
||||||
@@ -2492,7 +2479,10 @@ sudo make install</code>
|
|||||||
// Try to auto-start local ADS-B tracking if SDR is available
|
// Try to auto-start local ADS-B tracking if SDR is available
|
||||||
try {
|
try {
|
||||||
// Check if any SDR devices are available
|
// Check if any SDR devices are available
|
||||||
const devices = await fetchJsonWithTimeout('/devices');
|
const devResponse = await fetch('/devices');
|
||||||
|
if (!devResponse.ok) return;
|
||||||
|
|
||||||
|
const devices = await devResponse.json();
|
||||||
if (!devices || devices.length === 0) {
|
if (!devices || devices.length === 0) {
|
||||||
console.log('[ADS-B] No SDR devices found - cannot auto-start');
|
console.log('[ADS-B] No SDR devices found - cannot auto-start');
|
||||||
return;
|
return;
|
||||||
@@ -3852,9 +3842,7 @@ sudo make install</code>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize airband on page load
|
// Initialize airband on page load
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', initAirband);
|
||||||
scheduleAuxDashboardInit(initAirband, 1200);
|
|
||||||
});
|
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// ACARS Functions
|
// ACARS Functions
|
||||||
@@ -3888,35 +3876,38 @@ sudo make install</code>
|
|||||||
|
|
||||||
// Initialize ACARS sidebar state and frequency checkboxes
|
// Initialize ACARS sidebar state and frequency checkboxes
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
scheduleAuxDashboardInit(() => {
|
const sidebar = document.getElementById('acarsSidebar');
|
||||||
const sidebar = document.getElementById('acarsSidebar');
|
if (sidebar && acarsSidebarCollapsed) {
|
||||||
if (sidebar && acarsSidebarCollapsed) {
|
sidebar.classList.add('collapsed');
|
||||||
sidebar.classList.add('collapsed');
|
}
|
||||||
}
|
updateAcarsFreqCheckboxes();
|
||||||
updateAcarsFreqCheckboxes();
|
|
||||||
|
|
||||||
fetchJsonWithTimeout('/acars/status')
|
// Check if ACARS is already running (e.g. after page reload)
|
||||||
.then(data => {
|
fetch('/acars/status')
|
||||||
if (data.running) {
|
.then(r => r.json())
|
||||||
isAcarsRunning = true;
|
.then(data => {
|
||||||
acarsMessageCount = data.message_count || 0;
|
if (data.running) {
|
||||||
document.getElementById('acarsCount').textContent = acarsMessageCount;
|
isAcarsRunning = true;
|
||||||
document.getElementById('acarsToggleBtn').textContent = '■ STOP ACARS';
|
acarsMessageCount = data.message_count || 0;
|
||||||
document.getElementById('acarsToggleBtn').classList.add('active');
|
document.getElementById('acarsCount').textContent = acarsMessageCount;
|
||||||
document.getElementById('acarsPanelIndicator').classList.add('active');
|
document.getElementById('acarsToggleBtn').textContent = '■ STOP ACARS';
|
||||||
startAcarsStream(false);
|
document.getElementById('acarsToggleBtn').classList.add('active');
|
||||||
fetchJsonWithTimeout('/acars/messages?limit=50')
|
document.getElementById('acarsPanelIndicator').classList.add('active');
|
||||||
.then(msgs => {
|
startAcarsStream(false);
|
||||||
if (!msgs || !msgs.length) return;
|
// Reload message history from backend
|
||||||
for (let i = msgs.length - 1; i >= 0; i--) {
|
fetch('/acars/messages?limit=50')
|
||||||
addAcarsMessage(msgs[i]);
|
.then(r => r.json())
|
||||||
}
|
.then(msgs => {
|
||||||
})
|
if (!msgs || !msgs.length) return;
|
||||||
.catch(() => {});
|
// Add oldest first so newest ends up on top
|
||||||
}
|
for (let i = msgs.length - 1; i >= 0; i--) {
|
||||||
})
|
addAcarsMessage(msgs[i]);
|
||||||
.catch(() => {});
|
}
|
||||||
}, 1600);
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
function updateAcarsFreqCheckboxes() {
|
function updateAcarsFreqCheckboxes() {
|
||||||
@@ -4306,28 +4297,26 @@ sudo make install</code>
|
|||||||
|
|
||||||
// Populate ACARS device selector
|
// Populate ACARS device selector
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
scheduleAuxDashboardInit(() => {
|
fetch('/devices')
|
||||||
fetchJsonWithTimeout('/devices')
|
.then(r => r.json())
|
||||||
.then(devices => {
|
.then(devices => {
|
||||||
const select = document.getElementById('acarsDeviceSelect');
|
const select = document.getElementById('acarsDeviceSelect');
|
||||||
select.innerHTML = '';
|
select.innerHTML = '';
|
||||||
if (devices.length === 0) {
|
if (devices.length === 0) {
|
||||||
select.innerHTML = '<option value="rtlsdr:0">No SDR detected</option>';
|
select.innerHTML = '<option value="rtlsdr:0">No SDR detected</option>';
|
||||||
} else {
|
} else {
|
||||||
devices.forEach((d, i) => {
|
devices.forEach((d, i) => {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
const sdrType = d.sdr_type || 'rtlsdr';
|
const sdrType = d.sdr_type || 'rtlsdr';
|
||||||
const idx = d.index !== undefined ? d.index : i;
|
const idx = d.index !== undefined ? d.index : i;
|
||||||
opt.value = `${sdrType}:${idx}`;
|
opt.value = `${sdrType}:${idx}`;
|
||||||
opt.dataset.sdrType = sdrType;
|
opt.dataset.sdrType = sdrType;
|
||||||
opt.dataset.index = idx;
|
opt.dataset.index = idx;
|
||||||
opt.textContent = `SDR ${idx}: ${d.name || d.type || 'SDR'}`;
|
opt.textContent = `SDR ${idx}: ${d.name || d.type || 'SDR'}`;
|
||||||
select.appendChild(opt);
|
select.appendChild(opt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.catch(() => {});
|
|
||||||
}, 1800);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -4368,13 +4357,11 @@ sudo make install</code>
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
scheduleAuxDashboardInit(() => {
|
const sidebar = document.getElementById('vdl2Sidebar');
|
||||||
const sidebar = document.getElementById('vdl2Sidebar');
|
if (sidebar && vdl2SidebarCollapsed) {
|
||||||
if (sidebar && vdl2SidebarCollapsed) {
|
sidebar.classList.add('collapsed');
|
||||||
sidebar.classList.add('collapsed');
|
}
|
||||||
}
|
updateVdl2FreqCheckboxes();
|
||||||
updateVdl2FreqCheckboxes();
|
|
||||||
}, 1800);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function updateVdl2FreqCheckboxes() {
|
function updateVdl2FreqCheckboxes() {
|
||||||
@@ -4859,50 +4846,52 @@ sudo make install</code>
|
|||||||
|
|
||||||
// Populate VDL2 device selector and check running status
|
// Populate VDL2 device selector and check running status
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
scheduleAuxDashboardInit(() => {
|
fetch('/devices')
|
||||||
fetchJsonWithTimeout('/devices')
|
.then(r => r.json())
|
||||||
.then(devices => {
|
.then(devices => {
|
||||||
const select = document.getElementById('vdl2DeviceSelect');
|
const select = document.getElementById('vdl2DeviceSelect');
|
||||||
select.innerHTML = '';
|
select.innerHTML = '';
|
||||||
if (devices.length === 0) {
|
if (devices.length === 0) {
|
||||||
select.innerHTML = '<option value="rtlsdr:0">No SDR detected</option>';
|
select.innerHTML = '<option value="rtlsdr:0">No SDR detected</option>';
|
||||||
} else {
|
} else {
|
||||||
devices.forEach((d, i) => {
|
devices.forEach((d, i) => {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
const sdrType = d.sdr_type || 'rtlsdr';
|
const sdrType = d.sdr_type || 'rtlsdr';
|
||||||
const idx = d.index !== undefined ? d.index : i;
|
const idx = d.index !== undefined ? d.index : i;
|
||||||
opt.value = `${sdrType}:${idx}`;
|
opt.value = `${sdrType}:${idx}`;
|
||||||
opt.dataset.sdrType = sdrType;
|
opt.dataset.sdrType = sdrType;
|
||||||
opt.dataset.index = idx;
|
opt.dataset.index = idx;
|
||||||
opt.textContent = `SDR ${idx}: ${d.name || d.type || 'SDR'}`;
|
opt.textContent = `SDR ${idx}: ${d.name || d.type || 'SDR'}`;
|
||||||
select.appendChild(opt);
|
select.appendChild(opt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.catch(() => {});
|
|
||||||
|
|
||||||
fetchJsonWithTimeout('/vdl2/status')
|
// Check if VDL2 is already running (e.g. after page reload)
|
||||||
.then(data => {
|
fetch('/vdl2/status')
|
||||||
if (data.running) {
|
.then(r => r.json())
|
||||||
isVdl2Running = true;
|
.then(data => {
|
||||||
vdl2MessageCount = data.message_count || 0;
|
if (data.running) {
|
||||||
document.getElementById('vdl2Count').textContent = vdl2MessageCount;
|
isVdl2Running = true;
|
||||||
document.getElementById('vdl2ToggleBtn').innerHTML = '■ STOP VDL2';
|
vdl2MessageCount = data.message_count || 0;
|
||||||
document.getElementById('vdl2ToggleBtn').classList.add('active');
|
document.getElementById('vdl2Count').textContent = vdl2MessageCount;
|
||||||
document.getElementById('vdl2PanelIndicator').classList.add('active');
|
document.getElementById('vdl2ToggleBtn').innerHTML = '■ STOP VDL2';
|
||||||
startVdl2Stream(false);
|
document.getElementById('vdl2ToggleBtn').classList.add('active');
|
||||||
fetchJsonWithTimeout('/vdl2/messages?limit=50')
|
document.getElementById('vdl2PanelIndicator').classList.add('active');
|
||||||
.then(msgs => {
|
startVdl2Stream(false);
|
||||||
if (!msgs || !msgs.length) return;
|
// Reload message history from backend
|
||||||
for (let i = msgs.length - 1; i >= 0; i--) {
|
fetch('/vdl2/messages?limit=50')
|
||||||
addVdl2Message(msgs[i]);
|
.then(r => r.json())
|
||||||
}
|
.then(msgs => {
|
||||||
})
|
if (!msgs || !msgs.length) return;
|
||||||
.catch(() => {});
|
for (let i = msgs.length - 1; i >= 0; i--) {
|
||||||
}
|
addVdl2Message(msgs[i]);
|
||||||
})
|
}
|
||||||
.catch(() => {});
|
})
|
||||||
}, 2000);
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|||||||
@@ -603,7 +603,6 @@
|
|||||||
let _telemetryPollTimer = null;
|
let _telemetryPollTimer = null;
|
||||||
let _passRequestId = 0;
|
let _passRequestId = 0;
|
||||||
const DASHBOARD_FETCH_TIMEOUT_MS = 10000;
|
const DASHBOARD_FETCH_TIMEOUT_MS = 10000;
|
||||||
const DASHBOARD_AUX_INIT_DELAY_MS = 1200;
|
|
||||||
const BUILTIN_TX_FALLBACK = {
|
const BUILTIN_TX_FALLBACK = {
|
||||||
25544: [
|
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' },
|
{ 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' },
|
||||||
@@ -625,34 +624,6 @@
|
|||||||
|
|
||||||
const satColors = ['#00ffff', '#9370DB', '#ff00ff', '#00ff00', '#ff6600', '#ffff00', '#ff69b4', '#7b68ee'];
|
const satColors = ['#00ffff', '#9370DB', '#ff00ff', '#00ff00', '#ff6600', '#ffff00', '#ff69b4', '#7b68ee'];
|
||||||
|
|
||||||
async function fetchJsonWithTimeout(url, options = {}, timeoutMs = DASHBOARD_FETCH_TIMEOUT_MS) {
|
|
||||||
const controller = new AbortController();
|
|
||||||
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
||||||
try {
|
|
||||||
const response = await fetch(url, {
|
|
||||||
credentials: 'same-origin',
|
|
||||||
...options,
|
|
||||||
signal: controller.signal,
|
|
||||||
});
|
|
||||||
const contentType = response.headers.get('Content-Type') || '';
|
|
||||||
if (!contentType.includes('application/json')) {
|
|
||||||
throw new Error(`Unexpected response from ${url}`);
|
|
||||||
}
|
|
||||||
return await response.json();
|
|
||||||
} finally {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function scheduleAuxInit(fn, delay = DASHBOARD_AUX_INIT_DELAY_MS) {
|
|
||||||
const run = () => setTimeout(fn, delay);
|
|
||||||
if (typeof window.requestIdleCallback === 'function') {
|
|
||||||
window.requestIdleCallback(run, { timeout: delay + 1000 });
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadDashboardSatellites() {
|
function loadDashboardSatellites() {
|
||||||
const btn = document.getElementById('satRefreshBtn');
|
const btn = document.getElementById('satRefreshBtn');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
@@ -660,7 +631,8 @@
|
|||||||
void btn.offsetWidth; // force reflow to restart animation
|
void btn.offsetWidth; // force reflow to restart animation
|
||||||
btn.classList.add('spinning');
|
btn.classList.add('spinning');
|
||||||
}
|
}
|
||||||
fetchJsonWithTimeout('/satellite/tracked?enabled=true')
|
fetch('/satellite/tracked?enabled=true', { credentials: 'same-origin' })
|
||||||
|
.then(r => r.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const prevSelected = selectedSatellite;
|
const prevSelected = selectedSatellite;
|
||||||
const newSats = {
|
const newSats = {
|
||||||
@@ -954,20 +926,18 @@
|
|||||||
startSSETracking();
|
startSSETracking();
|
||||||
}
|
}
|
||||||
startTelemetryPolling();
|
startTelemetryPolling();
|
||||||
|
loadAgents();
|
||||||
loadTransmitters(selectedSatellite);
|
loadTransmitters(selectedSatellite);
|
||||||
fetchCurrentTelemetry();
|
fetchCurrentTelemetry();
|
||||||
if (!usedShared) {
|
if (!usedShared) {
|
||||||
getLocation();
|
getLocation();
|
||||||
}
|
}
|
||||||
scheduleAuxInit(() => {
|
|
||||||
loadAgents();
|
|
||||||
if (window.gsInit) window.gsInit();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function loadAgents() {
|
async function loadAgents() {
|
||||||
try {
|
try {
|
||||||
const data = await fetchJsonWithTimeout('/controller/agents');
|
const response = await fetch('/controller/agents');
|
||||||
|
const data = await response.json();
|
||||||
if (data.status === 'success' && data.agents) {
|
if (data.status === 'success' && data.agents) {
|
||||||
agents = data.agents;
|
agents = data.agents;
|
||||||
populateLocationSelector();
|
populateLocationSelector();
|
||||||
@@ -1848,14 +1818,14 @@
|
|||||||
gsLoadRecordings();
|
gsLoadRecordings();
|
||||||
gsConnectSSE();
|
gsConnectSSE();
|
||||||
}
|
}
|
||||||
window.gsInit = gsInit;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Scheduler status
|
// Scheduler status
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
function gsLoadStatus() {
|
function gsLoadStatus() {
|
||||||
fetchJsonWithTimeout('/ground_station/scheduler/status')
|
fetch('/ground_station/scheduler/status')
|
||||||
|
.then(r => r.json())
|
||||||
.then(data => { _gsEnabled = data.enabled; _applyStatus(data); })
|
.then(data => { _gsEnabled = data.enabled; _applyStatus(data); })
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
@@ -1895,7 +1865,8 @@
|
|||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
function gsLoadProfiles() {
|
function gsLoadProfiles() {
|
||||||
fetchJsonWithTimeout('/ground_station/profiles')
|
fetch('/ground_station/profiles')
|
||||||
|
.then(r => r.json())
|
||||||
.then(profiles => _renderProfiles(profiles))
|
.then(profiles => _renderProfiles(profiles))
|
||||||
.catch(() => { _renderProfiles([]); });
|
.catch(() => { _renderProfiles([]); });
|
||||||
}
|
}
|
||||||
@@ -2369,7 +2340,12 @@
|
|||||||
return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init is scheduled by the main dashboard boot once the primary UI is live.
|
// Init after DOM is ready
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', gsInit);
|
||||||
|
} else {
|
||||||
|
gsInit();
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user