fix: waterfall monitor state desync on frequency change and restart

When changing frequency with shared monitor active, the monitor retune
could be silently dropped if a previous retune was still in-flight,
leaving the UI stuck on "Starting <freq>". After stopping and restarting
the waterfall, the monitor button could remain disabled because
_startingMonitor was never reset and _monitorRetuneTimer was not cleared.

- Cancel in-flight monitor start when queuing a new retune
- Always clear _pendingSharedMonitorRearm in started handler
- Clear _monitorRetuneTimer and reset _startingMonitor in stop()
This commit is contained in:
Smittix
2026-02-23 21:35:34 +00:00
parent 365333d425
commit 2e6bb8882f

View File

@@ -1797,9 +1797,14 @@ const Waterfall = (function () {
function _queueMonitorRetune(delayMs) {
if (!_monitoring) return;
clearTimeout(_monitorRetuneTimer);
// If a monitor start is already in-flight, invalidate it so the
// new retune can proceed once the finally-block resets the flag.
if (_startingMonitor) {
_audioConnectNonce += 1;
}
_monitorRetuneTimer = setTimeout(() => {
_startMonitorInternal({ wasRunningWaterfall: false, retuneOnly: true }).catch(() => {});
}, delayMs);
}, _startingMonitor ? Math.max(delayMs, 250) : delayMs);
}
function _isSharedMonitorActive() {
@@ -2453,9 +2458,11 @@ const Waterfall = (function () {
}
_setStatus(`Streaming ${_startMhz.toFixed(4)} - ${_endMhz.toFixed(4)} MHz`);
_setVisualStatus('RUNNING');
if (_pendingSharedMonitorRearm && _monitoring && _monitorSource === 'waterfall') {
if (_pendingSharedMonitorRearm) {
_pendingSharedMonitorRearm = false;
_queueMonitorRetune(120);
if (_monitoring && _monitorSource === 'waterfall') {
_queueMonitorRetune(120);
}
}
} else if (msg.status === 'tuned') {
if (_onRetuneRequired(msg)) return;
@@ -3021,9 +3028,17 @@ const Waterfall = (function () {
async function stop({ keepStatus = false } = {}) {
stopScan('Scan stopped', { silent: keepStatus });
clearTimeout(_retuneTimer);
clearTimeout(_monitorRetuneTimer);
_clearWsFallbackTimer();
_wsOpened = false;
_pendingSharedMonitorRearm = false;
// Reset in-flight monitor start flag so the button is not left
// disabled after a waterfall stop/restart cycle.
if (_startingMonitor) {
_audioConnectNonce += 1;
_startingMonitor = false;
_syncMonitorButtons();
}
if (_ws) {
try {