diff --git a/static/css/index.css b/static/css/index.css index d84de78..555e661 100644 --- a/static/css/index.css +++ b/static/css/index.css @@ -3855,6 +3855,16 @@ header h1 .tagline { .wifi-zone.mid .wifi-zone-count { color: var(--accent-yellow); } .wifi-zone.far .wifi-zone-count { color: var(--accent-red); } +.wifi-radar-sweep { + transform-origin: 105px 105px; + animation: wifi-radar-rotate 3s linear infinite; +} + +@keyframes wifi-radar-rotate { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + /* WiFi Analysis Panel (RIGHT) */ .wifi-analysis-panel { display: flex; diff --git a/static/js/modes/wifi.js b/static/js/modes/wifi.js index 631249a..1efabbf 100644 --- a/static/js/modes/wifi.js +++ b/static/js/modes/wifi.js @@ -167,7 +167,6 @@ const WiFiMode = (function() { initScanModeTabs(); initNetworkFilters(); initSortControls(); - initProximityRadar(); initChannelChart(); scheduleRender({ table: true, stats: true, radar: true, chart: true }); @@ -201,7 +200,6 @@ const WiFiMode = (function() { networkFilters: document.getElementById('wifiNetworkFilters'), // Visualizations - proximityRadar: document.getElementById('wifiProximityRadar'), channelChart: document.getElementById('wifiChannelChart'), channelBandTabs: document.getElementById('wifiChannelBandTabs'), @@ -1077,7 +1075,7 @@ const WiFiMode = (function() { if (pendingRender.table) renderNetworks(); if (pendingRender.stats) updateStats(); - if (pendingRender.radar) updateProximityRadar(); + if (pendingRender.radar) renderRadar(Array.from(networks.values())); if (pendingRender.chart) updateChannelChart(); if (pendingRender.detail && selectedBssid) { updateDetailPanel(selectedBssid, { refreshClients: false }); @@ -1506,36 +1504,58 @@ const WiFiMode = (function() { // Proximity Radar // ========================================================================== - function initProximityRadar() { - if (!elements.proximityRadar) return; - - // Initialize radar component - if (typeof ProximityRadar !== 'undefined') { - ProximityRadar.init('wifiProximityRadar', { - mode: 'wifi', - size: 280, - onDeviceClick: (bssid) => selectNetwork(bssid), - }); + // Simple hash of BSSID string → stable angle in radians + function bssidToAngle(bssid) { + let hash = 0; + for (let i = 0; i < bssid.length; i++) { + hash = (hash * 31 + bssid.charCodeAt(i)) & 0xffffffff; } + return (hash >>> 0) / 0xffffffff * 2 * Math.PI; } - function updateProximityRadar() { - if (typeof ProximityRadar === 'undefined') return; + function renderRadar(networksList) { + const dotsGroup = document.getElementById('wifiRadarDots'); + if (!dotsGroup) return; - // Convert networks to radar-compatible format - const devices = Array.from(networks.values()).map(n => ({ - device_key: n.bssid, - device_id: n.bssid, - name: n.essid || '[Hidden]', - rssi_current: n.rssi_current, - rssi_ema: n.rssi_ema, - proximity_band: n.proximity_band, - estimated_distance_m: n.estimated_distance_m, - is_new: n.is_new, - heuristic_flags: n.heuristic_flags || [], - })); + const dots = []; + const zoneCounts = { immediate: 0, near: 0, far: 0 }; - ProximityRadar.updateDevices(devices); + networksList.forEach(network => { + const rssi = network.rssi_current ?? -100; + const strength = Math.max(0, Math.min(1, (rssi + 100) / 80)); + const dotR = 5 + (1 - strength) * 90; // stronger = closer to centre + const angle = bssidToAngle(network.bssid); + const cx = 105 + dotR * Math.cos(angle); + const cy = 105 + dotR * Math.sin(angle); + + // Zone counts + if (dotR < 35) zoneCounts.immediate++; + else if (dotR < 70) zoneCounts.near++; + else zoneCounts.far++; + + // Visual radius by zone + const vr = dotR < 35 ? 6 : dotR < 70 ? 4.5 : 3; + + // Colour by security + const sec = (network.security || '').toLowerCase(); + const colour = sec === 'open' || sec === '' ? '#e25d5d' + : sec.includes('wpa') ? '#38c180' + : sec.includes('wep') ? '#d6a85e' + : '#484f58'; + + dots.push(` + + + `); + }); + + dotsGroup.innerHTML = dots.join(''); + + if (elements.zoneImmediate) elements.zoneImmediate.textContent = zoneCounts.immediate; + if (elements.zoneNear) elements.zoneNear.textContent = zoneCounts.near; + if (elements.zoneFar) elements.zoneFar.textContent = zoneCounts.far; } // ========================================================================== diff --git a/templates/index.html b/templates/index.html index 8a89130..e7a4bce 100644 --- a/templates/index.html +++ b/templates/index.html @@ -876,7 +876,50 @@
Proximity Radar
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0