fix(watchlist): read the cluster's slot index, and cap the card width
The first version asked the alerts' worked-index — keyed by RAW mode (FT8) — with a CLASS name (DIGI). Nothing ever matched, and a DXpedition worked on five bands showed every slot as Needed. The verdict now reads the cluster's own WorkedCallSlotKeys set, built in the cached status maps (now unconditionally — it used to exist only when a display option wanted it). Same index, same mode normalisation as the grid, so the watchlist can never contradict the cluster about the same spot. The contest today-set is normalised through the same function. And the cards column is capped at a reading width instead of stretching callsign-to-badge lines across the whole window.
This commit is contained in:
+31
-12
@@ -11,7 +11,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"hamlog/internal/qso"
|
||||
"hamlog/internal/watchlist"
|
||||
|
||||
wruntime "github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
@@ -68,18 +67,38 @@ type WatchlistSlotQuery struct {
|
||||
|
||||
// WatchlistWorkedSlots answers a batch of slot questions for the tab.
|
||||
//
|
||||
// One pass over today's contacts and the in-memory worked index rather than a
|
||||
// query per spot: the tab refreshes on every spot burst, and a busy evening
|
||||
// must not turn into a query storm. Contest entries read the TODAY set — the
|
||||
// midnight-UTC reset is the query's date bound, nothing stored, nothing to
|
||||
// reset. Mode is compared at CLASS grain (FT8 and FT4 are both Digital),
|
||||
// matching how the cluster's own worked_slot judges a slot.
|
||||
// Normal entries read the CLUSTER's own slot set — the same cached
|
||||
// WorkedCallSlotKeys index that colours the grid — so the watchlist can never
|
||||
// contradict the cluster about the same spot. That index normalises the mode
|
||||
// exactly as the operator configured (digital grouping on → FT4 counts as FT8's
|
||||
// class; off → exact mode), and the first version of this ignored that: it
|
||||
// asked the alerts' raw-mode index with a CLASS name, matched nothing, and
|
||||
// showed a fully-worked DXpedition as all Needed.
|
||||
//
|
||||
// Contest entries read TODAY's contacts instead — the midnight-UTC reset is
|
||||
// the query's date bound, nothing stored, nothing to reset — normalised through
|
||||
// the same function so the two answers use one grammar.
|
||||
func (a *App) WatchlistWorkedSlots(queries []WatchlistSlotQuery) []bool {
|
||||
out := make([]bool, len(queries))
|
||||
if a.qso == nil || len(queries) == 0 {
|
||||
return out
|
||||
}
|
||||
// Today's slots, only if some entry needs them.
|
||||
idx := a.clusterStatusMaps()
|
||||
norm := func(m string) string {
|
||||
m = strings.ToUpper(strings.TrimSpace(m))
|
||||
if idx.normMode != nil {
|
||||
m = idx.normMode(m)
|
||||
}
|
||||
return m
|
||||
}
|
||||
slotKey := func(call, band, mode string) string {
|
||||
up := strings.ToUpper(strings.TrimSpace(call))
|
||||
b := strings.ToLower(strings.TrimSpace(band))
|
||||
if m := norm(mode); m != "" {
|
||||
return up + "|" + b + "|" + m
|
||||
}
|
||||
return up + "|" + b
|
||||
}
|
||||
needToday := false
|
||||
for _, q := range queries {
|
||||
if q.Contest {
|
||||
@@ -93,16 +112,16 @@ func (a *App) WatchlistWorkedSlots(queries []WatchlistSlotQuery) []bool {
|
||||
rows, err := a.qso.SlotsSince(a.ctx, midnight)
|
||||
if err == nil {
|
||||
for _, r := range rows {
|
||||
today[wcbmKey(r.Callsign, r.Band, qso.ModeClass(r.Mode))] = true
|
||||
today[slotKey(r.Callsign, r.Band, r.Mode)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, q := range queries {
|
||||
key := wcbmKey(q.Call, q.Band, qso.ModeClass(q.Mode))
|
||||
key := slotKey(q.Call, q.Band, q.Mode)
|
||||
if q.Contest {
|
||||
out[i] = today[key]
|
||||
} else {
|
||||
out[i] = a.isWorkedBandMode(q.Call, q.Band, qso.ModeClass(q.Mode))
|
||||
} else if idx.workedCallSlots != nil {
|
||||
_, out[i] = idx.workedCallSlots[key]
|
||||
}
|
||||
}
|
||||
return out
|
||||
|
||||
Reference in New Issue
Block a user