diff --git a/meshview/templates/map.html b/meshview/templates/map.html
index bdc1df8..0625f43 100644
--- a/meshview/templates/map.html
+++ b/meshview/templates/map.html
@@ -235,6 +235,7 @@ function labelFor(key, fallback){
function buildNodePopup(node){
const labels = {
channel: labelFor("channel_label", "Channel"),
+ nodeId: labelFor("node_id", "Node ID"),
model: labelFor("model_label", "Model"),
role: labelFor("role_label", "Role"),
mqtt: labelFor("mqtt_gateway", "MQTT Gateway"),
@@ -243,13 +244,16 @@ function buildNodePopup(node){
yes: mapTranslations.yes || "Yes",
no: mapTranslations.no || "No"
};
+ const displayName = node.long_name || node.short_name || `Node ${node.node_id}`;
+ const shortName = node.short_name ? ` (${escapeHtml(node.short_name)})` : "";
return `
- ${node.long_name} (${node.short_name})
+ ${escapeHtml(displayName)}${shortName}
- ${labels.channel} ${node.channel}
- ${labels.model} ${node.hw_model}
- ${labels.role} ${node.role}
+ ${labels.nodeId} ${node.node_id}
+ ${labels.channel} ${escapeHtml(node.channel || "N/A")}
+ ${labels.model} ${escapeHtml(node.hw_model || "N/A")}
+ ${labels.role} ${escapeHtml(node.role || "N/A")}
${labels.mqtt} ${node.is_mqtt_gateway ? labels.yes : labels.no}
${
@@ -260,7 +264,7 @@ function buildNodePopup(node){
${
node.firmware
- ? `${labels.firmware} ${node.firmware}
`
+ ? `${labels.firmware} ${escapeHtml(node.firmware)}
`
: ""
}
`;
@@ -468,34 +472,18 @@ function renderNodesOnMap(){
marker.nodeId = node.key;
marker.originalColor = color;
markerById[node.key] = marker;
+ marker.bindPopup(buildNodePopup(node), {
+ autoPan: true,
+ closeButton: true
+ });
- const popup = `
- ${node.long_name} (${node.short_name})
-
- ${node.channel}
- ${node.hw_model}
- ${node.role}
- ${
- node.is_mqtt_gateway ? (mapTranslations.yes || "Yes") : (mapTranslations.no || "No")
- }
-
- ${
- node.last_seen_us
- ? ` ${timeAgoFromUs(node.last_seen_us)}
`
- : ""
+ marker.on('click', e => {
+ if(e.originalEvent){
+ L.DomEvent.stopPropagation(e.originalEvent);
}
-
- ${
- node.firmware
- ? ` ${node.firmware}
`
- : ""
- }
- `;
-
- marker.on('click', () => {
- onNodeClick(node);
marker.setPopupContent(buildNodePopup(node));
marker.openPopup();
+ onNodeClick(node);
});
});
@@ -615,6 +603,8 @@ async function onNodeClick(node){
}
map.on('click', e=>{
+ if(e.originalEvent.defaultPrevented) return;
+
if(!e.originalEvent.target.classList.contains('leaflet-interactive')){
edgeLayer.clearLayers();
selectedNodeId=null;