mirror of
https://github.com/smittix/intercept.git
synced 2026-07-17 22:08:11 -07:00
fix(adsb): fix aircraft photo display and add Drone Intelligence docs
- Fix stale DOM refs in fetchAircraftPhoto: elements were captured before await fetch(), but showAircraftDetails rebuilds innerHTML on every RAF update, leaving the async path writing to detached nodes. Now re-queries the DOM after await, and the cache (synchronous) path queries inline so refs are always fresh. - Add thumbnail fallback in aircraft_photo route: fall back to thumbnail when thumbnail_large.src is absent rather than returning null. - Add Drone Intelligence to nav, help modal, cheat sheets, README, and docs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3555,17 +3555,15 @@ sudo make install</code>
|
||||
const photoCache = {};
|
||||
|
||||
async function fetchAircraftPhoto(registration) {
|
||||
const container = document.getElementById('aircraftPhotoContainer');
|
||||
const img = document.getElementById('aircraftPhoto');
|
||||
const link = document.getElementById('aircraftPhotoLink');
|
||||
const credit = document.getElementById('aircraftPhotoCredit');
|
||||
|
||||
if (!container || !img) return;
|
||||
|
||||
// Check cache first
|
||||
// Check cache first (synchronous path — DOM refs are always current here)
|
||||
if (photoCache[registration]) {
|
||||
const cached = photoCache[registration];
|
||||
if (cached.thumbnail) {
|
||||
const container = document.getElementById('aircraftPhotoContainer');
|
||||
const img = document.getElementById('aircraftPhoto');
|
||||
const link = document.getElementById('aircraftPhotoLink');
|
||||
const credit = document.getElementById('aircraftPhotoCredit');
|
||||
if (!container || !img) return;
|
||||
img.src = cached.thumbnail;
|
||||
link.href = cached.link || '#';
|
||||
credit.textContent = cached.photographer ? `Photo: ${cached.photographer}` : '';
|
||||
@@ -3574,13 +3572,24 @@ sudo make install</code>
|
||||
return;
|
||||
}
|
||||
|
||||
// Guard: bail early if the panel doesn't exist yet
|
||||
if (!document.getElementById('aircraftPhotoContainer')) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/adsb/aircraft-photo/${encodeURIComponent(registration)}`);
|
||||
const data = await response.json();
|
||||
|
||||
// Cache the result
|
||||
// Cache before touching DOM — subsequent synchronous calls will hit this
|
||||
photoCache[registration] = data;
|
||||
|
||||
// Re-query after the await: showAircraftDetails rebuilds innerHTML on every
|
||||
// RAF update, so refs captured before the await may point to detached nodes.
|
||||
const container = document.getElementById('aircraftPhotoContainer');
|
||||
const img = document.getElementById('aircraftPhoto');
|
||||
const link = document.getElementById('aircraftPhotoLink');
|
||||
const credit = document.getElementById('aircraftPhotoCredit');
|
||||
if (!container || !img) return;
|
||||
|
||||
if (data.success && data.thumbnail) {
|
||||
img.src = data.thumbnail;
|
||||
link.href = data.link || '#';
|
||||
@@ -3591,7 +3600,8 @@ sudo make install</code>
|
||||
}
|
||||
} catch (err) {
|
||||
console.debug('Failed to fetch aircraft photo:', err);
|
||||
container.style.display = 'none';
|
||||
const container = document.getElementById('aircraftPhotoContainer');
|
||||
if (container) container.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -270,6 +270,17 @@
|
||||
<li><em style="color: var(--text-muted);">Note: This feature is in early development</em></li>
|
||||
</ul>
|
||||
|
||||
<h3>Drone Intelligence Mode</h3>
|
||||
<ul class="tip-list">
|
||||
<li>Detects UAVs via three simultaneous vectors: Remote ID (WiFi/BLE), RTL-SDR 433/868 MHz RF, and HackRF 2.4/5.8 GHz</li>
|
||||
<li>Parses ASTM F3411 Remote ID broadcast frames — captures drone ID, operator ID, and GPS position</li>
|
||||
<li>RF fingerprinting on 433/868 MHz ISM bands and 2.4/5.8 GHz to detect drone control links and video downlinks</li>
|
||||
<li>Correlates observations across all vectors into unified <em>DroneContact</em> entries with risk scoring</li>
|
||||
<li>Risk levels: <strong>High</strong> (non-compliant / no Remote ID), <strong>Medium</strong> (multi-vector or RSSI delta >15 dB), <strong>Low</strong> (compliant, single vector)</li>
|
||||
<li>Live map shows last known position for Remote ID contacts with GPS data</li>
|
||||
<li>Requires: WiFi adapter (monitor mode) for BLE Remote ID, RTL-SDR for 433/868 MHz, HackRF for 2.4/5.8 GHz</li>
|
||||
</ul>
|
||||
|
||||
<h3>Network Monitor</h3>
|
||||
<ul class="tip-list">
|
||||
<li>Aggregates data from multiple remote INTERCEPT agents</li>
|
||||
|
||||
@@ -150,6 +150,7 @@
|
||||
{{ mode_item('tscm', 'TSCM', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>') }}
|
||||
{{ mode_item('spystations', 'Spy Stations', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.9 19.1C1 15.2 1 8.8 4.9 4.9"/><path d="M7.8 16.2c-2.3-2.3-2.3-6.1 0-8.5"/><circle cx="12" cy="12" r="2"/><path d="M16.2 7.8c2.3 2.3 2.3 6.1 0 8.5"/><path d="M19.1 4.9C23 8.8 23 15.1 19.1 19"/></svg>') }}
|
||||
{{ mode_item('websdr', 'WebSDR', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>') }}
|
||||
{{ mode_item('drone', 'Drone Intel', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/><rect x="9" y="9" width="6" height="6" rx="1"/><line x1="8" y1="8" x2="9" y2="9"/><line x1="16" y1="8" x2="15" y2="9"/><line x1="8" y1="16" x2="9" y2="15"/><line x1="16" y1="16" x2="15" y2="15"/></svg>') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user