mirror of
https://github.com/wavelog/wavelog.git
synced 2026-03-22 10:24:14 +00:00
Fix for ref population
This commit is contained in:
@@ -655,83 +655,121 @@ bc_bandmap.onmessage = function (ev) {
|
||||
}
|
||||
|
||||
// Store pending references from bandmap to populate AFTER callsign lookup completes
|
||||
var pendingReferences = null;
|
||||
// Map structure: callsign -> {seq, refs, timestamp, populated}
|
||||
var pendingReferencesMap = new Map();
|
||||
var referenceSequence = 0;
|
||||
|
||||
// Track last lookup to prevent duplicate calls
|
||||
var lastLookupCallsign = null;
|
||||
var lookupInProgress = false;
|
||||
|
||||
// Helper function to populate reference fields after callsign lookup completes
|
||||
function populatePendingReferences(refsToPopulate) {
|
||||
// Use provided references or fall back to global pendingReferences
|
||||
var refs = refsToPopulate || pendingReferences;
|
||||
|
||||
if (!refs) {
|
||||
return;
|
||||
// Uses Map-based storage with sequence validation to prevent race conditions
|
||||
function populatePendingReferences(callsign, expectedSeq) {
|
||||
// Handle legacy call without parameters
|
||||
if (!callsign) {
|
||||
callsign = $('#callsign').val();
|
||||
expectedSeq = $('#callsign').data('expected-refs-seq');
|
||||
}
|
||||
|
||||
// POTA - uses selectize
|
||||
const entry = pendingReferencesMap.get(callsign);
|
||||
|
||||
if (!entry) {
|
||||
console.log('No pending references for callsign:', callsign);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate sequence to prevent stale data
|
||||
if (expectedSeq && entry.seq !== expectedSeq) {
|
||||
console.warn('Sequence mismatch - ignoring stale references', {
|
||||
callsign: callsign,
|
||||
expected: expectedSeq,
|
||||
actual: entry.seq
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark as populated to prevent double-population
|
||||
if (entry.populated) {
|
||||
console.warn('References already populated for', callsign);
|
||||
return;
|
||||
}
|
||||
entry.populated = true;
|
||||
|
||||
const refs = entry.refs;
|
||||
|
||||
// POTA - set without triggering change initially (silent = true)
|
||||
if (refs.pota_ref && $('#pota_ref').length) {
|
||||
try {
|
||||
var $select = $('#pota_ref').selectize();
|
||||
if ($select.length && $select[0].selectize) {
|
||||
var selectize = $select[0].selectize;
|
||||
selectize.addOption({name: refs.pota_ref});
|
||||
selectize.setValue(refs.pota_ref, false);
|
||||
$('#pota_ref').trigger('change');
|
||||
selectize.setValue(refs.pota_ref, true); // Silent = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Could not set POTA reference:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// SOTA - uses selectize
|
||||
// SOTA - set without triggering change initially (silent = true)
|
||||
if (refs.sota_ref && $('#sota_ref').length) {
|
||||
try {
|
||||
var $select = $('#sota_ref').selectize();
|
||||
if ($select.length && $select[0].selectize) {
|
||||
var selectize = $select[0].selectize;
|
||||
selectize.addOption({name: refs.sota_ref});
|
||||
selectize.setValue(refs.sota_ref, false);
|
||||
$('#sota_ref').trigger('change');
|
||||
selectize.setValue(refs.sota_ref, true); // Silent = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Could not set SOTA reference:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// WWFF - uses selectize
|
||||
// WWFF - set without triggering change initially (silent = true)
|
||||
if (refs.wwff_ref && $('#wwff_ref').length) {
|
||||
try {
|
||||
var $select = $('#wwff_ref').selectize();
|
||||
if ($select.length && $select[0].selectize) {
|
||||
var selectize = $select[0].selectize;
|
||||
selectize.addOption({name: refs.wwff_ref});
|
||||
selectize.setValue(refs.wwff_ref, false);
|
||||
$('#wwff_ref').trigger('change');
|
||||
selectize.setValue(refs.wwff_ref, true); // Silent = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Could not set WWFF reference:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// IOTA - regular select dropdown (not selectize)
|
||||
// IOTA - set silently (no change trigger yet)
|
||||
if (refs.iota_ref && $('#iota_ref').length) {
|
||||
try {
|
||||
let $iotaSelect = $('#iota_ref');
|
||||
if ($iotaSelect.find('option[value="' + refs.iota_ref + '"]').length === 0) {
|
||||
$iotaSelect.append(new Option(refs.iota_ref, refs.iota_ref));
|
||||
}
|
||||
$iotaSelect.val(refs.iota_ref).trigger('change');
|
||||
$iotaSelect.val(refs.iota_ref); // Don't trigger change yet
|
||||
} catch (e) {
|
||||
console.warn('Could not set IOTA reference:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Only clear global pendingReferences if we used it (not a captured copy)
|
||||
if (!refsToPopulate && pendingReferences) {
|
||||
pendingReferences = null;
|
||||
}
|
||||
// NOW trigger gridsquare lookup ONLY ONCE for the highest priority reference
|
||||
// Priority: POTA > SOTA > WWFF (most commonly used)
|
||||
// This prevents multiple simultaneous AJAX gridsquare lookups that can race
|
||||
setTimeout(function() {
|
||||
if (refs.pota_ref && $('#pota_ref').length) {
|
||||
$('#pota_ref').trigger('change');
|
||||
} else if (refs.sota_ref && $('#sota_ref').length) {
|
||||
$('#sota_ref').trigger('change');
|
||||
} else if (refs.wwff_ref && $('#wwff_ref').length) {
|
||||
$('#wwff_ref').trigger('change');
|
||||
}
|
||||
}, 100); // Small delay to let form settle
|
||||
|
||||
// Cleanup after successful population
|
||||
setTimeout(function() {
|
||||
pendingReferencesMap.delete(callsign);
|
||||
}, 5000); // Keep for 5 seconds in case of retry
|
||||
}
|
||||
|
||||
var bc = new BroadcastChannel('qso_wish');
|
||||
@@ -746,21 +784,35 @@ bc.onmessage = function (ev) {
|
||||
} else {
|
||||
// Always process frequency, callsign, and reference data from bandmap
|
||||
// (regardless of manual mode - bandmap should control the form)
|
||||
const callsign = ev.data.call;
|
||||
const seq = ++referenceSequence;
|
||||
let delay = 0;
|
||||
|
||||
// Only reset if callsign is different from what we're about to set
|
||||
if ($("#callsign").val() != "" && $("#callsign").val() != ev.data.call) {
|
||||
if ($("#callsign").val() != "" && $("#callsign").val() != callsign) {
|
||||
reset_fields();
|
||||
delay = 600;
|
||||
}
|
||||
|
||||
// Store references for later population (after callsign lookup completes)
|
||||
pendingReferences = {
|
||||
pota_ref: ev.data.pota_ref,
|
||||
sota_ref: ev.data.sota_ref,
|
||||
wwff_ref: ev.data.wwff_ref,
|
||||
iota_ref: ev.data.iota_ref
|
||||
};
|
||||
// Store references with metadata in Map (prevents race conditions)
|
||||
pendingReferencesMap.set(callsign, {
|
||||
seq: seq,
|
||||
refs: {
|
||||
pota_ref: ev.data.pota_ref,
|
||||
sota_ref: ev.data.sota_ref,
|
||||
wwff_ref: ev.data.wwff_ref,
|
||||
iota_ref: ev.data.iota_ref
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
populated: false
|
||||
});
|
||||
|
||||
// Cleanup old entries (> 30 seconds)
|
||||
for (let [key, value] of pendingReferencesMap) {
|
||||
if (Date.now() - value.timestamp > 30000) {
|
||||
pendingReferencesMap.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (ev.data.frequency != null) {
|
||||
@@ -775,7 +827,11 @@ bc.onmessage = function (ev) {
|
||||
if (ev.data.mode) {
|
||||
$("#mode").val(ev.data.mode);
|
||||
}
|
||||
$("#callsign").val(ev.data.call);
|
||||
|
||||
// Store sequence for validation in populatePendingReferences
|
||||
$("#callsign").data('expected-refs-seq', seq);
|
||||
|
||||
$("#callsign").val(callsign);
|
||||
$("#callsign").focusout();
|
||||
$("#callsign").blur();
|
||||
}, delay);
|
||||
@@ -1057,9 +1113,9 @@ function reset_to_default() {
|
||||
|
||||
/* Function: reset_fields is used to reset the fields on the QSO page */
|
||||
function reset_fields() {
|
||||
// we set the pendingReferences to null to avoid they get prefilled in the next QSO after clear
|
||||
// Clear all pending references to avoid they get prefilled in the next QSO after clear
|
||||
// we do this first to avoid race conditions for slow javascript
|
||||
pendingReferences = null;
|
||||
pendingReferencesMap.clear();
|
||||
|
||||
$('#locator_info').text("");
|
||||
$('#comment').val("");
|
||||
|
||||
Reference in New Issue
Block a user