[feat](trx-rs): add ham sat pass predictions; rename SAT tab
- Rename "Weather Satellites" sub-tab to "SAT" - Add "Predictions" view: next 24 h flyby table for 13 ham sats (ISS, AO-91, AO-92, SO-50, AO-73, JO-97, PO-101, LilacSat-2, CAS-4B, EO-88, RS-44, SALSAT, GREENCUBE) - trx-core/geo: add PassPrediction, HAM_SATS, compute_upcoming_passes(), find_passes_for_sat(), compute_az_el() helpers; spawn_tle_refresh_task now also fetches CelesTrak amateur group on startup and every 24 h - trx-frontend-http: add GET /sat_passes endpoint - app.js: locator tooltips now accumulate all receivers per station via remotes Set; _detailPassesRigFilter checks the Set Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -7002,10 +7002,16 @@ function buildDecodeLocatorTooltipHtml(grid, entry, type) {
|
||||
Number.isFinite(detail?.dt_s) ? `dt ${Number(detail.dt_s).toFixed(2)}` : null,
|
||||
escapeMapHtml(freq),
|
||||
].filter(Boolean).join(" · ");
|
||||
const rxLabel = _receiverLabel(detail?.remote);
|
||||
const rxHtml = rxLabel
|
||||
? `<div class="decode-locator-tip-rx">${escapeMapHtml(rxLabel)}</div>`
|
||||
: "";
|
||||
const remoteIds = detail?.remotes instanceof Set && detail.remotes.size > 0
|
||||
? Array.from(detail.remotes)
|
||||
: (detail?.remote ? [detail.remote] : []);
|
||||
const rxHtml = remoteIds
|
||||
.map(rid => {
|
||||
const label = _receiverLabel(rid);
|
||||
return label ? `<div class="decode-locator-tip-rx">${escapeMapHtml(label)}</div>` : "";
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join("");
|
||||
const message = detail?.message
|
||||
? `<div class="decode-locator-tip-note">${escapeMapHtml(String(detail.message))}</div>`
|
||||
: "";
|
||||
@@ -7113,6 +7119,7 @@ function _locatorEntryVisibleOnMap(entry) {
|
||||
|
||||
function _detailPassesRigFilter(detail) {
|
||||
if (!mapRigFilter) return true;
|
||||
if (detail?.remotes instanceof Set) return detail.remotes.has(mapRigFilter);
|
||||
return detail?.remote === mapRigFilter;
|
||||
}
|
||||
|
||||
@@ -7603,6 +7610,7 @@ window.mapAddLocator = function(message, grids, type = "ft8", station = null, de
|
||||
freq_hz: Number.isFinite(details?.freq_hz) ? Number(details.freq_hz) : null,
|
||||
message: String(details?.message || message || "").trim() || null,
|
||||
remote: msgRigId || null,
|
||||
remotes: new Set(msgRigId ? [msgRigId] : []),
|
||||
};
|
||||
const detailKey = detailStationId || `${targetId || "decode"}:${detailEntry.message || "decode"}:${detailEntry.ts_ms || Date.now()}`;
|
||||
const key = `${markerType}:${grid}`;
|
||||
@@ -7614,7 +7622,10 @@ window.mapAddLocator = function(message, grids, type = "ft8", station = null, de
|
||||
? new Map(existing.stationDetails)
|
||||
: new Map();
|
||||
}
|
||||
existing.allStationDetails.set(detailKey, { ...detailEntry });
|
||||
const prevDetail = existing.allStationDetails.get(detailKey);
|
||||
const mergedRemotes = prevDetail?.remotes instanceof Set ? new Set(prevDetail.remotes) : new Set();
|
||||
if (msgRigId) mergedRemotes.add(msgRigId);
|
||||
existing.allStationDetails.set(detailKey, { ...detailEntry, remotes: mergedRemotes });
|
||||
existing.sourceType = markerType;
|
||||
if (msgRigId) {
|
||||
if (!existing.rigIds) existing.rigIds = new Set();
|
||||
|
||||
Reference in New Issue
Block a user