up
This commit is contained in:
@@ -3457,6 +3457,16 @@ func (a *App) QSOAudioBegin() bool {
|
||||
return a.qsoRec.Active()
|
||||
}
|
||||
|
||||
// QSOAudioRestart starts a fresh recording for a new target even if one is
|
||||
// already in progress (new call+freq from a clicked spot or external app).
|
||||
func (a *App) QSOAudioRestart() bool {
|
||||
if a.qsoRec == nil {
|
||||
return false
|
||||
}
|
||||
a.qsoRec.RestartQSO()
|
||||
return a.qsoRec.Active()
|
||||
}
|
||||
|
||||
// QSOAudioCancel drops the in-progress recording (callsign cleared, QSO
|
||||
// abandoned without logging).
|
||||
func (a *App) QSOAudioCancel() {
|
||||
@@ -4587,6 +4597,7 @@ func (a *App) runDownloadConfirmations(svc extsvc.Service, cfg extsvc.ExternalSe
|
||||
// that count for ARRL awards) so each incoming one is flagged NEW.
|
||||
sets, _ := a.qso.ConfirmedSlots(ctx, []string{"lotw_rcvd", "qsl_rcvd"})
|
||||
var items []ConfirmationItem
|
||||
var unmatched []string
|
||||
perr := adif.Parse(strings.NewReader(adifText), func(rec adif.Record) error {
|
||||
q, ok := adif.RecordToQSO(rec)
|
||||
if !ok {
|
||||
@@ -4611,6 +4622,12 @@ func (a *App) runDownloadConfirmations(svc extsvc.Service, cfg extsvc.ExternalSe
|
||||
keyIDs[key] = newID // guard against dup records in the report
|
||||
added++
|
||||
}
|
||||
} else {
|
||||
// No local QSO matched this confirmation on (call, minute, band,
|
||||
// mode). Record the specifics so the user can see WHICH one and
|
||||
// why (time off by a minute, FT4 logged as MFSK, portable call…).
|
||||
unmatched = append(unmatched, fmt.Sprintf("%s · %s · %s · %s",
|
||||
q.Callsign, q.QSODate.UTC().Format("2006-01-02 15:04Z"), q.Band, q.Mode))
|
||||
}
|
||||
// Build the result row + NEW flags (vs the pre-download snapshot),
|
||||
// then fold this slot into the sets so a repeat in the same batch
|
||||
@@ -4648,6 +4665,12 @@ func (a *App) runDownloadConfirmations(svc extsvc.Service, cfg extsvc.ExternalSe
|
||||
} else {
|
||||
emit(fmt.Sprintf("Matched %d of %d confirmed QSO(s)", matched, total))
|
||||
}
|
||||
// Surface confirmations with no local match so the user sees WHICH one
|
||||
// and why (time off by a minute, FT4 logged as MFSK, portable call, or
|
||||
// never logged). Tick "Add not-found" to import them instead.
|
||||
for _, u := range unmatched {
|
||||
emit(" ⚠ no local QSO for: " + u)
|
||||
}
|
||||
// Remember today so the next pull is incremental (per active profile).
|
||||
if a.settings != nil {
|
||||
_ = a.settings.Set(ctx, a.profileScope()+keyExtLoTWLastDownload, time.Now().UTC().Format("2006-01-02"))
|
||||
@@ -4658,10 +4681,11 @@ func (a *App) runDownloadConfirmations(svc extsvc.Service, cfg extsvc.ExternalSe
|
||||
// and (when a window is requested) skip records older than sinceDate by
|
||||
// QSO date. sinceDate is "YYYY-MM-DD".
|
||||
sinceDate := resolveSince(keyExtQRZLastDownload)
|
||||
emit(fmt.Sprintf("Window: since=%q → resolved date=%q (key %s%s)", since, sinceDate, a.profileScope(), keyExtQRZLastDownload))
|
||||
if sinceDate != "" {
|
||||
emit("Fetching QRZ.com logbook (QSOs since " + sinceDate + ")…")
|
||||
emit("Fetching QRZ.com logbook (will skip QSOs before " + sinceDate + ")…")
|
||||
} else {
|
||||
emit("Fetching QRZ.com logbook…")
|
||||
emit("Fetching QRZ.com logbook (full — no since date)…")
|
||||
}
|
||||
fr, err := extsvc.FetchQRZ(ctx, nil, cfg.QRZ.APIKey, "ALL")
|
||||
if err != nil {
|
||||
@@ -4671,6 +4695,14 @@ func (a *App) runDownloadConfirmations(svc extsvc.Service, cfg extsvc.ExternalSe
|
||||
}
|
||||
adifText := fr.ADIF
|
||||
emit(fmt.Sprintf("QRZ RESULT=%s COUNT=%s, ADIF %d bytes", fr.Result, fr.Count, len(adifText)))
|
||||
// Persist the last-download date NOW (right after a successful fetch),
|
||||
// not at the end: the QRZ logbook can be huge (tens of thousands of
|
||||
// records) and the user may close the panel mid-processing — storing it
|
||||
// late meant the date was never saved, so "since last download" kept
|
||||
// resolving to empty and re-pulled everything.
|
||||
if a.settings != nil {
|
||||
_ = a.settings.Set(ctx, a.profileScope()+keyExtQRZLastDownload, time.Now().UTC().Format("2006-01-02"))
|
||||
}
|
||||
if snip := strings.TrimSpace(adifText); snip != "" {
|
||||
if len(snip) > 300 {
|
||||
snip = snip[:300]
|
||||
@@ -4781,10 +4813,7 @@ func (a *App) runDownloadConfirmations(svc extsvc.Service, cfg extsvc.ExternalSe
|
||||
sort.Strings(keys)
|
||||
emit(fmt.Sprintf("Parsed %d record(s). Fields seen: %s", parsed, strings.Join(keys, ", ")))
|
||||
emit(fmt.Sprintf("Confirmed %d, added %d (of %d returned)", matched, added, total))
|
||||
// Remember today so a later "since last download" pull is incremental.
|
||||
if a.settings != nil {
|
||||
_ = a.settings.Set(ctx, a.profileScope()+keyExtQRZLastDownload, time.Now().UTC().Format("2006-01-02"))
|
||||
}
|
||||
// (last-download date already stored right after the fetch above)
|
||||
|
||||
default:
|
||||
emit(fmt.Sprintf("Confirmation download isn't available for %s yet.", svc))
|
||||
@@ -6296,7 +6325,12 @@ func (a *App) GetWinkeyerSettings() (WinkeyerSettings, error) {
|
||||
out.AutoSpace = v == "1"
|
||||
}
|
||||
out.UsePTT = m[keyWKUsePTT] == "1"
|
||||
out.SerialEcho = m[keyWKSerialEcho] == "1"
|
||||
// Only override the default (true) when the key is actually stored — otherwise
|
||||
// settings saved before serial_echo existed would silently disable the echo,
|
||||
// and the TX text would stop showing as it's keyed.
|
||||
if v := m[keyWKSerialEcho]; v != "" {
|
||||
out.SerialEcho = v == "1"
|
||||
}
|
||||
if v := m[keyWKMacros]; v != "" {
|
||||
var mac []WKMacro
|
||||
if json.Unmarshal([]byte(v), &mac) == nil && len(mac) > 0 {
|
||||
|
||||
Reference in New Issue
Block a user