feat: follow the SUB VFO over OmniRig; distance column in the QSO grids
OmniRig reports the VFO pair (AA/AB/BA/BB) on the whole Yaesu range and never the single-letter form. Only the latter was honoured, so every rig in that family stayed pinned to VFO A: pressing SUB moved the radio but not OpsLog, and a QSO worked on SUB was logged on the main VFO's frequency. The first letter of the pair is the VFO being listened on — Log4OM reads it and gets the right frequency on the same rigs, which is what showed the data was there. The enum now wins over the Yaesu Freq==FreqB inference, which is only a fallback for a rig file that names no VFO at all (the stock FTDX10 one answers neither VS; nor FR; usably — verified on the air). Split: the ON flag is still latched to survive a rig file that flips it on its own, but the latch is now ARMED only after 8 flips in 30 s. A first cut at 3-in-15s was armed by the operator toggling split while testing, imposing the 6 s clearing delay on a radio that did not need it; a misreading file flips a dozen times in that window untouched, so the two cases separate cleanly. Distance (km) column added to Recent QSOs and Worked before (shared catalog). Computed from the QSO's OWN my_grid/my_lat/lon first, falling back to the current profile's locator: a log spans years and portable outings, so the station a QSO was made from is not necessarily today's. Locator: a precise QRZ/HamQTH grid is no longer overwritten by the cty.dat entity centroid. The lookup runs several times per QSO and the provider gets 2 s; a slow second answer fell back to cty.dat and downgraded JN05JG to JN16 while name and QTH survived (they are only written when non-empty). The OmniRig diagnostic line now logs what OpsLog concluded, not just what OmniRig reported. icomnet.go: gofmt alignment only.
This commit is contained in:
+23
-4
@@ -612,6 +612,10 @@ export default function App() {
|
||||
|
||||
const userEditedRef = useRef<Set<string>>(new Set());
|
||||
const lastLookedUpRef = useRef<string>('');
|
||||
// Callsign for which a PROVIDER (QRZ/HamQTH) grid is currently in the field.
|
||||
// A later cty.dat-only answer for the same call must not replace that precise
|
||||
// locator with the entity centroid — see the apply block in doLookup.
|
||||
const providerGridCallRef = useRef<string>('');
|
||||
// Tracks the call we last auto-switched to the Worked-before tab for, so we
|
||||
// don't keep yanking the tab on every wb refresh of the same callsign.
|
||||
const lastWbFocusRef = useRef<string>('');
|
||||
@@ -2723,6 +2727,7 @@ export default function App() {
|
||||
|
||||
function resetAutoFill() {
|
||||
setName(''); setQth(''); setCountry(''); setGrid('');
|
||||
providerGridCallRef.current = ''; // the grid field is empty again
|
||||
// NOTE: don't clear `wb` here. It's owned by runWorkedBefore (fast 150 ms
|
||||
// pass) and the short-callsign guard in scheduleLookup. Clearing it inside
|
||||
// runLookup blanked the Worked-before table for the whole (possibly slow,
|
||||
@@ -3015,12 +3020,24 @@ export default function App() {
|
||||
if (!ue.has('name') && (r.name ?? '') !== '') setName(r.name ?? '');
|
||||
if (!ue.has('qth') && (r.qth ?? '') !== '') setQth(r.qth ?? '');
|
||||
if (!ue.has('grid')) {
|
||||
if ((r.grid ?? '') !== '') setGrid(r.grid ?? '');
|
||||
if ((r.grid ?? '') !== '') {
|
||||
setGrid(r.grid ?? '');
|
||||
providerGridCallRef.current = call;
|
||||
}
|
||||
// No provider grid (cty.dat-only / portable): derive a 4-char grid from
|
||||
// the entity centroid (e.g. Svalbard → JQ88) so the field — and the
|
||||
// bearing/map — aren't empty. 4 chars signals it's entity-level, not a
|
||||
// precise QTH (matches how Log4OM shows it).
|
||||
else if (r.lat || r.lon) setGrid(latLonToGrid(r.lat || 0, r.lon || 0, 4));
|
||||
//
|
||||
// Skipped when QRZ already gave a precise grid for THIS call: lookups run
|
||||
// more than once per QSO (debounced typing, then blur/Enter), and the
|
||||
// provider only has a 2-second budget — one slow answer fell back to
|
||||
// cty.dat and downgraded JN05JG to the France centroid JN16, while Name
|
||||
// and QTH stayed (they are only written when non-empty). Same rule as
|
||||
// those fields: a cty.dat answer never overwrites a richer one.
|
||||
else if ((r.lat || r.lon) && providerGridCallRef.current !== call) {
|
||||
setGrid(latLonToGrid(r.lat || 0, r.lon || 0, 4));
|
||||
}
|
||||
}
|
||||
// Country/zones are exactly what cty.dat IS authoritative for — set them
|
||||
// (only skipped if empty, so we never blank a known country).
|
||||
@@ -4139,7 +4156,7 @@ export default function App() {
|
||||
case 'worked':
|
||||
return (
|
||||
<div className="h-full w-full min-h-0 flex flex-col bg-card border border-border rounded-lg overflow-hidden">
|
||||
<WorkedBeforeGrid wb={wbWithAwards as any} awardCols={awardCols} busy={wbBusy} currentCall={callsign} onRowDoubleClicked={(q) => openEdit(q.id as number)}
|
||||
<WorkedBeforeGrid wb={wbWithAwards as any} myGrid={station.my_grid} awardCols={awardCols} busy={wbBusy} currentCall={callsign} onRowDoubleClicked={(q) => openEdit(q.id as number)}
|
||||
onUpdateFromCty={bulkUpdateFromCty} onUpdateFromQRZ={bulkUpdateFromQRZ} onUpdateFromClublog={bulkUpdateFromClublog}
|
||||
onSendTo={bulkSendTo} onSendRecording={bulkSendRecording} onSendEQSL={(ids) => setEqslQsoId(ids[0] ?? null)}
|
||||
onBulkEdit={openBulkEdit} onExportSelected={exportSelectedADIF} onExportSelectedFields={exportSelectedFields}
|
||||
@@ -4176,6 +4193,7 @@ export default function App() {
|
||||
<RecentQSOsGrid
|
||||
key={`rqg-${activeProfileId ?? 'x'}`}
|
||||
rows={qsosWithAwards as any}
|
||||
myGrid={station.my_grid}
|
||||
total={total}
|
||||
awardCols={awardCols}
|
||||
onRowDoubleClicked={(q) => openEdit(q.id as number)}
|
||||
@@ -5309,6 +5327,7 @@ export default function App() {
|
||||
<RecentQSOsGrid
|
||||
key={`rqg2-${activeProfileId ?? 'x'}`}
|
||||
rows={qsosWithAwards as any}
|
||||
myGrid={station.my_grid}
|
||||
total={total}
|
||||
awardCols={awardCols}
|
||||
onFilteredCountChange={setGridFilteredCount}
|
||||
@@ -5550,7 +5569,7 @@ export default function App() {
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="worked" className="mt-0 flex flex-col min-h-0 flex-1">
|
||||
<WorkedBeforeGrid wb={wbWithAwards as any} awardCols={awardCols} busy={wbBusy} currentCall={callsign} onRowDoubleClicked={(q) => openEdit(q.id as number)}
|
||||
<WorkedBeforeGrid wb={wbWithAwards as any} myGrid={station.my_grid} awardCols={awardCols} busy={wbBusy} currentCall={callsign} onRowDoubleClicked={(q) => openEdit(q.id as number)}
|
||||
onUpdateFromCty={bulkUpdateFromCty} onUpdateFromQRZ={bulkUpdateFromQRZ} onUpdateFromClublog={bulkUpdateFromClublog} onSendTo={bulkSendTo} onSendRecording={bulkSendRecording}
|
||||
onSendEQSL={(ids) => setEqslQsoId(ids[0] ?? null)}
|
||||
onBulkEdit={openBulkEdit} onExportSelected={exportSelectedADIF} onExportSelectedFields={exportSelectedFields}
|
||||
|
||||
Reference in New Issue
Block a user