fix(qsl): every confirmation service has a default, and the wiki explains them
HAMLOG.online was added after most profiles were configured, so it had no entry in the shipped defaults and no stored value either: it came back blank, and blank is not a status anybody chose. Every service now starts the same way — the sent side at R, the received side at N — and a blank left by a service that did not exist when the operator last saved is filled in from that. A status they chose themselves is untouched. Two tests hold the line: no sent side may default to Y, and no field may be left without a default. Y means "already sent", so it makes the uploader skip the contact for ever — an operator with eQSL Sent at Y had a logbook that never reached eQSL, and the only trace was one line in the application log. Wiki, both from operator reports: QSL Management opens with Confirmations — what the page actually is (the status stamped on every new QSO, not an action), what each status does, and the warning about Y in the plainest words available, because it fails silently and by design. Digital Modes and GridTracker is new. Unicast and multicast explained from the operating problem rather than the networking: one letterbox that two programs watch, against a broadcast everyone can tune to. It carries the real evidence — two starts of one station an hour apart, decodes in the second and none in the first, the only difference being whether GridTracker or OpsLog reached port 2237 first — then the settings for WSJT-X, JTDX, MSHV, GridTracker and OpsLog, the 127.0.0.1-in-the-group-box mistake, what to do if unicast is unavoidable, and how to check it from the log. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -11139,6 +11139,19 @@ func (a *App) UILog(msg string) {
|
||||
// that hasn't customised them: request the online confirmations (eQSL/LoTW/
|
||||
// Clublog/HRDLog/QRZ "sent"=R so OpsLog knows they still need uploading), and
|
||||
// "N" for paper and everything received.
|
||||
// defaultQSLDefaults is the status stamped on a new QSO when the operator has
|
||||
// not chosen otherwise.
|
||||
//
|
||||
// One rule, for every service: the SENT side starts at R (requested — this
|
||||
// contact is waiting to go out) and the RECEIVED side at N (nothing has come
|
||||
// back yet). Paper QSL is the exception on the sent side: a card is only
|
||||
// "requested" once somebody asks for one.
|
||||
//
|
||||
// The sent side must NEVER default to Y. Y means "already sent", so the
|
||||
// uploader skips the contact for ever — which is exactly how an operator ends
|
||||
// up with a logbook that never reaches eQSL and no error to explain it. Every
|
||||
// service added here has to appear in this list for that reason; a service left
|
||||
// out gets an empty status, which is a state nobody chose.
|
||||
func defaultQSLDefaults() QSLDefaults {
|
||||
return QSLDefaults{
|
||||
QSLSent: "N", QSLRcvd: "N",
|
||||
@@ -11146,10 +11159,40 @@ func defaultQSLDefaults() QSLDefaults {
|
||||
LOTWSent: "R", LOTWRcvd: "N",
|
||||
ClublogStatus: "R", ClublogCfm: "N", HRDLogStatus: "R",
|
||||
HamqthStatus: "R",
|
||||
HamlogStatus: "R", HamlogCfm: "N",
|
||||
QRZComStatus: "R", QRZComCfm: "N",
|
||||
}
|
||||
}
|
||||
|
||||
// fillMissingQSLDefaults replaces an empty status with the shipped one.
|
||||
//
|
||||
// A service added to OpsLog after an operator last saved their confirmations
|
||||
// has no stored value, so it came back blank — and blank is not one of the
|
||||
// statuses anything acts on, it is the absence of one. HAMLOG.online arrived
|
||||
// that way and every existing profile got nothing for it.
|
||||
//
|
||||
// An operator who genuinely wants a column left alone has "N" for that, which
|
||||
// says the same thing and is a status. So an empty value here means "this was
|
||||
// never asked", and the answer is what a fresh profile would have got.
|
||||
func fillMissingQSLDefaults(d QSLDefaults) QSLDefaults {
|
||||
def := defaultQSLDefaults()
|
||||
for _, f := range []struct{ cur, def *string }{
|
||||
{&d.QSLSent, &def.QSLSent}, {&d.QSLRcvd, &def.QSLRcvd},
|
||||
{&d.LOTWSent, &def.LOTWSent}, {&d.LOTWRcvd, &def.LOTWRcvd},
|
||||
{&d.EQSLSent, &def.EQSLSent}, {&d.EQSLRcvd, &def.EQSLRcvd},
|
||||
{&d.ClublogStatus, &def.ClublogStatus}, {&d.ClublogCfm, &def.ClublogCfm},
|
||||
{&d.HRDLogStatus, &def.HRDLogStatus},
|
||||
{&d.QRZComStatus, &def.QRZComStatus}, {&d.QRZComCfm, &def.QRZComCfm},
|
||||
{&d.HamlogStatus, &def.HamlogStatus}, {&d.HamlogCfm, &def.HamlogCfm},
|
||||
{&d.HamqthStatus, &def.HamqthStatus},
|
||||
} {
|
||||
if strings.TrimSpace(*f.cur) == "" {
|
||||
*f.cur = *f.def
|
||||
}
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func (a *App) GetQSLDefaults() (QSLDefaults, error) {
|
||||
out := QSLDefaults{}
|
||||
if a.settings == nil {
|
||||
@@ -11186,7 +11229,7 @@ func (a *App) GetQSLDefaults() (QSLDefaults, error) {
|
||||
out.HamlogStatus = m[keyQSLDefaultHamlogStatus]
|
||||
out.HamqthStatus = m[keyQSLDefaultHamqthStatus]
|
||||
out.HamlogCfm = m[keyQSLDefaultHamlogCfm]
|
||||
return out, nil
|
||||
return fillMissingQSLDefaults(out), nil
|
||||
}
|
||||
|
||||
// SaveQSLDefaults persists the configured defaults. Future QSO inserts
|
||||
|
||||
Reference in New Issue
Block a user