You've already forked fm-dx-webserver
mirror of
https://github.com/KubaPro010/fm-dx-webserver.git
synced 2026-02-26 22:13:53 +01:00
device types, bugfixes
This commit is contained in:
134
datahandler.js
134
datahandler.js
@@ -6,6 +6,7 @@ const path = require('path');
|
|||||||
const os = require('os');
|
const os = require('os');
|
||||||
const platform = os.platform();
|
const platform = os.platform();
|
||||||
const cpuArchitecture = os.arch();
|
const cpuArchitecture = os.arch();
|
||||||
|
const { configName, serverConfig, configUpdate, configSave } = require('./server_config');
|
||||||
let unicode_type;
|
let unicode_type;
|
||||||
let shared_Library;
|
let shared_Library;
|
||||||
|
|
||||||
@@ -207,8 +208,10 @@ var dataToSend = {
|
|||||||
freq: 87.500.toFixed(3),
|
freq: 87.500.toFixed(3),
|
||||||
previousFreq: 87.500.toFixed(3),
|
previousFreq: 87.500.toFixed(3),
|
||||||
signal: 0,
|
signal: 0,
|
||||||
|
highestSignal: -Infinity,
|
||||||
st: false,
|
st: false,
|
||||||
st_forced: false,
|
st_forced: false,
|
||||||
|
rds: false,
|
||||||
ps: '',
|
ps: '',
|
||||||
tp: 0,
|
tp: 0,
|
||||||
ta: 0,
|
ta: 0,
|
||||||
@@ -234,6 +237,14 @@ var dataToSend = {
|
|||||||
users: 0,
|
users: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const filterMappings = {
|
||||||
|
'G11': { eq: 1, ims: 1 },
|
||||||
|
'G01': { eq: 0, ims: 1 },
|
||||||
|
'G10': { eq: 1, ims: 0 },
|
||||||
|
'G00': { eq: 0, ims: 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var legacyRdsPiBuffer = null;
|
var legacyRdsPiBuffer = null;
|
||||||
const initialData = { ...dataToSend };
|
const initialData = { ...dataToSend };
|
||||||
const resetToDefault = dataToSend => Object.assign(dataToSend, initialData);
|
const resetToDefault = dataToSend => Object.assign(dataToSend, initialData);
|
||||||
@@ -243,8 +254,10 @@ function handleData(ws, receivedData) {
|
|||||||
// Retrieve the last update time for this client
|
// Retrieve the last update time for this client
|
||||||
let lastUpdateTime = clientUpdateIntervals.get(ws) || 0;
|
let lastUpdateTime = clientUpdateIntervals.get(ws) || 0;
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
|
|
||||||
let modifiedData, parsedValue;
|
let modifiedData, parsedValue;
|
||||||
const receivedLines = receivedData.split('\n');
|
const receivedLines = receivedData.split('\n');
|
||||||
|
|
||||||
for (const receivedLine of receivedLines) {
|
for (const receivedLine of receivedLines) {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case receivedLine.startsWith('P'):
|
case receivedLine.startsWith('P'):
|
||||||
@@ -272,86 +285,29 @@ function handleData(ws, receivedData) {
|
|||||||
initialData.ant = receivedLine.substring(1);
|
initialData.ant = receivedLine.substring(1);
|
||||||
break;
|
break;
|
||||||
case receivedLine.startsWith('G'):
|
case receivedLine.startsWith('G'):
|
||||||
switch (receivedLine) {
|
const mapping = filterMappings[receivedLine];
|
||||||
case 'G11':
|
if (mapping) {
|
||||||
initialData.eq = 1;
|
initialData.eq = mapping.eq;
|
||||||
dataToSend.eq = 1;
|
initialData.ims = mapping.ims;
|
||||||
initialData.ims = 1;
|
dataToSend.eq = mapping.eq;
|
||||||
dataToSend.ims = 1;
|
dataToSend.ims = mapping.ims;
|
||||||
break;
|
|
||||||
case 'G01':
|
|
||||||
initialData.eq = 0;
|
|
||||||
dataToSend.eq = 0;
|
|
||||||
initialData.ims = 1;
|
|
||||||
dataToSend.ims = 1;
|
|
||||||
break;
|
|
||||||
case 'G10':
|
|
||||||
initialData.eq = 1;
|
|
||||||
dataToSend.eq = 1;
|
|
||||||
initialData.ims = 0;
|
|
||||||
dataToSend.ims = 0;
|
|
||||||
break;
|
|
||||||
case 'G00':
|
|
||||||
initialData.eq = 0;
|
|
||||||
initialData.ims = 0;
|
|
||||||
dataToSend.eq = 0;
|
|
||||||
dataToSend.ims = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case receivedLine.startsWith('Sm'):
|
|
||||||
modifiedData = receivedLine.substring(2);
|
|
||||||
parsedValue = parseFloat(modifiedData);
|
|
||||||
dataToSend.st = false;
|
|
||||||
dataToSend.st_forced = false;
|
|
||||||
initialData.st = false;
|
|
||||||
initialData.st_forced = false;
|
|
||||||
|
|
||||||
if (!isNaN(parsedValue)) {
|
|
||||||
dataToSend.signal = parsedValue.toFixed(2);
|
|
||||||
initialData.signal = parsedValue.toFixed(2);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case receivedData.startsWith('Sm'):
|
||||||
|
processSignal(receivedData, false, false);
|
||||||
|
break;
|
||||||
case receivedData.startsWith('Ss'):
|
case receivedData.startsWith('Ss'):
|
||||||
modifiedData = receivedData.substring(2);
|
processSignal(receivedData, true, false);
|
||||||
parsedValue = parseFloat(modifiedData);
|
|
||||||
dataToSend.st = true;
|
|
||||||
dataToSend.st_forced = false;
|
|
||||||
initialData.st = true;
|
|
||||||
initialData.st_forced = false;
|
|
||||||
|
|
||||||
if (!isNaN(parsedValue)) {
|
|
||||||
dataToSend.signal = parsedValue.toFixed(2);
|
|
||||||
initialData.signal = parsedValue.toFixed(2);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case receivedData.startsWith('SS'):
|
case receivedData.startsWith('SS'):
|
||||||
modifiedData = receivedData.substring(2);
|
processSignal(receivedData, true, true);
|
||||||
parsedValue = parseFloat(modifiedData);
|
|
||||||
dataToSend.st = true;
|
|
||||||
dataToSend.st_forced = true;
|
|
||||||
initialData.st = true;
|
|
||||||
initialData.st_forced = true;
|
|
||||||
|
|
||||||
if (!isNaN(parsedValue)) {
|
|
||||||
dataToSend.signal = parsedValue.toFixed(2);
|
|
||||||
initialData.signal = parsedValue.toFixed(2);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case receivedData.startsWith('SM'):
|
case receivedData.startsWith('SM'):
|
||||||
modifiedData = receivedData.substring(2);
|
processSignal(receivedData, false, true);
|
||||||
parsedValue = parseFloat(modifiedData);
|
break;
|
||||||
dataToSend.st = false;
|
|
||||||
dataToSend.st_forced = true;
|
|
||||||
initialData.st = false;
|
|
||||||
initialData.st_forced = true;
|
|
||||||
|
|
||||||
if (!isNaN(parsedValue)) {
|
|
||||||
dataToSend.signal = parsedValue.toFixed(2);
|
|
||||||
initialData.signal = parsedValue.toFixed(2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case receivedLine.startsWith('R'):
|
case receivedLine.startsWith('R'):
|
||||||
modifiedData = receivedLine.slice(1);
|
modifiedData = receivedLine.slice(1);
|
||||||
|
dataToSend.rds = true;
|
||||||
|
|
||||||
if (modifiedData.length == 14) {
|
if (modifiedData.length == 14) {
|
||||||
// Handle legacy RDS message
|
// Handle legacy RDS message
|
||||||
@@ -411,6 +367,42 @@ function showOnlineUsers(currentUsers) {
|
|||||||
initialData.users = currentUsers;
|
initialData.users = currentUsers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertSignal(dBFS, fullScaleVoltage = 1, inputImpedance = 300) {
|
||||||
|
// Convert dBFS to voltage
|
||||||
|
let voltage = Math.pow(10, dBFS / 20) * fullScaleVoltage;
|
||||||
|
|
||||||
|
// Convert voltage to microvolts
|
||||||
|
let uV = voltage * 1e6;
|
||||||
|
|
||||||
|
// Convert microvolts to dBuV
|
||||||
|
let dBf = 20 * Math.log10(uV / Math.sqrt(2) / Math.sqrt(inputImpedance));
|
||||||
|
|
||||||
|
return dBf.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function processSignal(receivedData, st, stForced) {
|
||||||
|
const modifiedData = receivedData.substring(2);
|
||||||
|
const parsedValue = parseFloat(modifiedData);
|
||||||
|
dataToSend.st = st;
|
||||||
|
dataToSend.st_forced = stForced;
|
||||||
|
initialData.st = st;
|
||||||
|
initialData.st_forced = stForced;
|
||||||
|
|
||||||
|
if (!isNaN(parsedValue)) {
|
||||||
|
/*if (serverConfig.device && serverConfig.device === 'sdr') {
|
||||||
|
dataToSend.signal = convertSignal(parsedValue);
|
||||||
|
initialData.signal = convertSignal(parsedValue);
|
||||||
|
} else {*/
|
||||||
|
dataToSend.signal = parsedValue.toFixed(2);
|
||||||
|
initialData.signal = parsedValue.toFixed(2);
|
||||||
|
//}
|
||||||
|
|
||||||
|
if(dataToSend.signal > dataToSend.highestSignal) {
|
||||||
|
dataToSend.highestSignal = dataToSend.signal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
handleData, showOnlineUsers, dataToSend, initialData, resetToDefault
|
handleData, showOnlineUsers, dataToSend, initialData, resetToDefault
|
||||||
};
|
};
|
||||||
|
|||||||
14
fmdx_list.js
14
fmdx_list.js
@@ -2,7 +2,8 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const fetch = require('node-fetch');
|
const fetch = require('node-fetch');
|
||||||
const { logDebug, logError, logInfo, logWarn } = require('./console');
|
const { logDebug, logError, logInfo, logWarn } = require('./console');
|
||||||
const { serverConfig, configUpdate, configSave } = require('./server_config')
|
const { serverConfig, configUpdate, configSave } = require('./server_config');
|
||||||
|
var pjson = require('./package.json');
|
||||||
|
|
||||||
let timeoutID = null;
|
let timeoutID = null;
|
||||||
|
|
||||||
@@ -59,6 +60,12 @@ function sendKeepalive() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sendUpdate() {
|
function sendUpdate() {
|
||||||
|
|
||||||
|
let bwLimit = '';
|
||||||
|
if (serverConfig.webserver.tuningLimit === true) {
|
||||||
|
bwLimit = serverConfig.webserver.tuningLowerLimit + ' - ' + serverConfig.webserver.tuningUpperLimit + ' Mhz';
|
||||||
|
}
|
||||||
|
|
||||||
const request = {
|
const request = {
|
||||||
status: (serverConfig.lockToAdmin ? 2 : 1),
|
status: (serverConfig.lockToAdmin ? 2 : 1),
|
||||||
coords: [serverConfig.identification.lat, serverConfig.identification.lon],
|
coords: [serverConfig.identification.lat, serverConfig.identification.lon],
|
||||||
@@ -66,7 +73,10 @@ function sendUpdate() {
|
|||||||
desc: serverConfig.identification.tunerDesc,
|
desc: serverConfig.identification.tunerDesc,
|
||||||
audioChannels: serverConfig.audio.audioChannels,
|
audioChannels: serverConfig.audio.audioChannels,
|
||||||
audioQuality: serverConfig.audio.audioBitrate,
|
audioQuality: serverConfig.audio.audioBitrate,
|
||||||
contact: serverConfig.identification.contact || ''
|
contact: serverConfig.identification.contact || '',
|
||||||
|
device: serverConfig.deviceName || '',
|
||||||
|
bwLimit: bwLimit,
|
||||||
|
version: pjson.version
|
||||||
};
|
};
|
||||||
|
|
||||||
if (serverConfig.identification.token)
|
if (serverConfig.identification.token)
|
||||||
|
|||||||
7
index.js
7
index.js
@@ -108,6 +108,8 @@ function connectToSerial() {
|
|||||||
|
|
||||||
serialport.on('open', () => {
|
serialport.on('open', () => {
|
||||||
logInfo('Using COM device: ' + serverConfig.xdrd.comPort);
|
logInfo('Using COM device: ' + serverConfig.xdrd.comPort);
|
||||||
|
|
||||||
|
serialport.write('x\n');
|
||||||
serialport.write('M0\n');
|
serialport.write('M0\n');
|
||||||
serialport.write('Y100\n');
|
serialport.write('Y100\n');
|
||||||
serialport.write('D0\n');
|
serialport.write('D0\n');
|
||||||
@@ -128,8 +130,6 @@ function connectToSerial() {
|
|||||||
serialport.write('T87500\n');
|
serialport.write('T87500\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
serialport.write('x\n');
|
|
||||||
|
|
||||||
serialport.on('data', (data) => {
|
serialport.on('data', (data) => {
|
||||||
resolveDataBuffer(data);
|
resolveDataBuffer(data);
|
||||||
});
|
});
|
||||||
@@ -422,6 +422,7 @@ app.get('/', (req, res) => {
|
|||||||
tuningLowerLimit: serverConfig.webserver.tuningLowerLimit,
|
tuningLowerLimit: serverConfig.webserver.tuningLowerLimit,
|
||||||
tuningUpperLimit: serverConfig.webserver.tuningUpperLimit,
|
tuningUpperLimit: serverConfig.webserver.tuningUpperLimit,
|
||||||
chatEnabled: serverConfig.webserver.chatEnabled,
|
chatEnabled: serverConfig.webserver.chatEnabled,
|
||||||
|
device: serverConfig.device
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -637,7 +638,7 @@ wss.on('connection', (ws, request) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((serverConfig.publicTuner === true) || (request.session && request.session.isTuneAuthenticated === true && serverConfig.xdrd.wirelessConnection)) {
|
if((serverConfig.publicTuner === true) || (request.session && request.session.isTuneAuthenticated === true && serverConfig.xdrd.wirelessConnection)) {
|
||||||
|
|
||||||
if(serverConfig.lockToAdmin === true) {
|
if(serverConfig.lockToAdmin === true) {
|
||||||
if(request.session && request.session.isAdminAuthenticated === true) {
|
if(request.session && request.session.isAdminAuthenticated === true) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "fm-dx-webserver",
|
"name": "fm-dx-webserver",
|
||||||
"version": "1.1.3",
|
"version": "1.1.4",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ const fetchInterval = 3000;
|
|||||||
function fetchTx(freq, piCode, rdsPs) {
|
function fetchTx(freq, piCode, rdsPs) {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
freq = parseFloat(freq);
|
freq = parseFloat(freq);
|
||||||
|
|
||||||
|
if(isNaN(freq)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Check if it's been at least 3 seconds since the last fetch and if the QTH is correct
|
// Check if it's been at least 3 seconds since the last fetch and if the QTH is correct
|
||||||
if (now - lastFetchTime < fetchInterval || serverConfig.identification.lat.length < 2 || freq < 87) {
|
if (now - lastFetchTime < fetchInterval || serverConfig.identification.lat.length < 2 || freq < 87) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
|||||||
@@ -36,6 +36,24 @@ h4 {
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltiptext {
|
||||||
|
position: absolute;
|
||||||
|
background-color: var(--color-3);
|
||||||
|
color: var(--color-text);
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 30px;
|
||||||
|
padding: 5px 25px;
|
||||||
|
z-index: 1000;
|
||||||
|
opacity:var(--color-main);
|
||||||
|
transition: opacity 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
p#tuner-desc {
|
p#tuner-desc {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -78,6 +96,10 @@ label {
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.highest-signal-container {
|
||||||
|
margin-bottom: -20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.form-group {
|
.form-group {
|
||||||
float: left;
|
float: left;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
@@ -215,6 +237,17 @@ label {
|
|||||||
#tuner-wireless {
|
#tuner-wireless {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
pointer-events: auto; /* Ensure that the overlay captures clicks */
|
||||||
|
opacity: 0; /* Make the overlay invisible */
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
canvas, #flags-container {
|
canvas, #flags-container {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -234,6 +267,10 @@ label {
|
|||||||
.form-group {
|
.form-group {
|
||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
.highest-signal-container {
|
||||||
|
margin-top: -20px !important;
|
||||||
|
margin-bottom: 15px !important;
|
||||||
|
}
|
||||||
#data-pi {
|
#data-pi {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|||||||
@@ -202,6 +202,10 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-select-none {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
@media only screen and (max-width: 960px) {
|
||||||
.text-medium-big {
|
.text-medium-big {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<link href="css/flags.min.css" type="text/css" rel="stylesheet">
|
<link href="css/flags.min.css" type="text/css" rel="stylesheet">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" type="text/css" rel="stylesheet">
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" type="text/css" rel="stylesheet">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="favicon2.png" />
|
<link rel="icon" type="image/png" href="favicon2.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
@@ -73,12 +74,12 @@
|
|||||||
<div class="panel-10 no-bg h-100 m-0 m-right-20 hide-phone" style="width: 100px;margin-right: 20px !important;">
|
<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>
|
<button class="playbutton" aria-label="Play / Stop Button"><i class="fa-solid fa-play fa-lg"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-100 m-0 hover-brighten flex-center" id="ps-container" style="height: 90px;">
|
<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.">
|
||||||
<span class="text-big" id="data-ps"></span>
|
<span class="text-big" id="data-ps"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="flags-container-desktop" class="panel-33">
|
<div id="flags-container-desktop" class="panel-33 user-select-none">
|
||||||
<h2 class="show-phone">
|
<h2 class="show-phone">
|
||||||
<div class="data-pty text-color-default"></div>
|
<div class="data-pty text-color-default"></div>
|
||||||
</h2>
|
</h2>
|
||||||
@@ -88,14 +89,17 @@
|
|||||||
<div style="display:inline-block">
|
<div style="display:inline-block">
|
||||||
<span style="margin-left: 20px;display: block;margin-top: 2px;" class="data-flag"></span>
|
<span style="margin-left: 20px;display: block;margin-top: 2px;" class="data-flag"></span>
|
||||||
</div>
|
</div>
|
||||||
<span id="stereo-container" class="pointer"><span style="margin-left: 20px;" class="data-st">ST</span></span>
|
<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>
|
||||||
<span style="margin-left: 15px;" class="data-ms">MS</span>
|
<span style="margin-left: 15px;" class="data-ms">MS</span>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<div class="panel-33 hover-brighten" id="pi-code-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.">
|
||||||
<h2>PI CODE</h2>
|
<h2>PI CODE</h2>
|
||||||
<span id="data-pi" class="text-big text-uppercase"></span>
|
<span id="data-pi" class="text-big text-uppercase"></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -107,11 +111,16 @@
|
|||||||
|
|
||||||
<div class="panel-33">
|
<div class="panel-33">
|
||||||
<h2>SIGNAL</h2>
|
<h2>SIGNAL</h2>
|
||||||
<span class="text-big">
|
<div class="text-small text-gray highest-signal-container">
|
||||||
|
<i class="fa-solid fa-arrow-up"></i>
|
||||||
|
<span id="data-signal-highest"></span>
|
||||||
|
<span class="signal-units"></span>
|
||||||
|
</div>
|
||||||
|
<div class="text-big">
|
||||||
<span id="data-signal"></span><!--
|
<span id="data-signal"></span><!--
|
||||||
--><span id="data-signal-decimal" class="text-medium-big" style="opacity:0.7;"></span>
|
--><span id="data-signal-decimal" class="text-medium-big" style="opacity:0.7;"></span>
|
||||||
<span id="signal-units" class="text-medium">dBf</span>
|
<span class="signal-units text-medium">dBf</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -135,10 +144,12 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<div class="panel-100 no-bg h-100 m-0 button-eq">
|
<div class="panel-100 no-bg h-100 m-0 button-eq">
|
||||||
<button id="data-eq" style="border-radius: 30px 0px 0px 30px;" aria-label="EQ / RF+ Filter"><span class="text-bold">EQ</span><br><span class="text-smaller">(RF+)</span></button>
|
<% 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><% } %>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-100 no-bg h-100 m-0 button-ims">
|
<div class="panel-100 no-bg h-100 m-0 button-ims">
|
||||||
<button id="data-ims" style="border-radius: 0px 30px 30px 0px;" aria-label="iMS / IF+ Filter"><span class="text-bold">iMS</span><br><span class="text-smaller">(IF+)</span></button>
|
<% 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><% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,7 +173,7 @@
|
|||||||
<hr class="hide-desktop">
|
<hr class="hide-desktop">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-33 hover-brighten">
|
<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 id="data-station-container">
|
<div id="data-station-container">
|
||||||
<h2 style="margin-top: 0;" class="mb-0">
|
<h2 style="margin-top: 0;" class="mb-0">
|
||||||
<span id="data-station-name"></span>
|
<span id="data-station-name"></span>
|
||||||
@@ -277,7 +288,7 @@
|
|||||||
<a href="./setup">Setup</a> • <a class="logout-link" href="#">Logout</a>
|
<a href="./setup">Setup</a> • <a class="logout-link" href="#">Logout</a>
|
||||||
</p>
|
</p>
|
||||||
<% } else if (isTuneAuthenticated) { %>
|
<% } else if (isTuneAuthenticated) { %>
|
||||||
<p>You are logged in and can control the receiver. <a class="logout-link" href="#">Logout</a></p>
|
<p>You are logged in and can control the receiver.<br><a class="logout-link" href="#">Logout</a></p>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<form action="./login" method="post" id="login-form" class="top-25">
|
<form action="./login" method="post" id="login-form" class="top-25">
|
||||||
<label for="password">Password:</label>
|
<label for="password">Password:</label>
|
||||||
@@ -349,5 +360,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="js/webserver.js"></script>
|
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ function submitData() {
|
|||||||
return $(this).text() === $('#audio-quality').val();
|
return $(this).text() === $('#audio-quality').val();
|
||||||
}).data('value') || "192k");
|
}).data('value') || "192k");
|
||||||
|
|
||||||
|
const device = ($('.options .option').filter(function() {
|
||||||
|
return $(this).text() === $('#device-type').val();
|
||||||
|
}).data('value') || "tef");
|
||||||
|
|
||||||
const tunerName = $('#webserver-name').val() || 'FM Tuner';
|
const tunerName = $('#webserver-name').val() || 'FM Tuner';
|
||||||
const tunerDesc = $('#webserver-desc').val() || 'Default FM tuner description';
|
const tunerDesc = $('#webserver-desc').val() || 'Default FM tuner description';
|
||||||
const broadcastTuner = $("#broadcast-tuner").is(":checked");
|
const broadcastTuner = $("#broadcast-tuner").is(":checked");
|
||||||
@@ -94,6 +98,7 @@ function submitData() {
|
|||||||
tunePass,
|
tunePass,
|
||||||
adminPass,
|
adminPass,
|
||||||
},
|
},
|
||||||
|
device,
|
||||||
publicTuner,
|
publicTuner,
|
||||||
lockToAdmin,
|
lockToAdmin,
|
||||||
autoShutdown,
|
autoShutdown,
|
||||||
@@ -179,6 +184,12 @@ function submitData() {
|
|||||||
$("#com-devices").val(selectedDevice.text());
|
$("#com-devices").val(selectedDevice.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('#device-type').val(data.device);
|
||||||
|
var selectedDevice = $(".option[data-value='" + data.device + "']");
|
||||||
|
if (selectedDevice.length > 0) {
|
||||||
|
$("#device-type").val(selectedDevice.text());
|
||||||
|
}
|
||||||
|
|
||||||
$('#audio-devices').val(data.audio.audioDevice);
|
$('#audio-devices').val(data.audio.audioDevice);
|
||||||
$('#audio-channels').val(data.audio.audioChannels);
|
$('#audio-channels').val(data.audio.audioChannels);
|
||||||
var selectedChannels = $(".option[data-value='" + data.audio.audioChannels + "']");
|
var selectedChannels = $(".option[data-value='" + data.audio.audioChannels + "']");
|
||||||
|
|||||||
@@ -17,11 +17,17 @@ const europe_programmes = [
|
|||||||
"Oldies Music", "Folk Music", "Documentary", "Alarm Test"
|
"Oldies Music", "Folk Music", "Documentary", "Alarm Test"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const usa_programmes = [
|
||||||
|
"No PTY", "News", "Information", "Sports", "Talk", "Rock", "Classic Rock",
|
||||||
|
"Adults Hits", "Soft Rock", "Top 40", "Country", "Oldies", "Soft Music",
|
||||||
|
"Nostalgia", "Jazz", "Classical", "Rhythm and Blues", "Soft Rhythm and Blues",
|
||||||
|
"Language", "Religious Music", "Religious Talk", "Personality", "Public", "College",
|
||||||
|
"Spanish Talk", "Spanish Music", "Hip Hop", "", "", "Weather", "Emergency Test", "Emergency"
|
||||||
|
];
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
var canvas = $('#signal-canvas')[0];
|
var canvas = $('#signal-canvas')[0];
|
||||||
|
|
||||||
var signalToggle = $("#signal-units-toggle");
|
|
||||||
|
|
||||||
canvas.width = canvas.parentElement.clientWidth;
|
canvas.width = canvas.parentElement.clientWidth;
|
||||||
canvas.height = canvas.parentElement.clientHeight;
|
canvas.height = canvas.parentElement.clientHeight;
|
||||||
|
|
||||||
@@ -135,10 +141,11 @@ $(document).ready(function () {
|
|||||||
$(rtContainer).on("click", copyRt);
|
$(rtContainer).on("click", copyRt);
|
||||||
$(txContainer).on("click", copyTx);
|
$(txContainer).on("click", copyTx);
|
||||||
$(piCodeContainer).on("click", findOnMaps);
|
$(piCodeContainer).on("click", findOnMaps);
|
||||||
$(stereoContainer).on("click", toggleForcedStereo);
|
$(document).on("click", "#stereo-container", toggleForcedStereo);
|
||||||
$(freqContainer).on("click", function () {
|
$(freqContainer).on("click", function () {
|
||||||
textInput.focus();
|
textInput.focus();
|
||||||
});
|
});
|
||||||
|
initTooltips();
|
||||||
});
|
});
|
||||||
|
|
||||||
function getServerTime() {
|
function getServerTime() {
|
||||||
@@ -377,6 +384,27 @@ function checkKey(e) {
|
|||||||
case 82: // RDS Reset (R key)
|
case 82: // RDS Reset (R key)
|
||||||
tuneTo(Number(currentFreq));
|
tuneTo(Number(currentFreq));
|
||||||
break;
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
case 38:
|
case 38:
|
||||||
socket.send("T" + (Math.round(currentFreq*1000) + ((currentFreq > 30) ? 10 : 1)));
|
socket.send("T" + (Math.round(currentFreq*1000) + ((currentFreq > 30) ? 10 : 1)));
|
||||||
break;
|
break;
|
||||||
@@ -465,7 +493,7 @@ async function copyPs() {
|
|||||||
var ps = $('#data-ps').text();
|
var ps = $('#data-ps').text();
|
||||||
var signal = $('#data-signal').text();
|
var signal = $('#data-signal').text();
|
||||||
var signalDecimal = $('#data-signal-decimal').text();
|
var signalDecimal = $('#data-signal-decimal').text();
|
||||||
var signalUnit = $('#signal-units').text();
|
var signalUnit = $('.signal-units').text();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await copyToClipboard(frequency + " - " + pi + " | " + ps + " [" + signal + signalDecimal + " " + signalUnit + "]");
|
await copyToClipboard(frequency + " - " + pi + " | " + ps + " [" + signal + signalDecimal + " " + signalUnit + "]");
|
||||||
@@ -543,13 +571,14 @@ function findOnMaps() {
|
|||||||
function updateSignalUnits(parsedData, averageSignal) {
|
function updateSignalUnits(parsedData, averageSignal) {
|
||||||
const signalUnit = localStorage.getItem('signalUnit');
|
const signalUnit = localStorage.getItem('signalUnit');
|
||||||
let currentSignal;
|
let currentSignal;
|
||||||
|
let highestSignal = parsedData.highestSignal;
|
||||||
|
|
||||||
if(localStorage.getItem("smoothSignal") == 'true') {
|
if(localStorage.getItem("smoothSignal") == 'true') {
|
||||||
currentSignal = averageSignal
|
currentSignal = averageSignal
|
||||||
} else {
|
} else {
|
||||||
currentSignal = parsedData.signal;
|
currentSignal = parsedData.signal;
|
||||||
}
|
}
|
||||||
let signalText = $('#signal-units');
|
let signalText = $('.signal-units');
|
||||||
let signalValue;
|
let signalValue;
|
||||||
|
|
||||||
switch (signalUnit) {
|
switch (signalUnit) {
|
||||||
@@ -572,6 +601,7 @@ function updateSignalUnits(parsedData, averageSignal) {
|
|||||||
const formatted = (Math.round(signalValue * 10) / 10).toFixed(1);
|
const formatted = (Math.round(signalValue * 10) / 10).toFixed(1);
|
||||||
const [integerPart, decimalPart] = formatted.split('.');
|
const [integerPart, decimalPart] = formatted.split('.');
|
||||||
|
|
||||||
|
$('#data-signal-highest').text(Number(highestSignal).toFixed(1));
|
||||||
$('#data-signal').text(integerPart);
|
$('#data-signal').text(integerPart);
|
||||||
$('#data-signal-decimal').text('.' + decimalPart);
|
$('#data-signal-decimal').text('.' + decimalPart);
|
||||||
}
|
}
|
||||||
@@ -589,6 +619,7 @@ function updateDataElements(parsedData) {
|
|||||||
const $dataTp = $('.data-tp');
|
const $dataTp = $('.data-tp');
|
||||||
const $dataTa = $('.data-ta');
|
const $dataTa = $('.data-ta');
|
||||||
const $dataMs = $('.data-ms');
|
const $dataMs = $('.data-ms');
|
||||||
|
const $flagDesktopCointainer = $('#flags-container-desktop');
|
||||||
const $dataPty = $('.data-pty');
|
const $dataPty = $('.data-pty');
|
||||||
|
|
||||||
$dataFrequency.text(parsedData.freq);
|
$dataFrequency.text(parsedData.freq);
|
||||||
@@ -604,6 +635,12 @@ function updateDataElements(parsedData) {
|
|||||||
$dataRt1.html(processString(parsedData.rt1, parsedData.rt1_errors));
|
$dataRt1.html(processString(parsedData.rt1, parsedData.rt1_errors));
|
||||||
$dataPty.html(europe_programmes[parsedData.pty]);
|
$dataPty.html(europe_programmes[parsedData.pty]);
|
||||||
|
|
||||||
|
if(parsedData.rds === true) {
|
||||||
|
$flagDesktopCointainer.css('background-color', 'var(--color-2');
|
||||||
|
} else {
|
||||||
|
$flagDesktopCointainer.css('background-color', 'var(--color-1');
|
||||||
|
}
|
||||||
|
|
||||||
$('.data-flag').html(`<i title="${parsedData.country_name}" class="flag-sm flag-sm-${parsedData.country_iso}"></i>`);
|
$('.data-flag').html(`<i title="${parsedData.country_name}" class="flag-sm flag-sm-${parsedData.country_iso}"></i>`);
|
||||||
$('.data-flag-big').html(`<i title="${parsedData.country_name}" class="flag-md flag-md-${parsedData.country_iso}"></i>`);
|
$('.data-flag-big').html(`<i title="${parsedData.country_name}" class="flag-md flag-md-${parsedData.country_iso}"></i>`);
|
||||||
|
|
||||||
@@ -719,4 +756,28 @@ function toggleForcedStereo() {
|
|||||||
var message = "B";
|
var message = "B";
|
||||||
message += parsedData.st_forced = (parsedData.st_forced == "1") ? "0" : "1";
|
message += parsedData.st_forced = (parsedData.st_forced == "1") ? "0" : "1";
|
||||||
socket.send(message);
|
socket.send(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initTooltips() {
|
||||||
|
$('[data-tooltip]').hover(function(e){
|
||||||
|
var tooltipText = $(this).data('tooltip');
|
||||||
|
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;
|
||||||
|
|
||||||
|
tooltip.css({ top: posY, left: posX, opacity: 0.9 });
|
||||||
|
}, function() {
|
||||||
|
$('.tooltiptext').remove();
|
||||||
|
}).mousemove(function(e){
|
||||||
|
var tooltipWidth = $('.tooltiptext').outerWidth();
|
||||||
|
var tooltipHeight = $('.tooltiptext').outerHeight();
|
||||||
|
var posX = e.pageX - tooltipWidth / 2;
|
||||||
|
var posY = e.pageY - tooltipHeight - 10;
|
||||||
|
|
||||||
|
$('.tooltiptext').css({ top: posY, left: posX });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ 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.1.3 [' + formattedDate + ']';
|
var currentVersion = 'v1.1.4 [' + formattedDate + ']';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -48,13 +48,13 @@ function updateWizardContent() {
|
|||||||
$('.btn-prev').show();
|
$('.btn-prev').show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($('.step:visible').index() == 2) {
|
if($('.step:visible').index() == 3) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
map.invalidateSize();
|
map.invalidateSize();
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($('.step:visible').index() == 3) {
|
if($('.step:visible').index() == 4) {
|
||||||
$('.btn-next').text('Save');
|
$('.btn-next').text('Save');
|
||||||
} else {
|
} else {
|
||||||
$('.btn-next').text('Next')
|
$('.btn-next').text('Next')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>FM-DX Webserver</title>
|
<title>Setup - FM-DX Webserver</title>
|
||||||
<link href="css/entry.css" type="text/css" rel="stylesheet">
|
<link href="css/entry.css" type="text/css" rel="stylesheet">
|
||||||
<link href="css/flags.min.css" type="text/css" rel="stylesheet">
|
<link href="css/flags.min.css" type="text/css" rel="stylesheet">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" type="text/css" rel="stylesheet">
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" type="text/css" rel="stylesheet">
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
<div class="panel-100">
|
<div class="panel-100">
|
||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
<li data-panel="dashboard" class="active">Dashboard</li>
|
<li data-panel="dashboard" class="active">Dashboard</li>
|
||||||
|
<li data-panel="tuner">Tuner</li>
|
||||||
<li data-panel="connection">Connection</li>
|
<li data-panel="connection">Connection</li>
|
||||||
<li data-panel="audio">Audio</li>
|
<li data-panel="audio">Audio</li>
|
||||||
<li data-panel="webserver">Webserver</li>
|
<li data-panel="webserver">Webserver</li>
|
||||||
@@ -340,6 +341,21 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-100 tab-content" id="tuner">
|
||||||
|
<h2>Tuner Specific Settings</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="themes"><i class="fa-solid fa-radio"></i> Device:</label>
|
||||||
|
<div class="dropdown" id="device-selector" style="margin-right: 0;">
|
||||||
|
<input type="text" placeholder="TEF6686 / TEA685x" id="device-type" readonly>
|
||||||
|
<ul class="options">
|
||||||
|
<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>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel-100 tab-content" id="identification">
|
<div class="panel-100 tab-content" id="identification">
|
||||||
<h2>Identification & Map</h2>
|
<h2>Identification & Map</h2>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>FM-DX Webserver</title>
|
<title>Wizard - FM-DX Webserver</title>
|
||||||
<link href="css/entry.css" type="text/css" rel="stylesheet">
|
<link href="css/entry.css" type="text/css" rel="stylesheet">
|
||||||
<link href="css/flags.min.css" type="text/css" rel="stylesheet">
|
<link href="css/flags.min.css" type="text/css" rel="stylesheet">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" type="text/css" rel="stylesheet">
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" type="text/css" rel="stylesheet">
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
<% if (isAdminAuthenticated) { %>
|
<% if (isAdminAuthenticated) { %>
|
||||||
<div class="panel-100 no-bg">
|
<div class="panel-100 no-bg">
|
||||||
<img class="top-10" src="../images/openradio_logo_neutral.png" height="64px">
|
<img class="top-10" src="../images/openradio_logo_neutral.png" height="64px">
|
||||||
<h1 class="top-10">FM-DX WebServer</h1>
|
|
||||||
<h2 class="text-monospace text-light text-gray">[SETUP WIZARD]</h2>
|
<h2 class="text-monospace text-light text-gray">[SETUP WIZARD]</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-100 no-bg flex-container flex-center flex-phone">
|
<div class="panel-100 no-bg flex-container flex-center flex-phone">
|
||||||
@@ -24,14 +23,48 @@
|
|||||||
<div class="btn-rounded-cube">2</div>
|
<div class="btn-rounded-cube">2</div>
|
||||||
<div class="btn-rounded-cube">3</div>
|
<div class="btn-rounded-cube">3</div>
|
||||||
<div class="btn-rounded-cube">4</div>
|
<div class="btn-rounded-cube">4</div>
|
||||||
|
<div class="btn-rounded-cube">5</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-100">
|
<div class="panel-100">
|
||||||
|
|
||||||
<!-- BASIC SETTINGS -->
|
<!-- BASIC SETTINGS -->
|
||||||
<div class="panel-100 step" id="step1">
|
<div class="panel-100 step" id="step1">
|
||||||
<h2 class="settings-heading">BASIC SETTINGS</h2>
|
<h2 class="settings-heading">Basic settings</h2>
|
||||||
<p class="m-0">Welcome to the setup wizard! Let's set up some basic things.</p>
|
<p class="m-0">Welcome to the setup wizard! Let's set up some basic things.</p>
|
||||||
|
|
||||||
|
<h3>Webserver connection:</h3>
|
||||||
|
<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="form-group">
|
||||||
|
<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">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="webserver-port">Webserver port:</label>
|
||||||
|
<input class="input-text w-100" type="text" name="webserver-port" id="webserver-port" placeholder="8080">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- BASIC SETTINGS END -->
|
||||||
|
<!-- TUNER SETTINGS -->
|
||||||
|
<div id="step2" class="step" style="display: none">
|
||||||
|
<h2>Tuner settings</h2>
|
||||||
|
|
||||||
|
<h3>Tuner type:</h3>
|
||||||
|
<p class="text-gray">Settings a proper device type ensures that the correct interface and settings will load.</p>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="themes"><i class="fa-solid fa-radio"></i> Device:</label>
|
||||||
|
<div class="dropdown" id="device-selector" style="margin-right: 0;">
|
||||||
|
<input type="text" placeholder="TEF6686 / TEA685x" id="device-type" readonly>
|
||||||
|
<ul class="options">
|
||||||
|
<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>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3>Tuner connection:</h3>
|
<h3>Tuner connection:</h3>
|
||||||
<div style="width: 300px;" class="auto top-10">
|
<div style="width: 300px;" class="auto top-10">
|
||||||
<label class="toggleSwitch nolabel" onclick="">
|
<label class="toggleSwitch nolabel" onclick="">
|
||||||
@@ -74,24 +107,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br class="top-25">
|
|
||||||
<h3>Webserver connection:</h3>
|
|
||||||
<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="form-group">
|
|
||||||
<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">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="webserver-port">Webserver port:</label>
|
|
||||||
<input class="input-text w-100" type="text" name="webserver-port" id="webserver-port" placeholder="8080">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- BASIC SETTINGS END -->
|
<!-- TUNER SETTINGS END -->
|
||||||
<!-- AUDIO SETTINGS -->
|
<!-- AUDIO SETTINGS -->
|
||||||
<div id="step2" class="step" style="display: none;">
|
<div id="step3" class="step" style="display: none;">
|
||||||
<div class="panel-100" style="min-height: 120px;margin-bottom: 0;">
|
<div class="panel-100" style="min-height: 120px;margin-bottom: 0;">
|
||||||
<h2 class="settings-heading">AUDIO SETTINGS</h2>
|
<h2 class="settings-heading">AUDIO SETTINGS</h2>
|
||||||
<p class="m-0 text-gray">In this section, we will set up the audio.<br>
|
<p class="m-0 text-gray">In this section, we will set up the audio.<br>
|
||||||
@@ -143,7 +162,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- AUDIO SETTINGS END -->
|
<!-- AUDIO SETTINGS END -->
|
||||||
<!-- IDENTIFICATION START -->
|
<!-- IDENTIFICATION START -->
|
||||||
<div id="step3" class="step" style="display: none;">
|
<div id="step4" class="step" style="display: none;">
|
||||||
<div class="panel-100" style="padding-bottom: 20px;">
|
<div class="panel-100" style="padding-bottom: 20px;">
|
||||||
<h2 class="settings-heading">IDENTIFICATION INFO</h2>
|
<h2 class="settings-heading">IDENTIFICATION INFO</h2>
|
||||||
<p class="text-gray">In this part, we will set up your indentification info, such as the server name, description and location.</p>
|
<p class="text-gray">In this part, we will set up your indentification info, such as the server name, description and location.</p>
|
||||||
@@ -188,7 +207,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- IDENTIFICATION END -->
|
<!-- IDENTIFICATION END -->
|
||||||
<!-- ADMIN SETTINGS START -->
|
<!-- ADMIN SETTINGS START -->
|
||||||
<div id="step4" class="step" style="display: none;">
|
<div id="step5" class="step" style="display: none;">
|
||||||
<h2 class="settings-heading">Admin panel settings</h2>
|
<h2 class="settings-heading">Admin panel settings</h2>
|
||||||
<p>We are at the last and final step of the settings.</p>
|
<p>We are at the last and final step of the settings.</p>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user