fix(cluster): muting a worked spot must not brighten it
"No colour on worked" blanked the spot status as well as the worked-call flag, on the theory that a spot bringing no novelty should stop painting entirely. But the status is exactly what the cluster list reads to DIM a row. Blanking it made isDull() fall through its "unresolved, never dim" guard, so every quiet grey row came back at full brightness. The option meant to calm the list was the one making it shout. It also forced a `muted` flag to exist purely so tooltips could say that an empty status did not, this time, mean "entity not resolved". It now removes the blue already-worked mark and nothing else, which is all it ever needed to do: a worked entity already renders with no colour of its own and is already dimmed. The flag, its two tooltip strings and the special-cased band map styling all go with it.
This commit is contained in:
@@ -31,27 +31,8 @@ type Entry = {
|
||||
new_county?: boolean;
|
||||
new_pota?: boolean;
|
||||
new_pfx?: boolean;
|
||||
muted?: boolean;
|
||||
} | undefined;
|
||||
|
||||
// bringsNothingNew: the ENTITY is resolved and worked, and no other dimension
|
||||
// (county, park, prefix) is new. Same test the cluster list already used to dim
|
||||
// a row — muting reuses it rather than inventing a second notion of "done".
|
||||
//
|
||||
// Entity-level, NOT callsign-level: an operator can be on their 421st Bulgarian
|
||||
// and still have never worked that particular station. That spot is muted here
|
||||
// by design — it brings nothing to an award — and turning on the slot option is
|
||||
// what brings it back, which is why the promotion above runs first.
|
||||
//
|
||||
// Note what is NOT muted: a status of new-band / new-slot survives, because
|
||||
// having worked that callsign once on another band says nothing about the band
|
||||
// in front of you.
|
||||
function bringsNothingNew(s: Entry): boolean {
|
||||
if (!s || !s.status) return false; // unresolved — never hide, it would flicker
|
||||
if (s.status === 'new' || s.status === 'new-band' || s.status === 'new-mode' || s.status === 'new-slot' || s.status === 'new-call') return false;
|
||||
return !(s.new_pota || s.new_county || s.new_pfx);
|
||||
}
|
||||
|
||||
// applySpotDisplay rewrites a status entry per the options, so every consumer —
|
||||
// colour, badge, status text — follows from one decision instead of each panel
|
||||
// re-deriving it.
|
||||
@@ -59,27 +40,26 @@ export function applySpotDisplay<T extends Entry>(s: T, o: SpotDisplayOptions):
|
||||
if (!s) return s;
|
||||
let e = s;
|
||||
|
||||
// ORDER MATTERS, and it is the whole difference between the two options
|
||||
// composing and one cancelling the other.
|
||||
//
|
||||
// Slot promotion runs FIRST. A callsign not yet worked on this band and mode
|
||||
// is not "done", so it must never be swallowed by the mute below — yet the
|
||||
// mute test only looks at the entity, and an unworked callsign inside a worked
|
||||
// entity is precisely the spot the second option exists to surface. Promoting
|
||||
// first protects it for free: bringsNothingNew() returns false on new-slot.
|
||||
// Slot promotion runs first: a callsign not yet worked on this band and mode
|
||||
// is not done, whatever the entity says, so it earns a status before the mute
|
||||
// below can take its colour away.
|
||||
if (o.slotHighlight && e.worked_slot === false && (!e.status || e.status === 'worked')) {
|
||||
e = { ...e, status: 'new-call' } as NonNullable<T>;
|
||||
}
|
||||
|
||||
if (o.muteWorked && bringsNothingNew(e)) {
|
||||
// Strip everything that paints: the row keeps its data, loses its emphasis.
|
||||
//
|
||||
// muted says WHY the status went empty. An empty status already meant
|
||||
// "entity not resolved" in the band map, so without this flag every muted
|
||||
// spot claimed its entity was unknown — with the country printed right next
|
||||
// to it. Blanking is still what drives the colour, the badges and the
|
||||
// ranking; muted only lets the tooltip stay honest.
|
||||
return { ...e, status: '', worked_call: false, muted: true } as T;
|
||||
// Mute drops the blue already-worked-callsign mark, and NOTHING else.
|
||||
//
|
||||
// It used to blank the status as well, on the theory that a spot bringing no
|
||||
// novelty should stop painting entirely. That was wrong twice over. The status
|
||||
// is what the cluster list reads to DIM a row, so blanking it turned every
|
||||
// quiet grey row bright white — the option made the list louder, not quieter.
|
||||
// And an empty status means "entity not resolved" everywhere else, so muted
|
||||
// spots had to carry a flag saying they did not really mean that.
|
||||
//
|
||||
// Leaving the status alone costs nothing: a worked entity already renders with
|
||||
// no colour and gets dimmed, so removing the blue is the entire job.
|
||||
if (o.muteWorked) {
|
||||
e = { ...e, worked_call: false } as NonNullable<T>;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user