diff --git a/app/static/js/dm.js b/app/static/js/dm.js index 9eb511c..b6064b1 100644 --- a/app/static/js/dm.js +++ b/app/static/js/dm.js @@ -730,18 +730,63 @@ function populateContactInfoModal() { body.appendChild(div); } - // Path/route + // Path/route (device path) if (contact.path_or_mode) { const div = document.createElement('div'); - div.className = 'small mb-2'; + div.className = 'small mb-2 d-flex align-items-center gap-2'; const mode = contact.path_or_mode; if (mode === 'Flood') { - div.innerHTML = ' Flood'; + div.innerHTML = ' Flood'; } else if (mode === 'Direct') { - div.innerHTML = ' Direct'; + div.innerHTML = ' Direct'; } else { const hops = mode.split('→').length; - div.innerHTML = ` ${mode} (${hops} hops)`; + const outPathLen = contact.out_path_len || 0; + const hashSize = outPathLen > 0 ? ((outPathLen >> 6) + 1) : 1; + const hopCount = outPathLen & 0x3F; + const pathHex = contact.out_path ? contact.out_path.substring(0, hopCount * hashSize * 2) : ''; + + div.innerHTML = ` + ${mode} (${hops} hops) + ${pathHex ? `` : ''} + `; + + if (pathHex) { + // Defer event attachment to after DOM insertion + setTimeout(() => { + const importBtn = document.getElementById('dmImportDevicePathBtn'); + if (importBtn) { + importBtn.addEventListener('click', async () => { + const pubkey = getCurrentContactPubkey(); + try { + const response = await fetch(`/api/contacts/${encodeURIComponent(pubkey)}/paths`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + path_hex: pathHex, + hash_size: hashSize, + label: 'Device path', + is_primary: true + }) + }); + const data = await response.json(); + if (data.success) { + await renderPathList(pubkey); + showNotification('Device path imported', 'info'); + } else { + showNotification(data.error || 'Import failed', 'danger'); + } + } catch (e) { + showNotification('Import failed', 'danger'); + } + }); + } + }, 0); + } } body.appendChild(div); }