fix(spot): spot the references worth chasing, not the derived ones

The comment came out "SSB WAC EU WAZ 15 WPX HA5" — the QSO's materialised
award_refs hold both kinds, and I took them all. Those four are what every
reader of the spot derives from the callsign in their head. They spent the
whole 30-character comment saying nothing and buried SOTA HA/KM-018, the one
reference anyone would have acted on.

Computed awards are now filtered out with the same rule the QSO editor uses
(isComputedAwardField), which is why they are the ones it lists on the left
and not in its read-only panel. The field map moves from a ref to state as
well: a ref left the first spot of a session computing before GetAwardDefs
had answered.

Also opens 0.25.2, since 0.25.1 shipped before the spot work, and sets the
default mode list to SSB, CW, FT8, FT4, FT2, RTTY, PSK31, FM. AM and
DIGITALVOICE stay in the catalogue but are no longer selected on a fresh
install. FT2 joins the digital family everywhere its siblings are listed —
report list, RST defaults, Flex power class — so it gets dB reports rather
than the 59 an unknown mode falls back to.
This commit is contained in:
2026-08-14 13:31:17 +02:00
parent 4f9a366884
commit 7c781bf793
5 changed files with 76 additions and 32 deletions
+28 -7
View File
@@ -155,16 +155,37 @@ export function buildAwardRefs(qso: any, pickable: Array<{ code: string; field:
return out.join(';');
}
// spotRefList turns a code→ref map into the strings a DX-cluster comment wants:
// ["POTA FR-11553", "IOTA EU-064"]. A code carrying several references (a
// two-fer park activation) yields one entry per reference, so a spot can carry
// the one that fits and drop the rest rather than emitting a truncated pair.
// COMPUTED_AWARD_FIELDS mirrors isComputedAwardField in app.go: awards whose
// reference is derived from the callsign and cty.dat, never assigned by hand.
//
// Shortest first: cluster comments are 30 characters, and when they do not all
// fit, more references beat fewer.
export function spotRefList(byCode: Record<string, string>): string[] {
// State and county are deliberately absent, there as here — an operator sets
// those themselves and they drive real predefined-list awards (WAS, WAJA, JCC).
const COMPUTED_AWARD_FIELDS = new Set([
'dxcc', 'cqz', 'ituz', 'prefix', 'callsign', 'cont', 'country', 'grid', 'grid4',
]);
// spotRefList turns a QSO's code→ref map into the strings a DX-cluster comment
// wants: ["SOTA HA/KM-018"].
//
// COMPUTED awards are dropped. A QSO's materialised references hold both kinds,
// and the derived ones — DXCC, WAC, WAZ, WPX — are exactly what every reader of
// the spot works out from the callsign anyway. Announcing "WAC EU WAZ 15 WPX HA5"
// spends the whole 30-character comment saying nothing, and buries the one
// reference worth chasing. Same rule as the QSO editor, which is why these are
// the references it lists on the LEFT and not in its read-only panel.
//
// fieldOf is award code → scanned field (from GetAwardDefs). A code missing from
// it is dropped rather than guessed: showing a reference on the air matters more
// than showing all of them.
//
// A code carrying several references (a two-fer park) yields one entry each, so
// a spot can take the one that fits instead of emitting a truncated pair.
// Shortest first: when they cannot all fit, more references beat fewer.
export function spotRefList(byCode: Record<string, string>, fieldOf: Record<string, string>): string[] {
const out: string[] = [];
for (const [code, refs] of Object.entries(byCode ?? {})) {
const field = fieldOf?.[code.toUpperCase()];
if (!field || COMPUTED_AWARD_FIELDS.has(field)) continue;
for (const ref of String(refs).split(',').map((s) => s.trim()).filter(Boolean)) {
out.push(`${code.toUpperCase()} ${ref.toUpperCase()}`);
}