mirror of
https://github.com/wavelog/wavelog.git
synced 2026-03-22 10:24:14 +00:00
Fix for spot population
This commit is contained in:
@@ -113,6 +113,9 @@
|
||||
var lang_bandmap_spot = "<?= __("spot"); ?>";
|
||||
var lang_bandmap_spotters = "<?= __("spotters"); ?>";
|
||||
|
||||
// QSO preparation debounce messages
|
||||
var lang_bandmap_please_wait = "<?= __("Please Wait"); ?>";
|
||||
var lang_bandmap_wait_before_send = "<?= __("Please wait %s seconds before sending another callsign to the QSO form"); ?>";
|
||||
|
||||
// DataTables messages
|
||||
var lang_bandmap_loading_spots = "<?= __("Loading spots..."); ?>";
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
// ========================================
|
||||
|
||||
const SPOT_REFRESH_INTERVAL = 60; // Auto-refresh interval in seconds
|
||||
const QSO_SEND_DEBOUNCE_MS = 3000; // Debounce for sending callsign to QSO form (milliseconds)
|
||||
|
||||
// Mode display capitalization lookup (API returns lowercase)
|
||||
const MODE_CAPITALIZATION = { 'phone': 'Phone', 'cw': 'CW', 'digi': 'Digi' };
|
||||
@@ -1261,33 +1262,34 @@ $(function() {
|
||||
$(this).attr('title', lang_click_to_prepare_logging);
|
||||
});
|
||||
|
||||
// Initialize tooltips with error handling
|
||||
try {
|
||||
$('[data-bs-toggle="tooltip"]').each(function() {
|
||||
if (!this || !$(this).attr('title')) return;
|
||||
// Initialize tooltips with error handling
|
||||
try {
|
||||
$('[data-bs-toggle="tooltip"]').each(function() {
|
||||
if (!this || !$(this).attr('title')) return;
|
||||
|
||||
try {
|
||||
// Dispose existing tooltip instance if it exists
|
||||
const existingTooltip = bootstrap.Tooltip.getInstance(this);
|
||||
if (existingTooltip) {
|
||||
existingTooltip.dispose();
|
||||
}
|
||||
|
||||
// Create new tooltip instance
|
||||
new bootstrap.Tooltip(this, {
|
||||
boundary: 'window',
|
||||
trigger: 'hover',
|
||||
sanitize: false
|
||||
});
|
||||
} catch (err) {
|
||||
// Skip if tooltip fails to initialize
|
||||
try {
|
||||
// Dispose existing tooltip instance if it exists
|
||||
const existingTooltip = bootstrap.Tooltip.getInstance(this);
|
||||
if (existingTooltip) {
|
||||
existingTooltip.dispose();
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// Fallback if tooltip initialization fails
|
||||
}
|
||||
|
||||
let displayedCount = spots2render || 0;
|
||||
// Create new tooltip instance with proper configuration
|
||||
new bootstrap.Tooltip(this, {
|
||||
boundary: 'window',
|
||||
trigger: 'hover',
|
||||
sanitize: false,
|
||||
html: false,
|
||||
animation: true,
|
||||
delay: { show: 100, hide: 100 }
|
||||
});
|
||||
} catch (err) {
|
||||
// Skip if tooltip fails to initialize
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// Fallback if tooltip initialization fails
|
||||
} let displayedCount = spots2render || 0;
|
||||
|
||||
// Update band count badges after rendering
|
||||
updateBandCountBadges();
|
||||
@@ -2129,7 +2131,27 @@ $(function() {
|
||||
}
|
||||
}
|
||||
|
||||
// Track last QSO send time for debouncing
|
||||
let lastQsoSendTime = 0;
|
||||
|
||||
function prepareLogging(call, qrg, mode, spotData) {
|
||||
// Debounce check - prevent sending too quickly
|
||||
const now = Date.now();
|
||||
const timeSinceLastSend = now - lastQsoSendTime;
|
||||
|
||||
if (timeSinceLastSend < QSO_SEND_DEBOUNCE_MS) {
|
||||
const remainingSeconds = Math.ceil((QSO_SEND_DEBOUNCE_MS - timeSinceLastSend) / 1000);
|
||||
// Use translation with placeholder replacement
|
||||
const message = lang_bandmap_wait_before_send.replace('%s', remainingSeconds);
|
||||
if (typeof showToast === 'function') {
|
||||
showToast(lang_bandmap_please_wait, message, 'bg-warning text-dark', 3000);
|
||||
}
|
||||
return; // Don't proceed with sending
|
||||
}
|
||||
|
||||
// Update last send time
|
||||
lastQsoSendTime = now;
|
||||
|
||||
let ready_listener = true;
|
||||
|
||||
// If CAT Control is enabled, tune the radio to the spot frequency
|
||||
|
||||
@@ -664,23 +664,23 @@ var lastLookupCallsign = null;
|
||||
var lookupInProgress = false;
|
||||
|
||||
// Helper function to populate reference fields after callsign lookup completes
|
||||
// Uses Map-based storage with sequence validation to prevent race conditions
|
||||
// Uses Map-based storage to prevent race conditions
|
||||
function populatePendingReferences(callsign, expectedSeq) {
|
||||
// Handle legacy call without parameters
|
||||
if (!callsign) {
|
||||
callsign = $('#callsign').val();
|
||||
expectedSeq = $('#callsign').data('expected-refs-seq');
|
||||
}
|
||||
|
||||
const entry = pendingReferencesMap.get(callsign);
|
||||
|
||||
|
||||
if (!entry) {
|
||||
console.log('No pending references for callsign:', callsign);
|
||||
// No references for this callsign - this is normal for non-POTA/SOTA/WWFF spots
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate sequence to prevent stale data
|
||||
if (expectedSeq && entry.seq !== expectedSeq) {
|
||||
|
||||
// Validate sequence only if expectedSeq was provided
|
||||
// This prevents stale data from being populated
|
||||
if (expectedSeq !== null && expectedSeq !== undefined && entry.seq !== expectedSeq) {
|
||||
console.warn('Sequence mismatch - ignoring stale references', {
|
||||
callsign: callsign,
|
||||
expected: expectedSeq,
|
||||
@@ -688,14 +688,13 @@ function populatePendingReferences(callsign, expectedSeq) {
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark as populated to prevent double-population
|
||||
|
||||
// Check if already populated - prevent double-population for same instance
|
||||
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)
|
||||
@@ -764,12 +763,10 @@ function populatePendingReferences(callsign, expectedSeq) {
|
||||
} 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() {
|
||||
|
||||
// Cleanup immediately after triggering - we're done with these references
|
||||
pendingReferencesMap.delete(callsign);
|
||||
}, 5000); // Keep for 5 seconds in case of retry
|
||||
}, 100); // Small delay to let form settle
|
||||
}
|
||||
|
||||
var bc = new BroadcastChannel('qso_wish');
|
||||
@@ -827,10 +824,10 @@ bc.onmessage = function (ev) {
|
||||
if (ev.data.mode) {
|
||||
$("#mode").val(ev.data.mode);
|
||||
}
|
||||
|
||||
|
||||
// Store sequence for validation in populatePendingReferences
|
||||
$("#callsign").data('expected-refs-seq', seq);
|
||||
|
||||
|
||||
$("#callsign").val(callsign);
|
||||
$("#callsign").focusout();
|
||||
$("#callsign").blur();
|
||||
@@ -1267,13 +1264,10 @@ $("#callsign").on("focusout", function () {
|
||||
lastLookupCallsign = currentCallsign;
|
||||
lookupInProgress = true;
|
||||
|
||||
// Capture pendingReferences for THIS lookup (before it gets overwritten by another click)
|
||||
// If pendingReferences exists, use it; otherwise set to null to prevent old references
|
||||
// from being populated when user manually types a different callsign
|
||||
var capturedReferences = pendingReferences ? Object.assign({}, pendingReferences) : null;
|
||||
|
||||
// Clear pendingReferences immediately after capturing to prevent reuse on next manual lookup
|
||||
pendingReferences = null;
|
||||
// Check if we have pending references from bandmap for this callsign
|
||||
// If yes, get the sequence; if no, we'll populate without sequence validation
|
||||
var hasPendingRefs = pendingReferencesMap.has(currentCallsign);
|
||||
var expectedSeq = hasPendingRefs ? pendingReferencesMap.get(currentCallsign).seq : null;
|
||||
|
||||
// Disable Save QSO button and show fetch status
|
||||
$('#saveQso').prop('disabled', true);
|
||||
@@ -1833,9 +1827,9 @@ $("#callsign").on("focusout", function () {
|
||||
|
||||
// Populate pending references from bandmap (after all lookup logic completes)
|
||||
// Small delay to ensure DOM is fully updated
|
||||
// Use the captured references from when THIS lookup started
|
||||
// Use the Map-based approach with the current callsign and expected sequence
|
||||
setTimeout(function() {
|
||||
populatePendingReferences(capturedReferences);
|
||||
populatePendingReferences(currentCallsign, expectedSeq);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user