fix(cluster): group duplicates by call AND band AND mode

The grouping keyed on the callsign alone, so every spot of a station outside the
first one's band and mode was dropped from the list. RI1FJL spotted on 17m CW,
20m, 30m, 12m and 15m FT8 showed as a single row: four slots gone from the one
view an operator uses to find them.

A duplicate is the dozen skimmers that all heard the same CQ — same station,
same band, same mode. The same station on another band is the opposite of a
duplicate; it is what the chaser is scanning for.
This commit is contained in:
2026-08-28 16:25:06 +02:00
parent 47ddbed665
commit 8c7e1c1a3d
2 changed files with 12 additions and 4 deletions
+8 -2
View File
@@ -5926,11 +5926,17 @@ export default function App() {
});
let rendered = list as (ClusterSpot & { repeats?: number })[];
if (clusterGroup) {
// A DUPLICATE is the same station on the same band AND mode — the dozen
// skimmers that all heard one CQ. The same station on another band is the
// opposite of a duplicate: it is the line a DX chaser is scanning for, and
// grouping on the callsign alone deleted it. RI1FJL spotted on five bands
// showed as one row, so four slots simply vanished from the list.
const seen = new Map<string, ClusterSpot & { repeats: number }>();
for (const s of list) {
const e = seen.get(s.dx_call);
const key = `${(s.dx_call ?? '').toUpperCase()}|${(s.band ?? '').toLowerCase()}|${inferSpotMode(s.comment ?? '', s.freq_hz)}`;
const e = seen.get(key);
if (e) { e.repeats++; }
else seen.set(s.dx_call, { ...s, repeats: 1 });
else seen.set(key, { ...s, repeats: 1 });
}
rendered = Array.from(seen.values());
}