1
0
mirror of https://github.com/KubaPro010/fm-dx-webserver.git synced 2026-02-26 22:13:53 +01:00

bugfixes / sporadic e logging

This commit is contained in:
Marek Farkaš
2025-02-09 17:46:12 +01:00
parent b4928bcff8
commit ceb6e1bd11
14 changed files with 211 additions and 86 deletions

View File

@@ -302,7 +302,7 @@ pre {
position: absolute;
width: 16px;
height: 16px;
border: 2px solid var(--color-3);
border: 2px solid var(--color-text);
border-radius: 50%;
}

View File

@@ -333,6 +333,52 @@ select:hover {
background: var(--color-5);
}
.popup {
position: relative;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.popup .popup-content {
visibility: hidden;
width: 230px;
background-color: var(--color-2-transparent);
backdrop-filter: blur(5px);
color: var(--color-text);;
text-align: center;
border-radius: 15px;
padding: 8px;
position: absolute;
z-index: 1;
top: 125%;
left: 50%;
margin-left: -115px;
border: 3px solid var(--color-3);
}
.popup .show {
visibility: visible;
}
button[disabled] .popup-content {
visibility: hidden;
}
.popup .popup-content::after {
content: "";
position: absolute;
bottom: calc(100% + 3px);
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent var(--color-3) transparent;
}
@media only screen and (max-width: 768px) {
#tune-buttons input[type="text"] {
background-color: var(--color-1-transparent);

View File

@@ -4,7 +4,6 @@ body.modal-open {
.modal-panel, .modal-panel-chat {
max-height: 100vh;
overflow-y: auto;
}
.modal {
@@ -99,6 +98,7 @@ body.modal-open {
width: 64px;
background-color: var(--color-1);
cursor: pointer;
padding: 5px;
}
.modal-panel-content {

View File

@@ -70,9 +70,9 @@
<div id="flags-container-desktop" class="panel-33 user-select-none">
<h2 class="show-phone">
<div class="data-pty text-color-default"></div>
<div class="data-pty color-4"></div>
</h2>
<h3 style="margin-top:0;margin-bottom:0;" class="color-4 flex-center">
<h3 style="margin-top:0;margin-bottom:0;" class="text-color-default flex-center">
<span class="data-tp">TP</span>
<span style="margin-left: 15px;" class="data-ta">TA</span>
<div style="display:inline-block">
@@ -231,9 +231,16 @@
</div>
<% } %>
<% if (fmlist_integration == true) { %>
<button class="tooltip bg-color-4" id="log-fmlist"
<button class="tooltip bg-color-4 popup" id="log-fmlist"
data-tooltip="<strong>LOG TO FMLIST</strong><br>Clicking this button logs the current station to FMLIST's visual logbook." aria-label="Log to FMLIST"
style="width: 80px; height: 48px;margin-left: 15px !important;"><i class="fa-solid fa-flag fa-lg"></i></button>
style="width: 80px; height: 48px;margin-left: 15px !important;">
<i class="fa-solid fa-flag fa-lg"></i>
<span class="popup-content">
Choose the DX propagation type:<br>
<a class="top-10 bg-color-3 text-bold" style="padding: 10px; border-radius: 15px 0 0 15px; display: inline-block;" id="log-fmlist-tropo">Tropo</a><!--
--><a class="top-10 bg-color-3 text-bold" style="padding: 10px; border-radius: 0 15px 15px 0; display: inline-block;" id="log-fmlist-sporadice">Sporadic-E</a>
</span>
</button>
<% } %>
</div>
</div>
@@ -461,15 +468,15 @@
<div class="modal-panel-chat">
<div class="modal-panel-sidebar hover-brighten flex-center text-medium-big closeModal" role="button" aria-label="Close chat" tabindex="0"><i class="fa-solid fa-chevron-down"></i></div>
<div class="modal-panel-content text-left">
<div style="text-align: center;">
<input type="text" id="chat-nickname" name="chat-nickname" placeholder="Nickname">
<button class="br-0 w-100 top-10" style="height: 48px" id="chat-nickname-save">Save</button>
<p style="margin: 5px;">
<div style="text-align: center;white-space-collapse: collapse;">
<input type="text" id="chat-nickname" name="chat-nickname" placeholder="Nickname" style="border-radius: 15px 0 0 15px;padding-top:0;padding-bottom:0;border: 2px solid var(--color-4)">
<button class="br-0 w-100 top-10" style="height: 48px; border-radius: 0 15px 15px 0;margin-left:-3px;" id="chat-nickname-save">Save</button>
<p style="margin: 5px;" class="text-small">
Current identity: <span style="color: #bada55;" id="chat-admin"></span> <strong id="chat-identity-nickname"></strong>
</p>
</div>
<div id="chat-chatbox" class="bg-color-1" style="height: 270px;padding: 10px;overflow-y: auto;">
<div id="chat-chatbox" class="bg-color-1" style="height: 258px;padding: 10px;overflow-y: auto;">
</div>
<div class="flex-container flex-phone" style="align-content: stretch;">

View File

@@ -40,12 +40,18 @@ function OnPlayButtonClick(_ev) {
shouldReconnect = false;
destroyStream();
$playbutton.find('.fa-solid').toggleClass('fa-stop fa-play');
if ('audioSession' in navigator) {
navigator.audioSession.type = "none";
}
} else {
console.log("Starting stream...");
shouldReconnect = true;
createStream();
Stream.Start();
$playbutton.find('.fa-solid').toggleClass('fa-play fa-stop');
if ('audioSession' in navigator) {
navigator.audioSession.type = "playback"; // Android background play fix
}
}
$playbutton.addClass('bg-gray').prop('disabled', true);
setTimeout(() => {

View File

@@ -42,12 +42,28 @@ function populateFields(data, prefix = "") {
value = ""; // Convert null to an empty string
}
const id = `${prefix}${prefix ? "-" : ""}${key}`;
let id = `${prefix}${prefix ? "-" : ""}${key}`;
const $element = $(`#${id}`);
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
populateFields(value, id);
return;
if (typeof value === "object" && value !== null) {
if (Array.isArray(value)) {
// Handle arrays correctly
value.forEach((item, index) => {
const arrayId = `${id}-${index + 1}`;
const $arrayElement = $(`#${arrayId}`);
if ($arrayElement.length) {
$arrayElement.val(item);
} else {
console.log(`Element with id ${arrayId} not found`);
}
});
return;
} else {
// Handle nested objects
populateFields(value, id);
return;
}
}
if (!$element.length) {
@@ -64,16 +80,6 @@ function populateFields(data, prefix = "") {
} else {
$element.val(value);
}
if (key === "plugins" && Array.isArray(value)) {
const $options = $element.find('option');
$options.each(function() {
const dataName = $(this).data('name');
if (value.includes(dataName)) {
$(this).prop('selected', true);
}
});
}
});
}

View File

@@ -1,9 +1,9 @@
var currentDate = new Date('Jan 16, 2025 21:00:00');
var currentDate = new Date('Feb 9, 2025 18: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.3.1 [' + formattedDate + ']';
var currentVersion = 'v1.3.4 [' + formattedDate + ']';
getInitialSettings();
removeUrlParameters();

View File

@@ -204,35 +204,72 @@ $(document).ready(function () {
initTooltips();
//FMLIST logging
$('#log-fmlist').on('click', function() {
$.ajax({
url: './log_fmlist',
method: 'GET',
success: function(response) {
// Show a success toast with the response message
sendToast('success', 'Log successful', response, false, true);
},
error: function(xhr) {
let errorMessage;
// Handle different error status codes with custom messages
switch (xhr.status) {
case 429:
errorMessage = xhr.responseText;
break;
case 500:
errorMessage = 'Server error: ' + xhr.responseText || 'Internal Server Error';
break;
default:
errorMessage = xhr.statusText || 'An error occurred';
}
// Show an error toast with the specific error message
sendToast('error', 'Log failed', errorMessage, false, true);
}
});
$('.popup-content').on('click', function(event) {
event.stopPropagation();
$('.popup-content').removeClass('show');
});
$('#log-fmlist').on('click', function() {
const logKey = 'fmlistLogChoice';
const logTimestampKey = 'fmlistLogTimestamp';
const expirationTime = 10 * 60 * 1000;
const now = Date.now();
const storedChoice = localStorage.getItem(logKey);
const storedTimestamp = localStorage.getItem(logTimestampKey);
if (storedChoice && storedTimestamp && (now - storedTimestamp < expirationTime)) {
sendLog(storedChoice);
return;
}
if (parsedData.txInfo.dist > 700) {
$('#log-fmlist .popup-content').addClass('show'); // Show popup if no valid choice
$('#log-fmlist-sporadice').off('click').on('click', function () {
localStorage.setItem(logKey, './log_fmlist?type=sporadice');
localStorage.setItem(logTimestampKey, now);
if(parsedData.txInfo.dist > 700) sendLog('./log_fmlist?type=sporadice');
$('#log-fmlist .popup-content').removeClass('show');
});
$('#log-fmlist-tropo').off('click').on('click', function () {
localStorage.setItem(logKey, './log_fmlist?type=tropo');
localStorage.setItem(logTimestampKey, now);
if(parsedData.txInfo.dist > 700) sendLog('./log_fmlist?type=tropo');
$('#log-fmlist .popup-content').removeClass('show');
});
} else {
sendLog('./log_fmlist');
}
function sendLog(endpoint) {
$.ajax({
url: endpoint,
method: 'GET',
success: function(response) {
sendToast('success', 'Log successful', response, false, true);
},
error: function(xhr) {
let errorMessage;
switch (xhr.status) {
case 429:
errorMessage = xhr.responseText;
break;
case 500:
errorMessage = 'Server error: ' + (xhr.responseText || 'Internal Server Error');
break;
default:
errorMessage = xhr.statusText || 'An error occurred';
}
sendToast('error', 'Log failed', errorMessage, false, true);
}
});
}
});
});
function getServerTime() {
@@ -1040,40 +1077,55 @@ function toggleLock(buttonSelector, activeMessage, inactiveMessage, activeLabel,
function initTooltips() {
$('.tooltip').hover(function(e){
$('.tooltip').hover(function (e) {
// Check if hovered element is NOT `.popup-content`
if ($(e.target).closest('.popup-content').length) {
return;
}
var tooltipText = $(this).data('tooltip');
// Add a delay of 500 milliseconds before creating and appending the tooltip
// Delay tooltip appearance
$(this).data('timeout', setTimeout(() => {
var tooltip = $('<div class="tooltiptext"></div>').html(tooltipText);
if ($('.tooltiptext').length === 0) { $('body').append(tooltip); } // Don't allow more than one tooltip
if ($('.tooltip-wrapper').length === 0) {
var tooltip = $(`
<div class="tooltip-wrapper">
<div class="tooltiptext">
${tooltipText}
</div>
</div>
`);
$('body').append(tooltip);
}
var posX = e.pageX;
var posY = e.pageY;
var tooltipWidth = tooltip.outerWidth();
var tooltipHeight = tooltip.outerHeight();
var tooltipEl = $('.tooltiptext');
var tooltipWidth = tooltipEl.outerWidth();
var tooltipHeight = tooltipEl.outerHeight();
posX -= tooltipWidth / 2;
posY -= tooltipHeight + 10;
tooltip.css({ top: posY, left: posX, opacity: 1 }); // Set opacity to 1
// For touchscreen devices
if ((/Mobi|Android|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent)) && ('ontouchstart' in window || navigator.maxTouchPoints)) {
setTimeout(() => { $('.tooltiptext').remove(); }, 10000);
document.addEventListener('touchstart', function() { setTimeout(() => { $('.tooltiptext').remove(); }, 500); });
}
tooltipEl.css({ top: posY, left: posX, opacity: 1 });
}, 500));
}, function() {
// Clear the timeout if the mouse leaves before the delay completes
}, function () {
clearTimeout($(this).data('timeout'));
$('.tooltiptext').remove();
setTimeout(() => { $('.tooltiptext').remove(); }, 500); // Ensure no tooltips remain stuck
}).mousemove(function(e){
var tooltipWidth = $('.tooltiptext').outerWidth();
var tooltipHeight = $('.tooltiptext').outerHeight();
setTimeout(() => { $('.tooltip-wrapper').remove(); }, 500);
}).mousemove(function (e) {
var tooltipEl = $('.tooltiptext');
var tooltipWidth = tooltipEl.outerWidth();
var tooltipHeight = tooltipEl.outerHeight();
var posX = e.pageX - tooltipWidth / 2;
var posY = e.pageY - tooltipHeight - 10;
$('.tooltiptext').css({ top: posY, left: posX });
tooltipEl.css({ top: posY, left: posX });
});
// Prevent the tooltip from showing when hovering over .popup-content
$('.popup-content').on('mouseenter', function (e) {
clearTimeout($('.tooltip').data('timeout'));
$('.tooltip-wrapper').remove(); // Ensure tooltip does not appear
});
}
@@ -1085,4 +1137,4 @@ function fillPresets() {
tuneTo(Number(presetText));
});
}
}
}

View File

@@ -144,6 +144,11 @@
]
}) %>
</div>
<div class="panel-100 no-bg text-center">
<p>If you use an USB audio card on Linux, enabling this option might fix your audio issues.</p>
<%- include('_components', {component: 'checkbox', cssClass: 'panel-100 flex-container flex-center', label: 'ALSA Software mode', id: 'audio-softwareMode'}) %>
</div>
</div>
</div>
<!-- AUDIO SETTINGS END -->