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

admin dashboard, bugfixes, cleanup

This commit is contained in:
NoobishSVK
2024-03-19 22:16:24 +01:00
parent fa20a50e3e
commit 9499d99c7b
12 changed files with 221 additions and 259 deletions

View File

@@ -50,7 +50,7 @@ h4 {
border-radius: 30px;
padding: 5px 25px;
z-index: 1000;
opacity:var(--color-main);
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
@@ -248,6 +248,42 @@ label {
opacity: 0; /* Make the overlay invisible */
}
.admin-quick-dashboard {
position: absolute;
top: 0;
bottom: 0;
left: -96px;
width: 96px;
height: 286px;
background-color: var(--color-2);
margin: auto 0;
border-radius: 30px;
padding-top: 15px;
}
.admin-quick-dashboard .icon {
width: 72px;
height: 72px;
margin: 10px auto;
color: var(--color-1);
background-color: var(--color-3);
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
border-radius: 10px;
transition: 0.3s ease-in-out background-color;
cursor: pointer;
}
.admin-quick-dashboard .icon.active {
background-color: var(--color-4);
}
.admin-quick-dashboard .icon:hover {
background-color: var(--color-5);
}
@media (max-width: 768px) {
canvas, #flags-container {
display: none;

View File

@@ -52,8 +52,10 @@
<audio id="audioTag"></audio>
<div id="wrapper">
<div class="panel-100 no-bg tuner-info">
<h1 id="tuner-name"><%= tunerName %> <% if (!publicTuner) { %><i class="fa-solid fa-key pointer" title="Only people with tune password can tune."></i>
<% } else if (tunerLock) { %><i class="fa-solid fa-lock pointer" title="Tuner is currently locked to admin."></i><% } %>
<h1 id="tuner-name"><%= tunerName %>
<% if (!publicTuner) { %><i class="fa-solid fa-key pointer tooltip" data-tooltip="Only people with tune password can tune."></i>
<% } if (tunerLock) { %><i class="fa-solid fa-lock pointer tooltip" data-tooltip="Tuner is currently locked to admin."></i>
<% } %>
</h1>
<p id="tuner-desc">
<%- tunerDesc %>
@@ -74,7 +76,7 @@
<div class="panel-10 no-bg h-100 m-0 m-right-20 hide-phone" style="width: 100px;margin-right: 20px !important;">
<button class="playbutton" aria-label="Play / Stop Button"><i class="fa-solid fa-play fa-lg"></i></button>
</div>
<div class="panel-100 m-0 hover-brighten flex-center" id="ps-container" style="height: 90px;" data-tooltip="Clicking on the RDS PS will copy the RDS info into the clipboard.">
<div class="panel-100 m-0 hover-brighten flex-center tooltip" id="ps-container" style="height: 90px;" data-tooltip="Clicking on the RDS PS will copy the RDS info into the clipboard.">
<span class="text-big" id="data-ps"></span>
</div>
</div>
@@ -91,7 +93,7 @@
</div>
<span id="stereo-container" class="pointer" style="position: relative;">
<span style="margin-left: 20px;" class="data-st">ST</span>
<span class="overlay" data-tooltip="Stereo / Mono toggle. <br><strong>Click to toggle."></span>
<span class="overlay tooltip" data-tooltip="Stereo / Mono toggle. <br><strong>Click to toggle."></span>
</span>
<span style="margin-left: 15px;" class="data-ms">MS</span>
</h3>
@@ -99,7 +101,7 @@
</div>
<div class="flex-container">
<div class="panel-33 hover-brighten" id="pi-code-container" data-tooltip="Clicking on the PI code will show the current station on a map.">
<div class="panel-33 hover-brighten tooltip" id="pi-code-container" data-tooltip="Clicking on the PI code will show the current station on a map.">
<h2>PI CODE</h2>
<span id="data-pi" class="text-big text-uppercase"></span>
</div>
@@ -144,12 +146,12 @@
<% } %>
<div class="panel-100 no-bg h-100 m-0 button-eq">
<% if (device == 'tef') { %><button id="data-eq" style="border-radius: 30px 0px 0px 30px;" aria-label="EQ Filter" data-tooltip="<strong>The cEQ filter can reduce bandwidth below 56 KHz.</strong><br><br>Useful for weak stations next to strong ones,<br>although it may pick up more interference."><span class="text-bold">cEQ</span></button><% } %>
<% if (device == 'xdr') { %><button id="data-eq" style="border-radius: 30px 0px 0px 30px;" aria-label="RF+ Filter" data-tooltip="<strong>The RF+ filter increases gain by 5dB</strong>"><span class="text-bold">RF+</span></button><% } %>
<% if (device == 'tef') { %><button id="data-eq" style="border-radius: 30px 0px 0px 30px;" class="tooltip" aria-label="EQ Filter" data-tooltip="<strong>The cEQ filter can reduce bandwidth below 56 KHz.</strong><br><br>Useful for weak stations next to strong ones,<br>although it may pick up more interference."><span class="text-bold">cEQ</span></button><% } %>
<% if (device == 'xdr') { %><button id="data-eq" style="border-radius: 30px 0px 0px 30px;" class="tooltip" aria-label="RF+ Filter" data-tooltip="<strong>The RF+ filter increases gain by 5dB</strong>"><span class="text-bold">RF+</span></button><% } %>
</div>
<div class="panel-100 no-bg h-100 m-0 button-ims">
<% if (device == 'tef') { %><button id="data-ims" style="border-radius: 0px 30px 30px 0px;" aria-label="iMS + Filter" data-tooltip="<strong>The iMS filter reduces multipath audio artifacts.</strong><br><br>It's recommended to leave it on most of the time."><span class="text-bold">iMS</span></button><% } %>
<% if (device == 'xdr') { %><button id="data-ims" style="border-radius: 0px 30px 30px 0px;" aria-label="IF+ Filter" data-tooltip="<strong>The IF+ filter increases gain by 6dB</strong>"><span class="text-bold">IF+</span></button><% } %>
<% if (device == 'tef') { %><button id="data-ims" style="border-radius: 0px 30px 30px 0px;" class="tooltip" aria-label="iMS + Filter" data-tooltip="<strong>The iMS filter reduces multipath audio artifacts.</strong><br><br>It's recommended to leave it on most of the time."><span class="text-bold">iMS</span></button><% } %>
<% if (device == 'xdr') { %><button id="data-ims" style="border-radius: 0px 30px 30px 0px;" class="tooltip" aria-label="IF+ Filter" data-tooltip="<strong>The IF+ filter increases gain by 6dB</strong>"><span class="text-bold">IF+</span></button><% } %>
</div>
</div>
</div>
@@ -173,7 +175,7 @@
<hr class="hide-desktop">
</div>
<div class="panel-33 hover-brighten" data-tooltip="This panel contains the current TX info when RDS is loaded.<br><strong>Clicking on this panel copies the info into the clipboard.</strong>">
<div class="panel-33 hover-brighten tooltip" data-tooltip="This panel contains the current TX info when RDS is loaded.<br><strong>Clicking on this panel copies the info into the clipboard.</strong>">
<div id="data-station-container">
<h2 style="margin-top: 0;" class="mb-0">
<span id="data-station-name"></span>
@@ -228,6 +230,20 @@
<% } %>
<button id="users-online-container" class="hide-phone" aria-label="Online users"><i class="fa-solid fa-user"></i> <span class="users-online"></span></button>
<% if (isAdminAuthenticated) { %>
<div class="admin-quick-dashboard hide-phone">
<div class="icon tooltip <% if (tunerLock) { %>active<% } %>" id="dashboard-lock-admin" onClick="toggleAdminLock()" data-tooltip="Toggle admin lock<br>Lasts until restart">
<i class="fa-solid fa-lock"></i>
</div>
<div class="icon tooltip <% if (!publicTuner) { %>active<% } %>" id="dashboard-lock-tune" onClick="togglePasswordLock()" data-tooltip="Toggle password lock<br>Lasts until restart">
<i class="fa-solid fa-key"></i>
</div>
<div class="icon tooltip" data-tooltip="Go to admin menu" onClick="window.open('./setup', '_blank').focus();">
<i class="fa-solid fa-user"></i>
</div>
</div>
<% } %>
<div id="myModal" class="modal">
<div class="modal-panel">
<div class="flex-container flex-phone" style="height: calc(100% - 100px)">
@@ -285,7 +301,7 @@
<% if (isAdminAuthenticated) { %>
<p>You are logged in as an adminstrator.<br>
<a href="./setup">Setup</a> • <a class="logout-link" href="#">Logout</a>
<a href="./setup" target="_blank">Setup</a> • <a class="logout-link" href="#">Logout</a>
</p>
<% } else if (isTuneAuthenticated) { %>
<p>You are logged in and can control the receiver.<br><a class="logout-link" href="#">Logout</a></p>
@@ -360,9 +376,5 @@
</div>
<script src="js/webserver.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/screenshot-capture/2.0.0/screenshot-capture.min.js"></script>
</body>
</html>

View File

@@ -45,6 +45,8 @@ function submitData() {
return $(this).text() === $('#device-type').val();
}).data('value') || "tef");
const softwareMode = $('#audio-software-mode').is("checked") || false;
const tunerName = $('#webserver-name').val() || 'FM Tuner';
const tunerDesc = $('#webserver-desc').val() || 'Default FM tuner description';
const broadcastTuner = $("#broadcast-tuner").is(":checked");
@@ -84,6 +86,7 @@ function submitData() {
audioDevice,
audioChannels,
audioBitrate,
softwareMode,
},
identification: {
tunerName,
@@ -202,6 +205,8 @@ function submitData() {
$("#audio-quality").val(selectedQuality.text());
}
$('#audio-software-switch').prop("checked", data.audio.softwareMode || false);
$('#webserver-name').val(data.identification.tunerName);
$('#webserver-desc').val(data.identification.tunerDesc);
$("#broadcast-tuner").prop("checked", data.identification.broadcastTuner);

View File

@@ -28,6 +28,21 @@ const usa_programmes = [
$(document).ready(function () {
var canvas = $('#signal-canvas')[0];
var $panel = $('.admin-quick-dashboard');
var panelWidth = $panel.outerWidth();
$(document).mousemove(function(e) {
var mouseX = e.pageX;
var panelLeft = parseInt($panel.css('left'));
if (mouseX <= 10 || (panelLeft === 4 && mouseX <= 100)) {
$panel.css('left', '4px');
} else {
$panel.css('left', -panelWidth);
}
});
canvas.width = canvas.parentElement.clientWidth;
canvas.height = canvas.parentElement.clientHeight;
@@ -49,9 +64,9 @@ $(document).ready(function () {
const textInput = $('#commandinput');
textInput.on('change', function (event) {
const inputValue = textInput.val();
const inputValue = Number(textInput.val());
// Check if the user agent contains 'iPhone'
if (/iPhone/i.test(navigator.userAgent) && socket.readyState === WebSocket.OPEN) {
if (/iPhone/i.test(navigator.userAgent)) {
socket.send("T" + (inputValue * 1000));
// Clear the input field if needed
textInput.val('');
@@ -384,26 +399,7 @@ function checkKey(e) {
case 82: // RDS Reset (R key)
tuneTo(Number(currentFreq));
break;
case 83: // Screenshot (S key)
screenshotCapture.capture().then(function (dataUrl) {
// Create an input element to hold the data URL temporarily
var aux = $('<input>').attr({
type: 'text',
value: dataUrl
});
// Append the input element to the body, select its contents, and copy them to the clipboard
$('body').append(aux);
aux.select();
document.execCommand('copy');
aux.remove();
// Alert the user that the screenshot has been copied to the clipboard
alert('Screenshot copied to clipboard!');
}).catch(function (error) {
console.error('Error capturing screenshot:', error);
});
case 83: // Screenshot (S key)
break;
case 38:
socket.send("T" + (Math.round(currentFreq*1000) + ((currentFreq > 30) ? 10 : 1)));
@@ -758,19 +754,51 @@ function toggleForcedStereo() {
socket.send(message);
}
function toggleAdminLock() {
let $adminLockButton = $('#dashboard-lock-admin');
if($adminLockButton.hasClass('active')) {
socket.send('wL0');
$adminLockButton.removeClass('active');
} else {
socket.send('wL1');
$adminLockButton.addClass('active');
}
}
function togglePasswordLock() {
let $passwordLockButton = $('#dashboard-lock-tune');
if($passwordLockButton.hasClass('active')) {
socket.send('wT0');
$passwordLockButton.removeClass('active');
} else {
socket.send('wT1');
$passwordLockButton.addClass('active');
}
}
function initTooltips() {
$('[data-tooltip]').hover(function(e){
$('.tooltip').hover(function(e){
var tooltipText = $(this).data('tooltip');
var tooltip = $('<div class="tooltiptext"></div>').html(tooltipText);
$('body').append(tooltip);
// Add a delay of 500 milliseconds before creating and appending the tooltip
$(this).data('timeout', setTimeout(() => {
var tooltip = $('<div class="tooltiptext"></div>').html(tooltipText);
$('body').append(tooltip);
var tooltipWidth = tooltip.outerWidth();
var tooltipHeight = tooltip.outerHeight();
var posX = e.pageX - tooltipWidth / 2;
var posY = e.pageY - tooltipHeight - 10;
var posX = e.pageX;
var posY = e.pageY;
tooltip.css({ top: posY, left: posX, opacity: 0.9 });
var tooltipWidth = tooltip.outerWidth();
var tooltipHeight = tooltip.outerHeight();
posX -= tooltipWidth / 2;
posY -= tooltipHeight + 10;
tooltip.css({ top: posY, left: posX, opacity: 1 }); // Set opacity to 1
}, 500));
}, function() {
// Clear the timeout if the mouse leaves before the delay completes
clearTimeout($(this).data('timeout'));
$('.tooltiptext').remove();
}).mousemove(function(e){
var tooltipWidth = $('.tooltiptext').outerWidth();
@@ -780,4 +808,4 @@ function initTooltips() {
$('.tooltiptext').css({ top: posY, left: posX });
});
}
}

View File

@@ -3,7 +3,7 @@ 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.1.4 [' + formattedDate + ']';
var currentVersion = 'v1.1.5 [' + formattedDate + ']';
/**

View File

@@ -237,6 +237,11 @@
</ul>
</div>
</div>
<div class="form-group checkbox bottom-20">
<input type="checkbox" id="audio-software-switch">
<label for="audio-software-switch">ALSA software mode (plughw) - LINUX ONLY</label>
</div>
</div>
</div>
@@ -352,6 +357,7 @@
<li class="option" data-value="tef">TEF668x / TEA685x</li>
<li class="option" data-value="xdr">XDR (F1HD / S10HDiP)</li>
<li class="option" data-value="sdr">SDR (RTL-SDR / AirSpy)</li>
<li class="option" data-value="sdr">Other</li>
</ul>
</div>
</div>

View File

@@ -61,6 +61,7 @@
<li class="option" data-value="tef">TEF668x / TEA685x</li>
<li class="option" data-value="xdr">XDR (F1HD / S10HDiP)</li>
<li class="option" data-value="sdr">SDR (RTL-SDR / AirSpy)</li>
<li class="option" data-value="other">Other</li>
</ul>
</div>
</div>