You've already forked fm-dx-webserver
mirror of
https://github.com/KubaPro010/fm-dx-webserver.git
synced 2026-02-26 14:11:59 +01:00
ui, rds changes, bugfixes
This commit is contained in:
@@ -204,9 +204,11 @@ const clientUpdateIntervals = new Map(); // Store update intervals for each clie
|
||||
// Initialize the data object
|
||||
var dataToSend = {
|
||||
pi: '?',
|
||||
freq: 87.500.toFixed(3),
|
||||
freq: 87.500,
|
||||
previousFreq: 87.500,
|
||||
signal: 0,
|
||||
st: false,
|
||||
st_forced: false,
|
||||
ps: '',
|
||||
tp: false,
|
||||
ta: 0,
|
||||
@@ -243,7 +245,6 @@ function handleData(ws, receivedData) {
|
||||
const currentTime = Date.now();
|
||||
let modifiedData, parsedValue;
|
||||
const receivedLines = receivedData.split('\n');
|
||||
|
||||
for (const receivedLine of receivedLines) {
|
||||
switch (true) {
|
||||
case receivedLine.startsWith('P'):
|
||||
@@ -261,6 +262,7 @@ function handleData(ws, receivedData) {
|
||||
parsedValue = parseFloat(modifiedData);
|
||||
|
||||
if (!isNaN(parsedValue)) {
|
||||
initialData.freq = (parsedValue / 1000).toFixed(3);
|
||||
dataToSend.freq = (parsedValue / 1000).toFixed(3);
|
||||
dataToSend.pi = '?';
|
||||
}
|
||||
@@ -300,6 +302,9 @@ function handleData(ws, receivedData) {
|
||||
modifiedData = receivedLine.substring(2);
|
||||
parsedValue = parseFloat(modifiedData);
|
||||
dataToSend.st = false;
|
||||
dataToSend.st_forced = false;
|
||||
initialData.st = false;
|
||||
initialData.st_forced = false;
|
||||
|
||||
if (!isNaN(parsedValue)) {
|
||||
dataToSend.signal = parsedValue.toFixed(2);
|
||||
@@ -310,13 +315,41 @@ function handleData(ws, receivedData) {
|
||||
modifiedData = receivedData.substring(2);
|
||||
parsedValue = parseFloat(modifiedData);
|
||||
dataToSend.st = true;
|
||||
dataToSend.st_forced = false;
|
||||
initialData.st = true;
|
||||
initialData.st_forced = false;
|
||||
|
||||
if (!isNaN(parsedValue)) {
|
||||
dataToSend.signal = parsedValue.toFixed(2);
|
||||
initialData.signal = parsedValue.toFixed(2);
|
||||
}
|
||||
break;
|
||||
|
||||
case receivedData.startsWith('SS'):
|
||||
modifiedData = receivedData.substring(2);
|
||||
parsedValue = parseFloat(modifiedData);
|
||||
dataToSend.st = true;
|
||||
dataToSend.st_forced = true;
|
||||
initialData.st = true;
|
||||
initialData.st_forced = true;
|
||||
|
||||
if (!isNaN(parsedValue)) {
|
||||
dataToSend.signal = parsedValue.toFixed(2);
|
||||
initialData.signal = parsedValue.toFixed(2);
|
||||
}
|
||||
break;
|
||||
case receivedData.startsWith('SM'):
|
||||
modifiedData = receivedData.substring(2);
|
||||
parsedValue = parseFloat(modifiedData);
|
||||
dataToSend.st = false;
|
||||
dataToSend.st_forced = true;
|
||||
initialData.st = false;
|
||||
initialData.st_forced = true;
|
||||
|
||||
if (!isNaN(parsedValue)) {
|
||||
dataToSend.signal = parsedValue.toFixed(2);
|
||||
initialData.signal = parsedValue.toFixed(2);
|
||||
}
|
||||
break;
|
||||
case receivedLine.startsWith('R'):
|
||||
modifiedData = receivedLine.slice(1);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fm-dx-webserver",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.8",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -54,7 +54,7 @@ function parseAudioDevice(options, callback) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log('No matches found.');
|
||||
logWarn('No audio devices have been found.');
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
13
tx_search.js
13
tx_search.js
@@ -23,7 +23,7 @@ function fetchTx(freq, piCode, rdsPs) {
|
||||
return processData(cachedData[freq], piCode, rdsPs);
|
||||
}
|
||||
|
||||
const url = "https://maps.fmdx.pl/controller.php?freq=" + freq;
|
||||
const url = "https://maps.fmdx.pl/api?freq=" + freq;
|
||||
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
@@ -40,8 +40,9 @@ function fetchTx(freq, piCode, rdsPs) {
|
||||
function processData(data, piCode, rdsPs) {
|
||||
let matchingStation = null;
|
||||
let matchingCity = null;
|
||||
let minDistance = Infinity;
|
||||
let maxScore = -Infinity; // Initialize maxScore with a very low value
|
||||
let txAzimuth;
|
||||
let maxDistance;
|
||||
|
||||
for (const cityId in data.locations) {
|
||||
const city = data.locations[cityId];
|
||||
@@ -49,11 +50,13 @@ function processData(data, piCode, rdsPs) {
|
||||
for (const station of city.stations) {
|
||||
if (station.pi === piCode && !station.extra && station.ps && station.ps.toLowerCase().includes(rdsPs.replace(/ /g, '_').replace(/^_*(.*?)_*$/, '$1').toLowerCase())) {
|
||||
const distance = haversine(serverConfig.identification.lat, serverConfig.identification.lon, city.lat, city.lon);
|
||||
if (distance.distanceKm < minDistance) {
|
||||
minDistance = distance.distanceKm;
|
||||
const score = station.erp / distance.distanceKm; // Calculate score
|
||||
if (score > maxScore) {
|
||||
maxScore = score;
|
||||
txAzimuth = distance.azimuth;
|
||||
matchingStation = station;
|
||||
matchingCity = city;
|
||||
maxDistance = distance.distanceKm;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +70,7 @@ function processData(data, piCode, rdsPs) {
|
||||
erp: matchingStation.erp,
|
||||
city: matchingCity.name,
|
||||
itu: matchingCity.itu,
|
||||
distance: minDistance.toFixed(0),
|
||||
distance: maxDistance.toFixed(0),
|
||||
azimuth: txAzimuth.toFixed(0),
|
||||
foundStation: true
|
||||
};
|
||||
|
||||
@@ -94,10 +94,11 @@
|
||||
.modal-panel-content {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.modal-panel-content .version-info {
|
||||
margin-top: 75px;
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
@@ -229,10 +229,19 @@
|
||||
<li class="option" data-value="dbm">dBm</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div><br>
|
||||
|
||||
<div class="form-group checkbox">
|
||||
<input type="checkbox" id="extended-frequency-range">
|
||||
<label for="extended-frequency-range">Add decimals manually</label>
|
||||
</div>
|
||||
<div class="form-group checkbox">
|
||||
<input type="checkbox" id="ps-underscores">
|
||||
<label for="ps-underscores">Add undercores to RDS PS</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group bottom-20 hide-desktop" style="float: none;">
|
||||
<label for="themes"><i class="fa-solid fa-user"></i> Users online:</label>
|
||||
<label for="users-online"><i class="fa-solid fa-user"></i> Users online:</label>
|
||||
<span class="users-online" name="users-online">0</span>
|
||||
</div>
|
||||
|
||||
@@ -259,7 +268,7 @@
|
||||
|
||||
<div class="version-info">
|
||||
<p class="text-small">FM-DX WebServer <br>by <a href="https://noobish.eu" target="_blank">Noobish</a> & the OpenRadio community.</p>
|
||||
<span style="color: var(--color-3);">v1.0.6 [16/2/2024]</span>
|
||||
<span style="color: var(--color-3);">v1.0.7 [18/2/2024]</span>
|
||||
<p class="text-small bottom-50">
|
||||
<span class="text-smaller">librds & maps.fmdx.pl by <a href="https://fmdx.pl" target="_blank">Konrad Kosmatka</a></span><br>
|
||||
<span class="text-smaller">3LAS by <a href="https://github.com/JoJoBond/3LAS" target="_blank">JoJoBond</a></span><br>
|
||||
|
||||
@@ -2,9 +2,8 @@ var url = new URL('text', window.location.href);
|
||||
url.protocol = url.protocol.replace('http', 'ws');
|
||||
var socketAddress = url.href;
|
||||
var socket = new WebSocket(socketAddress);
|
||||
var parsedData;
|
||||
var parsedData, signalChart, previousFreq;
|
||||
var data = [];
|
||||
let signalChart;
|
||||
let updateCounter = 0;
|
||||
|
||||
const europe_programmes = [
|
||||
@@ -71,7 +70,8 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
textInput.on('keyup', function (event) {
|
||||
if (event.key !== 'Backspace') {
|
||||
|
||||
if (event.key !== 'Backspace' && localStorage.getItem('extendedFreqRange') != "true") {
|
||||
let inputValue = textInput.val();
|
||||
inputValue = inputValue.replace(/[^0-9.]/g, '');
|
||||
|
||||
@@ -174,17 +174,13 @@ function getInitialSettings() {
|
||||
}
|
||||
|
||||
function getLocalizedTime(serverTime) {
|
||||
// Convert server time to a Date object
|
||||
const serverDate = new Date(serverTime);
|
||||
|
||||
// Calculate local time by adding the offset
|
||||
const localTime = new Date(serverDate.getTime());
|
||||
|
||||
// Format local time
|
||||
|
||||
// Format server time using options for local time formatting
|
||||
const options = { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false };
|
||||
const formattedLocalTime = localTime.toLocaleString(navigator.language ? navigator.language : 'en-US', options);
|
||||
const formattedServerTime = serverDate.toLocaleString(navigator.language ? navigator.language : 'en-US', options);
|
||||
|
||||
return formattedLocalTime;
|
||||
return formattedServerTime;
|
||||
}
|
||||
|
||||
function getServerTime() {
|
||||
@@ -192,12 +188,8 @@ function getServerTime() {
|
||||
url: './server_time',
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
// Convert server time to local time format
|
||||
const localizedTimeServer = getLocalizedTime(data.serverTime);
|
||||
const localizedTimeClient = getLocalizedTime(new Date().toISOString());
|
||||
|
||||
$('#server-time').text(localizedTimeServer);
|
||||
$('#client-time').text(localizedTimeClient);
|
||||
$('#server-time').text(getLocalizedTime(data.serverTime));
|
||||
$('#client-time').text(getLocalizedTime(new Date()));
|
||||
},
|
||||
error: function (error) {
|
||||
console.error('Error:', error);
|
||||
@@ -389,6 +381,9 @@ function checkKey(e) {
|
||||
|
||||
if (socket.readyState === WebSocket.OPEN) {
|
||||
switch (e.keyCode) {
|
||||
case 66: // Back to previous frequency
|
||||
socket.send("T" + (previousFreq * 1000));
|
||||
break;
|
||||
case 82: // RDS Reset (R key)
|
||||
socket.send("T" + (currentFreq.toFixed(1) * 1000));
|
||||
break;
|
||||
@@ -408,6 +403,7 @@ function checkKey(e) {
|
||||
// Handle default case if needed
|
||||
break;
|
||||
}
|
||||
previousFreq = currentFreq;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,6 +567,9 @@ function updateDataElements(parsedData) {
|
||||
$('#data-frequency').text(parsedData.freq);
|
||||
$("#commandinput").attr("aria-label", "Current frequency: " + parsedData.freq);
|
||||
$('#data-pi').html(parsedData.pi === '?' ? "<span class='opacity-half'>?</span>" : parsedData.pi);
|
||||
if (localStorage.getItem('psUnderscores') === 'true') {
|
||||
parsedData.ps = parsedData.ps.replace(/\s/g, '_');
|
||||
}
|
||||
$('#data-ps').html(parsedData.ps === '?' ? "<span class='opacity-half'>?</span>" : processString(parsedData.ps, parsedData.ps_errors));
|
||||
$('.data-tp').html(parsedData.tp === false ? "<span class='opacity-half'>TP</span>" : "TP");
|
||||
$('.data-ta').html(parsedData.ta === 0 ? "<span class='opacity-half'>TA</span>" : "TA");
|
||||
@@ -582,15 +581,30 @@ function updateDataElements(parsedData) {
|
||||
)
|
||||
);
|
||||
$('.data-pty').html(europe_programmes[parsedData.pty]);
|
||||
$('.data-st').html(parsedData.st === false ? "<span class='text-gray'>ST</span>" : "ST");
|
||||
|
||||
|
||||
if(parsedData.st === true) {
|
||||
if (parsedData.st_forced == true) {
|
||||
$('.data-st').html("<span class='opacity-full'>MO</span>");
|
||||
} else {
|
||||
$('.data-st').html("<span class='opacity-full'>ST</span>");
|
||||
}
|
||||
} else {
|
||||
if (parsedData.st_forced == true) {
|
||||
$('.data-st').html("<span class='opacity-half'>MO</span>");
|
||||
} else {
|
||||
$('.data-st').html("<span class='opacity-half'>ST</span>");
|
||||
}
|
||||
}
|
||||
console.log(parsedData.st, parsedData.st_forced);
|
||||
|
||||
$('#data-rt0').html(processString(parsedData.rt0, parsedData.rt0_errors));
|
||||
$('#data-rt1').html(processString(parsedData.rt1, parsedData.rt1_errors));
|
||||
$('.data-flag').html(`<i title="${parsedData.country_name}" class="flag-sm flag-sm-${parsedData.country_iso}"></i>`);
|
||||
$('#data-ant input').val($('#data-ant li[data-value="' + parsedData.ant + '"]').text());
|
||||
|
||||
if (parsedData.txInfo.station.length > 1) {
|
||||
const sanitizedStation = parsedData.txInfo.station.replace(/%/g, '%25');
|
||||
$('#data-station-name').text(decodeURIComponent(sanitizedStation.replace(/\u009e/g, '\u017E')));
|
||||
$('#data-station-name').text(parsedData.txInfo.station.replace(/%/g, '%25'));
|
||||
$('#data-station-erp').text(parsedData.txInfo.erp);
|
||||
$('#data-station-city').text(parsedData.txInfo.city);
|
||||
$('#data-station-itu').text(parsedData.txInfo.itu);
|
||||
|
||||
@@ -104,6 +104,28 @@
|
||||
});
|
||||
});
|
||||
|
||||
var extendedFreqRange = localStorage.getItem("extendedFreqRange");
|
||||
if (extendedFreqRange === "true") {
|
||||
$("#extended-frequency-range").prop("checked", true);
|
||||
}
|
||||
|
||||
// Save the value of the checkbox into local storage when its state changes
|
||||
$("#extended-frequency-range").change(function() {
|
||||
var isChecked = $(this).is(":checked");
|
||||
localStorage.setItem("extendedFreqRange", isChecked);
|
||||
});
|
||||
|
||||
var extendedFreqRange = localStorage.getItem("psUnderscores");
|
||||
if (extendedFreqRange === "true") {
|
||||
$("#ps-underscores").prop("checked", true);
|
||||
}
|
||||
|
||||
// Save the value of the checkbox into local storage when its state changes
|
||||
$("#ps-underscores").change(function() {
|
||||
var isChecked = $(this).is(":checked");
|
||||
localStorage.setItem("psUnderscores", isChecked);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user