feat(udp): Highlight Callsign and Replay — the decoder becomes log-aware
Message 13 paints callsigns in WSJT-X/JTDX's own Band Activity window with verdicts from the same cluster status cache that colours the spot grid: watchlist pink, new DXCC green, new band for its entity orange. Deduplicated per instance+call+verdict, one datagram each; a verdict that lapses (the operator worked them) clears that call, and turning the option off clears everything via the protocol's CLEARALL!. Off by default, switch in the Connections panel. Message 7 asks a program heard for the first time this session to replay the decodes already on its screen, so the FT decodes panel starts full instead of empty until the next period. Replayed lines arrive marked not-new and are shown but never auto-answered — the auto-caller now checks, on top of its 30-second freshness gate.
This commit is contained in:
@@ -741,10 +741,15 @@ type App struct {
|
||||
watchlist *watchlist.Store // Tools → Watchlist (global watchlist.json)
|
||||
watchAlertMu sync.Mutex // throttles watchlist alerts…
|
||||
watchAlertAt map[string]time.Time // …per entry
|
||||
watchPattern atomic.Value // auto-contest pattern (string), loaded at startup
|
||||
operating *operating.Repo
|
||||
udp *udp.Manager
|
||||
udpRepo *udp.Repo
|
||||
|
||||
// WSJT-X decode highlighting (message 13) — see app_wsjt_highlight.go.
|
||||
wsjtHighlightOn atomic.Bool
|
||||
wsjtHLMu sync.Mutex
|
||||
wsjtHLSent map[string]string
|
||||
watchPattern atomic.Value // auto-contest pattern (string), loaded at startup
|
||||
operating *operating.Repo
|
||||
udp *udp.Manager
|
||||
udpRepo *udp.Repo
|
||||
// Program id of the last decoding application that reported its status.
|
||||
// Halt Tx is routed by id, and the panel's Halt button must work even when
|
||||
// nothing is transmitting at that instant — so the id is remembered from
|
||||
@@ -1205,6 +1210,11 @@ func (a *App) startup(ctx context.Context) {
|
||||
a.operating = operating.NewRepo(conn)
|
||||
a.udpRepo = udp.NewRepo(conn)
|
||||
a.udp = udp.NewManager(a.udpRepo)
|
||||
// A program heard for the first time is asked to replay the decodes already
|
||||
// on its screen, so the FT decodes panel starts full instead of waiting a
|
||||
// period. Replayed decodes arrive marked not-new and are shown but never
|
||||
// auto-answered.
|
||||
a.udp.SetOnNewInstance(func(id string) { _ = a.udp.SendReplay(id) })
|
||||
go a.consumeUDPEvents()
|
||||
a.cache = lookup.NewCache(conn, 30*24*time.Hour)
|
||||
a.lookup = lookup.NewManager(a.cache)
|
||||
@@ -1444,6 +1454,7 @@ func (a *App) startup(ctx context.Context) {
|
||||
a.pota = pota.New(func(format string, args ...any) { applog.Printf(format, args...) })
|
||||
a.startWatchlistClubLog()
|
||||
a.watchPattern.Store(strings.ToUpper(strings.TrimSpace(a.settingOr(keyWatchlistContestPattern, ""))))
|
||||
a.wsjtHighlightOn.Store(a.settingOr(keyWsjtHighlight, "0") == "1")
|
||||
go a.pota.Run(a.ctx)
|
||||
|
||||
// DX Cluster (multi-server): the spot callback enriches each spot
|
||||
@@ -13905,7 +13916,13 @@ func (a *App) consumeUDPEvents() {
|
||||
"low_conf": ev.DecodeLowConf,
|
||||
"mode_raw": ev.DecodeModeRaw,
|
||||
"msg_raw": ev.DecodeMsgRaw,
|
||||
// false on a Replay's resent history — shown, never auto-answered.
|
||||
"is_new": ev.DecodeIsNew,
|
||||
})
|
||||
// Log-aware colour in the decoder's own window (see
|
||||
// app_wsjt_highlight.go). After the emit: painting must never delay
|
||||
// the panel.
|
||||
a.maybeHighlightDecode(ev.ProgramID, ev.DecodeCall, bandForHz(ev.DecodeFreqHz))
|
||||
// A WSJT-X decode (heard station). Render it on the FlexRadio
|
||||
// panadapter when the option is on; green + SNR comment, auto-expiring
|
||||
// after the configured duration. De-duped per call in the Flex backend.
|
||||
|
||||
Reference in New Issue
Block a user