mirror of
https://github.com/KubaPro010/fm-dx-webserver.git
synced 2026-07-29 16:29:19 +02:00
some stuff
This commit is contained in:
+6
-12
@@ -130,7 +130,7 @@ function handleData(wss, receivedData, rdsWss) {
|
|||||||
dataToSend.agc = receivedLine.substring(1);
|
dataToSend.agc = receivedLine.substring(1);
|
||||||
initialData.agc = receivedLine.substring(1);
|
initialData.agc = receivedLine.substring(1);
|
||||||
break;
|
break;
|
||||||
case receivedLine.startsWith('G'): // EQ / iMS (RF+/IF+)
|
case receivedLine.startsWith('G'): // EQ / iMS
|
||||||
const mapping = filterMappings[receivedLine];
|
const mapping = filterMappings[receivedLine];
|
||||||
if (mapping) {
|
if (mapping) {
|
||||||
initialData.eq = mapping.eq;
|
initialData.eq = mapping.eq;
|
||||||
@@ -149,13 +149,13 @@ function handleData(wss, receivedData, rdsWss) {
|
|||||||
case receivedLine.startsWith('Ss'):
|
case receivedLine.startsWith('Ss'):
|
||||||
processSignal(receivedLine, true, false);
|
processSignal(receivedLine, true, false);
|
||||||
break;
|
break;
|
||||||
case receivedLine.startsWith('SS'):
|
case receivedLine.startsWith('SS'): // ss? oh no
|
||||||
processSignal(receivedLine, true, true);
|
processSignal(receivedLine, true, true);
|
||||||
break;
|
break;
|
||||||
case receivedLine.startsWith('SM'):
|
case receivedLine.startsWith('SM'):
|
||||||
processSignal(receivedLine, false, true);
|
processSignal(receivedLine, false, true);
|
||||||
break;
|
break;
|
||||||
case receivedLine.startsWith('R'): // RDS HEX
|
case receivedLine.startsWith('R'):
|
||||||
rdsReceived();
|
rdsReceived();
|
||||||
modifiedData = receivedLine.slice(1);
|
modifiedData = receivedLine.slice(1);
|
||||||
dataToSend.rds = true;
|
dataToSend.rds = true;
|
||||||
@@ -202,9 +202,7 @@ function handleData(wss, receivedData, rdsWss) {
|
|||||||
legacyRdsPiBuffer = null;
|
legacyRdsPiBuffer = null;
|
||||||
break;
|
break;
|
||||||
case receivedLine.startsWith("!"):
|
case receivedLine.startsWith("!"):
|
||||||
wss.clients.forEach((client) => {
|
wss.clients.forEach((client) => client.send(receivedLine.trim()));
|
||||||
client.send(receivedLine.trim());
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,9 +234,7 @@ function handleData(wss, receivedData, rdsWss) {
|
|||||||
// Send the updated data to the client
|
// Send the updated data to the client
|
||||||
const dataToSendJSON = JSON.stringify(dataToSend);
|
const dataToSendJSON = JSON.stringify(dataToSend);
|
||||||
if (currentTime - lastUpdateTime >= updateInterval) {
|
if (currentTime - lastUpdateTime >= updateInterval) {
|
||||||
wss.clients.forEach((client) => {
|
wss.clients.forEach((client) => client.send(dataToSendJSON));
|
||||||
client.send(dataToSendJSON);
|
|
||||||
});
|
|
||||||
lastUpdateTime = Date.now();
|
lastUpdateTime = Date.now();
|
||||||
serialportUpdateTime = process.hrtime();
|
serialportUpdateTime = process.hrtime();
|
||||||
}
|
}
|
||||||
@@ -307,6 +303,4 @@ function processSignal(receivedData, st, stForced) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { handleData, showOnlineUsers, dataToSend, initialData, resetToDefault, state };
|
||||||
handleData, showOnlineUsers, dataToSend, initialData, resetToDefault, state
|
|
||||||
};
|
|
||||||
|
|||||||
+33
-17
@@ -28,12 +28,15 @@ const pjson = require('../package.json');
|
|||||||
const client = new net.Socket();
|
const client = new net.Socket();
|
||||||
const wss = new WebSocket.Server({ noServer: true });
|
const wss = new WebSocket.Server({ noServer: true });
|
||||||
const rdsWss = new WebSocket.Server({ noServer: true });
|
const rdsWss = new WebSocket.Server({ noServer: true });
|
||||||
|
const rawComm = new WebSocket.Server({ noServer: true });
|
||||||
const pluginsWss = new WebSocket.Server({ noServer: true, perMessageDeflate: true });
|
const pluginsWss = new WebSocket.Server({ noServer: true, perMessageDeflate: true });
|
||||||
|
|
||||||
storage.websocket_delegation.set("/text", wss);
|
storage.websocket_delegation.set("/text", wss);
|
||||||
storage.websocket_delegation.set("/rds", rdsWss);
|
storage.websocket_delegation.set("/rds", rdsWss);
|
||||||
storage.websocket_delegation.set("/rdsspy", rdsWss);
|
storage.websocket_delegation.set("/rdsspy", rdsWss);
|
||||||
|
storage.websocket_delegation.set("/rawcomm", rawComm);
|
||||||
storage.websocket_delegation.set("/data_plugins", pluginsWss);
|
storage.websocket_delegation.set("/data_plugins", pluginsWss);
|
||||||
|
require('./stream/ws.js');
|
||||||
|
|
||||||
// Get all plugins from config and find corresponding server files
|
// Get all plugins from config and find corresponding server files
|
||||||
const plugins = findServerFiles(serverConfig.plugins);
|
const plugins = findServerFiles(serverConfig.plugins);
|
||||||
@@ -52,8 +55,6 @@ console.log('\x1b[32m\x1b[2mby Noobish @ \x1b[4mFMDX.org + KubaPro010\x1b[0m');
|
|||||||
console.log("v" + pjson.version)
|
console.log("v" + pjson.version)
|
||||||
console.log('\x1b[90m' + '─'.repeat(terminalWidth - 1) + '\x1b[0m');
|
console.log('\x1b[90m' + '─'.repeat(terminalWidth - 1) + '\x1b[0m');
|
||||||
|
|
||||||
require('./stream/ws.js');
|
|
||||||
require('./stream/index');
|
|
||||||
require('./plugins');
|
require('./plugins');
|
||||||
|
|
||||||
let currentUsers = 0;
|
let currentUsers = 0;
|
||||||
@@ -71,6 +72,7 @@ app.use(bodyParser.json());
|
|||||||
createChatServer(storage);
|
createChatServer(storage);
|
||||||
|
|
||||||
tunnel.download();
|
tunnel.download();
|
||||||
|
require('./stream/index');
|
||||||
connectToXdrd();
|
connectToXdrd();
|
||||||
connectToSerial();
|
connectToSerial();
|
||||||
|
|
||||||
@@ -146,6 +148,9 @@ function connectToSerial() {
|
|||||||
|
|
||||||
serialport.on('data', (data) => {
|
serialport.on('data', (data) => {
|
||||||
helpers.resolveDataBuffer(data, wss, rdsWss);
|
helpers.resolveDataBuffer(data, wss, rdsWss);
|
||||||
|
rawComm.clients.forEach((client) => {
|
||||||
|
if (client.readyState === WebSocket.OPEN) client.send(data);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
serialport.on('error', (error) => {
|
serialport.on('error', (error) => {
|
||||||
@@ -191,6 +196,9 @@ client.on('data', (data) => {
|
|||||||
const { xdrd } = serverConfig;
|
const { xdrd } = serverConfig;
|
||||||
|
|
||||||
helpers.resolveDataBuffer(data, wss, rdsWss);
|
helpers.resolveDataBuffer(data, wss, rdsWss);
|
||||||
|
rawComm.clients.forEach((client) => {
|
||||||
|
if (client.readyState === WebSocket.OPEN) client.send(data);
|
||||||
|
});
|
||||||
if (authFlags.authMsg == true && authFlags.messageCount > 1) return;
|
if (authFlags.authMsg == true && authFlags.messageCount > 1) return;
|
||||||
|
|
||||||
authFlags.messageCount++;
|
authFlags.messageCount++;
|
||||||
@@ -268,10 +276,6 @@ client.on('error', (err) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.set('view engine', 'ejs');
|
|
||||||
app.set('views', path.join(__dirname, '../views'));
|
|
||||||
app.use('/', endpoints);
|
|
||||||
|
|
||||||
const tunerLockTracker = new WeakMap();
|
const tunerLockTracker = new WeakMap();
|
||||||
const ipConnectionCounts = new Map(); // Per-IP limit variables
|
const ipConnectionCounts = new Map(); // Per-IP limit variables
|
||||||
const ipLogTimestamps = new Map();
|
const ipLogTimestamps = new Map();
|
||||||
@@ -290,7 +294,20 @@ setInterval(() => {
|
|||||||
ipLogTimestamps.delete(ip);
|
ipLogTimestamps.delete(ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 60 * 60 * 1000); // Run every hour
|
}, 30 * 60 * 1000); // Run every half hour
|
||||||
|
|
||||||
|
rawComm.on('connection', (ws, request) => {
|
||||||
|
const output = serverConfig.xdrd.wirelessConnection ? client : serialport;
|
||||||
|
const { isAdminAuthenticated } = request.session || {};
|
||||||
|
if(!isAdminAuthenticated) {
|
||||||
|
ws.close(1008, "No admin");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.on('message', (message) => {
|
||||||
|
output.write(`${message.toString()}\n`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
wss.on('connection', (ws, request) => {
|
wss.on('connection', (ws, request) => {
|
||||||
const output = serverConfig.xdrd.wirelessConnection ? client : serialport;
|
const output = serverConfig.xdrd.wirelessConnection ? client : serialport;
|
||||||
@@ -300,7 +317,7 @@ wss.on('connection', (ws, request) => {
|
|||||||
// Per-IP limit connection open
|
// Per-IP limit connection open
|
||||||
if (clientIp) {
|
if (clientIp) {
|
||||||
const isLocalIp = (
|
const isLocalIp = (
|
||||||
clientIp === '127.0.0.1' || clientIp === '::1' || clientIp === '::ffff:127.0.0.1' ||
|
clientIp === '127.0.0.1' || clientIp === '::1' ||
|
||||||
clientIp.startsWith('192.168.') || clientIp.startsWith('10.') || clientIp.startsWith('172.16.'));
|
clientIp.startsWith('192.168.') || clientIp.startsWith('10.') || clientIp.startsWith('172.16.'));
|
||||||
if (!isLocalIp) {
|
if (!isLocalIp) {
|
||||||
if (!ipConnectionCounts.has(clientIp)) ipConnectionCounts.set(clientIp, 0);
|
if (!ipConnectionCounts.has(clientIp)) ipConnectionCounts.set(clientIp, 0);
|
||||||
@@ -402,7 +419,7 @@ wss.on('connection', (ws, request) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientIp !== '::ffff:127.0.0.1' ||
|
if (clientIp !== ':127.0.0.1' ||
|
||||||
(request.socket && request.socket.remoteAddress && request.socket.remoteAddress !== '::ffff:127.0.0.1') ||
|
(request.socket && request.socket.remoteAddress && request.socket.remoteAddress !== '::ffff:127.0.0.1') ||
|
||||||
(request.headers && request.headers['origin'] && request.headers['origin'].trim() !== '')) {
|
(request.headers && request.headers['origin'] && request.headers['origin'].trim() !== '')) {
|
||||||
currentUsers--;
|
currentUsers--;
|
||||||
@@ -521,24 +538,23 @@ httpServer.on('upgrade', (request, socket, head) => {
|
|||||||
} else socket.destroy();
|
} else socket.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.set('view engine', 'ejs');
|
||||||
|
app.set('views', path.join(__dirname, '../views'));
|
||||||
|
app.use('/', endpoints);
|
||||||
app.use(express.static(path.join(__dirname, '../web'))); // Serve the entire web folder to the user
|
app.use(express.static(path.join(__dirname, '../web'))); // Serve the entire web folder to the user
|
||||||
pluginsApi.registerServerContext({ wss, pluginsWss, httpServer, serverConfig });
|
pluginsApi.registerServerContext({ wss, pluginsWss, httpServer, serverConfig });
|
||||||
|
|
||||||
const ipv4Address = serverConfig.webserver.webserverIp === '0.0.0.0' ? 'localhost' : serverConfig.webserver.webserverIp;
|
|
||||||
const port = serverConfig.webserver.webserverPort;
|
|
||||||
|
|
||||||
const logServerStart = (address) => {
|
const logServerStart = (address) => {
|
||||||
logInfo(`Web server has started on address \x1b[34mhttp://${address}:${port}\x1b[0m.`);
|
logInfo(`Web server has started on address \x1b[34mhttp://${address}:${serverConfig.webserver.webserverPort}\x1b[0m.`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const startServer = (address) => {
|
const startServer = (address) => {
|
||||||
httpServer.listen(port, address, () => {
|
httpServer.listen(serverConfig.webserver.webserverPort, address, () => {
|
||||||
if (!configExists()) logInfo(`Open your browser and proceed to \x1b[34mhttp://${address}:${port}\x1b[0m to continue with setup.`);
|
if (!configExists()) logInfo(`Open your browser and proceed to \x1b[34mhttp://${address}:${serverConfig.webserver.webserverPort}\x1b[0m to continue with setup.`);
|
||||||
else logServerStart(address);
|
else logServerStart(address);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
startServer(serverConfig.webserver.webserverIp === '0.0.0.0' ? 'localhost' : serverConfig.webserver.webserverIp);
|
||||||
startServer(ipv4Address);
|
|
||||||
tunnel.connect();
|
tunnel.connect();
|
||||||
fmdxList.update();
|
fmdxList.update();
|
||||||
+5
-9
@@ -2,13 +2,11 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const consoleCmd = require('./console');
|
const consoleCmd = require('./console');
|
||||||
|
|
||||||
// Function to read all .js files in a directory
|
|
||||||
function readJSFiles(dir) {
|
function readJSFiles(dir) {
|
||||||
const files = fs.readdirSync(dir);
|
const files = fs.readdirSync(dir);
|
||||||
return files.filter(file => file.endsWith('.js'));
|
return files.filter(file => file.endsWith('.js'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to parse plugin config from a file
|
|
||||||
function parsePluginConfig(filePath) {
|
function parsePluginConfig(filePath) {
|
||||||
const pluginConfig = {};
|
const pluginConfig = {};
|
||||||
|
|
||||||
@@ -75,10 +73,10 @@ if (!fs.existsSync(webJsPluginsDir)) fs.mkdirSync(webJsPluginsDir, { recursive:
|
|||||||
|
|
||||||
// Main function to create symlinks/junctions for plugins
|
// Main function to create symlinks/junctions for plugins
|
||||||
function createLinks() {
|
function createLinks() {
|
||||||
const pluginsDir = path.join(__dirname, '../plugins');
|
|
||||||
const destinationPluginsDir = path.join(__dirname, '../web/js/plugins');
|
|
||||||
|
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
|
const pluginsDir = path.join(__dirname, '../plugins');
|
||||||
|
const destinationPluginsDir = path.join(__dirname, '../web/js/plugins');
|
||||||
|
|
||||||
// On Windows, create a junction
|
// On Windows, create a junction
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(destinationPluginsDir)) fs.rmSync(destinationPluginsDir, { recursive: true });
|
if (fs.existsSync(destinationPluginsDir)) fs.rmSync(destinationPluginsDir, { recursive: true });
|
||||||
@@ -89,8 +87,6 @@ function createLinks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Usage example
|
// the usage example comment that was here got me so laughing, that i don't know about all of this
|
||||||
const allPluginConfigs = collectPluginConfigs();
|
|
||||||
createLinks();
|
createLinks();
|
||||||
|
module.exports = collectPluginConfigs();
|
||||||
module.exports = allPluginConfigs;
|
|
||||||
|
|||||||
@@ -187,6 +187,4 @@ if (configExists()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { configName, serverConfig, configUpdate, configSave, configExists, configPath };
|
||||||
configName, serverConfig, configUpdate, configSave, configExists, configPath
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ checkFFmpeg().then((ffmpegPath) => {
|
|||||||
return [
|
return [
|
||||||
"-fflags", "+nobuffer+flush_packets",
|
"-fflags", "+nobuffer+flush_packets",
|
||||||
"-flags", "low_delay",
|
"-flags", "low_delay",
|
||||||
"-rtbufsize", "4096",
|
"-rtbufsize", "2048",
|
||||||
"-probesize", "128",
|
"-probesize", "128",
|
||||||
|
|
||||||
...inputArgs,
|
...inputArgs,
|
||||||
|
|||||||
+1
-1
@@ -100,4 +100,4 @@ httpPassword = "<%= cfg.httpPassword %>"
|
|||||||
<% } %>
|
<% } %>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
module.exports = { connect, download};
|
module.exports = { connect, download };
|
||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
<div id="wrapper" class="auto">
|
<div id="wrapper" class="auto">
|
||||||
<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">
|
||||||
<h2 class="text-monospace text-light text-center">[403]</h2>
|
<h2 class="text-monospace text-light text-center">Forbidden</h2>
|
||||||
|
|
||||||
<div class="panel-100 p-10">
|
<div class="panel-100 p-10">
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
Helpers is part of 3LAS (Low Latency Live Audio Streaming)
|
Helpers is part of 3LAS (Low Latency Live Audio Streaming)
|
||||||
https://github.com/JoJoBond/3LAS
|
https://github.com/JoJoBond/3LAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Terrible
|
||||||
|
|
||||||
var isAndroid;
|
var isAndroid;
|
||||||
var isIOS;
|
var isIOS;
|
||||||
var isIPadOS;
|
var isIPadOS;
|
||||||
|
|||||||
+2
-2
@@ -17,7 +17,7 @@ class WebSocketAudioPlayer {
|
|||||||
const liveEdge = buffered.end(buffered.length - 1);
|
const liveEdge = buffered.end(buffered.length - 1);
|
||||||
const lag = liveEdge - this.audio.currentTime;
|
const lag = liveEdge - this.audio.currentTime;
|
||||||
|
|
||||||
if (lag > .5) this.audio.currentTime = liveEdge - 0.1; // snap to near live edge
|
if (lag > .3) this.audio.currentTime = liveEdge - 0.1; // snap to near live edge
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
@@ -111,7 +111,7 @@ function OnPlayButtonClick(_ev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$playbutton.addClass('bg-gray').prop('disabled', true);
|
$playbutton.addClass('bg-gray').prop('disabled', true);
|
||||||
setTimeout(() => $playbutton.removeClass('bg-gray').prop('disabled', false), 2500);
|
setTimeout(() => $playbutton.removeClass('bg-gray').prop('disabled', false), 2000);
|
||||||
if (Stream) Stream.setVolume($("#volumeSlider").val());
|
if (Stream) Stream.setVolume($("#volumeSlider").val());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ function submitConfig() {
|
|||||||
data: JSON.stringify(configData),
|
data: JSON.stringify(configData),
|
||||||
success: function (message) {
|
success: function (message) {
|
||||||
sendToast('success', 'Data saved!', message, true, true);
|
sendToast('success', 'Data saved!', message, true, true);
|
||||||
|
setTimeout(function () {
|
||||||
|
location.reload(true);
|
||||||
|
}, 1500);
|
||||||
},
|
},
|
||||||
error: function (error) {
|
error: function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|||||||
+74
-125
@@ -38,11 +38,8 @@ $(document).ready(function () {
|
|||||||
var mouseX = e.pageX;
|
var mouseX = e.pageX;
|
||||||
var panelLeft = parseInt($panel.css('left'));
|
var panelLeft = parseInt($panel.css('left'));
|
||||||
|
|
||||||
if (mouseX <= 10 || (panelLeft === 4 && mouseX <= 100)) {
|
if (mouseX <= 10 || (panelLeft === 4 && mouseX <= 100)) $panel.css('left', '4px');
|
||||||
$panel.css('left', '4px');
|
else $panel.css('left', -panelWidth);
|
||||||
} else {
|
|
||||||
$panel.css('left', -panelWidth);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fillPresets();
|
fillPresets();
|
||||||
@@ -50,13 +47,9 @@ $(document).ready(function () {
|
|||||||
signalToggle.on("change", function () {
|
signalToggle.on("change", function () {
|
||||||
const signalText = localStorage.getItem('signalUnit');
|
const signalText = localStorage.getItem('signalUnit');
|
||||||
|
|
||||||
if (signalText == 'dbuv') {
|
if (signalText == 'dbuv') signalText.text('dBµV');
|
||||||
signalText.text('dBµV');
|
else if (signalText == 'dbf') signalText.text('dBf');
|
||||||
} else if (signalText == 'dbf') {
|
else signalText.text('dBm');
|
||||||
signalText.text('dBf');
|
|
||||||
} else {
|
|
||||||
signalText.text('dBm');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if device is an iPhone to prevent zoom on button press
|
// Check if device is an iPhone to prevent zoom on button press
|
||||||
@@ -76,11 +69,8 @@ $(document).ready(function () {
|
|||||||
let content = $viewportMeta.attr('content');
|
let content = $viewportMeta.attr('content');
|
||||||
let re = /maximum\-scale=[0-9\.]+/g;
|
let re = /maximum\-scale=[0-9\.]+/g;
|
||||||
|
|
||||||
if (re.test(content)) {
|
if (re.test(content)) content = content.replace(re, 'maximum-scale=1.0');
|
||||||
content = content.replace(re, 'maximum-scale=1.0');
|
else content += ', maximum-scale=1.0';
|
||||||
} else {
|
|
||||||
content += ', maximum-scale=1.0';
|
|
||||||
}
|
|
||||||
|
|
||||||
$viewportMeta.attr('content', content);
|
$viewportMeta.attr('content', content);
|
||||||
}
|
}
|
||||||
@@ -99,7 +89,6 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
textInput.on('keyup', function (event) {
|
textInput.on('keyup', function (event) {
|
||||||
|
|
||||||
if (event.key !== 'Backspace' && localStorage.getItem('extendedFreqRange') != "true") {
|
if (event.key !== 'Backspace' && localStorage.getItem('extendedFreqRange') != "true") {
|
||||||
let inputValue = textInput.val();
|
let inputValue = textInput.val();
|
||||||
inputValue = inputValue.replace(/[^0-9.]/g, '');
|
inputValue = inputValue.replace(/[^0-9.]/g, '');
|
||||||
@@ -119,18 +108,15 @@ $(document).ready(function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
if (socket.readyState === WebSocket.OPEN) {
|
if (socket.readyState === WebSocket.OPEN) tuneTo(textInput.val());
|
||||||
tuneTo(textInput.val());
|
|
||||||
}
|
|
||||||
textInput.val('');
|
textInput.val('');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.onkeydown = function(event) {
|
document.onkeydown = function(event) {
|
||||||
if (!event.repeat) {
|
if (!event.repeat) checkKey(event);
|
||||||
checkKey(event);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -151,16 +137,11 @@ $(document).ready(function () {
|
|||||||
var delta = e.originalEvent.deltaY;
|
var delta = e.originalEvent.deltaY;
|
||||||
var adjustment = 0;
|
var adjustment = 0;
|
||||||
|
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) adjustment = e.altKey ? 1 : 0.01;
|
||||||
adjustment = e.altKey ? 1 : 0.01;
|
else if (e.ctrlKey) adjustment = 1;
|
||||||
} else if (e.ctrlKey) {
|
else {
|
||||||
adjustment = 1;
|
if (delta > 0) tuneDown();
|
||||||
} else {
|
else tuneUp();
|
||||||
if (delta > 0) {
|
|
||||||
tuneDown();
|
|
||||||
} else {
|
|
||||||
tuneUp();
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,9 +226,7 @@ $(document).ready(function () {
|
|||||||
if(parsedData.txInfo.dist > 700) sendLog('./log_fmlist?type=tropo');
|
if(parsedData.txInfo.dist > 700) sendLog('./log_fmlist?type=tropo');
|
||||||
$('.log-fmlist .mini-popup-content').removeClass('show');
|
$('.log-fmlist .mini-popup-content').removeClass('show');
|
||||||
});
|
});
|
||||||
} else {
|
} else sendLog('./log_fmlist');
|
||||||
sendLog('./log_fmlist');
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendLog(endpoint) {
|
function sendLog(endpoint) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@@ -261,13 +240,13 @@ $(document).ready(function () {
|
|||||||
|
|
||||||
switch (xhr.status) {
|
switch (xhr.status) {
|
||||||
case 429:
|
case 429:
|
||||||
errorMessage = xhr.responseText;
|
errorMessage = xhr.responseText;
|
||||||
break;
|
break;
|
||||||
case 500:
|
case 500:
|
||||||
errorMessage = 'Server error: ' + (xhr.responseText || 'Internal Server Error');
|
errorMessage = 'Server error: ' + (xhr.responseText || 'Internal Server Error');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errorMessage = xhr.statusText || 'An error occurred';
|
errorMessage = xhr.statusText || 'An error occurred';
|
||||||
}
|
}
|
||||||
|
|
||||||
sendToast('error', 'Log failed', errorMessage, false, true);
|
sendToast('error', 'Log failed', errorMessage, false, true);
|
||||||
@@ -368,9 +347,7 @@ function sendPingRequest() {
|
|||||||
if (connectionLost) sendToast('warning', 'Connection lost', 'Attempting to reconnect...', false, false);
|
if (connectionLost) sendToast('warning', 'Connection lost', 'Attempting to reconnect...', false, false);
|
||||||
console.log("Reconnecting due to no data received...");
|
console.log("Reconnecting due to no data received...");
|
||||||
}
|
}
|
||||||
} else {
|
} else messageCounter = 0;
|
||||||
messageCounter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Automatic reconnection on WebSocket close with cooldown
|
// Automatic reconnection on WebSocket close with cooldown
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@@ -414,9 +391,12 @@ function handleWebSocketMessage(event) {
|
|||||||
console.log('Kick initiated.')
|
console.log('Kick initiated.')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = '/403';
|
window.location.href = '/403';
|
||||||
}, 350);
|
}, 100);
|
||||||
return;
|
return;
|
||||||
} else if (event.data.startsWith("!")) sendToast('info', 'Info from server', event.data.slice(1), false, false)
|
} else if (event.data.startsWith("!")) {
|
||||||
|
sendToast('info', 'Info from server', event.data.slice(1), false, false)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parsedData = JSON.parse(event.data);
|
parsedData = JSON.parse(event.data);
|
||||||
|
|
||||||
@@ -427,6 +407,7 @@ function handleWebSocketMessage(event) {
|
|||||||
const averageSignal = sum / signalData.length;
|
const averageSignal = sum / signalData.length;
|
||||||
data.push(averageSignal);
|
data.push(averageSignal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach the message handler
|
// Attach the message handler
|
||||||
socket.onmessage = handleWebSocketMessage;
|
socket.onmessage = handleWebSocketMessage;
|
||||||
|
|
||||||
@@ -627,7 +608,7 @@ socket.onmessage = (event) => {
|
|||||||
console.log('Kick initiated.');
|
console.log('Kick initiated.');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = '/403';
|
window.location.href = '/403';
|
||||||
}, 500);
|
}, 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,6 +623,7 @@ socket.onmessage = (event) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function compareNumbers(a, b) {
|
function compareNumbers(a, b) {
|
||||||
|
// Really?
|
||||||
return a - b;
|
return a - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,11 +642,8 @@ function processString(string, errors) {
|
|||||||
|
|
||||||
for (let i = 0; i < string.length; i++) {
|
for (let i = 0; i < string.length; i++) {
|
||||||
alpha = parseInt(errors[i]) * (alpha_range / (max_error + 1));
|
alpha = parseInt(errors[i]) * (alpha_range / (max_error + 1));
|
||||||
if (alpha) {
|
if (alpha) output += "<span style='opacity: " + (max_alpha - alpha) + "%'>" + escapeHTML(string[i]) + "</span>";
|
||||||
output += "<span style='opacity: " + (max_alpha - alpha) + "%'>" + escapeHTML(string[i]) + "</span>";
|
else output += escapeHTML(string[i]);
|
||||||
} else {
|
|
||||||
output += escapeHTML(string[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
@@ -734,23 +713,23 @@ function checkKey(e) {
|
|||||||
|
|
||||||
let socketMessage = "Z" + $nextOption.data("value");
|
let socketMessage = "Z" + $nextOption.data("value");
|
||||||
socket.send(socketMessage);
|
socket.send(socketMessage);
|
||||||
break;
|
break;
|
||||||
case 112: // F1
|
case 112: // F1
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
tuneTo(Number(localStorage.getItem('preset1')));
|
tuneTo(Number(localStorage.getItem('preset1')));
|
||||||
break;
|
break;
|
||||||
case 113: // F2
|
case 113: // F2
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
tuneTo(Number(localStorage.getItem('preset2')));
|
tuneTo(Number(localStorage.getItem('preset2')));
|
||||||
break;
|
break;
|
||||||
case 114: // F3
|
case 114: // F3
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
tuneTo(Number(localStorage.getItem('preset3')));
|
tuneTo(Number(localStorage.getItem('preset3')));
|
||||||
break;
|
break;
|
||||||
case 115: // F4
|
case 115: // F4
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
tuneTo(Number(localStorage.getItem('preset4')));
|
tuneTo(Number(localStorage.getItem('preset4')));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Handle default case if needed
|
// Handle default case if needed
|
||||||
break;
|
break;
|
||||||
@@ -840,7 +819,6 @@ function findOnMaps() {
|
|||||||
window.open(url, "_blank");
|
window.open(url, "_blank");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateSignalUnits(parsedData, averageSignal) {
|
function updateSignalUnits(parsedData, averageSignal) {
|
||||||
const signalUnit = localStorage.getItem('signalUnit');
|
const signalUnit = localStorage.getItem('signalUnit');
|
||||||
let currentSignal;
|
let currentSignal;
|
||||||
@@ -852,21 +830,19 @@ function updateSignalUnits(parsedData, averageSignal) {
|
|||||||
|
|
||||||
switch (signalUnit) {
|
switch (signalUnit) {
|
||||||
case 'dbuv':
|
case 'dbuv':
|
||||||
signalValue = currentSignal - 11.25;
|
signalValue = currentSignal - 11.25;
|
||||||
highestSignal = highestSignal - 11.25;
|
highestSignal = highestSignal - 11.25;
|
||||||
signalText.text('dBµV');
|
signalText.text('dBµV');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'dbm':
|
case 'dbm':
|
||||||
signalValue = currentSignal - 120;
|
signalValue = currentSignal - 120;
|
||||||
highestSignal = highestSignal - 120;
|
highestSignal = highestSignal - 120;
|
||||||
signalText.text('dBm');
|
signalText.text('dBm');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
signalValue = currentSignal;
|
signalValue = currentSignal;
|
||||||
signalText.text('dBf');
|
signalText.text('dBf');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatted = (Math.round(signalValue * 10) / 10).toFixed(1);
|
const formatted = (Math.round(signalValue * 10) / 10).toFixed(1);
|
||||||
@@ -942,21 +918,15 @@ function buildAltTxList(txList) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateTextIfChanged($element, newText) {
|
function updateTextIfChanged($element, newText) {
|
||||||
if ($element.text() !== newText) {
|
if ($element.text() !== newText) $element.text(newText);
|
||||||
$element.text(newText);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateHtmlIfChanged($element, newHtml) {
|
function updateHtmlIfChanged($element, newHtml) {
|
||||||
if ($element.html() !== newHtml) {
|
if ($element.html() !== newHtml) $element.html(newHtml);
|
||||||
$element.html(newHtml);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDatasetValIfChanged($element, dataLabel, newVal) {
|
function updateDatasetValIfChanged($element, dataLabel, newVal) {
|
||||||
if ($element.attr(dataLabel) !== newVal) {
|
if ($element.attr(dataLabel) !== newVal) $element.attr(dataLabel, newVal);
|
||||||
$element.attr(dataLabel, newVal);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main function to update data elements, optimized
|
// Main function to update data elements, optimized
|
||||||
@@ -970,18 +940,12 @@ const updateDataElements = throttle(function(parsedData) {
|
|||||||
}
|
}
|
||||||
updateHtmlIfChanged($dataPs, parsedData.ps === '?' ? "<span class='opacity-half'>?</span>" : processString(parsedData.ps, parsedData.ps_errors));
|
updateHtmlIfChanged($dataPs, parsedData.ps === '?' ? "<span class='opacity-half'>?</span>" : processString(parsedData.ps, parsedData.ps_errors));
|
||||||
|
|
||||||
if(parsedData.st) {
|
if(parsedData.st) $dataSt.parent().removeClass('opacity-half');
|
||||||
$dataSt.parent().removeClass('opacity-half');
|
else $dataSt.parent().addClass('opacity-half');
|
||||||
} else {
|
|
||||||
$dataSt.parent().addClass('opacity-half');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parsedData.stForced) {
|
if(parsedData.stForced) {
|
||||||
if (!parsedData.st) {
|
if (!parsedData.st) stereoColor = 'gray';
|
||||||
stereoColor = 'gray';
|
else stereoColor = 'var(--color-4)';
|
||||||
} else {
|
|
||||||
stereoColor = 'var(--color-4)';
|
|
||||||
}
|
|
||||||
$('.data-st.circle1').css('left', '4px');
|
$('.data-st.circle1').css('left', '4px');
|
||||||
$('.data-st.circle2').css('display', 'none');
|
$('.data-st.circle2').css('display', 'none');
|
||||||
} else {
|
} else {
|
||||||
@@ -994,11 +958,8 @@ const updateDataElements = throttle(function(parsedData) {
|
|||||||
|
|
||||||
updateTextIfChanged($dataPty, rdsMode == 'true' ? usa_programmes[parsedData.pty] : europe_programmes[parsedData.pty]);
|
updateTextIfChanged($dataPty, rdsMode == 'true' ? usa_programmes[parsedData.pty] : europe_programmes[parsedData.pty]);
|
||||||
|
|
||||||
if (parsedData.rds === true) {
|
if (parsedData.rds === true) $flagDesktopCointainer.css('background-color', 'var(--color-2-transparent)');
|
||||||
$flagDesktopCointainer.css('background-color', 'var(--color-2-transparent)');
|
else $flagDesktopCointainer.css('background-color', 'var(--color-1-transparent)');
|
||||||
} else {
|
|
||||||
$flagDesktopCointainer.css('background-color', 'var(--color-1-transparent)');
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.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>`);
|
||||||
@@ -1056,9 +1017,7 @@ function updatePanels(parsedData) {
|
|||||||
updateCounter = (updateCounter % 10000) + 1; // Count to 10000 then reset back to 1
|
updateCounter = (updateCounter % 10000) + 1; // Count to 10000 then reset back to 1
|
||||||
|
|
||||||
signalData.push(parsedData.sig);
|
signalData.push(parsedData.sig);
|
||||||
if (signalData.length > 8) {
|
if (signalData.length > 8) signalData.shift(); // Remove the oldest element
|
||||||
signalData.shift(); // Remove the oldest element
|
|
||||||
}
|
|
||||||
const sum = signalData.reduce((acc, strNum) => acc + parseFloat(strNum), 0);
|
const sum = signalData.reduce((acc, strNum) => acc + parseFloat(strNum), 0);
|
||||||
const averageSignal = sum / signalData.length;
|
const averageSignal = sum / signalData.length;
|
||||||
|
|
||||||
@@ -1107,9 +1066,7 @@ function createListItem(element) {
|
|||||||
function updateButtonState(buttonId, value) {
|
function updateButtonState(buttonId, value) {
|
||||||
var button = $("#" + buttonId);
|
var button = $("#" + buttonId);
|
||||||
|
|
||||||
if (button.length === 0) {
|
if (button.length === 0) button = $("." + buttonId);
|
||||||
button = $("." + buttonId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button.length > 0) {
|
if (button.length > 0) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
@@ -1119,9 +1076,7 @@ function updateButtonState(buttonId, value) {
|
|||||||
button.hasClass("btn-disabled") ? button.removeClass("btn-disabled") : null;
|
button.hasClass("btn-disabled") ? button.removeClass("btn-disabled") : null;
|
||||||
button.attr('aria-description', 'On');
|
button.attr('aria-description', 'On');
|
||||||
}
|
}
|
||||||
} else {
|
} else console.log("Button not found!");
|
||||||
console.log("Button not found!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1182,9 +1137,7 @@ function initTooltips(target = null) {
|
|||||||
tooltips.off('mouseenter mouseleave');
|
tooltips.off('mouseenter mouseleave');
|
||||||
|
|
||||||
tooltips.hover(function () {
|
tooltips.hover(function () {
|
||||||
if ($(this).closest('.popup-content').length) {
|
if ($(this).closest('.popup-content').length) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tooltipText = $(this).data('tooltip');
|
var tooltipText = $(this).data('tooltip');
|
||||||
var placement = $(this).data('tooltip-placement') || 'top'; // Default to 'top'
|
var placement = $(this).data('tooltip-placement') || 'top'; // Default to 'top'
|
||||||
@@ -1212,22 +1165,22 @@ function initTooltips(target = null) {
|
|||||||
var posX, posY;
|
var posX, posY;
|
||||||
switch (placement) {
|
switch (placement) {
|
||||||
case 'bottom':
|
case 'bottom':
|
||||||
posX = targetOffset.left + targetWidth / 2 - tooltipWidth / 2;
|
posX = targetOffset.left + targetWidth / 2 - tooltipWidth / 2;
|
||||||
posY = targetOffset.top + targetHeight + 10;
|
posY = targetOffset.top + targetHeight + 10;
|
||||||
break;
|
break;
|
||||||
case 'left':
|
case 'left':
|
||||||
posX = targetOffset.left - tooltipWidth - 10;
|
posX = targetOffset.left - tooltipWidth - 10;
|
||||||
posY = targetOffset.top + targetHeight / 2 - tooltipHeight / 2;
|
posY = targetOffset.top + targetHeight / 2 - tooltipHeight / 2;
|
||||||
break;
|
break;
|
||||||
case 'right':
|
case 'right':
|
||||||
posX = targetOffset.left + targetWidth + 10;
|
posX = targetOffset.left + targetWidth + 10;
|
||||||
posY = targetOffset.top + targetHeight / 2 - tooltipHeight / 2;
|
posY = targetOffset.top + targetHeight / 2 - tooltipHeight / 2;
|
||||||
break;
|
break;
|
||||||
case 'top':
|
case 'top':
|
||||||
default:
|
default:
|
||||||
posX = targetOffset.left + targetWidth / 2 - tooltipWidth / 2;
|
posX = targetOffset.left + targetWidth / 2 - tooltipWidth / 2;
|
||||||
posY = targetOffset.top - tooltipHeight - 10;
|
posY = targetOffset.top - tooltipHeight - 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply positioning
|
// Apply positioning
|
||||||
@@ -1269,12 +1222,8 @@ function initTooltips(target = null) {
|
|||||||
$(`#preset${i}`).click(function() {
|
$(`#preset${i}`).click(function() {
|
||||||
tuneTo(Number(presetText));
|
tuneTo(Number(presetText));
|
||||||
});
|
});
|
||||||
} else {
|
} else $(`#preset${i}`).hide();
|
||||||
$(`#preset${i}`).hide();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasAnyPreset) {
|
if (!hasAnyPreset) $('#preset1').parent().hide();
|
||||||
$('#preset1').parent().hide();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-14
@@ -42,9 +42,7 @@ $(document).ready(() => {
|
|||||||
}, 1750);
|
}, 1750);
|
||||||
},
|
},
|
||||||
error: function (xhr, status, error) {
|
error: function (xhr, status, error) {
|
||||||
if (xhr.status === 403) {
|
if (xhr.status === 403) sendToast('error', 'Login failed!', xhr.responseJSON.message, false, true);
|
||||||
sendToast('error', 'Login failed!', xhr.responseJSON.message, false, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -59,7 +57,7 @@ $(document).ready(() => {
|
|||||||
sendToast('success', 'Logout success!', data.message, false, true);
|
sendToast('success', 'Logout success!', data.message, false, true);
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
location.reload(true);
|
location.reload(true);
|
||||||
}, 1000);
|
}, 500);
|
||||||
},
|
},
|
||||||
error: function (xhr, status, error) {
|
error: function (xhr, status, error) {
|
||||||
if (xhr.status === 403) {
|
if (xhr.status === 403) {
|
||||||
@@ -102,7 +100,6 @@ function setTheme(themeName) {
|
|||||||
// Extracting the RGBA components from themeColors[2] for --color-text-2
|
// Extracting the RGBA components from themeColors[2] for --color-text-2
|
||||||
const rgbaComponentsText = themeColors[2].match(/(\d+(\.\d+)?)/g);
|
const rgbaComponentsText = themeColors[2].match(/(\d+(\.\d+)?)/g);
|
||||||
const opacityText = parseFloat(rgbaComponentsText[3]);
|
const opacityText = parseFloat(rgbaComponentsText[3]);
|
||||||
const newOpacityText = opacityText * 0.75;
|
|
||||||
const textColor2 = `rgba(${rgbaComponentsText[0]}, ${rgbaComponentsText[1]}, ${rgbaComponentsText[2]})`;
|
const textColor2 = `rgba(${rgbaComponentsText[0]}, ${rgbaComponentsText[1]}, ${rgbaComponentsText[2]})`;
|
||||||
|
|
||||||
// Extracting the RGBA components from themeColors[0] for background color
|
// Extracting the RGBA components from themeColors[0] for background color
|
||||||
@@ -123,9 +120,7 @@ function setBg() {
|
|||||||
const disableBackgroundParameter = getQueryParameter('disableBackground');
|
const disableBackgroundParameter = getQueryParameter('disableBackground');
|
||||||
if(localStorage.getItem('bgImage').length > 5 && localStorage.getItem('theme') != 'theme9' && disableBackgroundParameter != 'true') {
|
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)');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInitialSettings() {
|
function getInitialSettings() {
|
||||||
@@ -135,14 +130,10 @@ function getInitialSettings() {
|
|||||||
success: function (data) {
|
success: function (data) {
|
||||||
|
|
||||||
['qthLatitude', 'qthLongitude', 'defaultTheme', 'bgImage', 'rdsMode', 'rdsTimeout'].forEach(key => {
|
['qthLatitude', 'qthLongitude', 'defaultTheme', 'bgImage', 'rdsMode', 'rdsTimeout'].forEach(key => {
|
||||||
if (data[key] !== undefined) {
|
if (data[key] !== undefined) localStorage.setItem(key, data[key]);
|
||||||
localStorage.setItem(key, data[key]);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
data.presets.forEach((preset, index) => {
|
data.presets.forEach((preset, index) => localStorage.setItem(`preset${index + 1}`, preset));
|
||||||
localStorage.setItem(`preset${index + 1}`, preset);
|
|
||||||
});
|
|
||||||
|
|
||||||
loadInitialSettings();
|
loadInitialSettings();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,11 +15,6 @@ $(document).ready(function() {
|
|||||||
setInterval(checkTunnelServers, 10000);
|
setInterval(checkTunnelServers, 10000);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to create & handle maps.
|
|
||||||
* Also contains map handling such as reloading / pin click registering.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function mapCreate() {
|
function mapCreate() {
|
||||||
if (!(typeof map == "object")) {
|
if (!(typeof map == "object")) {
|
||||||
map = L.map('map', {
|
map = L.map('map', {
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
const versionDate = new Date('Apr 3, 2026 9:30:00');
|
const versionDate = new Date('Apr 3, 2026 22:30:00');
|
||||||
const currentVersion = `v1.4.0a [${versionDate.getDate()}/${versionDate.getMonth() + 1}/${versionDate.getFullYear()}]`;
|
const currentVersion = `v1.4.0a [${versionDate.getDate()}/${versionDate.getMonth() + 1}/${versionDate.getFullYear()}]`;
|
||||||
+1
-1
@@ -16,7 +16,7 @@ function updateWizardContent() {
|
|||||||
$('.btn-prev').toggle(visibleStepIndex !== 0);
|
$('.btn-prev').toggle(visibleStepIndex !== 0);
|
||||||
$('.btn-next').text(visibleStepIndex === 4 ? 'Save' : 'Next');
|
$('.btn-next').text(visibleStepIndex === 4 ? 'Save' : 'Next');
|
||||||
|
|
||||||
visibleStepIndex === 3 && mapReload(); // What is this? Javascript? Toy?
|
visibleStepIndex === 3 && mapReload(); // What is this? Javascript?
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigateStep(isNext) {
|
function navigateStep(isNext) {
|
||||||
|
|||||||
Reference in New Issue
Block a user