diff --git a/datahandler.js b/datahandler.js index 3b5283f..faf77b4 100644 --- a/datahandler.js +++ b/datahandler.js @@ -198,6 +198,8 @@ var dataToSend = { af: [], rt0: '', rt1: '', + ims: 0, + eq: 0, country_name: '', country_iso: 'UN', users: '', @@ -235,6 +237,32 @@ function handleData(ws, receivedData) { dataToSend.pi = '?'; } break; + case receivedLine.startsWith('G'): + if(receivedLine === 'G11') { + initialData.eq = 1; + initialData.ims = 1; + dataToSend.eq = 1; + dataToSend.ims = 1; + } + if(receivedLine === 'G01') { + initialData.eq = 0; + initialData.ims = 1; + dataToSend.eq = 0; + dataToSend.ims = 1; + } + if(receivedLine === 'G10') { + initialData.eq = 1; + initialData.ims = 0; + dataToSend.eq = 1; + dataToSend.ims = 0; + } + if(receivedLine === 'G00') { + initialData.eq = 0; + initialData.ims = 0; + dataToSend.eq = 0; + dataToSend.ims = 0; + } + break; case receivedLine.startsWith('Sm'): modifiedData = receivedLine.substring(2); diff --git a/index.js b/index.js index b56bebf..cfb7eec 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ const path = require('path'); const net = require('net'); const client = new net.Socket(); const crypto = require('crypto'); -const commandExists = require('command-exists-promise') +const commandExists = require('command-exists-promise'); const dataHandler = require('./datahandler'); const consoleCmd = require('./console'); const config = require('./userconfig'); @@ -46,8 +46,8 @@ wss.on('connection', (ws, request) => { ws.on('message', (message) => { logDebug('Received message from client:', message.toString()); - newFreq = message.toString() * 1000; - client.write("T" + newFreq + '\n'); + command = message.toString(); + client.write(command + "\n"); }); ws.on('close', (code, reason) => { @@ -112,6 +112,8 @@ client.connect(xdrdServerPort, xdrdServerHost, () => { if (authFlags.authMsg && authFlags.firstClient) { client.write('T87500\n'); + client.write('A0\n'); + client.write('G11\n'); client.off('data', authDataHandler); return; } diff --git a/userconfig.js b/userconfig.js index 101c367..1e6c815 100644 --- a/userconfig.js +++ b/userconfig.js @@ -7,7 +7,7 @@ const audioPort = 8081; const xdrdServerHost = '127.0.0.1'; // xdrd server IP (if it's running on the same machine, use 127.0.0.1) const xdrdServerPort = 7373; // xdrd server port -const xdrdPassword = ''; // xdrd password (optional) +const xdrdPassword = 'password'; // xdrd password (optional) const qthLatitude = ''; // your latitude, useful for maps.fmdx.pl integration const qthLongitude = ''; // your longitude, useful for maps.fmdx.pl integration diff --git a/web/css/breadcrumbs.css b/web/css/breadcrumbs.css index b741e4f..9af94a9 100644 --- a/web/css/breadcrumbs.css +++ b/web/css/breadcrumbs.css @@ -49,4 +49,69 @@ h3 { font-size: 14px; max-height: 380px; overflow-y: auto; -} \ No newline at end of file +} + +#af-list a { + cursor: pointer; +} + +#flags-container-phone { + display: none; +} + +@media (max-width: 960px) { + canvas, #flags-container { + display: none; + } + #ps-container { + background-color: var(--color-1); + height: 100px !important; + } + h2 { + display: none; + } + #data-pi { + font-size: 24px; + margin-top: 50px; + color: #aaa; + } + h2.show-phone { + display: inline; + padding: 0 !important; + } + #data-ps { + font-size: 60px; + } + #data-frequency { + font-size: 72px; + } + #data-rt0, #data-rt1 { + font-size: 10px; + text-align: left; + width: 100%; + } + #rt-container { + height: 32px !important; + } + ul { + font-size: 16px; + } + ul li { + display: inline; + margin-right: 5px; + } + li:not(:last-child)::after { + content: " •"; + color: #aaa; + } + #flags-container-desktop { + display: none; + } + #flags-container-phone { + display: block; + } + #tune-buttons { + height: 64px; + } +} + diff --git a/web/css/buttons.css b/web/css/buttons.css index 5ba65e9..cd821f3 100644 --- a/web/css/buttons.css +++ b/web/css/buttons.css @@ -1,4 +1,4 @@ -.play-button { +button { width: 100%; height: 100%; border: 0; @@ -6,9 +6,10 @@ transition: 0.3s ease-in-out background-color; background-color: var(--color-4); cursor: pointer; + font-family: inherit; } -.play-button:hover { +button:hover { background-color: var(--color-main-bright); } diff --git a/web/css/entry.css b/web/css/entry.css index 5a460ec..e3e5004 100644 --- a/web/css/entry.css +++ b/web/css/entry.css @@ -2,6 +2,6 @@ @import url("main.css"); /* Root stuff that affects the entire webpage (body, wrapper etc.) */ @import url("breadcrumbs.css"); /* Stuff that applies to random elements only once/twice */ @import url("buttons.css"); /* Buttons, inputs, select boxes, checkboxes... */ -@import url("helpers.css"); /* Stuff that is used often such as text changers etc */ @import url("panels.css"); /* Different panels and their sizes */ -@import url("modal.css"); /* Modal window */ \ No newline at end of file +@import url("modal.css"); /* Modal window */ +@import url("helpers.css"); /* Stuff that is used often such as text changers etc */ \ No newline at end of file diff --git a/web/css/helpers.css b/web/css/helpers.css index 917e0ad..af35ac3 100644 --- a/web/css/helpers.css +++ b/web/css/helpers.css @@ -6,6 +6,10 @@ background: #100d1f; } +.bg-gray { + background: #999; +} + .bg-none { background: transparent !important; } @@ -30,6 +34,22 @@ border-radius: 5px; } +.m-0 { + margin: 0; +} + +.m-left-20 { + margin-left: 20px; +} + +.h-100 { + height: 100%; +} + +.no-bg { + background-color: transparent; +} + .flex-container { display: flex; } @@ -81,6 +101,10 @@ font-size: 11px; } +.text-bold { + font-weight: bold; +} + .text-gray { color: #666; } @@ -130,4 +154,7 @@ .flex-phone { display: flex; } + .hide-phone { + display: none; + } } \ No newline at end of file diff --git a/web/css/panels.css b/web/css/panels.css index d3a4e5a..9600ce3 100644 --- a/web/css/panels.css +++ b/web/css/panels.css @@ -48,5 +48,12 @@ margin: auto; width: 90%; margin-bottom: 20px; + background-color: transparent; + } + .flex-phone { + display: flex; + } + .panel-90 { + margin-top: 100px; } } \ No newline at end of file diff --git a/web/index.html b/web/index.html index 4b738dc..8b24d28 100644 --- a/web/index.html +++ b/web/index.html @@ -53,18 +53,18 @@ -
-

-
+
+

+

- TP - TA + TP + TA
- +
- - MS + + MS

@@ -91,8 +91,18 @@
-
- +
+
+
+ +
+
+ +
+
+ +
+
@@ -101,16 +111,8 @@
-
+
-
@@ -124,7 +126,7 @@

-
+

@@ -144,6 +146,20 @@
+
+

+
+

+

+ TP + TA +
+ +
+ + MS +

+
diff --git a/web/js/main.js b/web/js/main.js index 901b032..4db8e91 100644 --- a/web/js/main.js +++ b/web/js/main.js @@ -3,7 +3,7 @@ var hostname = hostParts[0]; // Extract the hostname var port = hostParts[1] || '8080'; // Extract the port or use a default (e.g., 8080) var socketAddress = 'ws://' + hostname + ':' + port + '/text'; // Use 'wss' for secure WebSocket connections (recommended for external access) var socket = new WebSocket(socketAddress); - +var parsedData; const europe_programmes = [ "No PTY", "News", "Current Affairs", "Info", @@ -42,8 +42,8 @@ $(document).ready(function() { // Modify the WebSocket onmessage callback socket.onmessage = (event) => { - const parsedData = JSON.parse(event.data); - + parsedData = JSON.parse(event.data); + updatePanels(parsedData); // Push the new signal data to the array data.push(parsedData.signal); @@ -117,71 +117,6 @@ $(document).ready(function() { }; requestAnimationFrame(updateCanvas); } - - function updatePanels(parsedData) { - const sortedAf = parsedData.af.sort(compareNumbers); - const scaledArray = sortedAf.map(element => element / 1000); - const listContainer = $('#af-list'); - const scrollTop = listContainer.scrollTop(); - let ul = listContainer.find('ul'); - - if (!ul.length) { - ul = $(''); - listContainer.append(ul); - } - ul.html(''); - - const listItems = scaledArray.map(element => { - return $('
  • ').text(element.toFixed(1))[0]; - }); - - ul.append(listItems); - listContainer.scrollTop(scrollTop); - - $('#data-frequency').text(parsedData.freq); - $('#data-pi').html(parsedData.pi === '?' ? "?" : parsedData.pi); - $('#data-ps').html(parsedData.ps === '?' ? "?" : processString(parsedData.ps, parsedData.ps_errors)); - $('#data-tp').html(parsedData.tp === false ? "TP" : "TP"); - $('#data-ta').html(parsedData.ta === 0 ? "TA" : "TA"); - $('#data-ms').html(parsedData.ms === 0 - ? "MS" - : (parsedData.ms === -1 - ? "MS" - : "MS" - ) - ); - $('#data-pty').html(europe_programmes[parsedData.pty]); - $('#data-st').html(parsedData.st === false ? "ST" : "ST"); - $('#data-rt0').html(processString(parsedData.rt0, parsedData.rt0_errors)); - $('#data-rt1').html(processString(parsedData.rt1, parsedData.rt1_errors)); - $('#data-flag').html(''); - - const signalUnit = localStorage.getItem('signalUnit'); - let signalText = $('#signal-units'); - let signalValue; - - switch (signalUnit) { - case 'dbuv': - signalValue = parsedData.signal - 11.25; - signalText.text('dBµV'); - break; - - case 'dbm': - signalValue = parsedData.signal - 120; - signalText.text('dBm'); - break; - default: - signalValue = parsedData.signal; - signalText.text('dBf'); - break; - } - const integerPart = Math.floor(signalValue); - const decimalPart = (signalValue - integerPart).toFixed(1).slice(1); // Adjusted this line - - $('#data-signal').text(integerPart); - $('#data-signal-decimal').text(decimalPart); - $('#users-online').text(parsedData.users); - } signalToggle.on("change", function() { const signalText = localStorage.getItem('signalUnit'); @@ -201,7 +136,7 @@ $(document).ready(function() { const inputValue = textInput.val(); // Check if the user agent contains 'iPhone' if (/iPhone/i.test(navigator.userAgent) && socket.readyState === WebSocket.OPEN) { - socket.send(inputValue); + socket.send("T" + (inputValue * 1000)); // Clear the input field if needed textInput.val(''); } @@ -230,7 +165,7 @@ $(document).ready(function() { if (event.key === 'Enter') { const inputValue = textInput.val(); if (socket.readyState === WebSocket.OPEN) { - socket.send(inputValue); + socket.send("T" + (inputValue * 1000)); } textInput.val(''); } @@ -259,6 +194,14 @@ $(document).ready(function() { var piCodeContainer = $('#pi-code-container')[0]; var freqContainer = $('#freq-container')[0]; + $("#data-eq").click(function () { + toggleButtonState("eq"); + }); + + $("#data-ims").click(function () { + toggleButtonState("ims"); + }); + $(freqUpButton).on("click", tuneUp); $(freqDownButton).on("click", tuneDown); $(psContainer).on("click", copyPs); @@ -333,16 +276,16 @@ function checkKey(e) { if (socket.readyState === WebSocket.OPEN) { if (e.keyCode == '38') { - socket.send((currentFreq + 0.01).toFixed(2)); + socket.send("T" + ((currentFreq + 0.01).toFixed(2) * 1000)); } else if (e.keyCode == '40') { - socket.send((currentFreq - 0.01).toFixed(2)); + socket.send("T" + ((currentFreq - 0.01).toFixed(2) * 1000)); } else if (e.keyCode == '37') { - socket.send((currentFreq - 0.10).toFixed(1)); + socket.send("T" + ((currentFreq - 0.10).toFixed(1) * 1000)); } else if (e.keyCode == '39') { - socket.send((currentFreq + 0.10).toFixed(1)); + socket.send("T" + ((currentFreq + 0.10).toFixed(1) * 1000)); } } } @@ -350,14 +293,20 @@ function checkKey(e) { function tuneUp() { if (socket.readyState === WebSocket.OPEN) { getCurrentFreq(); - socket.send((currentFreq + 0.10).toFixed(1)); + socket.send("T" + ((currentFreq + 0.10).toFixed(1) * 1000)); } } function tuneDown() { if (socket.readyState === WebSocket.OPEN) { getCurrentFreq(); - socket.send((currentFreq - 0.10).toFixed(1)); + socket.send("T" + ((currentFreq - 0.10).toFixed(1) * 1000)); + } +} + +function tuneTo(freq) { + if (socket.readyState === WebSocket.OPEN) { + socket.send("T" + ((freq).toFixed(1) * 1000)); } } @@ -424,4 +373,122 @@ function findOnMaps() { var url = "https://maps.fmdx.pl/#qth=" + longitude + "," + latitude + "&freq=" + frequency + "&pi=" + pi; window.open(url, "_blank"); +} + +function updateSignalUnits(parsedData) { + const signalUnit = localStorage.getItem('signalUnit'); + let signalText = $('#signal-units'); + let signalValue; + + switch (signalUnit) { + case 'dbuv': + signalValue = parsedData.signal - 11.25; + signalText.text('dBµV'); + break; + + case 'dbm': + signalValue = parsedData.signal - 120; + signalText.text('dBm'); + break; + + default: + signalValue = parsedData.signal; + signalText.text('dBf'); + break; + } + + const integerPart = Math.floor(signalValue); + const decimalPart = (signalValue - integerPart).toFixed(1).slice(1); + + $('#data-signal').text(integerPart); + $('#data-signal-decimal').text(decimalPart); +} + +function updateDataElements(parsedData) { + $('#data-frequency').text(parsedData.freq); + $('#data-pi').html(parsedData.pi === '?' ? "?" : parsedData.pi); + $('#data-ps').html(parsedData.ps === '?' ? "?" : processString(parsedData.ps, parsedData.ps_errors)); + $('.data-tp').html(parsedData.tp === false ? "TP" : "TP"); + $('.data-ta').html(parsedData.ta === 0 ? "TA" : "TA"); + $('.data-ms').html(parsedData.ms === 0 + ? "MS" + : (parsedData.ms === -1 + ? "MS" + : "MS" + ) + ); + $('.data-pty').html(europe_programmes[parsedData.pty]); + $('.data-st').html(parsedData.st === false ? "ST" : "ST"); + $('#data-rt0').html(processString(parsedData.rt0, parsedData.rt0_errors)); + $('#data-rt1').html(processString(parsedData.rt1, parsedData.rt1_errors)); + $('.data-flag').html(``); +} + +let isEventListenerAdded = false; + +let updateCounter = 0; + +function updatePanels(parsedData) { + updateCounter++; + + const sortedAf = parsedData.af.sort(compareNumbers); + const scaledArray = sortedAf.map(element => element / 1000); + + const listContainer = $('#af-list'); + const scrollTop = listContainer.scrollTop(); + let ul = listContainer.find('ul'); + + if (!ul.length) { + ul = $(''); + listContainer.append(ul); + } + + if (updateCounter % 3 === 0) { + + updateButtonState("data-eq", parsedData.eq); + updateButtonState("data-ims", parsedData.ims); + + // Only update #af-list on every 3rd call + ul.html(''); + const listItems = scaledArray.map(createListItem); + ul.append(listItems); + + // Add the event listener only once + if (!isEventListenerAdded) { + ul.on('click', 'a', function () { + const frequency = parseFloat($(this).text()); + tuneTo(frequency); + }); + isEventListenerAdded = true; + } + + listContainer.scrollTop(scrollTop); + } + + // Update other elements every time + updateDataElements(parsedData); + updateSignalUnits(parsedData); + $('#users-online').text(parsedData.users); +} + +function createListItem(element) { + return $('
  • ').html(`${element.toFixed(1)}`)[0]; +} + +function updateButtonState(buttonId, value) { + var button = $("#" + buttonId); + if (value === 0) { + button.addClass("bg-gray"); + } else { + button.removeClass("bg-gray"); + } +} + +function toggleButtonState(buttonId) { + parsedData[buttonId] = 1 - parsedData[buttonId]; // Toggle between 0 and 1 + updateButtonState(buttonId, parsedData[buttonId]); + var message = "G"; + message += parsedData.eq ? "1" : "0"; + message += parsedData.ims ? "1" : "0"; + socket.send(message); } \ No newline at end of file