(stats)
| 2801 | // Label the selection at the left edge of the band. |
| 2802 | const nm = sel.name || sel.vendor || sel.mac; |
| 2803 | const tag = `${nm.length > 18 ? nm.slice(0, 17) + '…' : nm} ${sel.rssi} dBm ${isLE ? '(BLE adv)' : '(Classic · hops band)'}`; |
| 2804 | ctx.fillStyle = '#fff'; ctx.font = 'bold 10px sans-serif'; ctx.textAlign = 'left'; |
| 2805 | ctx.fillText(tag, r24.x0 + 3, yR - 5); |
| 2806 | } else if (sel) { |
| 2807 | // Selected but no RSSI heard this scan. |
| 2808 | ctx.fillStyle = '#e2e8f0'; ctx.font = 'bold 10px sans-serif'; ctx.textAlign = 'left'; |
| 2809 | ctx.fillText(`${sel.name || sel.mac} — RSSI not heard this scan`, r24.x0 + 3, g.padT + 14); |
| 2810 | } |
| 2811 | } |
| 2812 | |
| 2813 | // ============================================================================ |
| 2814 | // Full-screen spectrum console |
| 2815 | // ---------------------------------------------------------------------------- |
| 2816 | // The same survey, the same _wifiState — but the whole viewport: a large |
| 2817 | // hit-testable spectrum, the AP list underneath it, and an inspector that |
| 2818 | // shows every field the scan produced for whatever is selected. |
| 2819 | // ============================================================================ |
| 2820 | |
| 2821 | function wifiToggleFullscreen() { |
| 2822 | const el = document.getElementById('wifi-fs'); if (!el) return; |
| 2823 | if (el.classList.contains('hidden')) _wifiFsOpen(el); else _wifiFsClose(el); |
| 2824 | } |
| 2825 | |
| 2826 | function _wifiFsOpen(el) { |
| 2827 | _wifiFsWire(); |
| 2828 | el.classList.remove('hidden'); |
| 2829 | el.setAttribute('aria-hidden', 'false'); |
| 2830 | document.body.classList.add('wifi-fs-open'); |
| 2831 | _wifiState.fs.open = true; |
| 2832 | document.addEventListener('keydown', _wifiFsKey); |
| 2833 | // Ask for real fullscreen as well — if the browser refuses, the fixed |
| 2834 | // overlay alone still fills the viewport. |
| 2835 | if (el.requestFullscreen && !document.fullscreenElement) { |
| 2836 | el.requestFullscreen().then(() => { _wifiState.fs.native = true; }).catch(() => {}); |
| 2837 | } |
| 2838 | _wifiSyncBandButtons(); |
| 2839 | wifiSetView(_wifiState.view); |
| 2840 | ['wifi-auto', 'wifi-bt', 'wifi-zb'].forEach(id => { |
| 2841 | const m = document.getElementById(id), f = document.getElementById(id.replace('wifi-', 'wifi-fs-')); |
| 2842 | if (m && f) f.checked = m.checked; |
| 2843 | }); |
| 2844 | _wifiFsRender(); |
| 2845 | // The canvas only gets a size once the overlay is laid out. |
| 2846 | requestAnimationFrame(() => { |
| 2847 | if (_wifiState.view === 'waterfall') _wifiDrawWaterfall(); |
| 2848 | else _wifiDrawSpectrum(); |
| 2849 | }); |
| 2850 | if (!_wifiState.data) wifiScan(); |
| 2851 | } |
| 2852 | |
| 2853 | function _wifiFsClose(el) { |
| 2854 | el.classList.add('hidden'); |
| 2855 | el.setAttribute('aria-hidden', 'true'); |
| 2856 | document.body.classList.remove('wifi-fs-open'); |
| 2857 | _wifiState.fs.open = false; |
| 2858 | _wifiState.hoverBssid = null; |
| 2859 | document.removeEventListener('keydown', _wifiFsKey); |
| 2860 | if (document.fullscreenElement && _wifiState.fs.native) document.exitFullscreen().catch(() => {}); |
no test coverage detected