feat: prefer the last QSO's precise locator over the cty.dat centroid; changelog → 0.21.2

For an entity resolved only via cty.dat (e.g. a French call not on QRZ/HamQTH),
the provider block sets a coarse country-centroid grid. The worked-before backfill
now overrides that with the precise locator from the last QSO with this call, and
takes that QSO's lat/lon (derived from the grid when the record stored none) so
the map and saved record stay consistent. A real provider grid still wins.

Moved the (unreleased) worked-before backfill entry into a new 0.21.2 changelog
block, since 0.21.1 is already out.
This commit is contained in:
2026-07-25 15:54:25 +02:00
parent 3564eecc36
commit 7e08553e6e
2 changed files with 41 additions and 18 deletions
+31 -16
View File
@@ -2871,23 +2871,38 @@ export default function App() {
const empty = (v: any) => (v ?? '') === '';
if (!ue.has('name') && empty(r?.name) && last.name) setName(last.name);
if (!ue.has('qth') && empty(r?.qth) && last.qth) setQth(last.qth);
if (!ue.has('grid') && empty(r?.grid) && !(r?.lat || r?.lon) && last.grid) setGrid(last.grid);
if (!ue.has('country') && empty(r?.country) && last.country) setCountry(last.country);
setDetails((d) => ({
...d,
address: d.address || last.address || '',
state: d.state || last.state || '',
cnty: d.cnty || last.cnty || '',
lat: d.lat ?? (last.lat ?? undefined),
lon: d.lon ?? (last.lon ?? undefined),
dxcc: d.dxcc ?? (last.dxcc || undefined),
cqz: d.cqz ?? (last.cqz || undefined),
ituz: d.ituz ?? (last.ituz || undefined),
cont: d.cont || last.cont || '',
email: d.email || last.email || '',
qsl_via: d.qsl_via || last.qsl_via || '',
}));
if (last.grid || last.lat) setMapZoomSignal((n) => n + 1);
// Grid: a REAL provider grid always wins. Otherwise the last QSO's precise
// locator beats the coarse cty.dat entity centroid the provider block set — so
// a French call resolves to its real JNxx, not the country's JN16 centroid.
const adoptLastGrid = !ue.has('grid') && empty(r?.grid) && !!last.grid;
if (adoptLastGrid) setGrid(last.grid);
setDetails((d) => {
// When we adopt the last QSO's locator, take its coordinates too (derive them
// from the grid if that QSO didn't store any) so the map + saved record match.
let lat = d.lat, lon = d.lon;
if (adoptLastGrid) {
if (last.lat != null && last.lon != null) { lat = last.lat; lon = last.lon; }
else { const ll = gridToLatLon(last.grid); if (ll) { lat = ll.lat; lon = ll.lon; } }
} else {
lat = d.lat ?? (last.lat ?? undefined);
lon = d.lon ?? (last.lon ?? undefined);
}
return {
...d,
address: d.address || last.address || '',
state: d.state || last.state || '',
cnty: d.cnty || last.cnty || '',
lat, lon,
dxcc: d.dxcc ?? (last.dxcc || undefined),
cqz: d.cqz ?? (last.cqz || undefined),
ituz: d.ituz ?? (last.ituz || undefined),
cont: d.cont || last.cont || '',
email: d.email || last.email || '',
qsl_via: d.qsl_via || last.qsl_via || '',
};
});
if (adoptLastGrid || last.grid || last.lat) setMapZoomSignal((n) => n + 1);
}
async function runLookup(call: string) {
if (call !== lastLookedUpRef.current) resetAutoFill();