1
0
mirror of https://github.com/KubaPro010/fm-dx-webserver.git synced 2026-02-27 06:23:53 +01:00

bugfixes, ui improvements

This commit is contained in:
Marek Farkaš
2025-05-30 21:28:37 +02:00
parent 1c8b16d27b
commit 9d7e4297e3
10 changed files with 265 additions and 275 deletions

View File

@@ -41,7 +41,7 @@ function tuneDown() {
function tuneTo(freq) {
previousFreq = getCurrentFreq();
socket.send("T" + ((freq).toFixed(1) * 1000));
socket.send("T" + ((parseFloat(freq)).toFixed(1) * 1000));
}
function resetRDS() {

View File

@@ -11,9 +11,8 @@ $(document).ready(function() {
const chatNicknameSave = $('#chat-nickname-save');
$(".chatbutton").on("click", function () {
$("#popup-panel-chat").fadeIn(200, function () {
chatMessages.scrollTop(chatMessages[0].scrollHeight);
});
togglePopup("#popup-panel-chat");
chatMessages.scrollTop(chatMessages[0].scrollHeight);
});
// Function to generate a random string

View File

@@ -1,38 +0,0 @@
var currentDate = new Date('May 2, 2025 16:00:00');
var day = currentDate.getDate();
var month = currentDate.getMonth() + 1; // Months are zero-indexed, so add 1
var year = currentDate.getFullYear();
var formattedDate = day + '/' + month + '/' + year;
var currentVersion = 'v1.3.8 [' + formattedDate + ']';
getInitialSettings();
removeUrlParameters();
function getInitialSettings() {
$.ajax({
url: './static_data',
dataType: 'json',
success: function (data) {
['qthLatitude', 'qthLongitude', 'defaultTheme', 'bgImage', 'rdsMode', 'rdsTimeout'].forEach(key => {
if (data[key] !== undefined) {
localStorage.setItem(key, data[key]);
}
});
data.presets.forEach((preset, index) => {
localStorage.setItem(`preset${index + 1}`, preset);
});
},
error: function (error) {
console.error('Error:', error);
}
});
}
function removeUrlParameters() {
if (window.location.pathname === "/") {
var urlWithoutParams = window.location.protocol + "//" + window.location.host + window.location.pathname;
window.history.replaceState({ path: urlWithoutParams }, '', urlWithoutParams);
}
}

View File

@@ -64,17 +64,29 @@ $(document).ready(function () {
// Check if device is an iPhone to prevent zoom on button press
if (/iPhone|iPod|iPad/.test(navigator.userAgent) && !window.MSStream) {
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('touchstart', function(e) {
// Prevent default zoom behavior
e.preventDefault();
// Allow default button action after short delay
setTimeout(() => {
e.target.click();
}, 0);
});
// Handle touchstart for buttons to prevent zoom
$('.button').on('touchstart', function(e) {
e.preventDefault();
let target = this;
setTimeout(function() {
target.click();
}, 0);
});
// Prevent zooming on input focus by modifying the viewport
let $viewportMeta = $('meta[name=viewport]');
if ($viewportMeta.length) {
let content = $viewportMeta.attr('content');
let re = /maximum\-scale=[0-9\.]+/g;
if (re.test(content)) {
content = content.replace(re, 'maximum-scale=1.0');
} else {
content += ', maximum-scale=1.0';
}
$viewportMeta.attr('content', content);
}
}
const textInput = $('#commandinput');
@@ -83,7 +95,7 @@ $(document).ready(function () {
const inputValue = Number(textInput.val());
// Check if the user agent contains 'iPhone'
if (/iPhone/i.test(navigator.userAgent)) {
socket.send("T" + (Math.round(inputValue * 1000)));
tuneTo(inputValue);
// Clear the input field if needed
textInput.val('');
}
@@ -111,9 +123,8 @@ $(document).ready(function () {
}
}
if (event.key === 'Enter') {
const inputValue = textInput.val();
if (socket.readyState === WebSocket.OPEN) {
socket.send("T" + (Math.round(inputValue * 1000)));
tuneTo(textInput.val());
}
textInput.val('');
}
@@ -703,10 +714,12 @@ function checkKey(e) {
if ($options.length === 0) return; // No antennas available
// Find the currently selected antenna
let currentText = $input.attr("placeholder").trim();
let currentText = $input.val().trim();
let currentIndex = $options.index($options.filter(function () {
return $(this).text().trim() === currentText;
}));
console.log(currentIndex, currentText);
// Cycle to the next option
let nextIndex = (currentIndex + 1) % $options.length;
@@ -716,7 +729,6 @@ function checkKey(e) {
$input.attr("placeholder", $nextOption.text());
$input.data("value", $nextOption.data("value"));
// Send socket message (e.g., "Z0", "Z1", ...)
let socketMessage = "Z" + $nextOption.data("value");
socket.send(socketMessage);
break;
@@ -906,20 +918,19 @@ function throttle(fn, wait) {
}
function buildAltTxList(txList) {
const wrapper = '<div class="panel-100 flex-container flex-phone" style="background:none;backdrop-filter:none;">';
const wrapper = '<div class="panel-100-real m-0 flex-container flex-phone" style="background:none;backdrop-filter:none;">';
let outString = '';
outString += wrapper;
for (let i = 0; i < txList.length; i++) {
const tx = txList[i];
outString += `<div class="panel-50 hover-brighten no-bg-phone" style="min-height: 91px;">
<div id="data-station-container-${i}" style="display: block;">
outString += `<div class="panel-100-real m-0 hover-brighten no-bg-phone m-0 br-0 p-10" style="min-height: 72px;padding-left: 20px;">
<div id="data-station-container-${i}" style="display: block;" class="text-left">
<h2 style="margin-top: 0;" class="mb-0">
<span id="data-station-name-${i}">${tx.station.replace("R.", "Radio ").replace(/%/g, '%25')}</span>
</h2>
<h4 class="m-0">
<span id="data-station-city-${i}" style="font-size: 16px;">${tx.name}</span> <span class="text-small">[<span id="data-station-itu">G</span>]</span>
</h4>
<span class="text-small">
<span id="data-station-city-${i}" style="font-size: 16px;">${tx.name}</span> <span class="text-small">[<span id="data-station-itu-${i}">${tx.itu}</span>]</span>
<span class="text-small" style="opacity: 0.8;">
<span style="margin-left: 20px;">&nbsp;</span>
<span id="data-station-erp">${tx.erp}</span> kW [<span id="data-station-pol">${tx.pol.toUpperCase()}</span>] <span class="text-gray">•</span> <span id="data-station-distance">${tx.distanceKm.toFixed(0)} km</span> <span class="text-gray">•</span> <span id="data-station-azimuth">${tx.azimuth.toFixed(0)}°</span>
</span>
</div>

View File

@@ -43,13 +43,11 @@ $(document).ready(function() {
});
$(".tuner-mobile-settings").on("click", function () {
$(".popup-window").fadeOut(200);
$("#popup-panel-mobile-settings").fadeIn(200);
togglePopup("#popup-panel-mobile-settings");
});
$("#data-station-others").on("click", function () {
$(".popup-window").fadeOut(200);
$("#popup-panel-transmitters").fadeIn(200);
togglePopup("#popup-panel-transmitters");
});
});
@@ -66,4 +64,15 @@ function initPopups() {
$(".popup-close").on("click", function () {
$(".popup-window").fadeOut(200);
});
}
function togglePopup(targetSelector) {
const $target = $(targetSelector);
if ($target.is(":visible")) {
$target.fadeOut(200);
} else {
$(".popup-window").fadeOut(200);
$target.fadeIn(200);
}
}

View File

@@ -25,6 +25,112 @@ const signalUnits = {
};
$(document).ready(() => {
getInitialSettings();
$('#login-form').submit(function (event) {
event.preventDefault();
$.ajax({
type: 'POST',
url: './login',
data: $(this).serialize(),
success: function (data) {
sendToast('success', 'Login success!', data.message, false, true);
setTimeout(function () {
location.reload(true);
}, 1750);
},
error: function (xhr, status, error) {
if (xhr.status === 403) {
sendToast('error', 'Login failed!', xhr.responseJSON.message, false, true);
}
}
});
});
$('.logout-link').click(function (event) {
event.preventDefault();
$.ajax({
type: 'GET', // Assuming the logout is a GET request, adjust accordingly
url: './logout',
success: function (data) {
sendToast('success', 'Logout success!', data.message, false, true);
setTimeout(function () {
location.reload(true);
}, 1000);
},
error: function (xhr, status, error) {
if (xhr.status === 403) {
sendToast('error', 'Logout failed!', xhr.responseJSON.message, false, true);
}
}
});
});
});
function getQueryParameter(name) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
}
function setTheme(themeName) {
const themeColors = themes[themeName];
if (themeColors) {
// Extracting the RGBA components from themeColors[2] for --color-text-2
const rgbaComponentsText = themeColors[2].match(/(\d+(\.\d+)?)/g);
const opacityText = parseFloat(rgbaComponentsText[3]);
const newOpacityText = opacityText * 0.75;
const textColor2 = `rgba(${rgbaComponentsText[0]}, ${rgbaComponentsText[1]}, ${rgbaComponentsText[2]})`;
// Extracting the RGBA components from themeColors[0] for background color
const rgbaComponentsBackground = themeColors[3].match(/(\d+(\.\d+)?)/g);
const backgroundOpacity = 0.75;
const backgroundColorWithOpacity = `rgba(${rgbaComponentsBackground[0]}, ${rgbaComponentsBackground[1]}, ${rgbaComponentsBackground[2]}, ${backgroundOpacity})`;
$(':root').css('--color-main', themeColors[0]);
$(':root').css('--color-main-bright', themeColors[1]);
$(':root').css('--color-text', themeColors[2]);
$(':root').css('--color-text-2', textColor2);
$('.wrapper-outer').css('background-color', backgroundColorWithOpacity);
}
}
function setBg() {
const disableBackgroundParameter = getQueryParameter('disableBackground');
if(localStorage.getItem('bgImage').length > 5 && localStorage.getItem('theme') != 'theme9' && disableBackgroundParameter != 'true') {
$('body').css('background', 'url(' + localStorage.getItem('bgImage') + ') top center / cover fixed no-repeat var(--color-main)');
} else {
$('body').css('background', 'var(--color-main)');
}
}
function getInitialSettings() {
$.ajax({
url: './static_data',
dataType: 'json',
success: function (data) {
['qthLatitude', 'qthLongitude', 'defaultTheme', 'bgImage', 'rdsMode', 'rdsTimeout'].forEach(key => {
if (data[key] !== undefined) {
localStorage.setItem(key, data[key]);
}
});
data.presets.forEach((preset, index) => {
localStorage.setItem(`preset${index + 1}`, preset);
});
loadInitialSettings();
},
error: function (error) {
console.error('Error:', error);
}
});
}
function loadInitialSettings() {
const themeSelector = $('#theme-selector');
const savedTheme = localStorage.getItem('theme');
const defaultTheme = localStorage.getItem('defaultTheme');
@@ -70,62 +176,7 @@ $(document).ready(() => {
signalSelector.find('input').val($(event.target).text()); // Set the text of the clicked option to the input
localStorage.setItem('signalUnit', selectedSignalUnit);
});
$('#login-form').submit(function (event) {
event.preventDefault();
// Perform an AJAX request to the /login endpoint
$.ajax({
type: 'POST',
url: './login',
data: $(this).serialize(),
success: function (data) {
// Update the content on the page with the message from the response
sendToast('success', 'Login success!', data.message, false, true);
//$('#login-message').text(data.message);
setTimeout(function () {
location.reload(true);
}, 1750);
},
error: function (xhr, status, error) {
// Handle error response
if (xhr.status === 403) {
// Update the content on the page with the message from the error response
sendToast('error', 'Login failed!', xhr.responseJSON.message, false, true);
} else {
// Handle other types of errors if needed
console.error('Error:', status, error);
}
}
});
});
$('.logout-link').click(function (event) {
event.preventDefault();
$.ajax({
type: 'GET', // Assuming the logout is a GET request, adjust accordingly
url: './logout',
success: function (data) {
sendToast('success', 'Logout success!', data.message, false, true);
setTimeout(function () {
location.reload(true);
}, 1000);
},
error: function (xhr, status, error) {
// Handle error response
if (xhr.status === 403) {
// Update the content on the page with the message from the error response
sendToast('error', 'Logout failed!', xhr.responseJSON.message, false, true);
} else {
// Handle other types of errors if needed
console.error('Error:', status, error);
}
}
});
});
var extendedFreqRange = localStorage.getItem("extendedFreqRange");
if (extendedFreqRange === "true") {
$("#extended-frequency-range").prop("checked", true);
@@ -166,41 +217,4 @@ $(document).ready(() => {
$('.version-string').text(currentVersion);
setBg();
});
function getQueryParameter(name) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
}
function setTheme(themeName) {
const themeColors = themes[themeName];
if (themeColors) {
// Extracting the RGBA components from themeColors[2] for --color-text-2
const rgbaComponentsText = themeColors[2].match(/(\d+(\.\d+)?)/g);
const opacityText = parseFloat(rgbaComponentsText[3]);
const newOpacityText = opacityText * 0.75;
const textColor2 = `rgba(${rgbaComponentsText[0]}, ${rgbaComponentsText[1]}, ${rgbaComponentsText[2]})`;
// Extracting the RGBA components from themeColors[0] for background color
const rgbaComponentsBackground = themeColors[3].match(/(\d+(\.\d+)?)/g);
const backgroundOpacity = 0.75;
const backgroundColorWithOpacity = `rgba(${rgbaComponentsBackground[0]}, ${rgbaComponentsBackground[1]}, ${rgbaComponentsBackground[2]}, ${backgroundOpacity})`;
$(':root').css('--color-main', themeColors[0]);
$(':root').css('--color-main-bright', themeColors[1]);
$(':root').css('--color-text', themeColors[2]);
$(':root').css('--color-text-2', textColor2);
$('.wrapper-outer').css('background-color', backgroundColorWithOpacity);
}
}
function setBg() {
const disableBackgroundParameter = getQueryParameter('disableBackground');
if(localStorage.getItem('bgImage').length > 5 && localStorage.getItem('theme') != 'theme9' && disableBackgroundParameter != 'true') {
$('body').css('background', 'url(' + localStorage.getItem('bgImage') + ') top center / cover fixed no-repeat var(--color-main)');
} else {
$('body').css('background', 'var(--color-main)');
}
}
}

View File

@@ -1,3 +1,7 @@
const versionDate = new Date('May 30, 2025 21:00:00');
const currentVersion = `v1.3.9 [${versionDate.getDate()}/${versionDate.getMonth() + 1}/${versionDate.getFullYear()}]`;
function loadScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');