Control WiFi 관측값 유지와 스크롤 보존
This commit is contained in:
+45
-6
@@ -151,6 +151,8 @@
|
||||
wifiScanEmpty: 'No nearby WiFi scan results.',
|
||||
wifiScanCached: 'cached',
|
||||
wifiScanFresh: 'fresh',
|
||||
wifiScanDisabledWithHistory: 'scan disabled, showing last observed networks',
|
||||
observed: 'Observed',
|
||||
ssid: 'SSID',
|
||||
channel: 'Channel',
|
||||
security: 'Security',
|
||||
@@ -301,6 +303,8 @@
|
||||
wifiScanEmpty: '주변 WiFi 스캔 결과가 없습니다.',
|
||||
wifiScanCached: '캐시',
|
||||
wifiScanFresh: '실시간',
|
||||
wifiScanDisabledWithHistory: '스캔 꺼짐, 마지막 관측 목록 표시',
|
||||
observed: '관측',
|
||||
ssid: 'SSID',
|
||||
channel: '채널',
|
||||
security: '보안',
|
||||
@@ -1301,6 +1305,8 @@
|
||||
function renderWifi(data) {
|
||||
const rows = data.wifi?.clients || [];
|
||||
if (!els.wifiTable) return;
|
||||
const tableWrap = els.wifiTable.closest('.table-wrap');
|
||||
const scrollLeft = tableWrap ? tableWrap.scrollLeft : 0;
|
||||
els.wifiTable.innerHTML = rows.length
|
||||
? rows.map(row => `
|
||||
<tr>
|
||||
@@ -1316,28 +1322,40 @@
|
||||
</tr>
|
||||
`).join('')
|
||||
: `<tr><td colspan="9">${escapeHtml(t('noWifiClients'))}</td></tr>`;
|
||||
if (tableWrap) {
|
||||
tableWrap.scrollLeft = scrollLeft;
|
||||
}
|
||||
|
||||
renderWifiScan(data.wifi?.scan || null);
|
||||
}
|
||||
|
||||
function renderWifiScan(scan) {
|
||||
if (!els.wifiScan) return;
|
||||
if (!scan || scan.enabled === false) {
|
||||
const previousScroll = {};
|
||||
els.wifiScan.querySelectorAll('.wifi-scan-band').forEach(section => {
|
||||
const band = section.dataset.band || '';
|
||||
const wrap = section.querySelector('.table-wrap');
|
||||
if (band && wrap) previousScroll[band] = wrap.scrollLeft;
|
||||
});
|
||||
|
||||
const networks = Array.isArray(scan?.networks) ? scan.networks : [];
|
||||
if (!scan || (scan.enabled === false && networks.length === 0)) {
|
||||
els.wifiScan.innerHTML = `<div class="wifi-scan-empty">${escapeHtml(t('wifiScanDisabled'))}</div>`;
|
||||
return;
|
||||
}
|
||||
|
||||
const networks = Array.isArray(scan.networks) ? scan.networks : [];
|
||||
const errors = Array.isArray(scan.errors) ? scan.errors : [];
|
||||
const status = `${scan.cached ? t('wifiScanCached') : t('wifiScanFresh')} · ${escapeHtml(scan.generated_at || '-')}`;
|
||||
const status = scan.enabled === false
|
||||
? `${t('wifiScanDisabledWithHistory')} · ${scan.observed_hours || '-'}h`
|
||||
: `${scan.cached ? t('wifiScanCached') : t('wifiScanFresh')} · ${escapeHtml(scan.generated_at || '-')}`;
|
||||
const groups = ['2.4G', '5G'].map(band => {
|
||||
const bandRows = networks.filter(row => row.band === band);
|
||||
return `
|
||||
<section class="wifi-scan-band">
|
||||
<section class="wifi-scan-band" data-band="${attr(band)}">
|
||||
<h3>${escapeHtml(band)} <span>${bandRows.length}${scan.total_found ? ` / ${scan.total_found}` : ''}</span></h3>
|
||||
<div class="table-wrap compact">
|
||||
<table class="wifi-scan-table">
|
||||
<thead><tr><th>${escapeHtml(t('ssid'))}</th><th>BSSID</th><th>${escapeHtml(t('channel'))}</th><th>${escapeHtml(t('signal'))}</th><th>${escapeHtml(t('security'))}</th><th>${escapeHtml(t('lastSeen'))}</th><th>WiFi</th><th>폭</th><th>속도</th><th>기능</th></tr></thead>
|
||||
<thead><tr><th>${escapeHtml(t('ssid'))}</th><th>BSSID</th><th>${escapeHtml(t('channel'))}</th><th>${escapeHtml(t('signal'))}</th><th>${escapeHtml(t('security'))}</th><th>${escapeHtml(t('observed'))}</th><th>WiFi</th><th>폭</th><th>속도</th><th>기능</th></tr></thead>
|
||||
<tbody>
|
||||
${bandRows.length ? bandRows.map(row => {
|
||||
const dbm = wifiSignalDbm(row.signal);
|
||||
@@ -1347,7 +1365,7 @@
|
||||
<td>${escapeHtml(row.channel ?? '-')} ${row.freq ? `(${escapeHtml(row.freq)}MHz)` : ''}</td>
|
||||
<td><span class="wifi-signal ${wifiSignalClass(dbm)}">${escapeHtml(row.signal || '-')}</span></td>
|
||||
<td>${escapeHtml(row.security || '-')}</td>
|
||||
<td>${row.last_seen_ms === null || row.last_seen_ms === undefined ? '-' : `${escapeHtml(row.last_seen_ms)}ms`}</td>
|
||||
<td>${escapeHtml(wifiObservedText(row))}</td>
|
||||
<td>${escapeHtml(wifiStandardText(row))}</td>
|
||||
<td>${escapeHtml(row.channel_width || '-')}</td>
|
||||
<td>${escapeHtml(row.rates || '-')}</td>
|
||||
@@ -1373,6 +1391,27 @@
|
||||
${errorHtml}
|
||||
<div class="wifi-scan-grid">${groups}</div>
|
||||
`;
|
||||
requestAnimationFrame(() => {
|
||||
els.wifiScan.querySelectorAll('.wifi-scan-band').forEach(section => {
|
||||
const band = section.dataset.band || '';
|
||||
const wrap = section.querySelector('.table-wrap');
|
||||
if (band && wrap && previousScroll[band] !== undefined) {
|
||||
wrap.scrollLeft = previousScroll[band];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function wifiObservedText(row) {
|
||||
if (row?.observed_source === 'live') {
|
||||
return row.last_seen_ms === null || row.last_seen_ms === undefined
|
||||
? '방금'
|
||||
: `방금 (${row.last_seen_ms}ms)`;
|
||||
}
|
||||
if (row?.observed_age_seconds !== null && row?.observed_age_seconds !== undefined) {
|
||||
return `${timeAgo(row.observed_age_seconds)} · ${row.last_seen_at || '-'}`;
|
||||
}
|
||||
return row?.last_seen_at || '-';
|
||||
}
|
||||
|
||||
function wifiStandardText(row) {
|
||||
|
||||
Reference in New Issue
Block a user