diff --git a/static/js/modes/listening-post.js b/static/js/modes/listening-post.js index 2987e39..4273b23 100644 --- a/static/js/modes/listening-post.js +++ b/static/js/modes/listening-post.js @@ -1018,8 +1018,16 @@ function addSignalHit(data) { ${data.frequency.toFixed(3)} ${snrText} ${mod.toUpperCase()} - + + + +
+
Pager
+
433 Sensor
+
RTLAMR
+
+
`; tbody.insertBefore(row, tbody.firstChild); @@ -3056,6 +3064,27 @@ function renderSignalGuess(result) { altsEl.innerHTML = ''; } } + + const sendToEl = document.getElementById('signalGuessSendTo'); + if (sendToEl) { + const freqInput = document.getElementById('signalGuessFreqInput'); + const freq = freqInput ? parseFloat(freqInput.value) : NaN; + if (!isNaN(freq) && freq > 0) { + const tags = (result.tags || []).map(t => t.toLowerCase()); + const modes = [ + { key: 'pager', label: 'Pager', highlight: tags.some(t => t.includes('pager') || t.includes('pocsag') || t.includes('flex')) }, + { key: 'sensor', label: '433 Sensor', highlight: tags.some(t => t.includes('ism') || t.includes('433') || t.includes('sensor') || t.includes('iot')) }, + { key: 'rtlamr', label: 'RTLAMR', highlight: tags.some(t => t.includes('meter') || t.includes('amr') || t.includes('utility')) } + ]; + sendToEl.style.display = 'block'; + sendToEl.innerHTML = '
Send to:
' + + modes.map(m => + `` + ).join('') + '
'; + } else { + sendToEl.style.display = 'none'; + } + } } function manualSignalGuess() { @@ -4023,21 +4052,88 @@ function bindWaterfallInteraction() { tooltip.style.display = 'none'; }; + // Right-click context menu for "Send to" decoder + let ctxMenu = document.getElementById('waterfallCtxMenu'); + if (!ctxMenu) { + ctxMenu = document.createElement('div'); + ctxMenu.id = 'waterfallCtxMenu'; + ctxMenu.style.cssText = 'position:fixed;display:none;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:4px;z-index:10000;min-width:120px;padding:4px 0;box-shadow:0 4px 12px rgba(0,0,0,0.5);font-size:11px;'; + document.body.appendChild(ctxMenu); + document.addEventListener('click', () => { ctxMenu.style.display = 'none'; }); + } + + const contextHandler = (event) => { + if (waterfallMode === 'audio') return; + event.preventDefault(); + const canvas = event.currentTarget; + const rect = canvas.getBoundingClientRect(); + const x = event.clientX - rect.left; + const ratio = Math.max(0, Math.min(1, x / rect.width)); + const freq = waterfallStartFreq + ratio * (waterfallEndFreq - waterfallStartFreq); + + const modes = [ + { key: 'pager', label: 'Pager' }, + { key: 'sensor', label: '433 Sensor' }, + { key: 'rtlamr', label: 'RTLAMR' } + ]; + + ctxMenu.innerHTML = `
${freq.toFixed(3)} MHz →
` + + modes.map(m => + `
Send to ${m.label}
` + ).join(''); + + ctxMenu.style.left = event.clientX + 'px'; + ctxMenu.style.top = event.clientY + 'px'; + ctxMenu.style.display = 'block'; + }; + if (waterfallCanvas) { waterfallCanvas.style.cursor = 'crosshair'; waterfallCanvas.addEventListener('click', handler); waterfallCanvas.addEventListener('mousemove', hoverHandler); waterfallCanvas.addEventListener('mouseleave', leaveHandler); + waterfallCanvas.addEventListener('contextmenu', contextHandler); } if (spectrumCanvas) { spectrumCanvas.style.cursor = 'crosshair'; spectrumCanvas.addEventListener('click', handler); spectrumCanvas.addEventListener('mousemove', hoverHandler); spectrumCanvas.addEventListener('mouseleave', leaveHandler); + spectrumCanvas.addEventListener('contextmenu', contextHandler); } } +// ============== CROSS-MODULE FREQUENCY ROUTING ============== + +function sendFrequencyToMode(freqMhz, targetMode) { + const inputMap = { + pager: 'frequency', + sensor: 'sensorFrequency', + rtlamr: 'rtlamrFrequency' + }; + + const inputId = inputMap[targetMode]; + if (!inputId) return; + + if (typeof switchMode === 'function') { + switchMode(targetMode); + } + + setTimeout(() => { + const input = document.getElementById(inputId); + if (input) { + input.value = freqMhz.toFixed(4); + } + }, 300); + + if (typeof showNotification === 'function') { + const modeLabels = { pager: 'Pager', sensor: '433 Sensor', rtlamr: 'RTLAMR' }; + showNotification('Frequency Sent', `${freqMhz.toFixed(3)} MHz → ${modeLabels[targetMode] || targetMode}`); + } +} + +window.sendFrequencyToMode = sendFrequencyToMode; window.stopDirectListen = stopDirectListen; window.toggleScanner = toggleScanner; window.startScanner = startScanner; diff --git a/templates/partials/modes/listening-post.html b/templates/partials/modes/listening-post.html index dac9b92..74b32cd 100644 --- a/templates/partials/modes/listening-post.html +++ b/templates/partials/modes/listening-post.html @@ -61,6 +61,7 @@
+