From 7e696a72bbeac7f14f1a8e10401fd02033bf0bf6 Mon Sep 17 00:00:00 2001 From: Gregory Salaun Date: Wed, 5 Aug 2026 14:38:19 +0200 Subject: [PATCH] feat(cluster): dim spots that represent nothing A spot whose entity/band/mode is already worked, whose callsign isn't in the log, and that carries no POTA/county/prefix novelty is dimmed (whole row, opacity) so the eye skips it. "Nothing" follows the status, which already obeys the "same slot" option and digital grouping. getRowStyle drives it; the spot-status effect now redrawRows so the dimming re-applies when a status lands. --- changelog.json | 6 ++++-- frontend/src/components/ClusterGrid.tsx | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/changelog.json b/changelog.json index ea6d78b..ced6c11 100644 --- a/changelog.json +++ b/changelog.json @@ -16,7 +16,8 @@ "Stats (F1): click any coloured band/mode square to list the contacts behind it.", "Awards: the DXCC list now shows each entity’s main prefix (XE, DL, F…) in its own sortable, searchable column.", "DX Cluster: new option \"Already worked only on the same slot\" (Settings → DX Cluster). With it on, a spot reads \"worked\" only when you worked that callsign on the SAME band and mode — not just anywhere. It respects the digital-mode grouping (Settings → General): grouped, a 20m FT8 contact also marks a 20m FT4 spot as worked; ungrouped, FT8 and FT4 are separate slots.", - "DX Cluster: added a WORKED status-filter chip, so you can show — or, with the other chips off, isolate — already-worked spots, not only hide them with the \"Hide worked\" checkbox." + "DX Cluster: added a WORKED status-filter chip, so you can show — or, with the other chips off, isolate — already-worked spots, not only hide them with the \"Hide worked\" checkbox.", + "DX Cluster: spots that represent nothing — entity/band/mode already worked, the callsign not in your log, no POTA/county/prefix novelty — are now dimmed, so your eye skips them and the spots worth working stand out. What counts as \"nothing\" follows the \"same slot\" option and the digital-mode grouping." ], "fr": [ "Visionneuse de log : la fenêtre conserve deux fois plus d'historique (512 Ko au lieu de 256 Ko, ~3200 lignes). Lors d'une trace chargée, les plus vieilles lignes défilaient hors du buffer pendant qu'on les lisait encore ; la fenêtre agrandie les garde.", @@ -32,7 +33,8 @@ "Stats (F1) : cliquer sur une case bande/mode colorée liste les contacts correspondants.", "Diplômes : la liste DXCC affiche le préfixe principal de chaque entité (XE, DL, F…) dans une colonne triable et cherchable.", "DX Cluster : nouvelle option « Déjà contacté seulement sur le même slot » (Réglages → DX Cluster). Activée, un spot n'affiche « contacté » que si vous avez contacté cet indicatif sur la MÊME bande et le MÊME mode — pas juste n'importe où. Elle respecte le groupage des modes numériques (Réglages → Général) : groupé, un contact 20m FT8 marque aussi un spot 20m FT4 comme contacté ; dégroupé, FT8 et FT4 sont des slots distincts.", - "DX Cluster : ajout d'un filtre de statut WORKED, pour afficher — ou, en désactivant les autres, isoler — les spots déjà contactés, pas seulement les masquer avec la case « Masquer les contactés »." + "DX Cluster : ajout d'un filtre de statut WORKED, pour afficher — ou, en désactivant les autres, isoler — les spots déjà contactés, pas seulement les masquer avec la case « Masquer les contactés ».", + "DX Cluster : les spots qui ne représentent rien — entité/bande/mode déjà faite, indicatif absent du journal, aucune nouveauté POTA/comté/préfixe — sont désormais atténués, pour que l'œil les ignore et que les spots à travailler ressortent. Ce qui compte comme « rien » suit l'option « même slot » et le groupage des modes numériques." ] }, { diff --git a/frontend/src/components/ClusterGrid.tsx b/frontend/src/components/ClusterGrid.tsx index 2094ff8..549db85 100644 --- a/frontend/src/components/ClusterGrid.tsx +++ b/frontend/src/components/ClusterGrid.tsx @@ -140,6 +140,19 @@ function statusColor(s: SpotStatusEntry | undefined): string | null { } } +// isDull reports a spot that "represents nothing" under the current worked/slot +// rules: the entity/band/mode is already worked (status resolved, not new in any +// dimension), the callsign itself isn't in the log, and there's no POTA / county +// / prefix novelty. Such rows are dimmed so the eye skips them. Because the +// status obeys the DX-cluster "same slot" option and the digital-mode grouping, +// what counts as dull follows those settings automatically. Unresolved statuses +// (still loading, or entity unknown) are NOT dimmed — that would flicker. +function isDull(s: SpotStatusEntry | undefined): boolean { + if (!s || !s.status) return false; + if (s.status === 'new' || s.status === 'new-band' || s.status === 'new-mode' || s.status === 'new-slot') return false; + return !(s.worked_call || s.new_pota || s.new_county || s.new_pfx); +} + const makeColCatalog = (t: TFn): ColEntry[] => [ { group: 'Spot', label: t('clg2.c.time'), colId: 'time', @@ -410,7 +423,9 @@ export function ClusterGrid({ rows, spotStatus, onSpotClick }: Props) { // won't re-render those cells on its own — force a refresh so e.g. a worked call // turns blue once its status loads. useEffect(() => { - gridRef.current?.api?.refreshCells({ force: true }); + // redrawRows (not refreshCells) so getRowStyle re-runs too — the whole-row + // dimming of "represents nothing" spots depends on the status that lands here. + gridRef.current?.api?.redrawRows(); }, [spotStatus]); // Restore AFTER the profile scope is known — this grid has no key= remount to @@ -496,6 +511,7 @@ export function ClusterGrid({ rows, spotStatus, onSpotClick }: Props) { onColumnVisible={saveColumnState} onSortChanged={saveColumnState} onRowClicked={handleRowClicked} + getRowStyle={(p: any) => (isDull(statusFor(p)) ? { opacity: 0.4 } : undefined)} animateRows={false} suppressCellFocus getRowId={(p) => `${(p.data as any).received_at}-${(p.data as any).dx_call}-${(p.data as any).source_id}`}