From 91b07fe7978fe09fe475f24cdf451fb23089fa3a Mon Sep 17 00:00:00 2001 From: Smittix Date: Wed, 21 Jan 2026 17:52:32 +0000 Subject: [PATCH] Fix card rendering - use string concat instead of template literals - Change card HTML generation from template literals to string concatenation - This avoids potential issues with special characters in device data - Also disable legacy handleBtDeviceImmediate when BluetoothMode exists - Use device_id as fallback name if name is missing Co-Authored-By: Claude Opus 4.5 --- static/js/components/device-card.js | 82 +++++++++++++---------------- templates/index.html | 5 ++ 2 files changed, 42 insertions(+), 45 deletions(-) diff --git a/static/js/components/device-card.js b/static/js/components/device-card.js index 26eba03..05847f9 100644 --- a/static/js/components/device-card.js +++ b/static/js/components/device-card.js @@ -184,57 +184,49 @@ const DeviceCard = (function() { const protocolBadge = createProtocolBadge(device.protocol) || ''; // Build card with explicit defaults for all values - const deviceName = device.name || 'Unknown Device'; + const deviceName = device.name || device.device_id || 'Unknown Device'; const deviceAddress = device.address || 'Unknown'; const addressType = device.address_type || 'unknown'; - const rssiDisplay = device.rssi_current !== null && device.rssi_current !== undefined + const rssiDisplay = (device.rssi_current !== null && device.rssi_current !== undefined) ? device.rssi_current + ' dBm' : '--'; const seenCount = device.seen_count || 0; const inBaseline = device.in_baseline || false; + const mfrName = device.manufacturer_name || ''; - card.innerHTML = ` -
-
- ${protocolBadge} - ${heuristicBadges} -
- - - ${inBaseline ? 'Known' : 'New'} - -
-
-
-
${escapeHtml(deviceName)}
-
- ${escapeHtml(deviceAddress)} - (${escapeHtml(addressType)}) -
-
-
-
- ${rssiDisplay} - ${sparkline} -
- ${rangeBand} -
- ${device.manufacturer_name ? ` -
- 🏭 - ${escapeHtml(device.manufacturer_name)} -
- ` : ''} -
- - 👁 - ${seenCount}× - - - ${escapeHtml(relativeTime)} - -
-
- `; + // Build the HTML parts separately to avoid template issues + const headerHtml = '
' + + '
' + protocolBadge + heuristicBadges + '
' + + '' + + '' + (inBaseline ? 'Known' : 'New') + '' + + '
'; + + const identityHtml = '
' + + '
' + escapeHtml(deviceName) + '
' + + '
' + + '' + escapeHtml(deviceAddress) + '' + + '(' + escapeHtml(addressType) + ')' + + '
'; + + const signalHtml = '
' + + '
' + + '' + rssiDisplay + '' + + sparkline + '
' + rangeBand + '
'; + + const mfrHtml = mfrName ? + '
' + + '🏭' + + '' + escapeHtml(mfrName) + '
' : ''; + + const metaHtml = '
' + + '' + + '👁' + seenCount + '×' + + '' + + escapeHtml(relativeTime) + '
'; + + const bodyHtml = '
' + + identityHtml + signalHtml + mfrHtml + metaHtml + '
'; + + card.innerHTML = headerHtml + bodyHtml; // Make card clickable - opens modal with full details card.addEventListener('click', () => { diff --git a/templates/index.html b/templates/index.html index be4f18e..b50d292 100644 --- a/templates/index.html +++ b/templates/index.html @@ -6090,6 +6090,11 @@ // Handle discovered Bluetooth device (called from batched update) function handleBtDeviceImmediate(device) { + // Skip if new BluetoothMode is handling devices + if (typeof BluetoothMode !== 'undefined') { + return; + } + const isNew = !btDevices[device.mac]; // Check for Find My network