diff --git a/changelog.json b/changelog.json index 84159ff..1458abc 100644 --- a/changelog.json +++ b/changelog.json @@ -3,10 +3,12 @@ "version": "0.24.9", "date": "", "en": [ - "Appearance: row colouring now defaults to a left stripe, with a filled row and its strength offered as choices." + "Appearance: row colouring now defaults to a left stripe, with a filled row and its strength offered as choices.", + "The band map now follows the cluster filters — LoTW only, spotter continent, hide worked, status and mode chips." ], "fr": [ - "Apparence : la coloration des lignes se fait par défaut sur une barre à gauche, la ligne remplie et son intensité restant proposées." + "Apparence : la coloration des lignes se fait par défaut sur une barre à gauche, la ligne remplie et son intensité restant proposées.", + "La band map suit désormais les filtres du cluster — LoTW seulement, continent du spotter, masquer les contactés, statuts et modes." ] }, { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index aa53e78..eb0b23c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4717,12 +4717,21 @@ export default function App() { // Cluster spots after every active filter (band / mode / status / search / // hide-worked / group). Shared by the Cluster tab and the Main-view cluster // pane so both show exactly the same list. - const clusterRenderedRows = useMemo(() => { - const bandsActive = clusterLockBand ? new Set([band]) : clusterBands; + // Everything the operator has said about WHICH STATIONS they care about — + // LoTW only, the spotter's continent, hide worked, the status and mode chips, + // the search box, the source node. + // + // Shared with the band map, which used to receive the raw stream filtered by + // band alone: switching on "LoTW users only" changed the cluster list and left + // the panadapter showing everyone. Two views of one spot stream disagreeing + // about the same spot is the fault lib/spotDisplay already exists to prevent. + // + // The BAND filter is deliberately not in here: a band map's band IS its + // filter, and applying the cluster's would empty every map but one. + const spotPassesStationFilters = useCallback((s: ClusterSpot): boolean => { const search = clusterSearch.trim().toUpperCase(); - const list = spots.filter((s) => { + { if (clusterFilterSource && s.source_id !== clusterFilterSource) return false; - if (bandsActive.size > 0 && !bandsActive.has(s.band ?? '')) return false; if (search && !s.dx_call.includes(search)) return false; if (clusterLockMode) { const spotMode = inferSpotMode(s.comment ?? '', s.freq_hz); @@ -4774,6 +4783,15 @@ export default function App() { if (e.worked_call || e.status === 'worked') return false; } return true; + } + }, [clusterFilterSource, clusterSearch, clusterLockMode, mode, clusterModeFilter, + clusterStatusFilter, spotStatus, clusterLotwOnly, clusterSpotterConts, clusterHideWorked]); + + const clusterRenderedRows = useMemo(() => { + const bandsActive = clusterLockBand ? new Set([band]) : clusterBands; + const list = spots.filter((s) => { + if (bandsActive.size > 0 && !bandsActive.has(s.band ?? '')) return false; + return spotPassesStationFilters(s); }); let rendered = list as (ClusterSpot & { repeats?: number })[]; if (clusterGroup) { @@ -6775,7 +6793,7 @@ export default function App() { s.band === b)} + spots={spots.filter((s) => s.band === b && spotPassesStationFilters(s))} spotStatus={spotStatus} currentFreqHz={band === b && freqMhz ? Math.round(parseFloat(freqMhz) * 1_000_000) : 0} onSpotClick={handleSpotClick} @@ -6811,7 +6829,7 @@ export default function App() { side={bandMapSide} onToggleSide={toggleBandMapSide} band={band} - spots={spots.filter((s) => s.band === band)} + spots={spots.filter((s) => s.band === band && spotPassesStationFilters(s))} spotStatus={spotStatus} currentFreqHz={band && freqMhz ? Math.round(parseFloat(freqMhz) * 1_000_000) : 0} onSpotClick={handleSpotClick}