[feat](trx-frontend-http): add rig source filter to map view
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -938,6 +938,26 @@ function applyRigList(activeRigId, rigIds, displayNames) {
|
|||||||
updateRigSubtitle(activeRigId);
|
updateRigSubtitle(activeRigId);
|
||||||
if (typeof setSchedulerRig === "function") setSchedulerRig(lastActiveRigId);
|
if (typeof setSchedulerRig === "function") setSchedulerRig(lastActiveRigId);
|
||||||
if (typeof setBackgroundDecodeRig === "function") setBackgroundDecodeRig(lastActiveRigId);
|
if (typeof setBackgroundDecodeRig === "function") setBackgroundDecodeRig(lastActiveRigId);
|
||||||
|
updateMapRigFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMapRigFilter() {
|
||||||
|
const el = document.getElementById("map-rig-filter");
|
||||||
|
if (!el) return;
|
||||||
|
const prev = el.value;
|
||||||
|
while (el.options.length > 1) el.remove(1);
|
||||||
|
for (const id of lastRigIds) {
|
||||||
|
const opt = document.createElement("option");
|
||||||
|
opt.value = id;
|
||||||
|
opt.textContent = lastRigDisplayNames[id] || id;
|
||||||
|
el.appendChild(opt);
|
||||||
|
}
|
||||||
|
if (prev && lastRigIds.includes(prev)) {
|
||||||
|
el.value = prev;
|
||||||
|
} else {
|
||||||
|
el.value = "";
|
||||||
|
mapRigFilter = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refreshRigList() {
|
async function refreshRigList() {
|
||||||
@@ -4095,6 +4115,7 @@ const DEFAULT_MAP_SOURCE_FILTER = { ais: true, vdes: true, aprs: true, bookmark:
|
|||||||
const mapFilter = { ...DEFAULT_MAP_SOURCE_FILTER };
|
const mapFilter = { ...DEFAULT_MAP_SOURCE_FILTER };
|
||||||
const mapLocatorFilter = { phase: "band", bands: new Set() };
|
const mapLocatorFilter = { phase: "band", bands: new Set() };
|
||||||
let mapSearchFilter = "";
|
let mapSearchFilter = "";
|
||||||
|
let mapRigFilter = ""; // "" = all rigs
|
||||||
let mapHistoryPruneTimer = null;
|
let mapHistoryPruneTimer = null;
|
||||||
let mapHistoryLimitMinutes = normalizeMapHistoryLimitMinutes(
|
let mapHistoryLimitMinutes = normalizeMapHistoryLimitMinutes(
|
||||||
Number(loadSetting("mapHistoryLimitMinutes", 1440))
|
Number(loadSetting("mapHistoryLimitMinutes", 1440))
|
||||||
@@ -4248,6 +4269,7 @@ function ensureAisMarker(key, entry) {
|
|||||||
.addTo(aprsMap)
|
.addTo(aprsMap)
|
||||||
.bindPopup(buildAisPopupHtml(entry.msg));
|
.bindPopup(buildAisPopupHtml(entry.msg));
|
||||||
marker.__trxType = "ais";
|
marker.__trxType = "ais";
|
||||||
|
marker.__trxRigIds = entry.rigIds || new Set();
|
||||||
marker._aisMmsi = String(key);
|
marker._aisMmsi = String(key);
|
||||||
entry.marker = marker;
|
entry.marker = marker;
|
||||||
mapMarkers.add(marker);
|
mapMarkers.add(marker);
|
||||||
@@ -4262,6 +4284,7 @@ function ensureVdesMarker(key, entry) {
|
|||||||
fillOpacity: 0.82,
|
fillOpacity: 0.82,
|
||||||
}).addTo(aprsMap).bindPopup(buildVdesPopupHtml(entry.msg));
|
}).addTo(aprsMap).bindPopup(buildVdesPopupHtml(entry.msg));
|
||||||
marker.__trxType = "vdes";
|
marker.__trxType = "vdes";
|
||||||
|
marker.__trxRigIds = entry.rigIds || new Set();
|
||||||
marker._vdesKey = String(key);
|
marker._vdesKey = String(key);
|
||||||
entry.marker = marker;
|
entry.marker = marker;
|
||||||
mapMarkers.add(marker);
|
mapMarkers.add(marker);
|
||||||
@@ -4277,6 +4300,7 @@ function ensureDecodeLocatorMarker(entry) {
|
|||||||
.addTo(aprsMap)
|
.addTo(aprsMap)
|
||||||
.bindPopup(tooltipHtml);
|
.bindPopup(tooltipHtml);
|
||||||
marker.__trxType = entry.sourceType;
|
marker.__trxType = entry.sourceType;
|
||||||
|
marker.__trxRigIds = entry.rigIds || new Set();
|
||||||
sendLocatorOverlayToBack(marker);
|
sendLocatorOverlayToBack(marker);
|
||||||
assignLocatorMarkerMeta(marker, entry.sourceType, entry.bandMeta);
|
assignLocatorMarkerMeta(marker, entry.sourceType, entry.bandMeta);
|
||||||
entry.marker = marker;
|
entry.marker = marker;
|
||||||
@@ -5575,6 +5599,13 @@ function initAprsMap() {
|
|||||||
applyMapFilter();
|
applyMapFilter();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
const mapRigFilterEl = document.getElementById("map-rig-filter");
|
||||||
|
if (mapRigFilterEl) {
|
||||||
|
mapRigFilterEl.addEventListener("change", () => {
|
||||||
|
mapRigFilter = mapRigFilterEl.value;
|
||||||
|
applyMapFilter();
|
||||||
|
});
|
||||||
|
}
|
||||||
if (mapSearchEl) {
|
if (mapSearchEl) {
|
||||||
mapSearchEl.value = mapSearchFilter;
|
mapSearchEl.value = mapSearchFilter;
|
||||||
mapSearchEl.addEventListener("input", () => {
|
mapSearchEl.addEventListener("input", () => {
|
||||||
@@ -6018,6 +6049,7 @@ function _aprsAddMarkerToMap(call, entry) {
|
|||||||
radius: 6, color: "#00d17f", fillColor: "#00d17f", fillOpacity: 0.8
|
radius: 6, color: "#00d17f", fillColor: "#00d17f", fillOpacity: 0.8
|
||||||
}).addTo(aprsMap).bindPopup(popupContent);
|
}).addTo(aprsMap).bindPopup(popupContent);
|
||||||
marker.__trxType = "aprs";
|
marker.__trxType = "aprs";
|
||||||
|
marker.__trxRigIds = entry.rigIds || new Set();
|
||||||
marker._aprsCall = call;
|
marker._aprsCall = call;
|
||||||
entry.marker = marker;
|
entry.marker = marker;
|
||||||
mapMarkers.add(marker);
|
mapMarkers.add(marker);
|
||||||
@@ -6034,6 +6066,10 @@ window.aprsMapAddStation = function(call, lat, lon, info, symbolTable, symbolCod
|
|||||||
existing.info = info;
|
existing.info = info;
|
||||||
existing.symbolTable = symbolTable;
|
existing.symbolTable = symbolTable;
|
||||||
existing.symbolCode = symbolCode;
|
existing.symbolCode = symbolCode;
|
||||||
|
if (lastActiveRigId) {
|
||||||
|
if (!existing.rigIds) existing.rigIds = new Set();
|
||||||
|
existing.rigIds.add(lastActiveRigId);
|
||||||
|
}
|
||||||
if (!Array.isArray(existing.trackHistory)) existing.trackHistory = [];
|
if (!Array.isArray(existing.trackHistory)) existing.trackHistory = [];
|
||||||
const prevPoint = existing.trackHistory[existing.trackHistory.length - 1];
|
const prevPoint = existing.trackHistory[existing.trackHistory.length - 1];
|
||||||
if (!aprsPositionsEqual(prevPoint, nextPoint)) {
|
if (!aprsPositionsEqual(prevPoint, nextPoint)) {
|
||||||
@@ -6059,6 +6095,7 @@ window.aprsMapAddStation = function(call, lat, lon, info, symbolTable, symbolCod
|
|||||||
info,
|
info,
|
||||||
symbolTable,
|
symbolTable,
|
||||||
symbolCode,
|
symbolCode,
|
||||||
|
rigIds: new Set(lastActiveRigId ? [lastActiveRigId] : []),
|
||||||
};
|
};
|
||||||
stationMarkers.set(call, entry);
|
stationMarkers.set(call, entry);
|
||||||
pruneAprsEntry(call, entry, mapHistoryCutoffMs());
|
pruneAprsEntry(call, entry, mapHistoryCutoffMs());
|
||||||
@@ -6156,6 +6193,10 @@ window.aisMapAddVessel = function(msg) {
|
|||||||
const existing = aisMarkers.get(key);
|
const existing = aisMarkers.get(key);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
existing.msg = msg;
|
existing.msg = msg;
|
||||||
|
if (lastActiveRigId) {
|
||||||
|
if (!existing.rigIds) existing.rigIds = new Set();
|
||||||
|
existing.rigIds.add(lastActiveRigId);
|
||||||
|
}
|
||||||
if (!Array.isArray(existing.trackHistory)) existing.trackHistory = [];
|
if (!Array.isArray(existing.trackHistory)) existing.trackHistory = [];
|
||||||
const prevPoint = existing.trackHistory[existing.trackHistory.length - 1];
|
const prevPoint = existing.trackHistory[existing.trackHistory.length - 1];
|
||||||
if (!aisPositionsEqual(prevPoint, nextPoint)) {
|
if (!aisPositionsEqual(prevPoint, nextPoint)) {
|
||||||
@@ -6175,6 +6216,7 @@ window.aisMapAddVessel = function(msg) {
|
|||||||
trackHistory: [{ lat: msg.lat, lon: msg.lon, tsMs }],
|
trackHistory: [{ lat: msg.lat, lon: msg.lon, tsMs }],
|
||||||
trackPoints: [nextPoint],
|
trackPoints: [nextPoint],
|
||||||
msg,
|
msg,
|
||||||
|
rigIds: new Set(lastActiveRigId ? [lastActiveRigId] : []),
|
||||||
});
|
});
|
||||||
pruneAisEntry(key, aisMarkers.get(key), mapHistoryCutoffMs());
|
pruneAisEntry(key, aisMarkers.get(key), mapHistoryCutoffMs());
|
||||||
if (aisMarkers.get(key)?.visibleInHistoryWindow) ensureAisMarker(key, aisMarkers.get(key));
|
if (aisMarkers.get(key)?.visibleInHistoryWindow) ensureAisMarker(key, aisMarkers.get(key));
|
||||||
@@ -6192,6 +6234,10 @@ window.vdesMapAddPoint = function(msg) {
|
|||||||
if (existing) {
|
if (existing) {
|
||||||
existing.msg = msg;
|
existing.msg = msg;
|
||||||
existing.visibleInHistoryWindow = visible;
|
existing.visibleInHistoryWindow = visible;
|
||||||
|
if (lastActiveRigId) {
|
||||||
|
if (!existing.rigIds) existing.rigIds = new Set();
|
||||||
|
existing.rigIds.add(lastActiveRigId);
|
||||||
|
}
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
if (!decodeHistoryMapRenderingDeferred()) {
|
if (!decodeHistoryMapRenderingDeferred()) {
|
||||||
setRetainedMapMarkerVisible(existing.marker, false);
|
setRetainedMapMarkerVisible(existing.marker, false);
|
||||||
@@ -6216,6 +6262,7 @@ window.vdesMapAddPoint = function(msg) {
|
|||||||
marker: null,
|
marker: null,
|
||||||
msg,
|
msg,
|
||||||
visibleInHistoryWindow: visible,
|
visibleInHistoryWindow: visible,
|
||||||
|
rigIds: new Set(lastActiveRigId ? [lastActiveRigId] : []),
|
||||||
};
|
};
|
||||||
vdesMarkers.set(key, entry);
|
vdesMarkers.set(key, entry);
|
||||||
if (!visible) return;
|
if (!visible) return;
|
||||||
@@ -6305,10 +6352,14 @@ function applyMapFilter() {
|
|||||||
const sourceVisible = noneSelected
|
const sourceVisible = noneSelected
|
||||||
? DEFAULT_MAP_SOURCE_FILTER[type] !== undefined ? DEFAULT_MAP_SOURCE_FILTER[type] : true
|
? DEFAULT_MAP_SOURCE_FILTER[type] !== undefined ? DEFAULT_MAP_SOURCE_FILTER[type] : true
|
||||||
: !!mapFilter[type];
|
: !!mapFilter[type];
|
||||||
|
const rigVisible = !mapRigFilter
|
||||||
|
|| marker.__trxType === "bookmark"
|
||||||
|
|| (marker.__trxRigIds instanceof Set && marker.__trxRigIds.has(mapRigFilter));
|
||||||
const visible = marker.__trxHistoryVisible !== false
|
const visible = marker.__trxHistoryVisible !== false
|
||||||
&& markerPassesSearchFilter(marker)
|
&& markerPassesSearchFilter(marker)
|
||||||
&& markerPassesLocatorFilters(marker)
|
&& markerPassesLocatorFilters(marker)
|
||||||
&& sourceVisible;
|
&& sourceVisible
|
||||||
|
&& rigVisible;
|
||||||
const onMap = aprsMap.hasLayer(marker);
|
const onMap = aprsMap.hasLayer(marker);
|
||||||
if (visible && !onMap) {
|
if (visible && !onMap) {
|
||||||
marker.addTo(aprsMap);
|
marker.addTo(aprsMap);
|
||||||
@@ -6929,6 +6980,7 @@ window.mapAddLocator = function(message, grids, type = "ft8", station = null, de
|
|||||||
dt_s: Number.isFinite(details?.dt_s) ? Number(details.dt_s) : null,
|
dt_s: Number.isFinite(details?.dt_s) ? Number(details.dt_s) : null,
|
||||||
freq_hz: Number.isFinite(details?.freq_hz) ? Number(details.freq_hz) : null,
|
freq_hz: Number.isFinite(details?.freq_hz) ? Number(details.freq_hz) : null,
|
||||||
message: String(details?.message || message || "").trim() || null,
|
message: String(details?.message || message || "").trim() || null,
|
||||||
|
rig_id: lastActiveRigId || null,
|
||||||
};
|
};
|
||||||
const detailKey = detailStationId || `${targetId || "decode"}:${detailEntry.message || "decode"}:${detailEntry.ts_ms || Date.now()}`;
|
const detailKey = detailStationId || `${targetId || "decode"}:${detailEntry.message || "decode"}:${detailEntry.ts_ms || Date.now()}`;
|
||||||
const key = `${markerType}:${grid}`;
|
const key = `${markerType}:${grid}`;
|
||||||
@@ -6942,6 +6994,10 @@ window.mapAddLocator = function(message, grids, type = "ft8", station = null, de
|
|||||||
}
|
}
|
||||||
existing.allStationDetails.set(detailKey, { ...detailEntry });
|
existing.allStationDetails.set(detailKey, { ...detailEntry });
|
||||||
existing.sourceType = markerType;
|
existing.sourceType = markerType;
|
||||||
|
if (lastActiveRigId) {
|
||||||
|
if (!existing.rigIds) existing.rigIds = new Set();
|
||||||
|
existing.rigIds.add(lastActiveRigId);
|
||||||
|
}
|
||||||
pruneLocatorEntry(key, existing, mapHistoryCutoffMs());
|
pruneLocatorEntry(key, existing, mapHistoryCutoffMs());
|
||||||
if (existing.marker) sendLocatorOverlayToBack(existing.marker);
|
if (existing.marker) sendLocatorOverlayToBack(existing.marker);
|
||||||
scheduleDecodeMapMaintenance();
|
scheduleDecodeMapMaintenance();
|
||||||
@@ -6958,6 +7014,7 @@ window.mapAddLocator = function(message, grids, type = "ft8", station = null, de
|
|||||||
allStationDetails,
|
allStationDetails,
|
||||||
sourceType: markerType,
|
sourceType: markerType,
|
||||||
bandMeta: new Map(),
|
bandMeta: new Map(),
|
||||||
|
rigIds: new Set(lastActiveRigId ? [lastActiveRigId] : []),
|
||||||
};
|
};
|
||||||
locatorMarkers.set(key, entry);
|
locatorMarkers.set(key, entry);
|
||||||
pruneLocatorEntry(key, entry, mapHistoryCutoffMs());
|
pruneLocatorEntry(key, entry, mapHistoryCutoffMs());
|
||||||
|
|||||||
@@ -746,6 +746,12 @@
|
|||||||
<span class="map-locator-filter-label" id="map-locator-choice-label">Show</span>
|
<span class="map-locator-filter-label" id="map-locator-choice-label">Show</span>
|
||||||
<div id="map-locator-choice-filter" class="map-locator-chip-row"></div>
|
<div id="map-locator-choice-filter" class="map-locator-chip-row"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="map-locator-filter-group">
|
||||||
|
<span class="map-locator-filter-label">Rig</span>
|
||||||
|
<select id="map-rig-filter" class="map-history-select" aria-label="Filter by rig source">
|
||||||
|
<option value="">All</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="map-locator-filter-group">
|
<div class="map-locator-filter-group">
|
||||||
<span class="map-locator-filter-label">Search</span>
|
<span class="map-locator-filter-label">Search</span>
|
||||||
<input type="text" id="map-search-filter" class="map-search-input" placeholder="Callsign, MMSI, locator, message..." />
|
<input type="text" id="map-search-filter" class="map-search-input" placeholder="Callsign, MMSI, locator, message..." />
|
||||||
|
|||||||
Reference in New Issue
Block a user