fix(bandmap): follow the cluster's filters
The band map received the raw spot stream filtered by band alone, so none of the cluster's filters reached it: switching on "LoTW users only" changed the list and left the panadapter showing everyone. The same was true of hide worked, the spotter continent, and the status and mode chips. The predicate is extracted and shared rather than copied — two views of one spot stream disagreeing about the same spot is the fault lib/spotDisplay already exists to prevent, and a second copy would have drifted the first time a filter was added. The BAND filter is deliberately excluded from the shared part: a band map's band is its filter, and applying the cluster's would empty every map but one.
This commit is contained in:
+24
-6
@@ -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() {
|
||||
</div>
|
||||
<BandMap
|
||||
band={b}
|
||||
spots={spots.filter((s) => 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}
|
||||
|
||||
Reference in New Issue
Block a user