You've already forked fm-dx-webserver
mirror of
https://github.com/KubaPro010/fm-dx-webserver.git
synced 2026-02-27 06:23:53 +01:00
bugfixes, global url params, rds endpoint
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,5 +1,7 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
/*.json
|
/*.json
|
||||||
/ffmpeg.exe
|
|
||||||
/serverlog.txt
|
/serverlog.txt
|
||||||
/web/js/plugins/
|
/web/js/plugins/
|
||||||
|
/plugins/*
|
||||||
|
!/plugins/example/frontend.js
|
||||||
|
!/plugins/example.js
|
||||||
1
index.js
1
index.js
@@ -6,4 +6,5 @@ require('./server/index.js');
|
|||||||
* Github repo: https://github.com/NoobishSVK/fm-dx-webserver
|
* Github repo: https://github.com/NoobishSVK/fm-dx-webserver
|
||||||
* Server files: /server
|
* Server files: /server
|
||||||
* Client files (web): /web
|
* Client files (web): /web
|
||||||
|
* Plugin files: /plugins
|
||||||
*/
|
*/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "fm-dx-webserver",
|
"name": "fm-dx-webserver",
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"description": "FM DX Webserver",
|
"description": "FM DX Webserver",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -205,12 +205,13 @@ const updateInterval = 75;
|
|||||||
var dataToSend = {
|
var dataToSend = {
|
||||||
pi: '?',
|
pi: '?',
|
||||||
freq: 87.500.toFixed(3),
|
freq: 87.500.toFixed(3),
|
||||||
previousFreq: 87.500.toFixed(3),
|
prevFreq: 87.500.toFixed(3),
|
||||||
signal: 0,
|
sig: 0,
|
||||||
highestSignal: -Infinity,
|
sigRaw: '',
|
||||||
|
sigTop: -Infinity,
|
||||||
bw: 0,
|
bw: 0,
|
||||||
st: false,
|
st: false,
|
||||||
st_forced: false,
|
stForced: false,
|
||||||
rds: false,
|
rds: false,
|
||||||
ps: '',
|
ps: '',
|
||||||
tp: 0,
|
tp: 0,
|
||||||
@@ -224,13 +225,14 @@ var dataToSend = {
|
|||||||
eq: 0,
|
eq: 0,
|
||||||
ant: 0,
|
ant: 0,
|
||||||
txInfo: {
|
txInfo: {
|
||||||
station: '',
|
tx: '',
|
||||||
pol: '',
|
pol: '',
|
||||||
erp: '',
|
erp: '',
|
||||||
city: '',
|
city: '',
|
||||||
itu: '',
|
itu: '',
|
||||||
distance: '',
|
dist: '',
|
||||||
azimuth: ''
|
azi: '',
|
||||||
|
id: ''
|
||||||
},
|
},
|
||||||
country_name: '',
|
country_name: '',
|
||||||
country_iso: 'UN',
|
country_iso: 'UN',
|
||||||
@@ -251,7 +253,7 @@ const initialData = { ...dataToSend };
|
|||||||
const resetToDefault = dataToSend => Object.assign(dataToSend, initialData);
|
const resetToDefault = dataToSend => Object.assign(dataToSend, initialData);
|
||||||
|
|
||||||
|
|
||||||
function handleData(wss, receivedData) {
|
function handleData(wss, receivedData, rdsWss) {
|
||||||
// Retrieve the last update time for this client
|
// Retrieve the last update time for this client
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
|
|
||||||
@@ -350,6 +352,10 @@ function handleData(wss, receivedData) {
|
|||||||
modifiedData += errorsNew.toString(16).padStart(2, '0');
|
modifiedData += errorsNew.toString(16).padStart(2, '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rdsWss.clients.forEach((client) => { // Send to /rds endpoint via WebSocket
|
||||||
|
client.send(modifiedData);
|
||||||
|
});
|
||||||
|
|
||||||
rdsparser.parse_string(rds, modifiedData);
|
rdsparser.parse_string(rds, modifiedData);
|
||||||
legacyRdsPiBuffer = null;
|
legacyRdsPiBuffer = null;
|
||||||
break;
|
break;
|
||||||
@@ -360,13 +366,14 @@ function handleData(wss, receivedData) {
|
|||||||
const currentTx = fetchTx(parseFloat(dataToSend.freq).toFixed(1), dataToSend.pi, dataToSend.ps);
|
const currentTx = fetchTx(parseFloat(dataToSend.freq).toFixed(1), dataToSend.pi, dataToSend.ps);
|
||||||
if(currentTx && currentTx.station !== undefined) {
|
if(currentTx && currentTx.station !== undefined) {
|
||||||
dataToSend.txInfo = {
|
dataToSend.txInfo = {
|
||||||
station: currentTx.station,
|
tx: currentTx.station,
|
||||||
pol: currentTx.pol,
|
pol: currentTx.pol,
|
||||||
erp: currentTx.erp,
|
erp: currentTx.erp,
|
||||||
city: currentTx.city,
|
city: currentTx.city,
|
||||||
itu: currentTx.itu,
|
itu: currentTx.itu,
|
||||||
distance: currentTx.distance,
|
dist: currentTx.distance,
|
||||||
azimuth: currentTx.azimuth
|
azi: currentTx.azimuth,
|
||||||
|
id: currentTx.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,20 +396,22 @@ function processSignal(receivedData, st, stForced) {
|
|||||||
const modifiedData = receivedData.substring(2);
|
const modifiedData = receivedData.substring(2);
|
||||||
const parsedValue = parseFloat(modifiedData);
|
const parsedValue = parseFloat(modifiedData);
|
||||||
dataToSend.st = st;
|
dataToSend.st = st;
|
||||||
dataToSend.st_forced = stForced;
|
dataToSend.stForced = stForced;
|
||||||
initialData.st = st;
|
initialData.st = st;
|
||||||
initialData.st_forced = stForced;
|
initialData.stForced = stForced;
|
||||||
|
|
||||||
if (!isNaN(parsedValue)) {
|
if (!isNaN(parsedValue)) {
|
||||||
// Convert parsedValue to a number
|
// Convert parsedValue to a number
|
||||||
var signal = parseFloat(parsedValue.toFixed(2));
|
var signal = parseFloat(parsedValue.toFixed(2));
|
||||||
dataToSend.signal = signal;
|
dataToSend.sig = signal;
|
||||||
initialData.signal = signal;
|
initialData.sig = signal;
|
||||||
|
dataToSend.sigRaw = receivedData;
|
||||||
|
initialData.sigRaw = receivedData;
|
||||||
|
|
||||||
// Convert highestSignal to a number for comparison
|
// Convert highestSignal to a number for comparison
|
||||||
var highestSignal = parseFloat(dataToSend.highestSignal);
|
var highestSignal = parseFloat(dataToSend.sigTop);
|
||||||
if (signal > highestSignal) {
|
if (signal > highestSignal) {
|
||||||
dataToSend.highestSignal = signal.toString(); // Convert back to string for consistency
|
dataToSend.sigTop = signal.toString(); // Convert back to string for consistency
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ router.get('/', (req, res) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const noPlugins = req.query.noPlugins === 'true';
|
||||||
|
|
||||||
if (configExists() === false) {
|
if (configExists() === false) {
|
||||||
let serialPorts;
|
let serialPorts;
|
||||||
|
|
||||||
@@ -57,6 +59,7 @@ router.get('/', (req, res) => {
|
|||||||
tuningUpperLimit: serverConfig.webserver.tuningUpperLimit,
|
tuningUpperLimit: serverConfig.webserver.tuningUpperLimit,
|
||||||
chatEnabled: serverConfig.webserver.chatEnabled,
|
chatEnabled: serverConfig.webserver.chatEnabled,
|
||||||
device: serverConfig.device,
|
device: serverConfig.device,
|
||||||
|
noPlugins,
|
||||||
plugins: serverConfig.plugins,
|
plugins: serverConfig.plugins,
|
||||||
bwSwitch: serverConfig.bwSwitch ? serverConfig.bwSwitch : false
|
bwSwitch: serverConfig.bwSwitch ? serverConfig.bwSwitch : false
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
const WebSocket = require('ws');
|
|
||||||
const dataHandler = require('./datahandler');
|
const dataHandler = require('./datahandler');
|
||||||
const storage = require('./storage');
|
const storage = require('./storage');
|
||||||
const consoleCmd = require('./console');
|
const consoleCmd = require('./console');
|
||||||
@@ -55,7 +54,7 @@ function formatUptime(uptimeInSeconds) {
|
|||||||
|
|
||||||
let incompleteDataBuffer = '';
|
let incompleteDataBuffer = '';
|
||||||
|
|
||||||
function resolveDataBuffer(data, wss) {
|
function resolveDataBuffer(data, wss, rdsWss) {
|
||||||
var receivedData = incompleteDataBuffer + data.toString();
|
var receivedData = incompleteDataBuffer + data.toString();
|
||||||
const isIncomplete = (receivedData.slice(-1) != '\n');
|
const isIncomplete = (receivedData.slice(-1) != '\n');
|
||||||
|
|
||||||
@@ -73,7 +72,7 @@ function resolveDataBuffer(data, wss) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (receivedData.length) {
|
if (receivedData.length) {
|
||||||
dataHandler.handleData(wss, receivedData);
|
dataHandler.handleData(wss, receivedData, rdsWss);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const httpServer = http.createServer(app);
|
|||||||
const WebSocket = require('ws');
|
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 path = require('path');
|
const path = require('path');
|
||||||
const net = require('net');
|
const net = require('net');
|
||||||
const client = new net.Socket();
|
const client = new net.Socket();
|
||||||
@@ -109,7 +110,7 @@ if (serverConfig.xdrd.wirelessConnection === false) {
|
|||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
serialport.on('data', (data) => {
|
serialport.on('data', (data) => {
|
||||||
helpers.resolveDataBuffer(data, wss);
|
helpers.resolveDataBuffer(data, wss, rdsWss);
|
||||||
});
|
});
|
||||||
|
|
||||||
serialport.on('error', (error) => {
|
serialport.on('error', (error) => {
|
||||||
@@ -185,7 +186,7 @@ function connectToXdrd() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
client.on('data', (data) => {
|
client.on('data', (data) => {
|
||||||
helpers.resolveDataBuffer(data, wss);
|
helpers.resolveDataBuffer(data, wss, rdsWss);
|
||||||
if (authFlags.authMsg == true && authFlags.messageCount > 1) {
|
if (authFlags.authMsg == true && authFlags.messageCount > 1) {
|
||||||
// If the limit is reached, remove the 'data' event listener
|
// If the limit is reached, remove the 'data' event listener
|
||||||
client.off('data', authDataHandler);
|
client.off('data', authDataHandler);
|
||||||
@@ -437,6 +438,15 @@ chatWss.on('connection', (ws, request) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
rdsWss.on('connection', (ws, request) => {
|
||||||
|
ws.on('message', function incoming(message) {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on('close', function close() {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Websocket register for /text, /audio and /chat paths
|
// Websocket register for /text, /audio and /chat paths
|
||||||
httpServer.on('upgrade', (request, socket, head) => {
|
httpServer.on('upgrade', (request, socket, head) => {
|
||||||
if (request.url === '/text') {
|
if (request.url === '/text') {
|
||||||
@@ -453,6 +463,12 @@ httpServer.on('upgrade', (request, socket, head) => {
|
|||||||
chatWss.emit('connection', ws, request);
|
chatWss.emit('connection', ws, request);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
} else if (request.url === '/rds') {
|
||||||
|
sessionMiddleware(request, {}, () => {
|
||||||
|
rdsWss.handleUpgrade(request, socket, head, (ws) => {
|
||||||
|
rdsWss.emit('connection', ws, request);
|
||||||
|
});
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
socket.destroy();
|
socket.destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ function processData(data, piCode, rdsPs) {
|
|||||||
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,
|
||||||
foundStation: true
|
foundStation: true
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -83,14 +83,14 @@ input[type="text"], textarea, input[type="password"] {
|
|||||||
|
|
||||||
#tune-buttons input[type="text"] {
|
#tune-buttons input[type="text"] {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
height: 100%;
|
height: 48px;
|
||||||
min-height: 46px;
|
min-height: 46px;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border: 2px solid transparent;
|
border: 2px solid transparent;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
background-color: var(--color-1-transparent);
|
background-color: transparent;
|
||||||
font-family: 'Titillium Web', sans-serif;
|
font-family: 'Titillium Web', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ input[type="text"], textarea, input[type="password"] {
|
|||||||
border: 0;
|
border: 0;
|
||||||
color: var(--color-1);
|
color: var(--color-1);
|
||||||
width: 25%;
|
width: 25%;
|
||||||
height: 100%;
|
height: 48px;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -158,7 +158,7 @@ input[type="range"] {
|
|||||||
/* Track: Mozilla Firefox */
|
/* Track: Mozilla Firefox */
|
||||||
input[type="range"]::-moz-range-track {
|
input[type="range"]::-moz-range-track {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
background: var(--color-1-transparent);
|
background-color: transpraent;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
@@ -341,3 +341,9 @@ select option {
|
|||||||
select:hover {
|
select:hover {
|
||||||
background: var(--color-5);
|
background: var(--color-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
#tune-buttons input[type="text"] {
|
||||||
|
background-color: var(--color-1-transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,11 @@
|
|||||||
background-color: var(--color-4);
|
background-color: var(--color-4);
|
||||||
color: var(--color-main);
|
color: var(--color-main);
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
|
transition: 0.35s ease-in-out background-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown input:hover {
|
||||||
|
background-color: var(--color-main-bright);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown.opened > input {
|
.dropdown.opened > input {
|
||||||
|
|||||||
@@ -112,7 +112,7 @@
|
|||||||
|
|
||||||
.hover-brighten:hover {
|
.hover-brighten:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: var(--color-2);
|
background-color: var(--color-2-transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-left {
|
.text-left {
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#wrapper {
|
#wrapper {
|
||||||
width: 1180px;
|
width: 100%;
|
||||||
max-width: 1180px;
|
max-width: calc(0% + 1180px);
|
||||||
}
|
}
|
||||||
#wrapper.setup-wrapper {
|
#wrapper.setup-wrapper {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|||||||
@@ -8,8 +8,25 @@
|
|||||||
transition: 0.3s ease-in-out background-color;
|
transition: 0.3s ease-in-out background-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
*[class^="panel-"]:not(.no-bg):not(.no-filter) {
|
*[class^="panel-"]:not(.no-bg):not(.no-filter):not(.w-100) {
|
||||||
backdrop-filter:blur(5px);
|
-webkit-backdrop-filter: blur(5px);
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-100.w-100 {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-100.w-100::before {
|
||||||
|
content: '';
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: -1;
|
||||||
|
border-radius: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-10 {
|
.panel-10 {
|
||||||
@@ -54,6 +71,9 @@
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
*[class^="panel-"]:not(.no-bg):not(.no-filter) {
|
||||||
|
backdrop-filter:blur(0px);
|
||||||
|
}
|
||||||
.flex-phone {
|
.flex-phone {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|||||||
160
web/index.ejs
160
web/index.ejs
@@ -125,12 +125,12 @@
|
|||||||
|
|
||||||
<% if (antennas.enabled == true) { %>
|
<% if (antennas.enabled == true) { %>
|
||||||
<div class="panel-50 no-bg h-100 br-0 m-0 dropdown" id="data-ant" style="margin-right: 25px;">
|
<div class="panel-50 no-bg h-100 br-0 m-0 dropdown" id="data-ant" style="margin-right: 25px;">
|
||||||
<input type="text" placeholder="Ant A" readonly>
|
<input type="text" placeholder="Ant A" readonly tabindex="0">
|
||||||
<ul class="options open-top">
|
<ul class="options open-top" tabindex="-1">
|
||||||
<% if(antennas.ant1.enabled == true) { %><li data-value="0" class="option"><%= antennas.ant1.name %></li><% } %>
|
<% if(antennas.ant1.enabled == true) { %><li data-value="0" class="option" tabindex="0"><%= antennas.ant1.name %></li><% } %>
|
||||||
<% if(antennas.ant2.enabled == true) { %><li data-value="1" class="option"><%= antennas.ant2.name %></li><% } %>
|
<% if(antennas.ant2.enabled == true) { %><li data-value="1" class="option" tabindex="0"><%= antennas.ant2.name %></li><% } %>
|
||||||
<% if(antennas.ant3.enabled == true) { %><li data-value="2" class="option"><%= antennas.ant3.name %></li><% } %>
|
<% if(antennas.ant3.enabled == true) { %><li data-value="2" class="option" tabindex="0"><%= antennas.ant3.name %></li><% } %>
|
||||||
<% if(antennas.ant4.enabled == true) { %><li data-value="3" class="option"><%= antennas.ant4.name %></li><% } %>
|
<% if(antennas.ant4.enabled == true) { %><li data-value="3" class="option" tabindex="0"><%= antennas.ant4.name %></li><% } %>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
@@ -165,71 +165,71 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
<% if (device == 'tef' && bwSwitch == true) { %>
|
<% if (device == 'tef' && bwSwitch == true) { %>
|
||||||
<div class="panel-50 w-150 no-bg h-100 m-0 dropdown" id="data-bw" style="margin-left: 25px;">
|
<div class="panel-50 w-150 no-bg h-100 m-0 dropdown" id="data-bw" style="margin-left: 25px;">
|
||||||
<input type="text" placeholder="Auto BW" readonly>
|
<input type="text" placeholder="Auto BW" readonly tabindex="0">
|
||||||
<ul class="options open-top">
|
<ul class="options open-top" tabindex="-1">
|
||||||
<li data-value="0" class="option">Auto</li>
|
<li data-value="0" class="option" tabindex="0">Auto</li>
|
||||||
<li data-value="56000" class="option">56 KHz</li>
|
<li data-value="56000" class="option" tabindex="0">56 KHz</li>
|
||||||
<li data-value="64000" class="option">64 KHz</li>
|
<li data-value="64000" class="option" tabindex="0">64 KHz</li>
|
||||||
<li data-value="72000" class="option">72 KHz</li>
|
<li data-value="72000" class="option" tabindex="0">72 KHz</li>
|
||||||
<li data-value="84000" class="option">84 KHz</li>
|
<li data-value="84000" class="option" tabindex="0">84 KHz</li>
|
||||||
<li data-value="97000" class="option">97 KHz</li>
|
<li data-value="97000" class="option" tabindex="0">97 KHz</li>
|
||||||
<li data-value="114000" class="option">114 KHz</li>
|
<li data-value="114000" class="option" tabindex="0">114 KHz</li>
|
||||||
<li data-value="133000" class="option">133 KHz</li>
|
<li data-value="133000" class="option" tabindex="0">133 KHz</li>
|
||||||
<li data-value="151000" class="option">151 KHz</li>
|
<li data-value="151000" class="option" tabindex="0">151 KHz</li>
|
||||||
<li data-value="184000" class="option">184 KHz</li>
|
<li data-value="184000" class="option" tabindex="0">184 KHz</li>
|
||||||
<li data-value="200000" class="option">200 KHz</li>
|
<li data-value="200000" class="option" tabindex="0">200 KHz</li>
|
||||||
<li data-value="217000" class="option">217 KHz</li>
|
<li data-value="217000" class="option" tabindex="0">217 KHz</li>
|
||||||
<li data-value="236000" class="option">236 KHz</li>
|
<li data-value="236000" class="option" tabindex="0">236 KHz</li>
|
||||||
<li data-value="254000" class="option">254 KHz</li>
|
<li data-value="254000" class="option" tabindex="0">254 KHz</li>
|
||||||
<li data-value="287000" class="option">287 KHz</li>
|
<li data-value="287000" class="option" tabindex="0">287 KHz</li>
|
||||||
<li data-value="311000" class="option">311 KHz</li>
|
<li data-value="311000" class="option" tabindex="0">311 KHz</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<% if (device == 'xdr' && bwSwitch == true) { %>
|
<% if (device == 'xdr' && bwSwitch == true) { %>
|
||||||
<div class="panel-50 w-150 no-bg h-100 m-0 dropdown" id="data-bw" style="margin-left: 25px;">
|
<div class="panel-50 w-150 no-bg h-100 m-0 dropdown" id="data-bw" style="margin-left: 25px;">
|
||||||
<input type="text" placeholder="Auto BW" readonly>
|
<input type="text" placeholder="Auto BW" readonly tabindex="0">
|
||||||
<ul class="options open-top">
|
<ul class="options open-top" tabindex="-1">
|
||||||
<li data-value="0" data-value2="-1" class="option">Auto</li>
|
<li data-value="0" data-value2="-1" class="option" tabindex="0">Auto</li>
|
||||||
<li data-value="55000" data-value2="0" class="option">55 KHz</li>
|
<li data-value="55000" data-value2="0" class="option" tabindex="0">55 KHz</li>
|
||||||
<li data-value="73000" data-value2="1" class="option">73 KHz</li>
|
<li data-value="73000" data-value2="1" class="option" tabindex="0">73 KHz</li>
|
||||||
<li data-value="90000" data-value2="2" class="option">90 KHz</li>
|
<li data-value="90000" data-value2="2" class="option" tabindex="0">90 KHz</li>
|
||||||
<li data-value="108000" data-value2="3" class="option">108 KHz</li>
|
<li data-value="108000" data-value2="3" class="option" tabindex="0">108 KHz</li>
|
||||||
<li data-value="125000" data-value2="4" class="option">125 KHz</li>
|
<li data-value="125000" data-value2="4" class="option" tabindex="0">125 KHz</li>
|
||||||
<li data-value="142000" data-value2="5" class="option">142 KHz</li>
|
<li data-value="142000" data-value2="5" class="option" tabindex="0">142 KHz</li>
|
||||||
<li data-value="159000" data-value2="6" class="option">159 KHz</li>
|
<li data-value="159000" data-value2="6" class="option" tabindex="0">159 KHz</li>
|
||||||
<li data-value="177000" data-value2="7" class="option">177 KHz</li>
|
<li data-value="177000" data-value2="7" class="option" tabindex="0">177 KHz</li>
|
||||||
<li data-value="194000" data-value2="8" class="option">194 KHz</li>
|
<li data-value="194000" data-value2="8" class="option" tabindex="0">194 KHz</li>
|
||||||
<li data-value="211000" data-value2="9" class="option">211 KHz</li>
|
<li data-value="211000" data-value2="9" class="option" tabindex="0">211 KHz</li>
|
||||||
<li data-value="229000" data-value2="10" class="option">229 KHz</li>
|
<li data-value="229000" data-value2="10" class="option" tabindex="0">229 KHz</li>
|
||||||
<li data-value="246000" data-value2="11" class="option">246 KHz</li>
|
<li data-value="246000" data-value2="11" class="option" tabindex="0">246 KHz</li>
|
||||||
<li data-value="263000" data-value2="12" class="option">263 KHz</li>
|
<li data-value="263000" data-value2="12" class="option" tabindex="0">263 KHz</li>
|
||||||
<li data-value="281000" data-value2="13" class="option">281 KHz</li>
|
<li data-value="281000" data-value2="13" class="option" tabindex="0">281 KHz</li>
|
||||||
<li data-value="298000" data-value2="14" class="option">298 KHz</li>
|
<li data-value="298000" data-value2="14" class="option" tabindex="0">298 KHz</li>
|
||||||
<li data-value="309000" data-value2="15" class="option">309 KHz</li>
|
<li data-value="309000" data-value2="15" class="option" tabindex="0">309 KHz</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<% if (device == 'sdr' && bwSwitch == true) { %>
|
<% if (device == 'sdr' && bwSwitch == true) { %>
|
||||||
<div class="panel-50 w-150 no-bg h-100 m-0 dropdown" id="data-bw" style="margin-left: 25px;">
|
<div class="panel-50 w-150 no-bg h-100 m-0 dropdown" id="data-bw" style="margin-left: 25px;">
|
||||||
<input type="text" placeholder="Auto BW" readonly>
|
<input type="text" placeholder="Auto BW" readonly tabindex="0">
|
||||||
<ul class="options open-top">
|
<ul class="options open-top" tabindex="-1">
|
||||||
<li data-value="0" class="option">Auto</li>
|
<li data-value="0" class="option" tabindex="0">Auto</li>
|
||||||
<li data-value="4000" class="option">4 KHz</li>
|
<li data-value="4000" class="option" tabindex="0">4 KHz</li>
|
||||||
<li data-value="8000" class="option">8 KHz</li>
|
<li data-value="8000" class="option" tabindex="0">8 KHz</li>
|
||||||
<li data-value="10000" class="option">10 KHz</li>
|
<li data-value="10000" class="option" tabindex="0">10 KHz</li>
|
||||||
<li data-value="20000" class="option">20 KHz</li>
|
<li data-value="20000" class="option" tabindex="0">20 KHz</li>
|
||||||
<li data-value="30000" class="option">30 KHz</li>
|
<li data-value="30000" class="option" tabindex="0">30 KHz</li>
|
||||||
<li data-value="50000" class="option">50 KHz</li>
|
<li data-value="50000" class="option" tabindex="0">50 KHz</li>
|
||||||
<li data-value="75000" class="option">75 KHz</li>
|
<li data-value="75000" class="option" tabindex="0">75 KHz</li>
|
||||||
<li data-value="100000" class="option">100 KHz</li>
|
<li data-value="100000" class="option" tabindex="0">100 KHz</li>
|
||||||
<li data-value="125000" class="option">125 KHz</li>
|
<li data-value="125000" class="option" tabindex="0">125 KHz</li>
|
||||||
<li data-value="150000" class="option">150 KHz</li>
|
<li data-value="150000" class="option" tabindex="0">150 KHz</li>
|
||||||
<li data-value="175000" class="option">175 KHz</li>
|
<li data-value="175000" class="option" tabindex="0">175 KHz</li>
|
||||||
<li data-value="200000" class="option">200 KHz</li>
|
<li data-value="200000" class="option" tabindex="0">200 KHz</li>
|
||||||
<li data-value="225000" class="option">225 KHz</li>
|
<li data-value="225000" class="option" tabindex="0">225 KHz</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
@@ -323,17 +323,17 @@
|
|||||||
<div class="form-group top-25">
|
<div class="form-group top-25">
|
||||||
<label for="themes"><i class="fa-solid fa-palette"></i> Theme:</label>
|
<label for="themes"><i class="fa-solid fa-palette"></i> Theme:</label>
|
||||||
<div class="dropdown" id="theme-selector">
|
<div class="dropdown" id="theme-selector">
|
||||||
<input type="text" placeholder="Default" readonly>
|
<input type="text" placeholder="Default" readonly tabindex="0">
|
||||||
<ul class="options">
|
<ul class="options" tabindex="-1">
|
||||||
<li class="option" data-value="theme1">Default</li>
|
<li class="option" tabindex="0" data-value="theme1">Default</li>
|
||||||
<li class="option" data-value="theme2">Cappuccino</li>
|
<li class="option" tabindex="0" data-value="theme2">Cappuccino</li>
|
||||||
<li class="option" data-value="theme3">Nature</li>
|
<li class="option" tabindex="0" data-value="theme3">Nature</li>
|
||||||
<li class="option" data-value="theme4">Ocean</li>
|
<li class="option" tabindex="0" data-value="theme4">Ocean</li>
|
||||||
<li class="option" data-value="theme5">Terminal</li>
|
<li class="option" tabindex="0" data-value="theme5">Terminal</li>
|
||||||
<li class="option" data-value="theme6">Nightlife</li>
|
<li class="option" tabindex="0" data-value="theme6">Nightlife</li>
|
||||||
<li class="option" data-value="theme7">Blurple</li>
|
<li class="option" tabindex="0" data-value="theme7">Blurple</li>
|
||||||
<li class="option" data-value="theme8">Construction</li>
|
<li class="option" tabindex="0" data-value="theme8">Construction</li>
|
||||||
<li class="option" data-value="theme9">AMOLED</li>
|
<li class="option" tabindex="0" data-value="theme9">AMOLED</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -342,22 +342,22 @@
|
|||||||
<div class="form-group top-25">
|
<div class="form-group top-25">
|
||||||
<label for="signal"><i class="fa-solid fa-signal"></i> Signal units:</label>
|
<label for="signal"><i class="fa-solid fa-signal"></i> Signal units:</label>
|
||||||
<div class="dropdown" id="signal-selector">
|
<div class="dropdown" id="signal-selector">
|
||||||
<input type="text" placeholder="dBf" readonly>
|
<input type="text" placeholder="dBf" readonly tabindex="0">
|
||||||
<ul class="options">
|
<ul class="options" tabindex="-1">
|
||||||
<li class="option" data-value="dbf">dBf</li>
|
<li class="option" tabindex="0" data-value="dbf">dBf</li>
|
||||||
<li class="option" data-value="dbuv">dBuV</li>
|
<li class="option" tabindex="0" data-value="dbuv">dBuV</li>
|
||||||
<li class="option" data-value="dbm">dBm</li>
|
<li class="option" tabindex="0" data-value="dbm">dBm</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div><br>
|
</div><br>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="extended-frequency-range">
|
<input type="checkbox" tabindex="0" id="extended-frequency-range" aria-label="Add decimals manually">
|
||||||
<label for="extended-frequency-range">Add decimals manually</label>
|
<label for="extended-frequency-range">Add decimals manually</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="ps-underscores">
|
<input type="checkbox" tabindex="0" id="ps-underscores" aria-label="Add underscores to RDS PS">
|
||||||
<label for="ps-underscores">Add underscores to RDS PS</label>
|
<label for="ps-underscores">Add underscores to RDS PS</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -491,8 +491,10 @@
|
|||||||
|
|
||||||
<script src="js/websocket.js"></script>
|
<script src="js/websocket.js"></script>
|
||||||
<script src="js/webserver.js"></script>
|
<script src="js/webserver.js"></script>
|
||||||
<% plugins?.forEach(function(plugin) { %>
|
<% if (!noPlugins) { %>
|
||||||
|
<% plugins?.forEach(function(plugin) { %>
|
||||||
<script src="js/plugins/<%= plugin %>"></script>
|
<script src="js/plugins/<%= plugin %>"></script>
|
||||||
<% }); %>
|
<% }); %>
|
||||||
|
<% } %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
const DefaultVolume = 0.5;
|
|
||||||
let Stream;
|
let Stream;
|
||||||
let shouldReconnect = true;
|
let shouldReconnect = true;
|
||||||
let newVolumeGlobal = 1;
|
let newVolumeGlobal = 1;
|
||||||
@@ -28,7 +27,7 @@ function destroyStream() {
|
|||||||
function OnConnectivityCallback(isConnected) {
|
function OnConnectivityCallback(isConnected) {
|
||||||
console.log("Connectivity changed:", isConnected);
|
console.log("Connectivity changed:", isConnected);
|
||||||
if (Stream) {
|
if (Stream) {
|
||||||
Stream.Volume = isConnected ? 1.0 : DefaultVolume;
|
Stream.Volume = $('#volumeSlider').val();
|
||||||
} else {
|
} else {
|
||||||
console.warn("Stream is not initialized.");
|
console.warn("Stream is not initialized.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,30 @@
|
|||||||
// Variables
|
$(document).ready(function() {
|
||||||
const $dropdowns = $('.dropdown');
|
// Variables
|
||||||
const $input = $('input');
|
const $dropdowns = $('.dropdown');
|
||||||
const $listOfOptions = $('.option');
|
const $listOfOptions = $('.option');
|
||||||
let currentDropdown = null; // Track the currently clicked dropdown
|
let currentDropdown = null; // Track the currently clicked dropdown
|
||||||
|
let currentIndex = -1; // Track the currently focused option
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
const toggleDropdown = (event) => {
|
const toggleDropdown = (event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const $currentDropdown = $(event.currentTarget);
|
const $currentDropdown = $(event.currentTarget).closest('.dropdown');
|
||||||
|
|
||||||
// Close the previously opened dropdown if any
|
// Close the previously opened dropdown if any
|
||||||
$dropdowns.not($currentDropdown).removeClass('opened');
|
$dropdowns.not($currentDropdown).removeClass('opened');
|
||||||
|
|
||||||
$currentDropdown.toggleClass('opened');
|
$currentDropdown.toggleClass('opened');
|
||||||
currentDropdown = $currentDropdown.hasClass('opened') ? $currentDropdown : null;
|
currentDropdown = $currentDropdown.hasClass('opened') ? $currentDropdown : null;
|
||||||
|
currentIndex = -1; // Reset the current index when toggling the dropdown
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectOption = (event) => {
|
const selectOption = (event) => {
|
||||||
const $currentDropdown = currentDropdown;
|
const $currentDropdown = currentDropdown;
|
||||||
|
|
||||||
switch($currentDropdown.attr('id')) {
|
switch($currentDropdown.attr('id')) {
|
||||||
case 'data-ant':
|
case 'data-ant':
|
||||||
socket.send("Z" + $(event.currentTarget).attr('data-value'));
|
socket.send("Z" + $(event.currentTarget).attr('data-value'));
|
||||||
tuneTo(getCurrentFreq()); //Reset RDS when change antenna input
|
tuneTo(getCurrentFreq()); // Reset RDS when change antenna input
|
||||||
break;
|
break;
|
||||||
case 'data-bw':
|
case 'data-bw':
|
||||||
legacyBwValue = $(event.currentTarget).attr('data-value2') || "";
|
legacyBwValue = $(event.currentTarget).attr('data-value2') || "";
|
||||||
@@ -40,9 +42,9 @@ const selectOption = (event) => {
|
|||||||
$currentDropdown.removeClass('opened');
|
$currentDropdown.removeClass('opened');
|
||||||
currentDropdown = null;
|
currentDropdown = null;
|
||||||
}, 10); // Adjust the delay as needed
|
}, 10); // Adjust the delay as needed
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeDropdownFromOutside = (event) => {
|
const closeDropdownFromOutside = (event) => {
|
||||||
const $currentDropdown = currentDropdown && $(currentDropdown);
|
const $currentDropdown = currentDropdown && $(currentDropdown);
|
||||||
const isClickedInsideDropdown = $currentDropdown && $currentDropdown.has(event.target).length > 0;
|
const isClickedInsideDropdown = $currentDropdown && $currentDropdown.has(event.target).length > 0;
|
||||||
|
|
||||||
@@ -50,18 +52,50 @@ const closeDropdownFromOutside = (event) => {
|
|||||||
$currentDropdown.removeClass('opened');
|
$currentDropdown.removeClass('opened');
|
||||||
currentDropdown = null;
|
currentDropdown = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Event Listeners
|
const navigateOptions = (event) => {
|
||||||
$(document).on('click', closeDropdownFromOutside);
|
if (!currentDropdown) return;
|
||||||
$listOfOptions.on('click', selectOption);
|
|
||||||
$dropdowns.on('click', toggleDropdown);
|
|
||||||
|
|
||||||
// MULTISELECT
|
const $options = currentDropdown.find('.option');
|
||||||
$('.multiselect option').mousedown(function(e) {
|
switch (event.key) {
|
||||||
|
case 'ArrowDown':
|
||||||
|
event.preventDefault();
|
||||||
|
currentIndex = (currentIndex + 1) % $options.length;
|
||||||
|
$options.eq(currentIndex).focus();
|
||||||
|
break;
|
||||||
|
case 'ArrowUp':
|
||||||
|
event.preventDefault();
|
||||||
|
currentIndex = (currentIndex - 1 + $options.length) % $options.length;
|
||||||
|
$options.eq(currentIndex).focus();
|
||||||
|
break;
|
||||||
|
case 'Enter':
|
||||||
|
event.preventDefault();
|
||||||
|
$options.eq(currentIndex).click();
|
||||||
|
break;
|
||||||
|
case 'Escape':
|
||||||
|
currentDropdown.removeClass('opened');
|
||||||
|
currentDropdown = null;
|
||||||
|
currentIndex = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Event Listeners
|
||||||
|
$(document).on('click', closeDropdownFromOutside);
|
||||||
|
$listOfOptions.on('click', selectOption);
|
||||||
|
$dropdowns.on('click', 'input', toggleDropdown);
|
||||||
|
$dropdowns.on('keydown', 'input', function(event) {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
toggleDropdown(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$dropdowns.on('keydown', '.option', navigateOptions);
|
||||||
|
|
||||||
|
// MULTISELECT
|
||||||
|
$('.multiselect option').mousedown(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var originalScrollTop = $(this).parent().scrollTop();
|
var originalScrollTop = $(this).parent().scrollTop();
|
||||||
console.log(originalScrollTop);
|
|
||||||
$(this).prop('selected', $(this).prop('selected') ? false : true);
|
$(this).prop('selected', $(this).prop('selected') ? false : true);
|
||||||
var self = this;
|
var self = this;
|
||||||
$(this).parent().focus();
|
$(this).parent().focus();
|
||||||
@@ -70,4 +104,5 @@ $('.multiselect option').mousedown(function(e) {
|
|||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
var currentDate = new Date('Jul 21, 2024 22:00:00');
|
var currentDate = new Date('Jul 31, 2024 17:00: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.5 [' + formattedDate + ']';
|
var currentVersion = 'v1.2.6 [' + formattedDate + ']';
|
||||||
|
|
||||||
getInitialSettings();
|
getInitialSettings();
|
||||||
|
|
||||||
|
|||||||
@@ -432,7 +432,8 @@ function checkKey(e) {
|
|||||||
if ($('#password:focus').length > 0
|
if ($('#password:focus').length > 0
|
||||||
|| $('#chat-send-message:focus').length > 0
|
|| $('#chat-send-message:focus').length > 0
|
||||||
|| $('#volumeSlider:focus').length > 0
|
|| $('#volumeSlider:focus').length > 0
|
||||||
|| $('#chat-nickname:focus').length > 0) {
|
|| $('#chat-nickname:focus').length > 0
|
||||||
|
|| $('.option:focus').length > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +613,7 @@ 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;
|
let highestSignal = parsedData.sigTop;
|
||||||
|
|
||||||
currentSignal = averageSignal
|
currentSignal = averageSignal
|
||||||
let signalText = $('.signal-units');
|
let signalText = $('.signal-units');
|
||||||
@@ -720,7 +721,7 @@ const updateDataElements = throttle(function(parsedData) {
|
|||||||
stereoColor = 'var(--color-3)';
|
stereoColor = 'var(--color-3)';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(parsedData.st_forced) {
|
if(parsedData.stForced) {
|
||||||
stereoColor = 'gray';
|
stereoColor = 'gray';
|
||||||
}
|
}
|
||||||
$dataSt.css('border', '2px solid ' + stereoColor);
|
$dataSt.css('border', '2px solid ' + stereoColor);
|
||||||
@@ -747,14 +748,14 @@ const updateDataElements = throttle(function(parsedData) {
|
|||||||
$dataBwInput.val($('#data-bw li[data-value="' + parsedData.bw + '"]').text());
|
$dataBwInput.val($('#data-bw li[data-value="' + parsedData.bw + '"]').text());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsedData.txInfo.station.length > 1) {
|
if (parsedData.txInfo.tx.length > 1) {
|
||||||
updateTextIfChanged($('#data-station-name'), parsedData.txInfo.station.replace(/%/g, '%25'));
|
updateTextIfChanged($('#data-station-name'), parsedData.txInfo.tx.replace(/%/g, '%25'));
|
||||||
updateTextIfChanged($('#data-station-erp'), parsedData.txInfo.erp);
|
updateTextIfChanged($('#data-station-erp'), parsedData.txInfo.erp);
|
||||||
updateTextIfChanged($('#data-station-city'), parsedData.txInfo.city);
|
updateTextIfChanged($('#data-station-city'), parsedData.txInfo.city);
|
||||||
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.distance);
|
updateTextIfChanged($('#data-station-distance'), parsedData.txInfo.dist);
|
||||||
updateTextIfChanged($('#data-station-azimuth'), parsedData.txInfo.azimuth);
|
updateTextIfChanged($('#data-station-azimuth'), parsedData.txInfo.azi);
|
||||||
$dataStationContainer.css('display', 'block');
|
$dataStationContainer.css('display', 'block');
|
||||||
} else {
|
} else {
|
||||||
$dataStationContainer.removeAttr('style');
|
$dataStationContainer.removeAttr('style');
|
||||||
@@ -786,7 +787,7 @@ let isEventListenerAdded = false;
|
|||||||
function updatePanels(parsedData) {
|
function updatePanels(parsedData) {
|
||||||
updateCounter++;
|
updateCounter++;
|
||||||
|
|
||||||
signalData.push(parsedData.signal);
|
signalData.push(parsedData.sig);
|
||||||
if (signalData.length > 8) {
|
if (signalData.length > 8) {
|
||||||
signalData.shift(); // Remove the oldest element
|
signalData.shift(); // Remove the oldest element
|
||||||
}
|
}
|
||||||
@@ -840,8 +841,10 @@ function updateButtonState(buttonId, value) {
|
|||||||
var button = $("#" + buttonId);
|
var button = $("#" + buttonId);
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
button.hasClass("btn-disabled") ? null : button.addClass("btn-disabled");
|
button.hasClass("btn-disabled") ? null : button.addClass("btn-disabled");
|
||||||
|
button.attr('aria-description', 'Off');
|
||||||
} else {
|
} else {
|
||||||
button.hasClass("btn-disabled") ? button.removeClass("btn-disabled") : null;
|
button.hasClass("btn-disabled") ? button.removeClass("btn-disabled") : null;
|
||||||
|
button.attr('aria-description', 'On');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -856,7 +859,7 @@ function toggleButtonState(buttonId) {
|
|||||||
|
|
||||||
function toggleForcedStereo() {
|
function toggleForcedStereo() {
|
||||||
var message = "B";
|
var message = "B";
|
||||||
message += parsedData.st_forced = (parsedData.st_forced == "1") ? "0" : "1";
|
message += parsedData.stForced = (parsedData.stForced == "1") ? "0" : "1";
|
||||||
socket.send(message);
|
socket.send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -865,7 +868,7 @@ function toggleAdminLock() {
|
|||||||
|
|
||||||
if($adminLockButton.hasClass('active')) {
|
if($adminLockButton.hasClass('active')) {
|
||||||
socket.send('wL0');
|
socket.send('wL0');
|
||||||
$adminLockButton.attr('aria-label', '"ock Tuner (Admin)')
|
$adminLockButton.attr('aria-label', 'Lock Tuner (Admin)')
|
||||||
$adminLockButton.removeClass('active');
|
$adminLockButton.removeClass('active');
|
||||||
} else {
|
} else {
|
||||||
socket.send('wL1');
|
socket.send('wL1');
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ $(document).ready(() => {
|
|||||||
setTheme(defaultTheme);
|
setTheme(defaultTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const themeParameter = getQueryParameter('theme');
|
||||||
|
if(themeParameter && themes[themeParameter]) {
|
||||||
|
setTheme(themeParameter);
|
||||||
|
themeSelector.find('input').val(themeSelector.find('.option[data-value="' + themeParameter + '"]').text());
|
||||||
|
}
|
||||||
|
|
||||||
if (savedTheme && themes[savedTheme]) {
|
if (savedTheme && themes[savedTheme]) {
|
||||||
setTheme(savedTheme);
|
setTheme(savedTheme);
|
||||||
themeSelector.find('input').val(themeSelector.find('.option[data-value="' + savedTheme + '"]').text());
|
themeSelector.find('input').val(themeSelector.find('.option[data-value="' + savedTheme + '"]').text());
|
||||||
@@ -49,6 +55,12 @@ $(document).ready(() => {
|
|||||||
|
|
||||||
const signalSelector = $('#signal-selector');
|
const signalSelector = $('#signal-selector');
|
||||||
|
|
||||||
|
const signalParameter = getQueryParameter('signalUnits');
|
||||||
|
if(signalParameter) {
|
||||||
|
signalSelector.find('input').val($(signalParameter).text());
|
||||||
|
localStorage.setItem('signalUnit', signalParameter);
|
||||||
|
}
|
||||||
|
|
||||||
if (localStorage.getItem('signalUnit')) {
|
if (localStorage.getItem('signalUnit')) {
|
||||||
signalSelector.find('input').val(signalSelector.find('.option[data-value="' + savedUnit + '"]').text());
|
signalSelector.find('input').val(signalSelector.find('.option[data-value="' + savedUnit + '"]').text());
|
||||||
}
|
}
|
||||||
@@ -123,9 +135,16 @@ $(document).ready(() => {
|
|||||||
localStorage.setItem("extendedFreqRange", isChecked);
|
localStorage.setItem("extendedFreqRange", isChecked);
|
||||||
});
|
});
|
||||||
|
|
||||||
var extendedFreqRange = localStorage.getItem("psUnderscores");
|
const psUnderscoreParameter = getQueryParameter('psUnderscores');
|
||||||
if (extendedFreqRange === "true") {
|
if(psUnderscoreParameter) {
|
||||||
$("#ps-underscores").prop("checked", true);
|
$("#ps-underscores").prop("checked", psUnderscoreParameter);
|
||||||
|
localStorage.setItem("psUnderscores", psUnderscoreParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
var psUnderscores = localStorage.getItem("psUnderscores");
|
||||||
|
if (psUnderscores) {
|
||||||
|
$("#ps-underscores").prop("checked", psUnderscores);
|
||||||
|
localStorage.setItem("psUnderscores", psUnderscores);
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#ps-underscores").change(function() {
|
$("#ps-underscores").change(function() {
|
||||||
@@ -138,6 +157,10 @@ $(document).ready(() => {
|
|||||||
setBg();
|
setBg();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getQueryParameter(name) {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
return urlParams.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
function setTheme(themeName) {
|
function setTheme(themeName) {
|
||||||
const themeColors = themes[themeName];
|
const themeColors = themes[themeName];
|
||||||
@@ -162,7 +185,8 @@ function setTheme(themeName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setBg() {
|
function setBg() {
|
||||||
if(localStorage.getItem('bgImage').length > 5 && localStorage.getItem('theme') != 'theme9') {
|
const disableBackgroundParameter = getQueryParameter('disableBackground');
|
||||||
|
if(localStorage.getItem('bgImage').length > 5 && localStorage.getItem('theme') != 'theme9' && disableBackgroundParameter != 'true') {
|
||||||
$('body').css('background', 'url(' + localStorage.getItem('bgImage') + ') top center / cover fixed no-repeat var(--color-main)');
|
$('body').css('background', 'url(' + localStorage.getItem('bgImage') + ') top center / cover fixed no-repeat var(--color-main)');
|
||||||
} else {
|
} else {
|
||||||
$('body').css('background', 'var(--color-main)');
|
$('body').css('background', 'var(--color-main)');
|
||||||
|
|||||||
106
web/setup.ejs
106
web/setup.ejs
@@ -101,15 +101,15 @@
|
|||||||
<h3>Maintenance</h3>
|
<h3>Maintenance</h3>
|
||||||
<div class="flex-container flex-center" style="margin: 30px;">
|
<div class="flex-container flex-center" style="margin: 30px;">
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="tuner-public">
|
<input type="checkbox" tabindex="0" id="tuner-public" aria-label="Public tuner (no password)">
|
||||||
<label for="tuner-public">Public tuner (no password)</label>
|
<label for="tuner-public">Public tuner (no password)</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="tuner-lock">
|
<input type="checkbox" tabindex="0" id="tuner-lock" aria-label="Admin lock (only admins can tune)">
|
||||||
<label for="tuner-lock">Admin lock [only admins can tune]</label>
|
<label for="tuner-lock">Admin lock (only admins can tune)</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="shutdown-tuner">
|
<input type="checkbox" tabindex="0" id="shutdown-tuner" aria-label="Auto shutdown">
|
||||||
<label for="shutdown-tuner">Auto-shutdown</label>
|
<label for="shutdown-tuner">Auto-shutdown</label>
|
||||||
</div><br>
|
</div><br>
|
||||||
</div>
|
</div>
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
|
|
||||||
<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="">
|
||||||
<input id="connection-type-toggle" type="checkbox" tabindex="0" />
|
<input id="connection-type-toggle" type="checkbox" tabindex="0" aria-label="Connection type"/>
|
||||||
<a></a>
|
<a></a>
|
||||||
<span>
|
<span>
|
||||||
<span class="left-span">Direct</span>
|
<span class="left-span">Direct</span>
|
||||||
@@ -158,10 +158,10 @@
|
|||||||
<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 tabindex="0" />
|
||||||
<ul class="options" id="deviceList">
|
<ul class="options" tabindex="-1" id="deviceList">
|
||||||
<% serialPorts.forEach(serialPort => { %>
|
<% serialPorts.forEach(serialPort => { %>
|
||||||
<li data-value="<%= serialPort.path %>" class="option"><%= serialPort.path %> - <%= serialPort.friendlyName %></li>
|
<li data-value="<%= serialPort.path %>" class="option" tabindex="0"><%= serialPort.path %> - <%= serialPort.friendlyName %></li>
|
||||||
<% }); %>
|
<% }); %>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -210,13 +210,13 @@
|
|||||||
</p>
|
</p>
|
||||||
<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 tabindex="0" />
|
||||||
<ul class="options" id="deviceList">
|
<ul class="options" tabindex="-1" id="deviceList">
|
||||||
<% videoDevices.forEach(device => { %>
|
<% videoDevices.forEach(device => { %>
|
||||||
<li data-value="<%= device.name %>" class="option"><%= device.name %></li>
|
<li data-value="<%= device.name %>" class="option" tabindex="0"><%= device.name %></li>
|
||||||
<% }); %>
|
<% }); %>
|
||||||
<% audioDevices.forEach(device => { %>
|
<% audioDevices.forEach(device => { %>
|
||||||
<li data-value="<%= device.name %>" class="option"><%= device.name %></li>
|
<li data-value="<%= device.name %>" class="option" tabindex="0"><%= device.name %></li>
|
||||||
<% }); %>
|
<% }); %>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -228,10 +228,10 @@
|
|||||||
</p>
|
</p>
|
||||||
<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 tabindex="0" />
|
||||||
<ul class="options">
|
<ul class="options" tabindex="-1">
|
||||||
<li data-value="2" class="option">Stereo</li>
|
<li data-value="2" class="option" tabindex="0">Stereo</li>
|
||||||
<li data-value="1" class="option">Mono</li>
|
<li data-value="1" class="option" tabindex="0">Mono</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -242,20 +242,20 @@
|
|||||||
</p>
|
</p>
|
||||||
<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 tabindex="0" />
|
||||||
<ul class="options">
|
<ul class="options" tabindex="-1">
|
||||||
<li data-value="64k" class="option">64k (lowest quality)</li>
|
<li data-value="64k" class="option" tabindex="0">64k (lowest quality)</li>
|
||||||
<li data-value="96k" class="option">96k (low quality)</li>
|
<li data-value="96k" class="option" tabindex="0">96k (low quality)</li>
|
||||||
<li data-value="128k" class="option">128k (standard)</li>
|
<li data-value="128k" class="option" tabindex="0">128k (standard)</li>
|
||||||
<li data-value="192k" class="option">192k (higher quality)</li>
|
<li data-value="192k" class="option" tabindex="0">192k (higher quality)</li>
|
||||||
<li data-value="256k" class="option">256k (very high quality)</li>
|
<li data-value="256k" class="option" tabindex="0">256k (very high quality)</li>
|
||||||
<li data-value="320k" class="option">320k (ultra quality)</li>
|
<li data-value="320k" class="option" tabindex="0">320k (ultra quality)</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group checkbox bottom-20">
|
<div class="form-group checkbox bottom-20">
|
||||||
<input type="checkbox" tabindex="0" id="audio-software-mode">
|
<input type="checkbox" tabindex="0" id="audio-software-mode" aria-label="ALSA Software mode (plughw) - Linux only">
|
||||||
<label for="audio-software-mode">ALSA software mode (plughw) - LINUX ONLY</label>
|
<label for="audio-software-mode">ALSA software mode (plughw) - LINUX ONLY</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -277,17 +277,17 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="themes"><i class="fa-solid fa-palette"></i> Default server theme:</label>
|
<label for="themes"><i class="fa-solid fa-palette"></i> Default server theme:</label>
|
||||||
<div class="dropdown" id="server-theme-selector" style="margin-right: 0;">
|
<div class="dropdown" id="server-theme-selector" style="margin-right: 0;">
|
||||||
<input type="text" placeholder="Default" id="selected-theme" readonly>
|
<input type="text" placeholder="Default" id="selected-theme" readonly tabindex="0">
|
||||||
<ul class="options">
|
<ul class="options" tabindex="-1">
|
||||||
<li class="option" data-value="theme1">Default</li>
|
<li class="option" tabindex="0" data-value="theme1">Default</li>
|
||||||
<li class="option" data-value="theme2">Cappuccino</li>
|
<li class="option" tabindex="0" data-value="theme2">Cappuccino</li>
|
||||||
<li class="option" data-value="theme3">Nature</li>
|
<li class="option" tabindex="0" data-value="theme3">Nature</li>
|
||||||
<li class="option" data-value="theme4">Ocean</li>
|
<li class="option" tabindex="0" data-value="theme4">Ocean</li>
|
||||||
<li class="option" data-value="theme5">Terminal</li>
|
<li class="option" tabindex="0" data-value="theme5">Terminal</li>
|
||||||
<li class="option" data-value="theme6">Nightlife</li>
|
<li class="option" tabindex="0" data-value="theme6">Nightlife</li>
|
||||||
<li class="option" data-value="theme7">Blurple</li>
|
<li class="option" tabindex="0" data-value="theme7">Blurple</li>
|
||||||
<li class="option" data-value="theme8">Construction</li>
|
<li class="option" tabindex="0" data-value="theme8">Construction</li>
|
||||||
<li class="option" data-value="theme9">AMOLED</li>
|
<li class="option" tabindex="0" data-value="theme9">AMOLED</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -296,12 +296,12 @@
|
|||||||
<div class="panel-50 no-bg">
|
<div class="panel-50 no-bg">
|
||||||
<h3>Antenna options</h3>
|
<h3>Antenna options</h3>
|
||||||
<div class="form-group checkbox bottom-20">
|
<div class="form-group checkbox bottom-20">
|
||||||
<input type="checkbox" tabindex="0" id="antenna-switch">
|
<input type="checkbox" tabindex="0" id="antenna-switch" aria-label="Antenna switch">
|
||||||
<label for="antenna-switch">Enable the antenna switch</label>
|
<label for="antenna-switch">Enable the antenna switch</label>
|
||||||
</div><br>
|
</div><br>
|
||||||
|
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="ant1-enabled">
|
<input type="checkbox" tabindex="0" id="ant1-enabled" aria-label="Enable antenna 1">
|
||||||
<label for="ant1-enabled"></label>
|
<label for="ant1-enabled"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -310,7 +310,7 @@
|
|||||||
</div><br>
|
</div><br>
|
||||||
|
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="ant2-enabled">
|
<input type="checkbox" tabindex="0" id="ant2-enabled" aria-label="Enable antenna 2">
|
||||||
<label for="ant2-enabled"></label>
|
<label for="ant2-enabled"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -319,7 +319,7 @@
|
|||||||
</div><br>
|
</div><br>
|
||||||
|
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="ant3-enabled">
|
<input type="checkbox" tabindex="0" id="ant3-enabled" aria-label="Enable antenna 3">
|
||||||
<label for="ant3-enabled"></label>
|
<label for="ant3-enabled"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -328,7 +328,7 @@
|
|||||||
</div><br>
|
</div><br>
|
||||||
|
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="ant4-enabled">
|
<input type="checkbox" tabindex="0" id="ant4-enabled" aria-label="Enable antenna 4">
|
||||||
<label for="ant4-enabled"></label>
|
<label for="ant4-enabled"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -344,7 +344,7 @@
|
|||||||
<div class="panel-50 no-bg">
|
<div class="panel-50 no-bg">
|
||||||
<h3>Tuning options</h3>
|
<h3>Tuning options</h3>
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="default-freq-enable">
|
<input type="checkbox" tabindex="0" id="default-freq-enable" aria-label="Enable deafult frequency for first client">
|
||||||
<label for="default-freq-enable">Enable default frequency for first client</label>
|
<label for="default-freq-enable">Enable default frequency for first client</label>
|
||||||
</div><br>
|
</div><br>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -354,7 +354,7 @@
|
|||||||
<p>If you want to limit which frequencies the users can tune to,<br>you can set the lower and upper limit here.<br>
|
<p>If you want to limit which frequencies the users can tune to,<br>you can set the lower and upper limit here.<br>
|
||||||
<span class="text-gray">Enter frequencies in MHz.</span>
|
<span class="text-gray">Enter frequencies in MHz.</span>
|
||||||
</p>
|
</p>
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox" aria-label="Limit tuning">
|
||||||
<input type="checkbox" tabindex="0" id="tuning-limit">
|
<input type="checkbox" tabindex="0" id="tuning-limit">
|
||||||
<label for="tuning-limit">Limit tuning</label>
|
<label for="tuning-limit">Limit tuning</label>
|
||||||
</div><br>
|
</div><br>
|
||||||
@@ -372,7 +372,7 @@
|
|||||||
<h3>RDS Mode</h3>
|
<h3>RDS Mode</h3>
|
||||||
<p>You can switch between American (RBDS) / Global (RDS) mode here.</p>
|
<p>You can switch between American (RBDS) / Global (RDS) mode here.</p>
|
||||||
<div class="form-group checkbox bottom-20">
|
<div class="form-group checkbox bottom-20">
|
||||||
<input type="checkbox" tabindex="0" id="rds-mode">
|
<input type="checkbox" tabindex="0" id="rds-mode" aria-label="Enable american RDS mode (RBDS)">
|
||||||
<label for="rds-mode">Enable American Mode (RBDS)</label>
|
<label for="rds-mode">Enable American Mode (RBDS)</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@
|
|||||||
<div class="panel-100 no-bg">
|
<div class="panel-100 no-bg">
|
||||||
<h3>Chat options</h3>
|
<h3>Chat options</h3>
|
||||||
<div class="form-group checkbox bottom-20">
|
<div class="form-group checkbox bottom-20">
|
||||||
<input type="checkbox" tabindex="0" id="chat-switch">
|
<input type="checkbox" tabindex="0" id="chat-switch" aria-label="Enable chat">
|
||||||
<label for="chat-switch">Enable chat</label>
|
<label for="chat-switch">Enable chat</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -443,18 +443,18 @@
|
|||||||
<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 tabindex="0">
|
||||||
<ul class="options">
|
<ul class="options" tabindex="0">
|
||||||
<li class="option" data-value="tef">TEF668x / TEA685x</li>
|
<li class="option" tabindex="0" data-value="tef">TEF668x / TEA685x</li>
|
||||||
<li class="option" data-value="xdr">XDR (F1HD / S10HDiP)</li>
|
<li class="option" tabindex="0" data-value="xdr">XDR (F1HD / S10HDiP)</li>
|
||||||
<li class="option" data-value="sdr">SDR (RTL-SDR / AirSpy)</li>
|
<li class="option" tabindex="0" data-value="sdr">SDR (RTL-SDR / AirSpy)</li>
|
||||||
<li class="option" data-value="other">Other</li>
|
<li class="option" tabindex="0" data-value="other">Other</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div><br>
|
</div><br>
|
||||||
|
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="toggle-bw">
|
<input type="checkbox" tabindex="0" id="toggle-bw" aria-label="Toggle bandwidth switch">
|
||||||
<label for="toggle-bw">Toggle bandwidth switch</label>
|
<label for="toggle-bw">Toggle bandwidth switch</label>
|
||||||
</div><br>
|
</div><br>
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@
|
|||||||
<p class="m-0 text-gray">If your location information is filled,<br>you can add your tuner to a public list.</p>
|
<p class="m-0 text-gray">If your location information is filled,<br>you can add your tuner to a public list.</p>
|
||||||
<p></p>
|
<p></p>
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" tabindex="0" id="broadcast-tuner">
|
<input type="checkbox" tabindex="0" id="broadcast-tuner" aria-label="Broadcast to map">
|
||||||
<label for="broadcast-tuner">Broadcast to map</label>
|
<label for="broadcast-tuner">Broadcast to map</label>
|
||||||
</div><br>
|
</div><br>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -70,7 +70,7 @@
|
|||||||
<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="">
|
||||||
<input id="connection-type-toggle" type="checkbox"/>
|
<input id="connection-type-toggle" type="checkbox" aria-label="Tuner connection type"/>
|
||||||
<a></a>
|
<a></a>
|
||||||
<span>
|
<span>
|
||||||
<span class="left-span">Direct</span>
|
<span class="left-span">Direct</span>
|
||||||
@@ -193,11 +193,11 @@
|
|||||||
|
|
||||||
<p class="text-gray">Only fill up your broadcast address if you are using a proxy. If you don't know what a proxy is, leave it empty.</p>
|
<p class="text-gray">Only fill up your broadcast address if you are using a proxy. If you don't know what a proxy is, leave it empty.</p>
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" id="broadcast-tuner">
|
<input type="checkbox" id="broadcast-tuner" aria-label="Broadcast to map">
|
||||||
<label for="broadcast-tuner">Show my tuner on the public list</label>
|
<label for="broadcast-tuner">Show my tuner on the public list</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group checkbox">
|
<div class="form-group checkbox">
|
||||||
<input type="checkbox" id="tuner-public">
|
<input type="checkbox" id="tuner-public" aria-label="Allow tuning wihtout password">
|
||||||
<label for="tuner-public">Allow tuning without password</label>
|
<label for="tuner-public">Allow tuning without password</label>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
Reference in New Issue
Block a user