diff --git a/app/static/js/app.js b/app/static/js/app.js index f239784..d47d61d 100644 --- a/app/static/js/app.js +++ b/app/static/js/app.js @@ -425,9 +425,9 @@ function setupEventListeners() { isUserScrolling = !isAtBottom; }); - // Load device info when settings modal opens - const settingsModal = document.getElementById('settingsModal'); - settingsModal.addEventListener('show.bs.modal', function() { + // Load device info when modal opens + const deviceInfoModal = document.getElementById('deviceInfoModal'); + deviceInfoModal.addEventListener('show.bs.modal', function() { loadDeviceInfo(); }); @@ -767,24 +767,110 @@ async function loadStatus() { } } +/** + * Copy text to clipboard with visual feedback + */ +async function copyToClipboard(text, btnElement) { + try { + await navigator.clipboard.writeText(text); + const icon = btnElement.querySelector('i'); + const originalClass = icon.className; + icon.className = 'bi bi-check'; + setTimeout(() => { icon.className = originalClass; }, 1500); + } catch (err) { + console.error('Failed to copy:', err); + } +} + /** * Load device information */ async function loadDeviceInfo() { - const infoEl = document.getElementById('deviceInfo'); - infoEl.innerHTML = '
Loading...'; + const container = document.getElementById('deviceInfoContent'); + container.innerHTML = '${escapeHtml(data.info)}`;
- } else {
- infoEl.innerHTML = `Error: ${escapeHtml(data.error)}`;
+ if (!data.success) {
+ container.innerHTML = `${escapeHtml(data.info)}`;
+ return;
+ }
+
+ if (!info) {
+ container.innerHTML = `${escapeHtml(data.info)}`;
+ return;
+ }
+
+ // Type mapping
+ const typeNames = { 1: 'Companion', 2: 'Repeater', 3: 'Room Server', 4: 'Sensor' };
+ const typeName = typeNames[info.adv_type] || `Unknown (${info.adv_type})`;
+
+ // Shorten public key for display
+ const pubKey = info.public_key || '';
+ const shortKey = pubKey.length > 12 ? `${pubKey.slice(0, 6)}...${pubKey.slice(-6)}` : pubKey;
+
+ // Location
+ const hasLocation = info.adv_lat && info.adv_lon && (info.adv_lat !== 0 || info.adv_lon !== 0);
+ const coords = hasLocation ? `${info.adv_lat.toFixed(6)}, ${info.adv_lon.toFixed(6)}` : 'Not available';
+
+ // Build table rows
+ const rows = [
+ { label: 'Name', value: escapeHtml(info.name || 'Unknown'), copyValue: info.name },
+ { label: 'Type', value: typeName },
+ { label: 'Public Key', value: `${escapeHtml(shortKey)}`, copyValue: pubKey },
+ { label: 'Location', value: coords, showMap: hasLocation, lat: info.adv_lat, lon: info.adv_lon, name: info.name },
+ { label: 'TX Power', value: `${info.tx_power || 0} / ${info.max_tx_power || 0} dBm` },
+ { label: 'Frequency', value: `${info.radio_freq || 0} MHz` },
+ { label: 'Bandwidth', value: `${info.radio_bw || 0} kHz` },
+ { label: 'Spreading Factor', value: info.radio_sf || 0 },
+ { label: 'Coding Rate', value: `4/${info.radio_cr || 0}` },
+ { label: 'Multi Acks', value: info.multi_acks ? 'Enabled' : 'Disabled' },
+ { label: 'Location Sharing', value: info.adv_loc_policy ? 'Enabled' : 'Disabled' },
+ { label: 'Manual Add Contacts', value: info.manual_add_contacts ? 'Yes' : 'No' }
+ ];
+
+ let html = '| ${row.label} | `; + html += ''; + html += row.value; + + // Copy button + if (row.copyValue) { + html += ` `; + } + + // Map button + if (row.showMap) { + html += ` `; + } + + html += ' | '; + html += '