mirror of
https://github.com/smittix/intercept.git
synced 2026-05-01 10:09:59 -07:00
chore: commit all pending changes
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="{% if offline_settings.tile_provider in ['cartodb_dark', 'cartodb_dark_cyan'] %}map-cyber-enabled{% elif offline_settings.tile_provider == 'cartodb_dark_flir' %}map-flir-enabled{% endif %}">
|
||||
<html lang="en" class="{% if offline_settings.tile_provider in ['cartodb_dark', 'cartodb_dark_cyan'] %}map-cyber-enabled{% endif %}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -423,9 +423,16 @@
|
||||
let alertsEnabled = true;
|
||||
let detectionSoundEnabled = localStorage.getItem('adsb_detectionSound') !== 'false'; // Default on
|
||||
let soundedAircraft = {}; // Track aircraft we've played detection sound for
|
||||
const MAP_CROSSHAIR_DURATION_MS = 620;
|
||||
const MAP_CROSSHAIR_DURATION_MS = 1500;
|
||||
const PANEL_SELECTION_BASE_ZOOM = 10;
|
||||
const PANEL_SELECTION_MAX_ZOOM = 12;
|
||||
const PANEL_SELECTION_ZOOM_INCREMENT = 1.4;
|
||||
const PANEL_SELECTION_STAGE1_DURATION_SEC = 1.05;
|
||||
const PANEL_SELECTION_STAGE2_DURATION_SEC = 1.15;
|
||||
const PANEL_SELECTION_STAGE_GAP_MS = 180;
|
||||
let mapCrosshairResetTimer = null;
|
||||
let mapCrosshairFallbackTimer = null;
|
||||
let panelSelectionFallbackTimer = null;
|
||||
let panelSelectionStageTimer = null;
|
||||
let mapCrosshairRequestId = 0;
|
||||
// Watchlist - persisted to localStorage
|
||||
let watchlist = JSON.parse(localStorage.getItem('adsb_watchlist') || '[]');
|
||||
@@ -2792,18 +2799,32 @@ sudo make install</code>
|
||||
`;
|
||||
}
|
||||
|
||||
function triggerMapCrosshairAnimation(lat, lon) {
|
||||
function triggerMapCrosshairAnimation(lat, lon, durationMs = MAP_CROSSHAIR_DURATION_MS, lockToMapCenter = false) {
|
||||
if (!radarMap) return;
|
||||
const overlay = document.getElementById('mapCrosshairOverlay');
|
||||
if (!overlay) return;
|
||||
|
||||
const point = radarMap.latLngToContainerPoint([lat, lon]);
|
||||
const size = radarMap.getSize();
|
||||
const targetX = Math.max(0, Math.min(size.x, point.x));
|
||||
const targetY = Math.max(0, Math.min(size.y, point.y));
|
||||
let targetX;
|
||||
let targetY;
|
||||
|
||||
overlay.style.setProperty('--target-x', `${targetX}px`);
|
||||
overlay.style.setProperty('--target-y', `${targetY}px`);
|
||||
if (lockToMapCenter) {
|
||||
targetX = size.x / 2;
|
||||
targetY = size.y / 2;
|
||||
} else {
|
||||
const point = radarMap.latLngToContainerPoint([lat, lon]);
|
||||
targetX = Math.max(0, Math.min(size.x, point.x));
|
||||
targetY = Math.max(0, Math.min(size.y, point.y));
|
||||
}
|
||||
|
||||
const startX = size.x + 8;
|
||||
const startY = size.y + 8;
|
||||
|
||||
overlay.style.setProperty('--crosshair-x-start', `${startX}px`);
|
||||
overlay.style.setProperty('--crosshair-y-start', `${startY}px`);
|
||||
overlay.style.setProperty('--crosshair-x-end', `${targetX}px`);
|
||||
overlay.style.setProperty('--crosshair-y-end', `${targetY}px`);
|
||||
overlay.style.setProperty('--crosshair-duration', `${durationMs}ms`);
|
||||
overlay.classList.remove('active');
|
||||
void overlay.offsetWidth;
|
||||
overlay.classList.add('active');
|
||||
@@ -2814,16 +2835,102 @@ sudo make install</code>
|
||||
mapCrosshairResetTimer = setTimeout(() => {
|
||||
overlay.classList.remove('active');
|
||||
mapCrosshairResetTimer = null;
|
||||
}, MAP_CROSSHAIR_DURATION_MS + 40);
|
||||
}, durationMs + 100);
|
||||
}
|
||||
|
||||
function getPanelSelectionFinalZoom() {
|
||||
if (!radarMap) return PANEL_SELECTION_BASE_ZOOM;
|
||||
const currentZoom = radarMap.getZoom();
|
||||
const maxZoom = typeof radarMap.getMaxZoom === 'function' ? radarMap.getMaxZoom() : PANEL_SELECTION_MAX_ZOOM;
|
||||
return Math.min(
|
||||
PANEL_SELECTION_MAX_ZOOM,
|
||||
maxZoom,
|
||||
Math.max(PANEL_SELECTION_BASE_ZOOM, currentZoom + PANEL_SELECTION_ZOOM_INCREMENT)
|
||||
);
|
||||
}
|
||||
|
||||
function getPanelSelectionIntermediateZoom(finalZoom) {
|
||||
if (!radarMap) return finalZoom;
|
||||
const currentZoom = radarMap.getZoom();
|
||||
if (finalZoom - currentZoom < 0.8) {
|
||||
return finalZoom;
|
||||
}
|
||||
const midpointZoom = currentZoom + ((finalZoom - currentZoom) * 0.55);
|
||||
return Math.min(finalZoom - 0.45, midpointZoom);
|
||||
}
|
||||
|
||||
function runPanelSelectionAnimation(lat, lon, requestId) {
|
||||
if (!radarMap) return;
|
||||
|
||||
const finalZoom = getPanelSelectionFinalZoom();
|
||||
const intermediateZoom = getPanelSelectionIntermediateZoom(finalZoom);
|
||||
const sequenceDurationMs = Math.round(
|
||||
((PANEL_SELECTION_STAGE1_DURATION_SEC + PANEL_SELECTION_STAGE2_DURATION_SEC) * 1000) +
|
||||
PANEL_SELECTION_STAGE_GAP_MS + 260
|
||||
);
|
||||
const startSecondStage = () => {
|
||||
if (requestId !== mapCrosshairRequestId) return;
|
||||
radarMap.flyTo([lat, lon], finalZoom, {
|
||||
animate: true,
|
||||
duration: PANEL_SELECTION_STAGE2_DURATION_SEC,
|
||||
easeLinearity: 0.2
|
||||
});
|
||||
};
|
||||
|
||||
triggerMapCrosshairAnimation(
|
||||
lat,
|
||||
lon,
|
||||
Math.max(MAP_CROSSHAIR_DURATION_MS, sequenceDurationMs),
|
||||
true
|
||||
);
|
||||
|
||||
if (intermediateZoom >= finalZoom - 0.1) {
|
||||
radarMap.flyTo([lat, lon], finalZoom, {
|
||||
animate: true,
|
||||
duration: PANEL_SELECTION_STAGE2_DURATION_SEC,
|
||||
easeLinearity: 0.2
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let stage1Handled = false;
|
||||
const finishStage1 = () => {
|
||||
if (stage1Handled || requestId !== mapCrosshairRequestId) return;
|
||||
stage1Handled = true;
|
||||
if (panelSelectionFallbackTimer) {
|
||||
clearTimeout(panelSelectionFallbackTimer);
|
||||
panelSelectionFallbackTimer = null;
|
||||
}
|
||||
panelSelectionStageTimer = setTimeout(() => {
|
||||
panelSelectionStageTimer = null;
|
||||
startSecondStage();
|
||||
}, PANEL_SELECTION_STAGE_GAP_MS);
|
||||
};
|
||||
|
||||
radarMap.once('moveend', finishStage1);
|
||||
panelSelectionFallbackTimer = setTimeout(
|
||||
finishStage1,
|
||||
Math.round(PANEL_SELECTION_STAGE1_DURATION_SEC * 1000) + 160
|
||||
);
|
||||
|
||||
radarMap.flyTo([lat, lon], intermediateZoom, {
|
||||
animate: true,
|
||||
duration: PANEL_SELECTION_STAGE1_DURATION_SEC,
|
||||
easeLinearity: 0.2
|
||||
});
|
||||
}
|
||||
|
||||
function selectAircraft(icao, source = 'map') {
|
||||
const prevSelected = selectedIcao;
|
||||
selectedIcao = icao;
|
||||
mapCrosshairRequestId += 1;
|
||||
if (mapCrosshairFallbackTimer) {
|
||||
clearTimeout(mapCrosshairFallbackTimer);
|
||||
mapCrosshairFallbackTimer = null;
|
||||
if (panelSelectionFallbackTimer) {
|
||||
clearTimeout(panelSelectionFallbackTimer);
|
||||
panelSelectionFallbackTimer = null;
|
||||
}
|
||||
if (panelSelectionStageTimer) {
|
||||
clearTimeout(panelSelectionStageTimer);
|
||||
panelSelectionStageTimer = null;
|
||||
}
|
||||
|
||||
// Update marker icons for both previous and new selection
|
||||
@@ -2853,19 +2960,8 @@ sudo make install</code>
|
||||
const targetLon = ac.lon;
|
||||
|
||||
if (source === 'panel' && radarMap) {
|
||||
const requestId = mapCrosshairRequestId;
|
||||
let crosshairTriggered = false;
|
||||
const runCrosshair = () => {
|
||||
if (crosshairTriggered || requestId !== mapCrosshairRequestId) return;
|
||||
crosshairTriggered = true;
|
||||
if (mapCrosshairFallbackTimer) {
|
||||
clearTimeout(mapCrosshairFallbackTimer);
|
||||
mapCrosshairFallbackTimer = null;
|
||||
}
|
||||
triggerMapCrosshairAnimation(targetLat, targetLon);
|
||||
};
|
||||
radarMap.once('moveend', runCrosshair);
|
||||
mapCrosshairFallbackTimer = setTimeout(runCrosshair, 450);
|
||||
runPanelSelectionAnimation(targetLat, targetLon, mapCrosshairRequestId);
|
||||
return;
|
||||
}
|
||||
|
||||
radarMap.setView([targetLat, targetLon], 10);
|
||||
|
||||
Reference in New Issue
Block a user