[feat](trx-frontend): rich popup for receiver/owner marker on map
Replace plain-text receiver marker popup with a styled info card matching the APRS popup layout. Shows callsign, trx-server version and build date, owner callsign (when different), QTH coordinates, and all configured rigs with manufacturer/model; active rig is badged. Rig data (manufacturer, model, display_name, active state) is stored in serverRigs/serverActiveRigId on each /rigs refresh. Popup content is rebuilt live on popupopen so it always reflects current state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -639,6 +639,8 @@ async function refreshRigList() {
|
||||
displayNames[r.rig_id] = r.rig_id;
|
||||
}
|
||||
});
|
||||
serverRigs = rigs;
|
||||
serverActiveRigId = data.active_rig_id || null;
|
||||
applyRigList(data.active_rig_id, rigIds, displayNames);
|
||||
} catch (e) {
|
||||
// Non-fatal: SSE/status path still drives main UI.
|
||||
@@ -1245,6 +1247,8 @@ let serverVersion = null;
|
||||
let serverBuildDate = null;
|
||||
let serverCallsign = null;
|
||||
let ownerCallsign = null;
|
||||
let serverRigs = [];
|
||||
let serverActiveRigId = null;
|
||||
let serverLat = null;
|
||||
let serverLon = null;
|
||||
let initialMapZoom = 10;
|
||||
@@ -2442,17 +2446,21 @@ function initAprsMap() {
|
||||
updateMapBaseLayerForTheme(currentTheme());
|
||||
|
||||
if (hasLocation) {
|
||||
const popupText = serverCallsign ? serverCallsign : "Receiver";
|
||||
aprsMapReceiverMarker = L.circleMarker([serverLat, serverLon], {
|
||||
radius: 8, color: "#3388ff", fillColor: "#3388ff", fillOpacity: 0.8
|
||||
}).addTo(aprsMap).bindPopup(popupText);
|
||||
}).addTo(aprsMap).bindPopup("");
|
||||
}
|
||||
|
||||
// Rebuild APRS popup content on open so age and distance are always fresh
|
||||
// and draw an animated radio path from receiver to the station
|
||||
// Rebuild popup content on open (keeps age/distance/rig list fresh)
|
||||
aprsMap.on("popupopen", function(e) {
|
||||
const marker = e.popup._source;
|
||||
if (aprsRadioPath) { aprsRadioPath.remove(); aprsRadioPath = null; }
|
||||
|
||||
if (marker === aprsMapReceiverMarker) {
|
||||
e.popup.setContent(buildReceiverPopupHtml());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!marker || !marker._aprsCall) return;
|
||||
const entry = stationMarkers.get(marker._aprsCall);
|
||||
if (!entry) return;
|
||||
@@ -2572,6 +2580,33 @@ function formatTimeAgo(tsMs) {
|
||||
return remMins > 0 ? `${hrs}h ${remMins}min ago` : `${hrs}h ago`;
|
||||
}
|
||||
|
||||
function buildReceiverPopupHtml() {
|
||||
const call = serverCallsign || ownerCallsign || "Receiver";
|
||||
let meta = "";
|
||||
if (serverVersion) {
|
||||
meta = `trx-server v${escapeMapHtml(serverVersion)}`;
|
||||
if (serverBuildDate) meta += ` · ${escapeMapHtml(serverBuildDate)}`;
|
||||
}
|
||||
let rows = "";
|
||||
if (ownerCallsign && ownerCallsign !== serverCallsign) {
|
||||
rows += `<tr><td class="aprs-popup-label">Owner</td><td>${escapeMapHtml(ownerCallsign)}</td></tr>`;
|
||||
}
|
||||
if (serverLat != null && serverLon != null) {
|
||||
rows += `<tr><td class="aprs-popup-label">QTH</td><td>${serverLat.toFixed(5)}, ${serverLon.toFixed(5)}</td></tr>`;
|
||||
}
|
||||
for (const rig of serverRigs) {
|
||||
const name = rig.display_name || `${rig.manufacturer} ${rig.model}`.trim();
|
||||
const active = rig.rig_id === serverActiveRigId
|
||||
? ` <span class="receiver-popup-active">active</span>` : "";
|
||||
rows += `<tr><td class="aprs-popup-label">Rig</td><td>${escapeMapHtml(name)}${active}</td></tr>`;
|
||||
}
|
||||
return `<div class="aprs-popup">` +
|
||||
`<div class="aprs-popup-call">${escapeMapHtml(call)}</div>` +
|
||||
(meta ? `<div class="aprs-popup-meta">${meta}</div>` : "") +
|
||||
(rows ? `<table class="aprs-popup-table">${rows}</table>` : "") +
|
||||
`</div>`;
|
||||
}
|
||||
|
||||
function buildAprsPopupHtml(call, lat, lon, info, pkt) {
|
||||
const age = pkt?._tsMs ? formatTimeAgo(pkt._tsMs) : (pkt?._ts || null);
|
||||
const distKm = (serverLat != null && serverLon != null)
|
||||
|
||||
Reference in New Issue
Block a user