feat(chase): the global hunt — new, or new plus unconfirmed, every category

The gap between worked and confirmed becomes visible everywhere. A Chase
setting on the DX Cluster page picks the mode; in new-plus-unconfirmed the
verdicts for DXCC/band/mode/slot, prefix, county and state are judged against
CONFIRMED-only ledgers built from the operator's chosen sources (LoTW, card,
eQSL, QRZ.com — HRDLog has no confirmation field in ADIF to offer), and a
need that exists only because a QSL never arrived is flagged Unconf: the
cluster and decode badges render it dimmed, the convention the grid hunt
introduced. The grid's own Chase selector folds into the global one; its
square-matching scope stays where it was, being grid-specific. One snapshot
key change rebuilds the cache when any of it flips.
This commit is contained in:
2026-08-30 21:02:34 +02:00
parent 52e98a71f4
commit 4e28098a4e
10 changed files with 292 additions and 33 deletions
+11 -2
View File
@@ -73,6 +73,10 @@ type StatusEntry = {
new_pfx?: boolean;
new_grid?: boolean;
new_state?: boolean;
unconf_status?: boolean;
unconf_pfx?: boolean;
unconf_cty?: boolean;
unconf_state?: boolean;
// "new" = never worked, "unconf" = worked and awaiting a confirmation.
grid_state?: string;
state?: string;
@@ -1145,7 +1149,9 @@ export function DecodesPanel({ decodes, txMsgs, txState, txStates, spotStatus, o
</span>
)}
{entities.map((b) => (
<span key={b.label} className={cn('rounded px-1 py-px text-[10px] font-bold uppercase tracking-wide shrink-0', b.cls)}>
<span key={b.label}
title={e?.unconf_status ? t('dec.unconfTip') : undefined}
className={cn('rounded px-1 py-px text-[10px] font-bold uppercase tracking-wide shrink-0', b.cls, e?.unconf_status && 'opacity-50')}>
{t(b.label)}
</span>
))}
@@ -1155,7 +1161,10 @@ export function DecodesPanel({ decodes, txMsgs, txState, txStates, spotStatus, o
// Same hue, held back — the badge reads as "less" of the
// same thing, and its label says which. One badge for both
// is what made a station worked an hour ago read as new.
const unconf = b.key === 'new_grid' && e?.grid_state === 'unconf';
const unconf = (b.key === 'new_grid' && e?.grid_state === 'unconf')
|| (b.key === 'new_state' && !!e?.unconf_state)
|| (b.key === 'new_county' && !!e?.unconf_cty)
|| (b.key === 'new_pfx' && !!e?.unconf_pfx);
const c = markerColour(b.marker);
return (
<span key={b.key as string}