1
0
mirror of https://github.com/KubaPro010/fm-dx-webserver.git synced 2026-02-26 14:11:59 +01:00
This commit is contained in:
NoobishSVK
2024-04-06 00:40:12 +02:00
parent 05c8c641c0
commit 0d71f4437d
13 changed files with 24 additions and 34 deletions

View File

@@ -5,7 +5,7 @@ FM-DX Webserver is a cross-platform web server designed for FM DXers who want to
# Officially supported devices
- **TEF668x:** Supported with PE5PVB's and Konrad's FM-DX Tuner firmware, although Arduino versions with other firmwares will work too
- **XDR F1HD:** Officially supported, works best with Konrad's FM-DX Tuner firmware
- **SDR (AirSpy / RTL-SDR):** Supported unofficially via SDRSharp and XDR-GTK plugin
- **SDR (AirSpy / RTL-SDR):** Supported unofficially via SDRSharp and the XDR-GTK plugin
## Features
- **Web-Based Control:** Access and control your TEF6686 / F1HD receiver from any device with a web browser.
@@ -20,7 +20,7 @@ Check [here](https://trello.com/b/OAKo7n0Q/fm-dx-webserver) for an up to date ta
Join our **Discord community** to get the latest development update info, share feedback and receive support.
[<img alt="Join the OpenRadio Discord community!" src="https://i.imgur.com/lI9Tuxf.png" height="120">](https://discord.gg/ZAVNdS74mC)
## Getting Started
## Getting Started (Windows)
1. Install node.js from here:
```bash
@@ -46,6 +46,9 @@ Join our **Discord community** to get the latest development update info, share
5. Open your web browser and navigate to `http:/localhost:8080` to access the web interface.
## Getting Started (Linux)
[Click here for the Linux installation tutorial.](https://gist.github.com/bkram/788098558312d2fa71c07dc443e03d10)
## Utilized projects
This project utilizes these libraries:

View File

@@ -274,6 +274,7 @@ function handleData(ws, receivedData) {
if((modifiedData / 1000).toFixed(3) == dataToSend.freq) {
resetToDefault(dataToSend);
rdsparser.clear(rds);
dataToSend.af = [];
return; // Prevent tune spamming using scrollwheel
}

View File

@@ -141,15 +141,11 @@ function connectToXdrd() {
authFlags.authMsg = true;
logInfo('Authentication with xdrd successful.');
} else if (line.startsWith('G')) {
const [command, value] = line.split('');
switch (command) {
case 'G':
dataHandler.initialData.eq = value[1];
dataHandler.dataToSend.eq = value[1];
dataHandler.initialData.ims = value[0];
dataHandler.dataToSend.ims = value[0];
break;
}
const value = line.substring(1);
dataHandler.initialData.eq = value.charAt(0);
dataHandler.dataToSend.eq = value.charAt(0);
dataHandler.initialData.ims = value.charAt(1);
dataHandler.dataToSend.ims = value.charAt(1);
} else if (line.startsWith('Z')) {
let modifiedLine = line.slice(1);
dataHandler.initialData.ant = modifiedLine;

View File

@@ -36,7 +36,7 @@ function enableAudioStream() {
childProcess.stderr.on('data', (data) => {
logFfmpeg(`stderr: ${data}`);
if(data.includes('I/O error')) {
logError('Audio device \x1b[35m' + serverConfig.audio.audioDevice + '\x1b[0m failed to start. Start server with the command \x1b[33mnode . --ffmpegdebug \x1b[0mfor more info.')
logError('Audio device \x1b[35m' + serverConfig.audio.audioDevice + '\x1b[0m failed to start. Start server with the command \x1b[33mnode . --ffmpegdebug \x1b[0mfor more info.');
}
if(data.includes('size=') && startupSuccess === false) {
logInfo('Audio stream started up successfully.');

View File

@@ -16,7 +16,7 @@
position: absolute;
right: 10px;
top: 18px;
z-index: 9999;
z-index: 100;
width: 6px;
height: 6px;
border: 1px solid var(--color-main);

View File

@@ -420,7 +420,7 @@
<br>
<% if(ownerContact){ %>
<span>Owner contact:</span><br>
<span class="text-small m-0"><%= ownerContact %></span>
<span class="text-small m-0 bottom-20"><%= ownerContact %></span>
<% } %>
</div>
</div>
@@ -452,7 +452,7 @@
<input type="text" id="chat-nickname" name="chat-nickname" placeholder="Nickname">
<button class="br-0 w-100 top-10" style="height: 44px" id="chat-nickname-save">Save</button>
<p style="margin: 5px;">
Current identity: <span style="color: #bada55;" id="chat-admin"></span> <strong id="chat-identity-nickname">Anonymous User</strong>
Current identity: <span style="color: #bada55;" id="chat-admin"></span> <strong id="chat-identity-nickname"></strong>
</p>
</div>

View File

@@ -11,10 +11,10 @@ $(document).ready(function() {
chatSocket.onmessage = function(event) {
const messageData = JSON.parse(event.data);
const isAdmin = messageData.admin ? '<span style="color: lime">[ADMIN]</span>' : '';
const isAdmin = messageData.admin ? '<span style="color: #bada55">[ADMIN]</span>' : '';
if (messageData.type === 'clientIp') {
chatIdentityNickname.html(isAdmin + " " + savedNickname.length > 0 ? savedNickname : 'Anonymous User');
chatIdentityNickname.html(isAdmin + " " + (savedNickname.length > 0 ? savedNickname : 'Anonymous User'));
chatIdentityNickname.attr('title', messageData.ip);
} else {
const chatMessage = `

View File

@@ -254,7 +254,7 @@ function submitData() {
});
$('#audio-software-mode').prop("checked", data.audio.softwareMode || false);
$('#startup-volume').val(data.audio.startupVolume || 100);
$('#startup-volume').val(data.audio.startupVolume || 1);
$('#volume-percentage-value').text(data.audio.startupVolume !== undefined ? (data.audio.startupVolume * 100).toFixed(0) + '%' : '100%');
$('#webserver-name').val(data.identification.tunerName);

View File

@@ -1,4 +1,4 @@
var currentDate = new Date('March 28, 2024 22:00:00');
var currentDate = new Date('April 6, 2024 01:00:00');
var day = currentDate.getDate();
var month = currentDate.getMonth() + 1; // Months are zero-indexed, so add 1
var year = currentDate.getFullYear();
@@ -12,10 +12,8 @@ function getInitialSettings() {
url: './static_data',
dataType: 'json',
success: function (data) {
// Use the received data (data.qthLatitude, data.qthLongitude) as needed
localStorage.setItem('qthLatitude', data.qthLatitude);
localStorage.setItem('qthLongitude', data.qthLongitude);
localStorage.setItem('streamEnabled', data.streamEnabled);
localStorage.setItem('defaultTheme', data.defaultTheme);
localStorage.setItem('preset1', data.presets[0]);
localStorage.setItem('preset2', data.presets[1]);

View File

@@ -805,10 +805,10 @@ function createListItem(element) {
function updateButtonState(buttonId, value) {
var button = $("#" + buttonId);
if (value === 0) {
button.addClass("btn-disabled");
if (value == 0) {
button.hasClass("btn-disabled") ? null : button.addClass("btn-disabled");
} else {
button.removeClass("btn-disabled");
button.hasClass("btn-disabled") ? button.removeClass("btn-disabled") : null;
}
}

View File

@@ -24,7 +24,6 @@ const signalUnits = {
};
$(document).ready(() => {
// Theme Selector
const themeSelector = $('#theme-selector');
const savedTheme = localStorage.getItem('theme');
const defaultTheme = localStorage.getItem('defaultTheme');
@@ -47,7 +46,6 @@ $(document).ready(() => {
setBg();
});
// Signal Selector
const signalSelector = $('#signal-selector');
if (localStorage.getItem('signalUnit')) {
@@ -88,7 +86,6 @@ $(document).ready(() => {
});
});
// Assuming you have an anchor tag with id 'logout-link'
$('.logout-link').click(function (event) {
event.preventDefault();
@@ -97,11 +94,10 @@ $(document).ready(() => {
type: 'GET', // Assuming the logout is a GET request, adjust accordingly
url: './logout',
success: function (data) {
// Update the content on the page with the message from the response
$('#login-message').text(data.message);
setTimeout(function () {
location.reload(true);
}, 1750);
}, 1000);
},
error: function (xhr, status, error) {
// Handle error response
@@ -121,7 +117,6 @@ $(document).ready(() => {
$("#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);
@@ -137,7 +132,6 @@ $(document).ready(() => {
$("#smooth-signal").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);
@@ -160,7 +154,6 @@ function setTheme(themeName) {
// Extracting the RGBA components and opacity value
const rgbaComponents = themeColors[2].match(/(\d+(\.\d+)?)/g);
const opacity = parseFloat(rgbaComponents[3]);
// Calculating 80% of the opacity
const newOpacity = opacity * 0.75;
// Constructing the new RGBA string with the adjusted opacity
const textColor2 = `rgba(${rgbaComponents[0]}, ${rgbaComponents[1]}, ${rgbaComponents[2]}, ${newOpacity})`;

View File

@@ -10,7 +10,6 @@ $(document).ready(function() {
fetchData();
$('#startup-volume').on('change', function() {
console.log('changed');
var value = $(this).val(); // Get the value of the range input
var percentage = value * 100; // Convert to percentage
$('#volume-percentage-value').text(percentage.toFixed(0) + '%'); // Display the percentage value

View File

@@ -423,7 +423,7 @@
<div class="panel-75 auto" style="height: 48px;">
<input type="range" id="startup-volume" min="0" max="1" step="0.01" value="1" aria-label="Startup Volume slider">
</div>
<h3 class="top-25" id="volume-percentage-value">asdf</hš>
<h3 class="top-25" id="volume-percentage-value"></h3>
</div>
</div>