[feat](trx-frontend-http): rich APRS map tooltips with distance and age

Each station popup now shows:
- Callsign/SSID header
- Age (s/min/h ago, from _tsMs stamped on receive)
- Distance from receiver (Haversine, km or m)
- Packet type and via path
- Full info/comment string

Adds haversineKm(), formatTimeAgo(), buildAprsPopupHtml() helpers in
app.js and .aprs-popup-* CSS. Passes full packet object as 7th arg
to aprsMapAddStation from aprs.js.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-03-01 17:19:00 +01:00
parent dd051beee3
commit db425156a4
3 changed files with 60 additions and 5 deletions
@@ -139,6 +139,7 @@ function addAprsPacket(pkt) {
// Stamp timestamp for persistence
pkt._ts = new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
pkt._tsMs = Date.now();
// Persist to history
aprsPacketHistory.unshift(pkt);
@@ -150,7 +151,7 @@ function addAprsPacket(pkt) {
const row = renderAprsRow(pkt);
if (pkt.lat != null && pkt.lon != null && window.aprsMapAddStation) {
window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info, pkt.symbolTable, pkt.symbolCode);
window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info, pkt.symbolTable, pkt.symbolCode, pkt);
}
aprsPacketsEl.prepend(row);
while (aprsPacketsEl.children.length > APRS_MAX_PACKETS) {
@@ -171,7 +172,7 @@ for (let i = aprsPacketHistory.length - 1; i >= 0; i--) {
const pkt = aprsPacketHistory[i];
aprsPacketsEl.prepend(renderAprsRow(pkt));
if (pkt.lat != null && pkt.lon != null && window.aprsMapAddStation) {
window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info, pkt.symbolTable, pkt.symbolCode);
window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info, pkt.symbolTable, pkt.symbolCode, pkt);
}
}
updateAprsBar();