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

bugfixes & plugins WS & UI fixes

This commit is contained in:
NoobishSVK
2024-09-12 21:30:12 +02:00
parent 0fa3e85258
commit 51121132d5
12 changed files with 111 additions and 95 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "fm-dx-webserver", "name": "fm-dx-webserver",
"version": "1.2.8", "version": "1.2.8.1",
"description": "FM DX Webserver", "description": "FM DX Webserver",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@@ -234,7 +234,9 @@ var dataToSend = {
itu: '', itu: '',
dist: '', dist: '',
azi: '', azi: '',
id: '' id: '',
reg: '',
pi: '',
}, },
country_name: '', country_name: '',
country_iso: 'UN', country_iso: 'UN',
@@ -294,6 +296,7 @@ function handleData(wss, receivedData, rdsWss) {
initialData.freq = (parsedValue / 1000).toFixed(3); initialData.freq = (parsedValue / 1000).toFixed(3);
dataToSend.freq = (parsedValue / 1000).toFixed(3); dataToSend.freq = (parsedValue / 1000).toFixed(3);
dataToSend.pi = '?'; dataToSend.pi = '?';
dataToSend.txInfo.reg = false;
rdsWss.clients.forEach((client) => { rdsWss.clients.forEach((client) => {
client.send("G:\r\nRESET-------\r\n\r\n"); client.send("G:\r\nRESET-------\r\n\r\n");
@@ -401,7 +404,9 @@ function handleData(wss, receivedData, rdsWss) {
itu: currentTx.itu, itu: currentTx.itu,
dist: currentTx.distance, dist: currentTx.distance,
azi: currentTx.azimuth, azi: currentTx.azimuth,
id: currentTx.id id: currentTx.id,
pi: currentTx.pi,
reg: currentTx.reg
} }
} }

View File

@@ -1,6 +1,3 @@
// index.js - Mod by Highpoint
// Version for loading server-side plugins
// Library imports // Library imports
const express = require('express'); const express = require('express');
const endpoints = require('./endpoints'); const endpoints = require('./endpoints');
@@ -15,7 +12,7 @@ const WebSocket = require('ws');
const wss = new WebSocket.Server({ noServer: true }); const wss = new WebSocket.Server({ noServer: true });
const chatWss = new WebSocket.Server({ noServer: true }); const chatWss = new WebSocket.Server({ noServer: true });
const rdsWss = new WebSocket.Server({ noServer: true }); const rdsWss = new WebSocket.Server({ noServer: true });
const ExtraWss = new WebSocket.Server({ noServer: true }); const pluginsWss = new WebSocket.Server({ noServer: true });
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const net = require('net'); const net = require('net');
@@ -537,14 +534,14 @@ rdsWss.on('connection', (ws, request) => {
}); });
//additional web socket for using plugins //additional web socket for using plugins
ExtraWss.on('connection', (ws, request) => { pluginsWss.on('connection', (ws, request) => {
ws.on('message', message => { ws.on('message', message => {
const messageData = JSON.parse(message); const messageData = JSON.parse(message);
const modifiedMessage = JSON.stringify(messageData); const modifiedMessage = JSON.stringify(messageData);
//Broadcast the message to all other clients //Broadcast the message to all other clients
ExtraWss.clients.forEach(client => { pluginsWss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) { if (client.readyState === WebSocket.OPEN) {
client.send(modifiedMessage); // Send the message to all clients client.send(modifiedMessage); // Send the message to all clients
} }
@@ -582,10 +579,10 @@ httpServer.on('upgrade', (request, socket, head) => {
rdsWss.emit('connection', ws, request); rdsWss.emit('connection', ws, request);
}); });
}); });
} else if (request.url === '/extra') { } else if (request.url === '/data_plugins') {
sessionMiddleware(request, {}, () => { sessionMiddleware(request, {}, () => {
ExtraWss.handleUpgrade(request, socket, head, (ws) => { pluginsWss.handleUpgrade(request, socket, head, (ws) => {
ExtraWss.emit('connection', ws, request); pluginsWss.emit('connection', ws, request);
}); });
}); });
} else { } else {
@@ -599,25 +596,28 @@ app.use(express.static(path.join(__dirname, '../web'))); // Serve the entire web
checkIPv6Support((isIPv6Supported) => { checkIPv6Support((isIPv6Supported) => {
const ipv4Address = serverConfig.webserver.webserverIp === '0.0.0.0' ? 'localhost' : serverConfig.webserver.webserverIp; const ipv4Address = serverConfig.webserver.webserverIp === '0.0.0.0' ? 'localhost' : serverConfig.webserver.webserverIp;
const ipv6Address = '::'; // This will bind to all available IPv6 interfaces const ipv6Address = '::'; // This will bind to all available IPv6 interfaces
const port = serverConfig.webserver.webserverPort;
if (isIPv6Supported) {
// Start server on both IPv4 and IPv6 addresses
httpServer.listen(serverConfig.webserver.webserverPort, ipv4Address, () => {
logInfo(`Web server has started on address \x1b[34mhttp://${ipv4Address}:${serverConfig.webserver.webserverPort}\x1b[0m.`);
});
httpServer.listen(serverConfig.webserver.webserverPort, ipv6Address, () => { const logServerStart = (address, isIPv6) => {
logInfo(`Web server has started on address \x1b[34mhttp://[${ipv6Address}]:${serverConfig.webserver.webserverPort}\x1b[0m.`); const formattedAddress = isIPv6 ? `[${address}]` : address;
}); logInfo(`Web server has started on address \x1b[34mhttp://${formattedAddress}:${port}\x1b[0m.`);
} else { };
// Start server only on IPv4 address
httpServer.listen(serverConfig.webserver.webserverPort, ipv4Address, () => { const startServer = (address, isIPv6) => {
if (configExists()) { httpServer.listen(port, address, () => {
logInfo(`Web server has started on address \x1b[34mhttp://${ipv4Address}:${serverConfig.webserver.webserverPort}\x1b[0m.`); if (!isIPv6 && !configExists()) {
logInfo(`Open your browser and proceed to \x1b[34mhttp://${address}:${port}\x1b[0m to continue with setup.`);
} else { } else {
logInfo(`Open your browser and proceed to \x1b[34mhttp://${ipv4Address}:${serverConfig.webserver.webserverPort}\x1b[0m to continue with setup.`); logServerStart(address, isIPv6);
} }
}); });
};
if (isIPv6Supported) {
startServer(ipv4Address, false); // Start on IPv4
startServer(ipv6Address, true); // Start on IPv6
} else {
startServer(ipv4Address, false); // Start only on IPv4
} }
}); });

View File

@@ -50,42 +50,69 @@ function processData(data, piCode, rdsPs) {
let txAzimuth; let txAzimuth;
let maxDistance; let maxDistance;
let esMode = checkEs(); let esMode = checkEs();
let detectedByPireg = false; // To track if the station was found by pireg
// Helper function to calculate score and update matching station/city
function evaluateStation(station, city, distance) {
let weightDistance = distance.distanceKm;
if (esMode && distance.distanceKm > 500) {
weightDistance = Math.abs(distance.distanceKm - 1500);
}
let erp = station.erp && station.erp > 0 ? station.erp : 1;
const score = (10 * Math.log10(erp * 1000)) / weightDistance; // Calculate score
if (score > maxScore) {
maxScore = score;
txAzimuth = distance.azimuth;
matchingStation = station;
matchingCity = city;
maxDistance = distance.distanceKm;
}
}
// First attempt: Try to match station using the piCode
for (const cityId in data.locations) { for (const cityId in data.locations) {
const city = data.locations[cityId]; const city = data.locations[cityId];
if (city.stations) { if (city.stations) {
for (const station of city.stations) { for (const station of city.stations) {
if (station.pi === piCode.toUpperCase() && !station.extra && station.ps && station.ps.toLowerCase().includes(rdsPs.replace(/ /g, '_').replace(/^_*(.*?)_*$/, '$1').toLowerCase())) { if (station.pi === piCode.toUpperCase() && !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); const distance = haversine(serverConfig.identification.lat, serverConfig.identification.lon, city.lat, city.lon);
let weightDistance = distance.distanceKm evaluateStation(station, city, distance);
if (esMode && (distance.distanceKm > 500)) { detectedByPireg = false; // Detected by pi, not pireg
weightDistance = Math.abs(distance.distanceKm-1500); }
} }
let erp = (station.erp && station.erp > 0) ? station.erp : 1; }
const score = (10*Math.log10(erp*1000)) / weightDistance; // Calculate score }
if (score > maxScore) {
maxScore = score; // If no matching station is found, fallback to pireg
txAzimuth = distance.azimuth; if (!matchingStation) {
matchingStation = station; for (const cityId in data.locations) {
matchingCity = city; const city = data.locations[cityId];
maxDistance = distance.distanceKm; if (city.stations) {
for (const station of city.stations) {
if (station.pireg && station.pireg.toUpperCase() === piCode.toUpperCase() && !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);
evaluateStation(station, city, distance);
detectedByPireg = true; // Detected by pireg
} }
} }
} }
} }
} }
// Return the results if a station was found, otherwise return undefined
if (matchingStation) { if (matchingStation) {
return { return {
station: matchingStation.station.replace("R.", "Radio "), station: matchingStation.station.replace("R.", "Radio "),
pol: matchingStation.pol.toUpperCase(), pol: matchingStation.pol.toUpperCase(),
erp: (matchingStation.erp && matchingStation.erp > 0) ? matchingStation.erp : '?', erp: matchingStation.erp && matchingStation.erp > 0 ? matchingStation.erp : '?',
city: matchingCity.name, city: matchingCity.name,
itu: matchingCity.itu, itu: matchingCity.itu,
distance: maxDistance.toFixed(0), distance: maxDistance.toFixed(0),
azimuth: txAzimuth.toFixed(0), azimuth: txAzimuth.toFixed(0),
id: matchingStation.id, id: matchingStation.id,
foundStation: true pi: matchingStation.pi,
foundStation: true,
reg: detectedByPireg // Indicates if it was detected by pireg
}; };
} else { } else {
return; return;

View File

@@ -82,6 +82,10 @@ input[type="text"], textarea, input[type="password"] {
caret-color: var(--color-4); caret-color: var(--color-4);
} }
input[type="password"]:not(#xdrd-password) {
border-radius: 15px 0 0 15px;
}
#tune-buttons input[type="text"] { #tune-buttons input[type="text"] {
width: 50%; width: 50%;
height: 48px; height: 48px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -93,6 +93,9 @@
<div class="flex-container"> <div class="flex-container">
<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."> <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> <h2>PI CODE</h2>
<div class="text-small text-gray highest-signal-container">
<span id="data-regular-pi">&nbsp;</span>
</div>
<span id="data-pi" class="text-big text-uppercase"></span> <span id="data-pi" class="text-big text-uppercase"></span>
</div> </div>
@@ -261,7 +264,7 @@
<span id="data-station-city" style="font-size: 16px;"></span> <span class="text-small">[<span id="data-station-itu"></span>]</span> <span id="data-station-city" style="font-size: 16px;"></span> <span class="text-small">[<span id="data-station-itu"></span>]</span>
</h4> </h4>
<span class="text-small"> <span class="text-small">
<span id="data-station-erp"></span> kW [<span id="data-station-pol"></span>] <span class="text-gray">•</span> <span id="data-station-distance"></span> km <span class="text-gray">•</span> <span id="data-station-azimuth"></span>° <span id="data-station-erp"></span> kW [<span id="data-station-pol"></span>] <span class="text-gray">•</span> <span id="data-station-distance"></span> km <span class="text-gray">•</span> <span id="data-station-azimuth"></span>
</span> </span>
</div> </div>
</div> </div>
@@ -395,7 +398,7 @@
<% } else { %> <% } else { %>
<form action="./login" method="post" id="login-form" class="top-25"> <form action="./login" method="post" id="login-form" class="top-25">
<input type="password" id="password" name="password" placeholder="Password" style="width: 145px;" required> <input type="password" id="password" name="password" placeholder="Password" style="width: 145px;" required>
<button type="submit" class="br-0 top-10 tooltip" style="height: 46px; width: 50px; margin-left: 0;" role="button" aria-label="Log in" tabindex="0" data-tooltip="Log in"> <button type="submit" class="br-0 top-10 tooltip" style="height: 46px; width: 50px; margin-left: -2px;border-radius: 0 15px 15px 0;" role="button" aria-label="Log in" tabindex="0" data-tooltip="Log in">
<i class="fa-solid fa-right-to-bracket"></i> <i class="fa-solid fa-right-to-bracket"></i>
</button> </button>
</form> </form>
@@ -436,7 +439,7 @@
<p class="m-0"> <p class="m-0">
FM-DX Webserver <span style="color: var(--color-3);" class="version-string"></span> FM-DX Webserver <span style="color: var(--color-3);" class="version-string"></span>
</p> </p>
<p class="text-small m-0 color-3">by <a href="https://noobish.eu" target="_blank">Noobish</a>, <a href="https://fmdx.pl" target="_blank">kkonradpl</a> & the OpenRadio community.</p> <p class="text-small m-0 color-3">by <a href="https://fmdx.org" target="_blank">FMDX.org</a></p>
<span class="text-small" style="color: var(--color-3);">[<a href="https://servers.fmdx.org/" target="_blank">Receiver Map</a>]</span> <span class="text-small" style="color: var(--color-3);">[<a href="https://servers.fmdx.org/" target="_blank">Receiver Map</a>]</span>
<br> <br>
<br> <br>

View File

@@ -1,9 +1,9 @@
var currentDate = new Date('Sep 11, 2024 23:50:00'); var currentDate = new Date('Sep 12, 2024 21:30:00');
var day = currentDate.getDate(); var day = currentDate.getDate();
var month = currentDate.getMonth() + 1; // Months are zero-indexed, so add 1 var month = currentDate.getMonth() + 1; // Months are zero-indexed, so add 1
var year = currentDate.getFullYear(); var year = currentDate.getFullYear();
var formattedDate = day + '/' + month + '/' + year; var formattedDate = day + '/' + month + '/' + year;
var currentVersion = 'v1.2.8 [' + formattedDate + ']'; var currentVersion = 'v1.2.8.1 [' + formattedDate + ']';
getInitialSettings(); getInitialSettings();
removeUrlParameters(); // Call this function to remove URL parameters removeUrlParameters(); // Call this function to remove URL parameters

View File

@@ -827,7 +827,8 @@ const updateDataElements = throttle(function(parsedData) {
updateTextIfChanged($('#data-station-itu'), parsedData.txInfo.itu); updateTextIfChanged($('#data-station-itu'), parsedData.txInfo.itu);
updateTextIfChanged($('#data-station-pol'), parsedData.txInfo.pol); updateTextIfChanged($('#data-station-pol'), parsedData.txInfo.pol);
updateTextIfChanged($('#data-station-distance'), parsedData.txInfo.dist); updateTextIfChanged($('#data-station-distance'), parsedData.txInfo.dist);
updateTextIfChanged($('#data-station-azimuth'), parsedData.txInfo.azi); updateHtmlIfChanged($('#data-station-azimuth'), parsedData.txInfo.azi + '°');
updateHtmlIfChanged($('#data-regular-pi'), parsedData.txInfo.reg === true ? parsedData.txInfo.pi : '&nbsp;');
$dataStationContainer.css('display', 'block'); $dataStationContainer.css('display', 'block');
} else { } else {
$dataStationContainer.removeAttr('style'); $dataStationContainer.removeAttr('style');

View File

@@ -64,37 +64,8 @@ $(document).ready(function() {
$('#tuner-wireless').hide(); $('#tuner-wireless').hide();
$('#tuner-usb').show(); $('#tuner-usb').show();
} }
}); });
$('#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
$('#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
$('#login-message').text(xhr.responseJSON.message);
} else {
// Handle other types of errors if needed
console.error('Error:', status, error);
}
}
});
});
// Assuming you have an anchor tag with id 'logout-link'
$('.logout-link').click(function (event) { $('.logout-link').click(function (event) {
event.preventDefault(); event.preventDefault();

View File

@@ -20,7 +20,6 @@
<img class="top-10" src="./images/openradio_logo_neutral.png" height="64px"> <img class="top-10" src="./images/openradio_logo_neutral.png" height="64px">
<h2 class="text-monospace text-light">[ADMIN PANEL]</h2> <h2 class="text-monospace text-light">[ADMIN PANEL]</h2>
</div> </div>
<div id="login-message"></div>
<div class="panel-100" style="border-radius: 15px 15px 0 0;"> <div class="panel-100" style="border-radius: 15px 15px 0 0;">
<ul class="nav" role="tablist" style="border-radius: 15px 15px 0 0;"> <ul class="nav" role="tablist" style="border-radius: 15px 15px 0 0;">
<li role="presentation" data-panel="dashboard" aria-selected="true"> <li role="presentation" data-panel="dashboard" aria-selected="true">
@@ -544,15 +543,17 @@
<div class="panel-100 p-bottom-20"> <div class="panel-100 p-bottom-20">
<h2>LOGIN</h2> <h2>LOGIN</h2>
<form action="./login" method="post" id="login-form"> <form action="./login" method="post" id="login-form">
<input style="background-color: var(--color-2);" type="password" id="password" name="password" required> <input type="password" id="password" name="password" placeholder="Password" style="width: 250px;" required>
<button type="submit" class="br-0 w-100" style="height: 44px;">Login</button> <button type="submit" class="br-0 top-10 tooltip" style="height: 46px; width: 50px; margin-left: -2px;border-radius: 0 15px 15px 0;" role="button" aria-label="Log in" tabindex="0" data-tooltip="Log in">
<i class="fa-solid fa-right-to-bracket"></i>
</button>
</form> </form>
<div id="login-message"></div>
</div> </div>
<% } %> <% } %>
</div> </div>
</div> </div>
<script src="js/init.js"></script> <script src="js/init.js"></script>
<script src="js/toast.js"></script>
<script src="js/settings.js"></script> <script src="js/settings.js"></script>
<script src="js/dropdown.js"></script> <script src="js/dropdown.js"></script>
<script src="js/setup.js"></script> <script src="js/setup.js"></script>

View File

@@ -39,11 +39,11 @@
<p class="m-0 text-gray">Leave the IP at 0.0.0.0 unless you explicitly know you have to change it.<br>Don't enter your public IP here.</p> <p class="m-0 text-gray">Leave the IP at 0.0.0.0 unless you explicitly know you have to change it.<br>Don't enter your public IP here.</p>
<div class="flex-center top-25"> <div class="flex-center top-25">
<div class="form-group"> <div class="form-group">
<label for="webserver-ip">Webserver IP:</label> <label for="webserver-ip">Webserver IP</label>
<input class="input-text w-150" type="text" name="webserver-ip" id="webserver-ip" placeholder="0.0.0.0"> <input class="input-text w-150" type="text" name="webserver-ip" id="webserver-ip" placeholder="0.0.0.0">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="webserver-port">Webserver port:</label> <label for="webserver-port">Webserver port</label>
<input class="input-text w-100" type="text" name="webserver-port" id="webserver-port" placeholder="8080"> <input class="input-text w-100" type="text" name="webserver-port" id="webserver-port" placeholder="8080">
</div> </div>
</div> </div>
@@ -56,7 +56,7 @@
<h3>Tuner type:</h3> <h3>Tuner type:</h3>
<p class="text-gray">Settings a proper device type ensures that the correct interface and settings will load.</p> <p class="text-gray">Settings a proper device type ensures that the correct interface and settings will load.</p>
<div class="form-group"> <div class="form-group">
<label for="themes"><i class="fa-solid fa-radio"></i> Device:</label> <label for="themes"><i class="fa-solid fa-radio"></i> Device</label>
<div class="dropdown" id="device-selector" style="margin-right: 0;"> <div class="dropdown" id="device-selector" style="margin-right: 0;">
<input type="text" placeholder="TEF6686 / TEA685x" id="device-type" readonly> <input type="text" placeholder="TEF6686 / TEA685x" id="device-type" readonly>
<ul class="options"> <ul class="options">
@@ -82,7 +82,7 @@
<div id="tuner-usb" class="top-25"> <div id="tuner-usb" class="top-25">
<p>It's time to choose your USB device.</p> <p>It's time to choose your USB device.</p>
<div class="form-group"> <div class="form-group">
<label for="com-devices"><i class="fa-brands fa-usb"></i> USB Device:</label> <label for="com-devices"><i class="fa-brands fa-usb"></i> USB Device</label>
<div class="dropdown" style="width: 300px;margin-right: 0;"> <div class="dropdown" style="width: 300px;margin-right: 0;">
<input id="com-devices" type="text" name="com-devices" placeholder="Choose your USB device" readonly /> <input id="com-devices" type="text" name="com-devices" placeholder="Choose your USB device" readonly />
<ul class="options" id="deviceList"> <ul class="options" id="deviceList">
@@ -97,15 +97,15 @@
<p class="m-0 text-gray">If you are connecting your tuner <strong>wirelessly</strong>, enter the tuner IP. <br> If you use <strong>xdrd</strong>, use 127.0.0.1 as your IP.</p> <p class="m-0 text-gray">If you are connecting your tuner <strong>wirelessly</strong>, enter the tuner IP. <br> If you use <strong>xdrd</strong>, use 127.0.0.1 as your IP.</p>
<div class="flex-center top-25"> <div class="flex-center top-25">
<div class="form-group"> <div class="form-group">
<label for="xdrd-ip">xdrd ip address:</label> <label for="xdrd-ip">xdrd ip address</label>
<input class="input-text w-150" type="text" name="xdrd-ip" id="xdrd-ip" placeholder="127.0.0.1"> <input class="input-text w-150" type="text" name="xdrd-ip" id="xdrd-ip" placeholder="127.0.0.1">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="xdrd-port">xdrd port:</label> <label for="xdrd-port">xdrd port</label>
<input class="input-text w-100" type="text" name="xdrd-port" id="xdrd-port" placeholder="7373"> <input class="input-text w-100" type="text" name="xdrd-port" id="xdrd-port" placeholder="7373">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="xdrd-password">xdrd server password:</label> <label for="xdrd-password">xdrd server password</label>
<input class="input-text w-150" type="password" name="xdrd-password" id="xdrd-password"> <input class="input-text w-150" type="password" name="xdrd-password" id="xdrd-password">
</div> </div>
</div> </div>
@@ -122,7 +122,7 @@
<div class="panel-100 p-bottom-20"> <div class="panel-100 p-bottom-20">
<div class="form-group"> <div class="form-group">
<label for="audio-devices"><i class="fa-solid fa-headphones"></i> STREAM AUDIO FROM:</label> <label for="audio-devices"><i class="fa-solid fa-headphones"></i> Stream audio from</label>
<div class="dropdown" style="width: 300px;"> <div class="dropdown" style="width: 300px;">
<input id="audio-devices" type="text" name="audio-devices" placeholder="Choose your audio device" readonly /> <input id="audio-devices" type="text" name="audio-devices" placeholder="Choose your audio device" readonly />
<ul class="options" id="deviceList"> <ul class="options" id="deviceList">
@@ -137,7 +137,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="audio-devices"><i class="fa-solid fa-microphone-lines"></i> AUDIO CHANNELS:</label> <label for="audio-devices"><i class="fa-solid fa-microphone-lines"></i> Audio channels</label>
<div class="dropdown" style="width: 300px;"> <div class="dropdown" style="width: 300px;">
<input id="audio-channels" type="text" name="audio-channels" placeholder="Stereo" readonly /> <input id="audio-channels" type="text" name="audio-channels" placeholder="Stereo" readonly />
<ul class="options"> <ul class="options">
@@ -148,7 +148,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="audio-quality"><i class="fa-solid fa-wave-square"></i> AUDIO QUALITY:</label> <label for="audio-quality"><i class="fa-solid fa-wave-square"></i> Audio quality</label>
<div class="dropdown" style="width: 300px;"> <div class="dropdown" style="width: 300px;">
<input id="audio-quality" type="text" name="audio-quality" placeholder="128k (standard)" readonly /> <input id="audio-quality" type="text" name="audio-quality" placeholder="128k (standard)" readonly />
<ul class="options"> <ul class="options">
@@ -235,23 +235,27 @@
<% } else { %> <% } else { %>
<div class="panel-100 no-bg"> <div class="panel-100 no-bg">
<img class="top-25" src="../images/openradio_logo_neutral.png" height="64px"> <img class="top-25" src="../images/openradio_logo_neutral.png" height="64px">
<h2 class="text-monospace text-light">[ADMIN PANEL]</h2> <h2 class="text-monospace text-light">[Wizard]</h2>
<p>You are currently not logged in as an administrator and therefore can't change the settings.</p> <p>You are currently not logged in as an administrator and therefore can't change the settings.</p>
<p>Please login below.</p> <p>Please login below.</p>
</div> </div>
<div class="panel-100 p-bottom-20"> <div class="panel-100 p-bottom-20">
<h2>LOGIN</h2> <h2>LOGIN</h2>
<form action="./login" method="post" id="login-form"> <form action="./login" method="post" id="login-form">
<input style="background-color: var(--color-2);" type="password" id="password" name="password" required> <input type="password" id="password" name="password" placeholder="Password" style="width: 250px; background-color: var(--color-2);" required>
<button type="submit" class="br-0 w-100" style="height: 44px;">Login</button> <button type="submit" class="br-0 top-10 tooltip" style="height: 46px; width: 50px; margin-left: -4px;border-radius: 0 15px 15px 0;" role="button" aria-label="Log in" tabindex="0" data-tooltip="Log in">
<i class="fa-solid fa-right-to-bracket"></i>
</button>
</form> </form>
<div id="login-message"></div>
</div> </div>
<% } %> <% } %>
</div> </div>
</div> </div>
<script src="js/init.js"></script>
<script src="js/settings.js"></script> <script src="js/settings.js"></script>
<script src="js/dropdown.js"></script> <script src="js/dropdown.js"></script>
<script src="js/toast.js"></script>
<script src="js/settings.js"></script>
<script src="js/setup.js"></script> <script src="js/setup.js"></script>
<script src="js/wizard.js"></script> <script src="js/wizard.js"></script>
<script src="js/confighandler.js"></script> <script src="js/confighandler.js"></script>