|
4 | 4 | D.state.wifiSelectedFlags = ''; |
5 | 5 | D.timers.wifiConnectPoll = null; |
6 | 6 |
|
| 7 | + D.clearWifiScanList = function () { |
| 8 | + const container = D.el('wifi-scan-list'); |
| 9 | + if (container) { |
| 10 | + container.replaceChildren(); |
| 11 | + } |
| 12 | + return container; |
| 13 | + }; |
| 14 | + |
| 15 | + D.renderWifiScanMessage = function (message, className) { |
| 16 | + const container = D.clearWifiScanList(); |
| 17 | + if (!container) return; |
| 18 | + const text = document.createElement('p'); |
| 19 | + text.className = className; |
| 20 | + text.textContent = message; |
| 21 | + container.appendChild(text); |
| 22 | + }; |
| 23 | + |
| 24 | + D.renderWifiScanLoading = function () { |
| 25 | + const container = D.clearWifiScanList(); |
| 26 | + if (!container) return; |
| 27 | + |
| 28 | + const wrapper = document.createElement('div'); |
| 29 | + wrapper.className = 'flex items-center justify-center py-8'; |
| 30 | + |
| 31 | + const spinner = document.createElement('div'); |
| 32 | + spinner.className = 'w-5 h-5 border-2 border-ln-pink border-t-transparent rounded-full animate-spin mr-3'; |
| 33 | + |
| 34 | + const label = document.createElement('span'); |
| 35 | + label.className = 'text-ln-muted font-mono text-sm'; |
| 36 | + label.textContent = 'Scanning...'; |
| 37 | + |
| 38 | + wrapper.appendChild(spinner); |
| 39 | + wrapper.appendChild(label); |
| 40 | + container.appendChild(wrapper); |
| 41 | + }; |
| 42 | + |
| 43 | + D.renderWifiScanResults = function (networks) { |
| 44 | + const container = D.clearWifiScanList(); |
| 45 | + if (!container) return; |
| 46 | + |
| 47 | + const list = document.createElement('div'); |
| 48 | + list.className = 'space-y-1 max-h-72 overflow-y-auto'; |
| 49 | + |
| 50 | + networks.forEach(function (net) { |
| 51 | + const button = document.createElement('button'); |
| 52 | + button.type = 'button'; |
| 53 | + button.dataset.wifiSsid = net.ssid || ''; |
| 54 | + button.dataset.wifiFlags = net.flags || ''; |
| 55 | + button.className = 'wifi-network-btn w-full flex items-center justify-between px-3 py-2.5 rounded-lg hover:bg-ln-surface transition-colors group'; |
| 56 | + |
| 57 | + const left = document.createElement('div'); |
| 58 | + left.className = 'flex items-center gap-2 min-w-0'; |
| 59 | + |
| 60 | + if (D.isEncrypted(net.flags)) { |
| 61 | + const lock = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); |
| 62 | + lock.setAttribute('class', 'w-3.5 h-3.5 text-ln-muted shrink-0'); |
| 63 | + lock.setAttribute('fill', 'currentColor'); |
| 64 | + lock.setAttribute('viewBox', '0 0 20 20'); |
| 65 | + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); |
| 66 | + path.setAttribute('fill-rule', 'evenodd'); |
| 67 | + path.setAttribute('clip-rule', 'evenodd'); |
| 68 | + path.setAttribute('d', 'M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z'); |
| 69 | + lock.appendChild(path); |
| 70 | + left.appendChild(lock); |
| 71 | + } |
| 72 | + |
| 73 | + const ssid = document.createElement('span'); |
| 74 | + ssid.className = 'font-mono text-sm truncate'; |
| 75 | + ssid.textContent = net.ssid || ''; |
| 76 | + left.appendChild(ssid); |
| 77 | + |
| 78 | + const signal = document.createElement('span'); |
| 79 | + signal.className = 'font-mono text-sm text-ln-muted shrink-0 ml-2'; |
| 80 | + signal.textContent = D.signalBars(net.signal); |
| 81 | + |
| 82 | + button.appendChild(left); |
| 83 | + button.appendChild(signal); |
| 84 | + list.appendChild(button); |
| 85 | + }); |
| 86 | + |
| 87 | + container.appendChild(list); |
| 88 | + }; |
| 89 | + |
7 | 90 | D.signalBars = function (dbm) { |
8 | 91 | if (dbm >= -50) return '\u2582\u2584\u2586\u2588'; |
9 | 92 | if (dbm >= -60) return '\u2582\u2584\u2586\u2007'; |
|
24 | 107 | D.openWifiScan = async function () { |
25 | 108 | D.el('wifi-modal').classList.remove('hidden'); |
26 | 109 | D.showWifiView('wifi-scan-list'); |
27 | | - D.el('wifi-scan-list').innerHTML = '<div class="flex items-center justify-center py-8"><div class="w-5 h-5 border-2 border-ln-pink border-t-transparent rounded-full animate-spin mr-3"></div><span class="text-ln-muted font-mono text-sm">Scanning...</span></div>'; |
| 110 | + D.renderWifiScanLoading(); |
28 | 111 | try { |
29 | 112 | const resp = await fetch('/box/api/wifi/scan', { method: 'POST' }); |
30 | 113 | if (!resp.ok) throw new Error('Scan failed'); |
31 | 114 | const data = await resp.json(); |
32 | 115 | if (data.error) throw new Error(data.error); |
33 | 116 | if (!data.networks || data.networks.length === 0) { |
34 | | - D.el('wifi-scan-list').innerHTML = '<p class="text-ln-muted font-mono text-sm text-center py-8">No networks found</p>'; |
| 117 | + D.renderWifiScanMessage('No networks found', 'text-ln-muted font-mono text-sm text-center py-8'); |
35 | 118 | return; |
36 | 119 | } |
37 | | - let html = '<div class="space-y-1 max-h-72 overflow-y-auto">'; |
38 | | - data.networks.forEach(function (net) { |
39 | | - const lock = D.isEncrypted(net.flags) ? '<svg class="w-3.5 h-3.5 text-ln-muted shrink-0" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"></path></svg>' : ''; |
40 | | - html += '<button type="button" data-wifi-ssid="' + encodeURIComponent(net.ssid) + '" data-wifi-flags="' + encodeURIComponent(net.flags || '') + '" class="wifi-network-btn w-full flex items-center justify-between px-3 py-2.5 rounded-lg hover:bg-ln-surface transition-colors group">' + |
41 | | - '<div class="flex items-center gap-2 min-w-0">' + lock + '<span class="font-mono text-sm truncate">' + net.ssid + '</span></div>' + |
42 | | - '<span class="font-mono text-sm text-ln-muted shrink-0 ml-2">' + D.signalBars(net.signal) + '</span></button>'; |
43 | | - }); |
44 | | - html += '</div>'; |
45 | | - D.el('wifi-scan-list').innerHTML = html; |
| 120 | + D.renderWifiScanResults(data.networks); |
46 | 121 | } catch (error) { |
47 | | - D.el('wifi-scan-list').innerHTML = '<p class="text-red-400 font-mono text-sm text-center py-8">Scan failed: ' + error.message + '</p>'; |
| 122 | + const message = error && error.message ? error.message : 'Scan failed'; |
| 123 | + D.renderWifiScanMessage('Scan failed: ' + message, 'text-red-400 font-mono text-sm text-center py-8'); |
48 | 124 | } |
49 | 125 | }; |
50 | 126 |
|
|
0 commit comments