feat(cluster): county and prefix get their chase switches, and the grid one tells the whole truth

Chase POTA already withdrew its badge, filter chip and column when
unchecked; US counties and new prefixes now have the same switch, and
unchecking Chase new grids finally withdraws the NEW GRID badge too (the
backend stopped learning squares but the display kept shouting the ones
it knew — the setting is mirrored to localStorage so the display layer
can gate synchronously). All withdrawal happens at the display layer:
the facts keep being computed, so re-ticking a box needs no rescan.
This commit is contained in:
2026-08-31 16:41:13 +02:00
parent a03d907128
commit 7152d11007
5 changed files with 58 additions and 10 deletions
+27 -2
View File
@@ -20,6 +20,7 @@ export type SpotDisplayOptions = {
// keep being computed; only the telling stops, so ticking the box back on
// needs no rescan.
chasePota: boolean; chaseSota: boolean;
chaseCounty: boolean; chasePfx: boolean; chaseGrid: boolean;
};
// chasePota/chaseSota read the switches directly — for the places that show a
@@ -30,6 +31,18 @@ export function chasePota(): boolean {
export function chaseSota(): boolean {
try { return localStorage.getItem('opslog.chaseSota') !== '0'; } catch { return true; }
}
export function chaseCounty(): boolean {
try { return localStorage.getItem('opslog.chaseCounty') !== '0'; } catch { return true; }
}
export function chasePfx(): boolean {
try { return localStorage.getItem('opslog.chasePfx') !== '0'; } catch { return true; }
}
// chaseGrid mirrors the backend "chase new grids" setting (Settings writes the
// mirror on load and on toggle) so the display layer can gate NEW GRID without
// an async round-trip per row.
export function chaseGrid(): boolean {
try { return localStorage.getItem('opslog.chaseGrids') !== '0'; } catch { return true; }
}
// Both options are withdrawn from the filter panel for now. The machinery below
// is deliberately kept whole — it is correct and hard-won — so putting the two
@@ -44,16 +57,17 @@ export function readSpotDisplayOptions(): SpotDisplayOptions {
// The EXPOSED flag only withdraws the two original switches; the chase
// switches are live regardless.
if (!SPOT_DISPLAY_OPTIONS_EXPOSED) {
return { muteWorked: false, slotHighlight: false, chasePota: chasePota(), chaseSota: chaseSota() };
return { muteWorked: false, slotHighlight: false, chasePota: chasePota(), chaseSota: chaseSota(), chaseCounty: chaseCounty(), chasePfx: chasePfx(), chaseGrid: chaseGrid() };
}
try {
return {
muteWorked: localStorage.getItem('opslog.clusterMuteWorked') === '1',
slotHighlight: localStorage.getItem('opslog.clusterSlotHighlight') === '1',
chasePota: chasePota(), chaseSota: chaseSota(),
chaseCounty: chaseCounty(), chasePfx: chasePfx(), chaseGrid: chaseGrid(),
};
} catch {
return { muteWorked: false, slotHighlight: false, chasePota: true, chaseSota: true };
return { muteWorked: false, slotHighlight: false, chasePota: true, chaseSota: true, chaseCounty: true, chasePfx: true, chaseGrid: true };
}
}
@@ -98,6 +112,17 @@ export function applySpotDisplay<T extends Entry>(s: T, o: SpotDisplayOptions):
if (!o.chasePota && e.new_pota) {
e = { ...e, new_pota: false } as NonNullable<T>;
}
// Same withdrawal for the other extra markers: the facts keep being
// computed, only the telling stops — re-ticking a box needs no rescan.
if (!o.chaseCounty && e.new_county) {
e = { ...e, new_county: false } as NonNullable<T>;
}
if (!o.chasePfx && e.new_pfx) {
e = { ...e, new_pfx: false } as NonNullable<T>;
}
if (!o.chaseGrid && e.new_grid) {
e = { ...e, new_grid: false } as NonNullable<T>;
}
return e;
}