diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 4660034a..039946ab 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -16,13 +16,11 @@ updates:
# Maintain dependencies for npm
- package-ecosystem: "npm"
- directory: "/gui_vue"
+ directory: "/gui"
schedule:
interval: "daily"
target-branch: "ls-gui-single-pager"
-
-
# Maintain dependencies for pip
- package-ecosystem: "pip"
directory: "/"
diff --git a/.gitignore b/.gitignore
index 77eda681..ce0407d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,9 +24,9 @@ coverage.sh
coverage.xml
#ignore node_modules
-/gui_vue/node_modules/
+/gui/node_modules/
-#Ignore gui_vue build items
-/gui_vue/dist
-/gui_vue/release
-/gui_vue/dist-electron
\ No newline at end of file
+#Ignore gui build items
+/gui/dist
+/gui/release
+/gui/dist-electron
\ No newline at end of file
diff --git a/gui_vue/.eslintrc.json b/gui/.eslintrc.json
similarity index 100%
rename from gui_vue/.eslintrc.json
rename to gui/.eslintrc.json
diff --git a/gui/.gitignore b/gui/.gitignore
deleted file mode 100644
index 67045665..00000000
--- a/gui/.gitignore
+++ /dev/null
@@ -1,104 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# TypeScript v1 declaration files
-typings/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-.env
-.env.test
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-
-# Next.js build output
-.next
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and *not* Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
diff --git a/gui_vue/README.md b/gui/README.md
similarity index 100%
rename from gui_vue/README.md
rename to gui/README.md
diff --git a/gui/daemon.js b/gui/daemon.js
deleted file mode 100644
index 779b25f9..00000000
--- a/gui/daemon.js
+++ /dev/null
@@ -1,347 +0,0 @@
-var net = require("net");
-const path = require("path");
-const { ipcRenderer } = require("electron");
-const log = require("electron-log");
-const daemonLog = log.scope("daemon");
-
-// https://stackoverflow.com/a/26227660
-var appDataFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Application Support"
- : process.env.HOME + "/.config");
-var configFolder = path.join(appDataFolder, "FreeDATA");
-var configPath = path.join(configFolder, "config.json");
-const config = require(configPath);
-
-var daemon = new net.Socket();
-var socketchunk = ""; // Current message, per connection.
-
-// global to keep track of daemon connection error emissions
-var daemonShowConnectStateError = 1;
-
-// global for storing ip information
-var daemon_port = config.daemon_port;
-var daemon_host = config.daemon_host;
-
-setTimeout(connectDAEMON, 500);
-
-function connectDAEMON() {
- if (daemonShowConnectStateError == 1) {
- daemonLog.info("connecting to daemon");
- }
-
- //clear message buffer after reconnecting or initial connection
- socketchunk = "";
-
- daemon.connect(config.daemon_port, config.daemon_host);
-
- //client.setTimeout(5000);
-}
-
-daemon.on("connect", function (err) {
- daemonLog.info("daemon connection established");
- let Data = {
- daemon_connection: daemon.readyState,
- };
- ipcRenderer.send("request-update-daemon-connection", Data);
-
- daemonShowConnectStateError = 1;
-});
-
-daemon.on("error", function (err) {
- if (daemonShowConnectStateError == 1) {
- daemonLog.error("daemon connection error");
- daemonLog.info("Make sure the daemon is started.");
- daemonLog.info('Run "python daemon.py" in the tnc directory.');
-
- daemonShowConnectStateError = 0;
- }
- setTimeout(connectDAEMON, 500);
- daemon.destroy();
- let Data = {
- daemon_connection: daemon.readyState,
- };
- ipcRenderer.send("request-update-daemon-connection", Data);
-});
-
-/*
-client.on('close', function(data) {
- console.log(' TNC connection closed');
- setTimeout(connectTNC, 2000)
- let Data = {
- daemon_connection: daemon.readyState,
- };
- ipcRenderer.send('request-update-daemon-connection', Data);
-});
-*/
-
-daemon.on("end", function (data) {
- daemonLog.warn("daemon connection ended");
- daemon.destroy();
- setTimeout(connectDAEMON, 500);
- let Data = {
- daemon_connection: daemon.readyState,
- };
- ipcRenderer.send("request-update-daemon-connection", Data);
-});
-
-//exports.writeCommand = function(command){
-writeDaemonCommand = function (command) {
- // we use the writingCommand function to update our TCPIP state because we are calling this function a lot
- // if socket opened, we are able to run commands
- if (daemon.readyState == "open") {
- //uiMain.setDAEMONconnection('open')
- daemon.write(command + "\n");
- }
-
- if (daemon.readyState == "closed") {
- //uiMain.setDAEMONconnection('closed')
- }
-
- if (daemon.readyState == "opening") {
- //uiMain.setDAEMONconnection('opening')
- }
-
- let Data = {
- daemon_connection: daemon.readyState,
- };
- ipcRenderer.send("request-update-daemon-connection", Data);
-};
-
-// "https://stackoverflow.com/questions/9070700/nodejs-net-createserver-large-amount-of-data-coming-in"
-
-daemon.on("data", function (socketdata) {
- /*
- inspired by:
- stackoverflow.com questions 9070700 nodejs-net-createserver-large-amount-of-data-coming-in
- */
-
- socketdata = socketdata.toString("utf8"); // convert data to string
- socketchunk += socketdata; // append data to buffer so we can stick long data together
-
- // check if we received begin and end of json data
- if (socketchunk.startsWith('{"') && socketchunk.endsWith('"}\n')) {
- var data = "";
-
- // split data into chunks if we received multiple commands
- socketchunk = socketchunk.split("\n");
- data = JSON.parse(socketchunk[0]);
-
- // search for empty entries in socketchunk and remove them
- for (i = 0; i < socketchunk.length; i++) {
- if (socketchunk[i] === "") {
- socketchunk.splice(i, 1);
- }
- }
-
- //iterate through socketchunks array to execute multiple commands in row
- for (i = 0; i < socketchunk.length; i++) {
- //check if data is not empty
- if (socketchunk[i].length > 0) {
- //try to parse JSON
- try {
- data = JSON.parse(socketchunk[i]);
- } catch (e) {
- console.log(e); // "SyntaxError
- daemonLog.error(e);
- daemonLog.debug(socketchunk[i]);
- socketchunk = "";
- }
- }
-
- if (data["command"] == "daemon_state") {
- let Data = {
- input_devices: data["input_devices"],
- output_devices: data["output_devices"],
- python_version: data["python_version"],
- hamlib_version: data["hamlib_version"],
- serial_devices: data["serial_devices"],
- tnc_running_state: data["daemon_state"][0]["status"],
- ram_usage: data["ram"],
- cpu_usage: data["cpu"],
- version: data["version"],
- };
- ipcRenderer.send("request-update-daemon-state", Data);
- }
-
- if (data["command"] == "test_hamlib") {
- let Data = {
- hamlib_result: data["result"],
- };
- ipcRenderer.send("request-update-hamlib-test", Data);
- }
- }
-
- //finally delete message buffer
- socketchunk = "";
- }
-});
-
-function hexToBytes(hex) {
- for (var bytes = [], c = 0; c < hex.length; c += 2)
- bytes.push(parseInt(hex.substr(c, 2), 16));
- return bytes;
-}
-
-exports.getDaemonState = function () {
- //function getDaemonState(){
- command = '{"type" : "get", "command" : "daemon_state"}';
- writeDaemonCommand(command);
-};
-
-// START TNC
-// ` `== multi line string
-
-exports.startTNC = function (
- mycall,
- mygrid,
- rx_audio,
- tx_audio,
- radiocontrol,
- devicename,
- deviceport,
- pttprotocol,
- pttport,
- serialspeed,
- data_bits,
- stop_bits,
- handshake,
- rigctld_ip,
- rigctld_port,
- enable_fft,
- enable_scatter,
- low_bandwidth_mode,
- tuning_range_fmin,
- tuning_range_fmax,
- enable_fsk,
- tx_audio_level,
- respond_to_cq,
- rx_buffer_size,
- enable_explorer,
- explorer_stats,
- auto_tune,
- tx_delay,
- tci_ip,
- tci_port,
- enable_mesh,
-) {
- var json_command = JSON.stringify({
- type: "set",
- command: "start_tnc",
- parameter: [
- {
- mycall: mycall,
- mygrid: mygrid,
- rx_audio: rx_audio,
- tx_audio: tx_audio,
- radiocontrol: radiocontrol,
- devicename: devicename,
- deviceport: deviceport,
- pttprotocol: pttprotocol,
- pttport: pttport,
- serialspeed: serialspeed,
- data_bits: data_bits,
- stop_bits: stop_bits,
- handshake: handshake,
- rigctld_port: rigctld_port,
- rigctld_ip: rigctld_ip,
- enable_scatter: enable_scatter,
- enable_fft: enable_fft,
- enable_fsk: enable_fsk,
- low_bandwidth_mode: low_bandwidth_mode,
- tuning_range_fmin: tuning_range_fmin,
- tuning_range_fmax: tuning_range_fmax,
- tx_audio_level: tx_audio_level,
- respond_to_cq: respond_to_cq,
- rx_buffer_size: rx_buffer_size,
- enable_explorer: enable_explorer,
- enable_stats: explorer_stats,
- enable_auto_tune: auto_tune,
- tx_delay: tx_delay,
- tci_ip: tci_ip,
- tci_port: tci_port,
- enable_mesh: enable_mesh,
- },
- ],
- });
-
- daemonLog.debug(json_command);
- writeDaemonCommand(json_command);
-};
-
-// STOP TNC
-exports.stopTNC = function () {
- command = '{"type" : "set", "command": "stop_tnc" , "parameter": "---" }';
- writeDaemonCommand(command);
-};
-
-// TEST HAMLIB
-exports.testHamlib = function (
- radiocontrol,
- devicename,
- deviceport,
- serialspeed,
- pttprotocol,
- pttport,
- data_bits,
- stop_bits,
- handshake,
- rigctld_ip,
- rigctld_port,
-) {
- var json_command = JSON.stringify({
- type: "get",
- command: "test_hamlib",
- parameter: [
- {
- radiocontrol: radiocontrol,
- devicename: devicename,
- deviceport: deviceport,
- pttprotocol: pttprotocol,
- pttport: pttport,
- serialspeed: serialspeed,
- data_bits: data_bits,
- stop_bits: stop_bits,
- handshake: handshake,
- rigctld_port: rigctld_port,
- rigctld_ip: rigctld_ip,
- },
- ],
- });
- daemonLog.debug(json_command);
- writeDaemonCommand(json_command);
-};
-
-//Save myCall
-exports.saveMyCall = function (callsign) {
- command =
- '{"type" : "set", "command": "mycallsign" , "parameter": "' +
- callsign +
- '"}';
- writeDaemonCommand(command);
-};
-
-// Save myGrid
-exports.saveMyGrid = function (grid) {
- command =
- '{"type" : "set", "command": "mygrid" , "parameter": "' + grid + '"}';
- writeDaemonCommand(command);
-};
-
-ipcRenderer.on("action-update-daemon-ip", (event, arg) => {
- daemon.destroy();
- let Data = {
- busy_state: "-",
- arq_state: "-",
- //channel_state: "-",
- frequency: "-",
- mode: "-",
- bandwidth: "-",
- dbfs_level: 0,
- };
- ipcRenderer.send("request-update-tnc-state", Data);
- daemon_port = arg.port;
- daemon_host = arg.adress;
- connectDAEMON();
-});
diff --git a/gui_vue/electron-builder.json5 b/gui/electron-builder.json5
similarity index 100%
rename from gui_vue/electron-builder.json5
rename to gui/electron-builder.json5
diff --git a/gui_vue/electron/electron-env.d.ts b/gui/electron/electron-env.d.ts
similarity index 100%
rename from gui_vue/electron/electron-env.d.ts
rename to gui/electron/electron-env.d.ts
diff --git a/gui_vue/electron/main/index.ts b/gui/electron/main/index.ts
similarity index 100%
rename from gui_vue/electron/main/index.ts
rename to gui/electron/main/index.ts
diff --git a/gui_vue/electron/preload/index.ts b/gui/electron/preload/index.ts
similarity index 100%
rename from gui_vue/electron/preload/index.ts
rename to gui/electron/preload/index.ts
diff --git a/gui/freedata.js b/gui/freedata.js
deleted file mode 100644
index 6b02a8d2..00000000
--- a/gui/freedata.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const fs = require("fs");
-const { ipcRenderer } = require("electron");
-
-/**
- * Save config and update config setting globally
- * @param {string} config - config data
- * @param {string} configPath
- */
-exports.saveConfig = function (config, configPath) {
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- ipcRenderer.send("set-config-global", config);
-};
-
-/**
- * Binary to ASCII replacement
- * @param {string} data in normal/usual utf-8 format
- * @returns base64 encoded string
- */
-exports.btoa_FD = function (data) {
- return Buffer.from(data, "utf-8").toString("base64");
-};
-/**
- * ASCII to Binary replacement
- * @param {string} data in base64 encoding
- * @returns utf-8 normal/usual string
- */
-exports.atob_FD = function (data) {
- return Buffer.from(data, "base64").toString("utf-8");
-};
-/**
- * UTF8 to ASCII btoa
- * @param {string} data in base64 encoding
- * @returns base64 bota compatible data for use in browser
- */
-exports.atob = function (data) {
- return window.btoa(Buffer.from(data, "base64").toString("utf8"));
-};
diff --git a/gui_vue/index.html b/gui/index.html
similarity index 100%
rename from gui_vue/index.html
rename to gui/index.html
diff --git a/gui/main.js b/gui/main.js
deleted file mode 100644
index 4ca90f81..00000000
--- a/gui/main.js
+++ /dev/null
@@ -1,998 +0,0 @@
-const { app, BrowserWindow, ipcMain, dialog, shell } = require("electron");
-const https = require("https");
-const { autoUpdater } = require("electron-updater");
-const path = require("path");
-const fs = require("fs");
-const os = require("os");
-const spawn = require("child_process").spawn;
-
-const log = require("electron-log");
-const mainLog = log.scope("main");
-const daemonProcessLog = log.scope("freedata-daemon");
-const mime = require("mime");
-const net = require("net");
-const FD = require("./freedata");
-
-//Useful for debugging event emitter memory leaks
-//require('events').EventEmitter.defaultMaxListeners = 10;
-//process.traceProcessWarnings=true;
-
-const sysInfo = log.scope("system information");
-sysInfo.info("SYSTEM INFORMATION ----------------------------- ");
-sysInfo.info("APP VERSION : " + app.getVersion());
-sysInfo.info("PLATFORM : " + os.platform());
-sysInfo.info("ARCHITECTURE: " + os.arch());
-sysInfo.info("FREE MEMORY: " + os.freemem());
-sysInfo.info("TOTAL MEMORY: " + os.totalmem());
-sysInfo.info("LOAD AVG : " + os.loadavg());
-sysInfo.info("RELEASE : " + os.release());
-sysInfo.info("TYPE : " + os.type());
-sysInfo.info("VERSION : " + os.version());
-sysInfo.info("UPTIME : " + os.uptime());
-
-app.setName("FreeDATA");
-
-var appDataFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Application Support"
- : process.env.HOME + "/.config");
-var configFolder = path.join(appDataFolder, "FreeDATA");
-var configPath = path.join(configFolder, "config.json");
-
-// create config folder if not exists
-if (!fs.existsSync(configFolder)) {
- fs.mkdirSync(configFolder);
-}
-
-// create config file if not exists with defaults
-const configDefaultSettings =
- '{\
- "tnc_host": "127.0.0.1",\
- "tnc_port": "3000",\
- "daemon_host": "127.0.0.1",\
- "daemon_port": "3001",\
- "mycall": "AA0AA-0",\
- "mygrid": "JN40aa",\
- "radiocontrol" : "disabled",\
- "hamlib_deviceid": "RIG_MODEL_DUMMY_NOVFO",\
- "hamlib_deviceport": "ignore",\
- "hamlib_stop_bits": "ignore",\
- "hamlib_data_bits": "ignore",\
- "hamlib_handshake": "ignore",\
- "hamlib_serialspeed": "ignore",\
- "hamlib_dtrstate": "ignore",\
- "hamlib_pttprotocol": "ignore",\
- "hamlib_ptt_port": "ignore",\
- "hamlib_dcd": "ignore",\
- "hamlbib_serialspeed_ptt": "9600",\
- "hamlib_rigctld_port" : "4532",\
- "hamlib_rigctld_ip" : "127.0.0.1",\
- "hamlib_rigctld_path" : "",\
- "hamlib_rigctld_server_port" : "4532",\
- "hamlib_rigctld_custom_args": "",\
- "tci_port" : "50001",\
- "tci_ip" : "127.0.0.1",\
- "spectrum": "waterfall",\
- "tnclocation": "localhost",\
- "enable_scatter" : "False",\
- "enable_fft" : "False",\
- "enable_fsk" : "False",\
- "low_bandwidth_mode" : "False",\
- "theme" : "default",\
- "screen_height" : 430,\
- "screen_width" : 1050,\
- "update_channel" : "latest",\
- "beacon_interval" : 300,\
- "received_files_folder" : "None",\
- "tuning_range_fmin" : "-50.0",\
- "tuning_range_fmax" : "50.0",\
- "respond_to_cq" : "True",\
- "rx_buffer_size" : "16", \
- "enable_explorer" : "False", \
- "wftheme": 2, \
- "high_graphics" : "True",\
- "explorer_stats" : "False", \
- "auto_tune" : "False", \
- "enable_is_writing" : "True", \
- "shared_folder_path" : ".", \
- "enable_request_profile" : "True", \
- "enable_request_shared_folder" : "False", \
- "max_retry_attempts" : 5, \
- "enable_auto_retry" : "False", \
- "tx_delay" : 0, \
- "auto_start": 0, \
- "enable_sys_notification": 1, \
- "enable_mesh_features": "False" \
- }';
-
-if (!fs.existsSync(configPath)) {
- fs.writeFileSync(configPath, configDefaultSettings);
-}
-
-// load settings
-var config = require(configPath);
-
-//config validation
-// check running config against default config.
-// if parameter not exists, add it to running config to prevent errors
-sysInfo.info("CONFIG VALIDATION ----------------------------- ");
-
-var parsedConfig = JSON.parse(configDefaultSettings);
-for (key in parsedConfig) {
- if (config.hasOwnProperty(key)) {
- sysInfo.info("FOUND SETTTING [" + key + "]: " + config[key]);
- } else {
- sysInfo.error("MISSING SETTTING [" + key + "] : " + parsedConfig[key]);
- config[key] = parsedConfig[key];
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- }
-}
-sysInfo.info("------------------------------------------ ");
-/*
-var chatDB = path.join(configFolder, 'chatDB.json')
-// create chat database file if not exists
-const configContentChatDB = `
-{ "chatDB" : [{
- "id" : "00000000",
- "timestamp" : 1234566,
- "mycall" : "AA0AA",
- "dxcall" : "AB0AB",
- "dxgrid" : "JN1200",
- "message" : "hallowelt"
-}]
-}
-`;
-if (!fs.existsSync(chatDB)) {
- fs.writeFileSync(chatDB, configContentChatDB);
-}
-*/
-
-/*
-// Creates receivedFiles folder if not exists
-// https://stackoverflow.com/a/26227660
-var appDataFolder = process.env.HOME
-var applicationFolder = path.join(appDataFolder, "FreeDATA");
-var receivedFilesFolder = path.join(applicationFolder, "receivedFiles");
-
-// https://stackoverflow.com/a/13544465
-fs.mkdir(receivedFilesFolder, {
- recursive: true
-}, function(err) {
- console.log(err);
-});
-
-*/
-
-let win = null;
-let logViewer = null;
-var daemonProcess = null;
-
-// create a splash screen
-function createSplashScreen() {
- splashScreen = new BrowserWindow({
- height: 250,
- width: 250,
- transparent: true,
- frame: false,
- alwaysOnTop: true,
- });
- splashScreen.loadFile("src/splash.html");
- splashScreen.center();
-}
-
-function createWindow() {
- win = new BrowserWindow({
- width: config.screen_width,
- height: config.screen_height,
- show: false,
- autoHideMenuBar: true,
- icon: "src/img/icon.png",
- webPreferences: {
- //preload: path.join(__dirname, 'preload-main.js'),
- backgroundThrottle: false,
- preload: require.resolve("./preload-main.js"),
- nodeIntegration: true,
- contextIsolation: false,
- enableRemoteModule: false,
- sandbox: false,
- //https://stackoverflow.com/questions/53390798/opening-new-window-electron/53393655
- //https://github.com/electron/remote
- },
- });
- // hide menu bar
- win.setMenuBarVisibility(false);
-
- //open dev tools
- /*win.webContents.openDevTools({
- mode: 'undocked',
- activate: true,
- })
- */
- win.loadFile("src/index.html");
-
-
- // Emitted when the window is closed.
- win.on("closed", function () {
- console.log("closing all windows.....");
- close_all();
- });
-
- win.once("ready-to-show", () => {
- log.transports.file.level = "debug";
- autoUpdater.logger = log.scope("updater");
-
- autoUpdater.channel = config.update_channel;
-
- autoUpdater.autoInstallOnAppQuit = false;
- autoUpdater.autoDownload = true;
- autoUpdater.checkForUpdatesAndNotify();
- //autoUpdater.quitAndInstall();
- });
-
-
-}
-
-app.whenReady().then(() => {
- // show splash screen
- createSplashScreen();
-
- // create main window
- createWindow();
-
- // wait some time, then close splash screen and show main windows
- setTimeout(function () {
- splashScreen.close();
- win.show();
- }, 3000);
-
- //Generate daemon binary path
- var daemonPath = "";
- switch (os.platform().toLowerCase()) {
- case "darwin":
- case "linux":
- daemonPath = path.join(process.resourcesPath, "tnc", "freedata-daemon");
-
- break;
- case "win32":
- case "win64":
- daemonPath = path.join(
- process.resourcesPath,
- "tnc",
- "freedata-daemon.exe",
- );
- break;
- default:
- console.log("Unhandled OS Platform: ", os.platform());
- break;
- }
-
- //Start daemon binary if it exists
- if (fs.existsSync(daemonPath)) {
- mainLog.info("Starting freedata-daemon binary");
- daemonProcess = spawn(daemonPath, [], {
- cwd: path.join(daemonPath, ".."),
- });
- // return process messages
- daemonProcess.on("error", (err) => {
- daemonProcessLog.error(`error when starting daemon: ${err}`);
- });
- daemonProcess.on("message", (data) => {
- daemonProcessLog.info(`${data}`);
- });
- daemonProcess.stdout.on("data", (data) => {
- daemonProcessLog.info(`${data}`);
- });
- daemonProcess.stderr.on("data", (data) => {
- daemonProcessLog.info(`${data}`);
- let arg = {
- entry: `${data}`,
- };
- // send info to log only if log screen available
- // it seems an error occurs when updating
- if (logViewer !== null && logViewer !== "") {
- try {
- //logViewer.webContents.send("action-update-log", arg);
- } catch (e) {
- // empty for keeping error stuff silent
- // this is important to avoid error messages if we are going to close the app while
- // an logging information will be pushed to the logger
- }
- }
- });
- daemonProcess.on("close", (code) => {
- daemonProcessLog.warn(`daemonProcess exited with code ${code}`);
- });
- } else {
- daemonProcess = null;
- daemonPath = null;
- mainLog.info("Daemon binary doesn't exist--normal for dev environments.");
- }
- win.send("action-set-app-version", app.getVersion());
-});
-
-app.on("activate", () => {
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow();
- }
-});
-
-app.on("window-all-closed", () => {
- close_all();
-});
-
-// IPC HANDLER
-//Update configuration globally
-ipcMain.on("set-config-global", (event, data) => {
- config = data;
- win.webContents.send("update-config", config);
-
-});
-
-//Show/update task bar/button progressbar
-ipcMain.on("request-show-electron-progressbar", (event, data) => {
- win.setProgressBar(data / 100);
-});
-
-
-ipcMain.on("request-update-dbclean-spinner", () => {
- //Turn off dbclean spinner
- win.webContents.send("action-update-dbclean-spinner");
-});
-
-// UPDATE TNC CONNECTION
-ipcMain.on("request-update-tnc-ip", (event, data) => {
- win.webContents.send("action-update-tnc-ip", data);
-});
-
-// UPDATE DAEMON CONNECTION
-ipcMain.on("request-update-daemon-ip", (event, data) => {
- win.webContents.send("action-update-daemon-ip", data);
-});
-
-ipcMain.on("request-update-tnc-state", (event, arg) => {
- win.webContents.send("action-update-tnc-state", arg);
- //meshViewer.send("action-update-mesh-table", arg);
- //data.webContents.send('action-update-tnc-state', arg);
-});
-
-/*
-ipcMain.on('request-update-data-state', (event, arg) => {
- //win.webContents.send('action-update-data-state', arg);
- //data.webContents.send('action-update-data-state', arg);
-});
-
-ipcMain.on('request-update-heard-stations', (event, arg) => {
- win.webContents.send('action-update-heard-stations', arg);
-});
-*/
-ipcMain.on("request-update-daemon-state", (event, arg) => {
- win.webContents.send("action-update-daemon-state", arg);
-});
-
-ipcMain.on("request-update-hamlib-test", (event, arg) => {
- win.webContents.send("action-update-hamlib-test", arg);
-});
-
-ipcMain.on("request-update-tnc-connection", (event, arg) => {
- win.webContents.send("action-update-tnc-connection", arg);
-});
-
-ipcMain.on("request-update-daemon-connection", (event, arg) => {
- win.webContents.send("action-update-daemon-connection", arg);
-});
-
-ipcMain.on("run-tnc-command", (event, arg) => {
- win.webContents.send("run-tnc-command", arg);
-});
-
-ipcMain.on("tnc-fec-iswriting", (event, arg) => {
- win.webContents.send("run-tnc-command-fec-iswriting");
-});
-
-ipcMain.on("request-update-rx-buffer", (event, arg) => {
- win.webContents.send("action-update-rx-buffer", arg);
-});
-
-/*
-ipcMain.on('request-update-rx-msg-buffer', (event, arg) => {
- win.webContents.send('action-update-rx-msg-buffer', arg);
-});
-*/
-ipcMain.on("request-new-msg-received", (event, arg) => {
- win.webContents.send("action-new-msg-received", arg);
-});
-ipcMain.on("request-update-transmission-status", (event, arg) => {
- //chat.webContents.send("action-update-transmission-status", arg);
- win.webContents.send("action-update-transmission-status", arg);
-});
-
-ipcMain.on("request-update-reception-status", (event, arg) => {
- win.webContents.send("action-update-reception-status", arg);
- //chat.webContents.send("action-update-reception-status", arg);
-});
-
-//Called by main to query chat if there are new messages
-ipcMain.on("request-update-unread-messages", () => {
- //mainLog.info("Got request to check if chat has new messages")
- win.webContents.send("action-update-unread-messages");
-});
-//Called by chat to notify main if there are new messages
-ipcMain.on("request-update-unread-messages-main", (event, arg) => {
- win.webContents.send("action-update-unread-messages-main", arg);
- //mainLog.info("Received reply from chat and ?new messages = " +arg);
-});
-
-//Called by main to notify chat we should clean the DB
-ipcMain.on("request-clean-db", () => {
- win.webContents.send("action-clean-db");
-});
-
-
-//file selector
-ipcMain.on("get-file-path", (event, data) => {
- dialog
- .showOpenDialog({
- defaultPath: path.join(__dirname, "../"),
- buttonLabel: "Select File",
- properties: ["openFile"],
- })
- .then((filePaths) => {
- if (filePaths.canceled == false) {
- win.webContents.send(data.action, { path: filePaths });
- }
- });
-});
-
-//folder selector
-ipcMain.on("get-folder-path", (event, data) => {
- dialog
- .showOpenDialog({
- defaultPath: path.join(__dirname, "../"),
- buttonLabel: "Select folder",
- properties: ["openDirectory"],
- })
- .then((folderPaths) => {
- if (folderPaths.canceled == false) {
- win.webContents.send(data.action, { path: folderPaths });
- //win.webContents.send(data.action, { path: filePaths });
- }
- });
-});
-
-//open folder
-ipcMain.on("open-folder", (event, data) => {
- shell.showItemInFolder(data.path);
-});
-
-//select file
-ipcMain.on("select-file", (event, data) => {
- dialog
- .showOpenDialog({
- defaultPath: path.join(__dirname, "../"),
- buttonLabel: "Select file",
- properties: ["openFile"],
- })
- .then((filepath) => {
- console.log(filepath.filePaths[0]);
-
- try {
- //fs.readFile(filepath.filePaths[0], 'utf8', function (err, data) {
- //Has to be binary
- fs.readFile(filepath.filePaths[0], "binary", function (err, data) {
- console.log(data.length);
-
- console.log(data);
-
- var filename = path.basename(filepath.filePaths[0]);
- var mimeType = mime.getType(filename);
- console.log(mimeType);
- if (mimeType == "" || mimeType == null) {
- mimeType = "plain/text";
- }
-
- win.webContents.send("return-selected-files", {
- data: data,
- mime: mimeType,
- filename: filename,
- });
-
- });
- } catch (err) {
- console.log(err);
- }
- });
-});
-
-//select image file
-ipcMain.on("select-user-image", (event, data) => {
- dialog
- .showOpenDialog({
- defaultPath: path.join(__dirname, "../"),
- buttonLabel: "Select file",
- properties: ["openFile"],
- })
- .then((filepath) => {
- console.log(filepath.filePaths[0]);
-
- try {
- // read data as base64 which makes conversion to blob easier
- fs.readFile(filepath.filePaths[0], "base64", function (err, data) {
- var filename = path.basename(filepath.filePaths[0]);
- var mimeType = mime.getType(filename);
-
- if (mimeType == "" || mimeType == null) {
- mimeType = "plain/text";
- }
-
- win.webContents.send("return-select-user-image", {
- data: data,
- mime: mimeType,
- filename: filename,
- });
-
- });
- } catch (err) {
- console.log(err);
- }
- });
-});
-
-// read files in folder - use case "shared folder"
-ipcMain.on("read-files-in-folder", (event, data) => {
- let fileList = [];
- if (config["enable_request_shared_folder"].toLowerCase() == "false") {
- //mainLog.info("Shared file folder is disable, not populating fileList");
-
- win.webContents.send("return-shared-folder-files", {
- files: fileList,
- });
-
- return;
- }
- let folder = data.folder;
- let files = fs.readdirSync(folder);
- console.log(folder);
- console.log(files);
- files.forEach((file) => {
- try {
- let filePath = folder + "/" + file;
- if (fs.lstatSync(filePath).isFile()) {
- let fileSizeInBytes = fs.statSync(filePath).size;
- let extension = path.extname(filePath);
- fileList.push({
- name: file,
- extension: extension.substring(1),
- size: fileSizeInBytes,
- });
- }
- } catch (err) {
- console.log(err);
- }
- });
-
- win.webContents.send("return-shared-folder-files", {
- files: fileList,
- });
-
-});
-
-//save file to folder
-ipcMain.on("save-file-to-folder", (event, data) => {
- console.log(data.file);
-
- dialog.showSaveDialog({ defaultPath: data.filename }).then((filepath) => {
- console.log(filepath.filePath);
- console.log(data.file);
-
- try {
- let arraybuffer = Buffer.from(data.file, "base64").toString("utf-8");
- console.log(arraybuffer);
- //Has to be binary
- fs.writeFile(
- filepath.filePath,
- arraybuffer,
- "binary",
- function (err, data) {},
- );
- } catch (err) {
- console.log(err);
- }
- });
-});
-
-//tnc messages START --------------------------------------
-
-// FEC iswriting received
-ipcMain.on("request-show-fec-toast-iswriting", (event, data) => {
- win.webContents.send("action-show-fec-toast-iswriting", data);
- win.webContents.send("action-show-feciswriting", data);
-});
-
-// CQ TRANSMITTING
-ipcMain.on("request-show-cq-toast-transmitting", (event, data) => {
- win.webContents.send("action-show-cq-toast-transmitting", data);
-});
-
-// CQ RECEIVED
-ipcMain.on("request-show-cq-toast-received", (event, data) => {
- win.webContents.send("action-show-cq-toast-received", data);
-});
-
-// QRV TRANSMITTING
-ipcMain.on("request-show-qrv-toast-transmitting", (event, data) => {
- win.webContents.send("action-show-qrv-toast-transmitting", data);
-});
-
-// QRV RECEIVED
-ipcMain.on("request-show-qrv-toast-received", (event, data) => {
- win.webContents.send("action-show-qrv-toast-received", data);
-});
-
-// BEACON TRANSMITTING
-ipcMain.on("request-show-beacon-toast-transmitting", (event, data) => {
- win.webContents.send("action-show-beacon-toast-transmitting", data);
-});
-
-// BEACON RECEIVED
-ipcMain.on("request-show-beacon-toast-received", (event, data) => {
- win.webContents.send("action-show-beacon-toast-received", data);
-});
-
-// PING TRANSMITTING
-ipcMain.on("request-show-ping-toast-transmitting", (event, data) => {
- win.webContents.send("action-show-ping-toast-transmitting", data);
-});
-
-// PING RECEIVED
-ipcMain.on("request-show-ping-toast-received", (event, data) => {
- win.webContents.send("action-show-ping-toast-received", data);
-});
-
-// PING RECEIVED ACK
-ipcMain.on("request-show-ping-toast-received-ack", (event, data) => {
- win.webContents.send("action-show-ping-toast-received-ack", data);
-});
-
-// ARQ DATA CHANNEL OPENING
-ipcMain.on("request-show-arq-toast-datachannel-opening", (event, data) => {
- win.webContents.send("action-show-arq-toast-datachannel-opening", data);
-});
-
-// ARQ DATA CHANNEL WAITING
-ipcMain.on("request-show-arq-toast-datachannel-waiting", (event, data) => {
- win.webContents.send("action-show-arq-toast-datachannel-waiting", data);
-});
-
-// ARQ DATA CHANNEL OPEN
-ipcMain.on("request-show-arq-toast-datachannel-opened", (event, data) => {
- win.webContents.send("action-show-arq-toast-datachannel-opened", data);
-});
-
-// ARQ DATA RECEIVED OPENER
-ipcMain.on(
- "request-show-arq-toast-datachannel-received-opener",
- (event, data) => {
- win.webContents.send(
- "action-show-arq-toast-datachannel-received-opener",
- data,
- );
- },
-);
-
-// ARQ TRANSMISSION FAILED
-ipcMain.on("request-show-arq-toast-transmission-failed", (event, data) => {
- win.webContents.send("action-show-arq-toast-transmission-failed", data);
-});
-
-// ARQ TRANSMISSION FAILED
-ipcMain.on("request-show-arq-toast-transmission-failed-ver", (event, data) => {
- win.webContents.send("action-show-arq-toast-transmission-failed-ver", data);
-});
-
-// ARQ TRANSMISSION RECEIVING
-ipcMain.on("request-show-arq-toast-transmission-receiving", (event, data) => {
- win.webContents.send("action-show-arq-toast-transmission-receiving", data);
-});
-
-// ARQ TRANSMISSION RECEIVED
-ipcMain.on("request-show-arq-toast-transmission-received", (event, data) => {
- win.webContents.send("action-show-arq-toast-transmission-received", data);
-});
-
-// ARQ TRANSMISSION TRANSMITTING
-ipcMain.on(
- "request-show-arq-toast-transmission-transmitting",
- (event, data) => {
- win.webContents.send(
- "action-show-arq-toast-transmission-transmitting",
- data,
- );
- },
-);
-
-// ARQ TRANSMISSION TRANSMITTED
-ipcMain.on("request-show-arq-toast-transmission-transmitted", (event, data) => {
- win.webContents.send("action-show-arq-toast-transmission-transmitted", data);
-});
-
-// ARQ SESSION CONNECTING
-ipcMain.on("request-show-arq-toast-session-connecting", (event, data) => {
- win.webContents.send("action-show-arq-toast-session-connecting", data);
-});
-
-// ARQ SESSION WAITING
-ipcMain.on("request-show-arq-toast-session-waiting", (event, data) => {
- win.webContents.send("action-show-arq-toast-session-waiting", data);
-});
-
-// ARQ SESSION CONNECTED
-ipcMain.on("request-show-arq-toast-session-connected", (event, data) => {
- win.webContents.send("action-show-arq-toast-session-connected", data);
-});
-
-// ARQ SESSION CLOSE
-ipcMain.on("request-show-arq-toast-session-close", (event, data) => {
- win.webContents.send("action-show-arq-toast-session-close", data);
-});
-
-// ARQ SESSION FAILED
-ipcMain.on("request-show-arq-toast-session-failed", (event, data) => {
- win.webContents.send("action-show-arq-toast-session-failed", data);
-});
-
-//tnc messages END --------------------------------------
-
-//restart and install udpate
-ipcMain.on("request-restart-and-install", (event, data) => {
- close_sub_processes();
- autoUpdater.quitAndInstall();
-});
-
-// LISTENER FOR UPDATER EVENTS
-autoUpdater.on("update-available", (info) => {
- mainLog.info("update available");
-
- let arg = {
- status: "update-available",
- info: info,
- };
- win.webContents.send("action-updater", arg);
-});
-
-autoUpdater.on("update-not-available", (info) => {
- mainLog.info("update not available");
- let arg = {
- status: "update-not-available",
- info: info,
- };
- win.webContents.send("action-updater", arg);
-});
-
-autoUpdater.on("update-downloaded", (info) => {
- mainLog.info("update downloaded");
- let arg = {
- status: "update-downloaded",
- info: info,
- };
- win.webContents.send("action-updater", arg);
- // we need to call this at this point.
- // if an update is available and we are force closing the app
- // the entire screen crashes...
- //mainLog.info('quit application and install update');
- //autoUpdater.quitAndInstall();
-});
-
-autoUpdater.on("checking-for-update", () => {
- mainLog.info("checking for update");
- let arg = {
- status: "checking-for-update",
- version: app.getVersion(),
- };
- win.webContents.send("action-updater", arg);
-});
-
-autoUpdater.on("download-progress", (progress) => {
- let arg = {
- status: "download-progress",
- progress: progress,
- };
- win.webContents.send("action-updater", arg);
-});
-
-autoUpdater.on("error", (error) => {
- mainLog.info("update error");
- let arg = {
- status: "error",
- progress: error,
- };
- win.webContents.send("action-updater", arg);
- mainLog.error("AUTO UPDATER : " + error);
-});
-
-function close_sub_processes() {
- mainLog.warn("closing sub processes");
-
- // closing the tnc binary if not closed when closing application and also our daemon which has been started by the gui
- try {
- if (daemonProcess != null) {
- daemonProcess.kill();
- }
- } catch (e) {
- mainLog.error(e);
- }
-
- mainLog.warn("closing tnc and daemon");
- try {
- if (os.platform() == "win32" || os.platform() == "win64") {
- spawn("Taskkill", ["/IM", "freedata-tnc.exe", "/F"]);
- spawn("Taskkill", ["/IM", "freedata-daemon.exe", "/F"]);
- }
-
- if (os.platform() == "linux") {
- spawn("pkill", ["-9", "freedata-tnc"]);
- spawn("pkill", ["-9", "freedata-daemon"]);
- }
-
- if (os.platform() == "darwin") {
- spawn("pkill", ["-9", "freedata-tnc"]);
- spawn("pkill", ["-9", "freedata-daemon"]);
- }
- } catch (e) {
- mainLog.error(e);
- }
-}
-
-function close_all() {
- // function for closing the application with closing all used processes
-
- close_sub_processes();
-
- mainLog.warn("quitting app");
-
- win.destroy();
-
-
- app.quit();
-}
-
-// RUN RIGCTLD
-ipcMain.on("request-start-rigctld", (event, data) => {
- try {
- let rigctld_proc = spawn(data.path, data.parameters, {
- windowsVerbatimArguments: true,
- });
-
- rigctld_proc.on("exit", function (code) {
- console.log("rigctld process exited with code " + code);
-
- // if rigctld crashes, error code is -2
- // then we are going to restart rigctld
- // this "fixes" a problem with latest rigctld on raspberry pi
- //if (code == -2){
- // setTimeout(ipcRenderer.send('request-start-rigctld', data), 500);
- //}
- //let rigctld_proc = spawn(data.path, data.parameters);
- });
- } catch (e) {
- console.log(e);
- }
-
- /*
- const rigctld = exec(data.path, data.parameters);
- rigctld.stdout.on("data", data => {
- console.log(`stdout: ${data}`);
- });
- */
-});
-
-// STOP RIGCTLD
-ipcMain.on("request-stop-rigctld", (event, data) => {
- mainLog.warn("closing rigctld");
- try {
- if (os.platform() == "win32" || os.platform() == "win64") {
- spawn("Taskkill", ["/IM", "rigctld.exe", "/F"]);
- }
-
- if (os.platform() == "linux") {
- spawn("pkill", ["-9", "rigctld"]);
- }
-
- if (os.platform() == "darwin") {
- spawn("pkill", ["-9", "rigctld"]);
- }
- } catch (e) {
- mainLog.error(e);
- }
-});
-
-// CHECK RIGCTLD CONNECTION
-// create new socket so we are not reopening every time a new one
-var rigctld_connection = new net.Socket();
-var rigctld_connection_state = false;
-var rigctld_events_wired = false;
-
-ipcMain.on("request-check-rigctld", (event, data) => {
- try {
- let Data = {
- state: "unknown",
- };
-
- if (!rigctld_connection_state) {
- rigctld_connection = new net.Socket();
- rigctld_events_wired = false;
- rigctld_connection.connect(data.port, data.ip);
- }
-
- // Check if we have created a new socket object and attach listeners if not already created
- if (typeof rigctld_connection != "undefined" && !rigctld_events_wired) {
- rigctld_connection.on("connect", function () {
- rigctld_events_wired = true;
- mainLog.info("Starting rigctld event listeners");
- rigctld_connection_state = true;
- Data["state"] = "Connected";
- Data["active"] = true;
- if (win !== null && win !== "" && typeof win != "undefined") {
- // try catch for being sure we have a clean app close
- try {
- win.webContents.send("action-check-rigctld", Data);
- } catch (e) {
- console.log(e);
- }
- }
- });
-
- rigctld_connection.on("error", function () {
- rigctld_connection_state = false;
- Data["state"] = "Not Connected";
- Data["active"] = false;
- if (win !== null && win !== "" && typeof win != "undefined") {
- // try catch for being sure we have a clean app close
- try {
- win.webContents.send("action-check-rigctld", Data);
- } catch (e) {
- console.log(e);
- }
- }
- });
-
- rigctld_connection.on("end", function () {
- rigctld_connection_state = false;
- });
- }
- } catch (e) {
- console.log(e);
- }
-});
-
-function downloadJsonUrlToFile(url, callsignPath) {
- // https://nodejs.org/api/https.html#httpsgetoptions-callback
-
- https
- .get(url, (res) => {
- //console.log("statusCode:", res.statusCode);
- //console.log("headers:", res.headers);
-
- res.on("data", (d) => {
- //console.log(d);
- let json = JSON.parse(d);
- fs.writeFileSync(callsignPath, JSON.stringify(json, null, 2));
- sysInfo.info(
- "Download " + url + " return statuscode: " + res.statusCode,
- );
- });
- })
- .on("error", (e) => {
- console.error(e);
- });
-}
-function downloadCallsignReverseLookupData() {
- sysInfo.info("Downloading callsigns.json");
- var callsignPath = path.join(configFolder, "callsigns.json");
- downloadJsonUrlToFile(
- "https://api.freedata.app/callsign_lookup.php",
- callsignPath,
- );
-}
-
-downloadCallsignReverseLookupData();
diff --git a/gui/package.json b/gui/package.json
index 45cd7b48..4deaaf3c 100644
--- a/gui/package.json
+++ b/gui/package.json
@@ -1,15 +1,17 @@
{
"name": "FreeDATA",
- "version": "0.10.2-alpha.1",
"description": "FreeDATA ",
- "main": "main.js",
+ "private": true,
+ "version": "0.11.0-alpha",
+ "main": "dist-electron/main/index.js",
"scripts": {
- "start": "electron .",
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "engines": {
- "node": ">=18.17.0",
- "npm": ">=9.0.0"
+ "start": "git pull && npm i && vite",
+ "dev": "vite",
+ "check" : "vue-tsc --noEmit",
+ "build": "vue-tsc --noEmit && vite build && electron-builder",
+ "preview": "vite preview",
+ "lint": "eslint --ext .js,.vue src",
+ "lint-fix": "eslint --ext .js,.vue --fix src"
},
"repository": {
"type": "git",
@@ -28,9 +30,8 @@
},
"homepage": "https://freedata.app",
"dependencies": {
- "@electron/asar": "^3.2.4",
- "@electron/osx-sign": "^1.0.4",
- "@popperjs/core": "^2.11.8",
+ "@electron/notarize": "^2.1.0",
+ "@vueuse/electron": "^10.4.1",
"blob-util": "^2.0.2",
"bootstrap": "^5.3.1",
"bootstrap-icons": "^1.10.5",
@@ -38,73 +39,44 @@
"browser-image-compression": "^2.0.2",
"chart.js": "^4.3.3",
"chartjs-plugin-annotation": "^3.0.1",
+ "electron-builder-notarize": "^1.5.1",
"electron-log": "^4.4.8",
- "electron-updater": "^6.1.1",
+ "electron-updater": "^6.1.4",
"emoji-picker-element": "^1.18.3",
"emoji-picker-element-data": "^1.4.0",
- "express-pouchdb": "^4.2.0",
+ "file-saver": "^2.0.5",
"mime": "^3.0.0",
+ "pinia": "^2.1.6",
"pouchdb": "^8.0.1",
"pouchdb-browser": "^8.0.1",
- "pouchdb-express-router": "^0.0.11",
"pouchdb-find": "^8.0.1",
- "pouchdb-replication": "^8.0.1",
"pouchdb-upsert": "^2.2.0",
"qth-locator": "^2.1.0",
- "utf8": "^3.0.0",
- "uuid": "^9.0.0"
+ "sass": "^1.66.1",
+ "socket.io": "^4.7.2",
+ "uuid": "^9.0.0",
+ "vue": "^3.3.4",
+ "vue-chartjs": "^5.2.0",
+ "vuemoji-picker": "^0.2.0"
},
"devDependencies": {
- "@electron/notarize": "^2.1.0",
+ "@typescript-eslint/eslint-plugin": "^6.7.4",
+ "@vitejs/plugin-vue": "^4.4.0",
"electron": "^27.0.0",
"electron-builder": "^24.6.3",
- "electron-builder-notarize": "^1.5.1"
- },
- "build": {
- "productName": "FreeDATA",
- "appId": "app.freedata",
- "afterSign": "electron-builder-notarize",
- "npmRebuild": "false",
- "directories": {
- "buildResources": "build",
- "output": "dist"
- },
- "mac": {
- "target": [
- "default"
- ],
- "icon": "build/icon.png",
- "hardenedRuntime": true,
- "entitlements": "build/entitlements.plist",
- "entitlementsInherit": "build/entitlements.plist",
- "gatekeeperAssess": false
- },
- "win": {
- "icon": "build/icon.png",
- "target": [
- "nsis"
- ]
- },
- "linux": {
- "icon": "build/icon.png",
- "target": [
- "AppImage"
- ],
- "category": "Development"
- },
- "publish": {
- "provider": "github",
- "releaseType": "release"
- },
- "extraResources": [
- {
- "from": "../tnc/dist/tnc/",
- "to": "tnc",
- "filter": [
- "**/*",
- "!**/.git"
- ]
- }
- ]
+ "eslint": "^8.50.0",
+ "eslint-config-prettier": "^9.0.0",
+ "eslint-config-standard-with-typescript": "^39.1.0",
+ "eslint-plugin-import": "^2.28.1",
+ "eslint-plugin-n": "^16.1.0",
+ "eslint-plugin-prettier": "^5.0.0",
+ "eslint-plugin-promise": "^6.1.1",
+ "eslint-plugin-vue": "^9.17.0",
+ "typescript": "^5.2.2",
+ "vite": "^4.3.2",
+ "vite-plugin-electron": "^0.14.0",
+ "vite-plugin-electron-renderer": "^0.14.5",
+ "vue": "^3.3.4",
+ "vue-tsc": "^1.4.2"
}
}
diff --git a/gui/preload-chat.js b/gui/preload-chat.js
deleted file mode 100644
index 4299bd86..00000000
--- a/gui/preload-chat.js
+++ /dev/null
@@ -1,2967 +0,0 @@
-const path = require("path");
-const { ipcRenderer } = require("electron");
-const { v4: uuidv4 } = require("uuid");
-const imageCompression = require("browser-image-compression");
-const blobUtil = require("blob-util");
-const FD = require("./freedata");
-const fs = require("fs");
-
-// https://stackoverflow.com/a/26227660
-var appDataFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Application Support"
- : process.env.HOME + "/.config");
-var configFolder = path.join(appDataFolder, "FreeDATA");
-var configPath = path.join(configFolder, "config.json");
-var config = require(configPath);
-// set date format
-const dateFormat = new Intl.DateTimeFormat(navigator.language, {
- timeStyle: "long",
- dateStyle: "short",
-});
-// set date format information
-const dateFormatShort = new Intl.DateTimeFormat(navigator.language, {
- year: "numeric",
- month: "numeric",
- day: "numeric",
- hour: "numeric",
- minute: "numeric",
- second: "numeric",
- hour12: false,
-});
-
-const dateFormatHours = new Intl.DateTimeFormat(navigator.language, {
- hour: "numeric",
- minute: "numeric",
- hour12: false,
-});
-// split character
-const split_char = "\0;\1;";
-// global for our selected file we want to transmit
-// ----------------- some chat globals
-var filetype = "";
-var file = "";
-var filename = "";
-var callsign_counter = 0;
-var selected_callsign = "";
-var lastIsWritingBroadcast = new Date().getTime();
-var defaultUserIcon =
- "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktcGVyc29uLWJvdW5kaW5nLWJveCIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNMS41IDFhLjUuNSAwIDAgMC0uNS41djNhLjUuNSAwIDAgMS0xIDB2LTNBMS41IDEuNSAwIDAgMSAxLjUgMGgzYS41LjUgMCAwIDEgMCAxaC0zek0xMSAuNWEuNS41IDAgMCAxIC41LS41aDNBMS41IDEuNSAwIDAgMSAxNiAxLjV2M2EuNS41IDAgMCAxLTEgMHYtM2EuNS41IDAgMCAwLS41LS41aC0zYS41LjUgMCAwIDEtLjUtLjV6TS41IDExYS41LjUgMCAwIDEgLjUuNXYzYS41LjUgMCAwIDAgLjUuNWgzYS41LjUgMCAwIDEgMCAxaC0zQTEuNSAxLjUgMCAwIDEgMCAxNC41di0zYS41LjUgMCAwIDEgLjUtLjV6bTE1IDBhLjUuNSAwIDAgMSAuNS41djNhMS41IDEuNSAwIDAgMS0xLjUgMS41aC0zYS41LjUgMCAwIDEgMC0xaDNhLjUuNSAwIDAgMCAuNS0uNXYtM2EuNS41IDAgMCAxIC41LS41eiIvPgogIDxwYXRoIGQ9Ik0zIDE0cy0xIDAtMS0xIDEtNCA2LTQgNiAzIDYgNC0xIDEtMSAxSDN6bTgtOWEzIDMgMCAxIDEtNiAwIDMgMyAwIDAgMSA2IDB6Ii8+Cjwvc3ZnPg==";
-var defaultGroupIcon =
- "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktcGVvcGxlLWZpbGwiIHZpZXdCb3g9IjAgMCAxNiAxNiI+CiAgPHBhdGggZD0iTTcgMTRzLTEgMC0xLTEgMS00IDUtNCA1IDMgNSA0LTEgMS0xIDFIN1ptNC02YTMgMyAwIDEgMCAwLTYgMyAzIDAgMCAwIDAgNlptLTUuNzg0IDZBMi4yMzggMi4yMzggMCAwIDEgNSAxM2MwLTEuMzU1LjY4LTIuNzUgMS45MzYtMy43MkE2LjMyNSA2LjMyNSAwIDAgMCA1IDljLTQgMC01IDMtNSA0czEgMSAxIDFoNC4yMTZaTTQuNSA4YTIuNSAyLjUgMCAxIDAgMC01IDIuNSAyLjUgMCAwIDAgMCA1WiIvPgo8L3N2Zz4=";
-
-// -----------------------------------
-// Initially fill sharedFolderFileList
-//TODO: Make this automatically ever N seconds
-var sharedFolderFileList = "";
-ipcRenderer.send("read-files-in-folder", {
- folder: config.shared_folder_path,
-});
-
-var chatDB = path.join(configFolder, "chatDB");
-var userDB = path.join(configFolder, "userDB");
-// ---- MessageDB
-try {
- var PouchDB = require("pouchdb");
-} catch (err) {
- console.log(err);
-
- /*
- This is a fix for raspberryPi where we get an error when loading pouchdb because of
- leveldown package isnt running on ARM devices.
- pouchdb-browser does not depend on leveldb and seems to be working.
- */
- console.log("using pouchdb-browser fallback");
- var PouchDB = require("pouchdb-browser");
-}
-
-PouchDB.plugin(require("pouchdb-find"));
-//PouchDB.plugin(require('pouchdb-replication'));
-PouchDB.plugin(require("pouchdb-upsert"));
-
-var db = new PouchDB(chatDB);
-var users = new PouchDB(userDB);
-
-/* -------- CREATE DATABASE INDEXES */
-createChatIndex();
-createUserIndex();
-
-// REMOTE SYNC ATTEMPTS
-
-//var remoteDB = new PouchDB('http://172.20.10.4:5984/chatDB')
-
-/*
-
-// we need express packages for running pouchdb sync "express-pouchdb"
-var express = require('express');
-var app = express();
-app.use('/', require('express-pouchdb')(PouchDB));
-app.listen(5984);
-var db = new PouchDB(chatDB);
-
-
-app.use('/chatDB', require('pouchdb-express-router')(PouchDB));
-app.listen(5984);
-
-
-
-db.sync('http://172.20.10.4:5984/jojo', {
-//var sync = PouchDB.sync('chatDB', 'http://172.20.10.4:5984/chatDB', {
- live: true,
- retry: false
-}).on('change', function (change) {
- // yo, something changed!
- console.log(change)
-}).on('paused', function (err) {
- // replication was paused, usually because of a lost connection
- console.log(err)
-}).on('active', function (info) {
- // replication was resumed
- console.log(info)
-}).on('error', function (err) {
- // totally unhandled error (shouldn't happen)
- console.log(err)
-}).on('denied', function (err) {
- // a document failed to replicate (e.g. due to permissions)
- console.log(err)
-}).on('complete', function (info) {
- // handle complete;
- console.log(info)
-});
-*/
-
-var dxcallsigns = new Set();
-
-//Set default chat filter
-var chatFilter = [
- { type: "newchat" },
- { type: "received" },
- { type: "transmit" },
- { type: "ping-ack" },
- { type: "broadcast_received" },
- { type: "broadcast_transmit" },
-
- //{ type: "request" },
- //{ type: "response" },
-];
-
-// WINDOW LISTENER
-window.addEventListener("DOMContentLoaded", () => {
- updateAllChat(false);
- // theme selector
- changeGuiDesign(config.theme);
-
- const userInfoFields = [
- "user_info_image",
- "user_info_callsign",
- "user_info_gridsquare",
- "user_info_name",
- "user_info_age",
- "user_info_location",
- "user_info_radio",
- "user_info_antenna",
- "user_info_email",
- "user_info_website",
- "user_info_comments",
- ];
- users
- .find({
- selector: {
- user_info_callsign: config.mycall,
- },
- })
- .then(function (result) {
- console.log(result);
- if (typeof result.docs[0] !== "undefined") {
- // handle result
- userInfoFields.forEach(function (elem) {
- if (elem !== "user_info_image") {
- document.getElementById(elem).value = result.docs[0][elem];
- } else {
- document.getElementById(elem).src = result.docs[0][elem];
- }
- });
- } else {
- console.log(
- config.mycall + " not found in user db - creating new entry",
- );
- // add initial entry for own callsign and grid
- let obj = new Object();
- obj.user_info_callsign = config.mycall;
- obj.user_info_gridsquare = config.mygrid;
- addUserToDatabaseIfNotExists(obj);
-
- document.getElementById("user_info_callsign").value = config.mycall;
- document.getElementById("user_info_gridsquare").value = config.mygrid;
- }
- })
- .catch(function (err) {
- console.log(err);
- });
-
- //save user info
- document.getElementById("userInfoSave").addEventListener("click", () => {
- let obj = new Object();
- userInfoFields.forEach(function (subelem) {
- if (subelem !== "user_info_image") {
- obj[subelem] = document.getElementById(subelem).value;
- } else {
- obj[subelem] = document.getElementById(subelem).src;
- }
- });
- addUserToDatabaseIfNotExists(obj);
- });
-
- //Add event listener for filter apply button
- document.getElementById("btnFilter").addEventListener("click", () => {
- chatFilter.length = 0;
- if (document.getElementById("chkMessage").checked == true) {
- chatFilter = [{ type: "newchat" }];
- chatFilter.push(
- { type: "received" },
- { type: "transmit" },
- { type: "broadcast_received" },
- { type: "broadcast_transmit" },
- );
- }
- if (document.getElementById("chkPing").checked == true)
- chatFilter.push({ type: "ping" });
- if (document.getElementById("chkPingAck").checked == true)
- chatFilter.push({ type: "ping-ack" });
- if (document.getElementById("chkBeacon").checked == true)
- chatFilter.push({ type: "beacon" });
- if (document.getElementById("chkRequest").checked == true)
- chatFilter.push({ type: "request" });
- if (document.getElementById("chkResponse").checked == true)
- chatFilter.push({ type: "response" });
- if (document.getElementById("chkNewMessage").checked == true)
- chatFilter.push({ new: 1 });
- updateAllChat(true);
- });
-
- document
- .querySelector("emoji-picker")
- .addEventListener("emoji-click", (event) => {
- var msg = document.getElementById("chatModuleMessage");
- //Convert to utf-8--so we can just use utf-8 everywhere
- msg.setRangeText(event.detail.emoji.unicode.toString("utf-8"));
- //console.log(event.detail);
- //msg.focus();
- });
- document.getElementById("emojipickerbutton").addEventListener("click", () => {
- var element = document.getElementById("emojipickercontainer");
- console.log(element.style.display);
- if (element.style.display === "none") {
- element.style.display = "block";
- } else {
- element.style.display = "none";
- }
- });
-
- document
- .getElementById("delete_selected_chat")
- .addEventListener("click", () => {
- db.find({
- selector: {
- dxcallsign: selected_callsign,
- },
- })
- .then(function (result) {
- // handle result
- if (typeof result !== "undefined") {
- result.docs.forEach(function (item) {
- console.log(item);
- db.get(item._id)
- .then(function (doc) {
- db.remove(doc)
- .then(function (doc) {
- updateAllChat(true);
- return true;
- })
- .catch(function (err) {
- console.log(err);
- });
- })
- .catch(function (err) {
- console.log(err);
- });
- });
- }
- })
- .catch(function (err) {
- console.log(err);
- });
- });
- document.getElementById("selectFilesButton").addEventListener("click", () => {
- //document.getElementById('selectFiles').click();
- ipcRenderer.send("select-file", {
- title: "Title",
- });
- });
-
- document.getElementById("requestUserInfo").addEventListener("click", () => {
- ipcRenderer.send("run-tnc-command", {
- command: "requestUserInfo",
- dxcallsign: selected_callsign,
- });
-
- pauseButton(document.getElementById("requestUserInfo"), 60000);
- });
-
- document.getElementById("ping").addEventListener("click", () => {
- ipcRenderer.send("run-tnc-command", {
- command: "ping",
- dxcallsign: selected_callsign,
- });
- });
-
- document.addEventListener("keyup", function (event) {
- // Number 13 == Enter
- if (
- event.keyCode === 13 &&
- !event.shiftKey &&
- document.activeElement.id == "chatModuleMessage"
- ) {
- // Cancel the default action, if needed
- event.preventDefault();
- // Trigger the button element with a click
- document.getElementById("sendMessage").click();
- }
- });
-
- // ADJUST TEXTAREA SIZE
- document.getElementById("chatModuleMessage").addEventListener("input", () => {
- var textarea = document.getElementById("chatModuleMessage");
- var text = textarea.value;
-
- if (document.getElementById("expand_textarea").checked) {
- var lines = 6;
- } else {
- var lines = text.split("\n").length;
-
- if (lines >= 6) {
- lines = 6;
- }
- }
- var message_container_height_offset = 180 + 20 * lines;
- var message_container_height = `calc(100% - ${message_container_height_offset}px)`;
- document.getElementById("message-container").style.height =
- message_container_height;
- textarea.rows = lines;
-
- console.log(textarea.value);
- if (lastIsWritingBroadcast < new Date().getTime() - 5 * 2000) {
- //console.log("Sending FECIsWriting");
- console.log(config.enable_is_writing);
- if (config.enable_is_writing == "True") {
- ipcRenderer.send("tnc-fec-iswriting");
- }
- lastIsWritingBroadcast = new Date().getTime();
- }
- });
-
- document.getElementById("expand_textarea").addEventListener("click", () => {
- var textarea = document.getElementById("chatModuleMessage");
-
- if (document.getElementById("expand_textarea").checked) {
- var lines = 6;
- document.getElementById("expand_textarea_button").className =
- "bi bi-chevron-compact-down";
- } else {
- var lines = 1;
- document.getElementById("expand_textarea_button").className =
- "bi bi-chevron-compact-up";
- }
-
- var message_container_height_offset = 180 + 20 * lines;
- //var message_container_height_offset = 90 + (23*lines);
- var message_container_height = `calc(100% - ${message_container_height_offset}px)`;
- document.getElementById("message-container").style.height =
- message_container_height;
- textarea.rows = lines;
- console.log(textarea.rows);
- });
-
- // NEW CHAT
-
- document
- .getElementById("createNewChatButton")
- .addEventListener("click", () => {
- var dxcallsign = document.getElementById("chatModuleNewDxCall").value;
- var uuid = uuidv4();
- db.post({
- _id: uuid,
- timestamp: Math.floor(Date.now() / 1000),
- dxcallsign: dxcallsign.toUpperCase(),
- dxgrid: "---",
- msg: "null",
- checksum: "null",
- type: "newchat",
- status: "null",
- uuid: uuid,
- })
- .then(function (response) {
- // handle response
- console.log("new database entry");
- console.log(response);
- })
- .catch(function (err) {
- console.log(err);
- });
- update_chat_obj_by_uuid(uuid);
- });
-
- // open file selector for user image
- document.getElementById("userImageSelector").addEventListener("click", () => {
- ipcRenderer.send("select-user-image", {
- title: "Title",
- });
- });
-
- // open file selector for shared folder
- document
- .getElementById("sharedFolderButton")
- .addEventListener("click", () => {
- ipcRenderer.send("read-files-in-folder", {
- folder: config.shared_folder_path,
- });
- });
-
- document
- .getElementById("openSharedFilesFolder")
- .addEventListener("click", () => {
- ipcRenderer.send("open-folder", {
- path: config.shared_folder_path,
- });
- });
-
- document
- .getElementById("requestSharedFolderList")
- .addEventListener("click", () => {
- ipcRenderer.send("run-tnc-command", {
- command: "requestSharedFolderList",
- dxcallsign: selected_callsign,
- });
-
- pauseButton(document.getElementById("requestSharedFolderList"), 60000);
- });
-
- // SEND MSG
- document.getElementById("sendMessage").addEventListener("click", () => {
- document.getElementById("emojipickercontainer").style.display = "none";
-
- var dxcallsign = selected_callsign.toUpperCase();
- var textarea = document.getElementById("chatModuleMessage");
- var chatmessage = textarea.value;
- //Remove non-printable chars from begining and end of string--should save us a byte here and there
- chatmessage = chatmessage.toString().trim();
- // reset textarea size
- var message_container_height_offset = 200;
- var message_container_height = `calc(100% - ${message_container_height_offset}px)`;
- document.getElementById("message-container").style.height =
- message_container_height;
- textarea.rows = 1;
- document.getElementById("expand_textarea_button").className =
- "bi bi-chevron-compact-up";
- document.getElementById("expand_textarea").checked = false;
-
- //console.log(file);
- //console.log(filename);
- //console.log(filetype);
- if (filetype == "") {
- filetype = "plain/text";
- }
- var timestamp = Math.floor(Date.now() / 1000);
-
- var uuid = uuidv4();
- let uuidlast = uuid.lastIndexOf("-");
- uuidlast += 1;
- if (uuidlast > 0) {
- uuid = uuid.substring(uuidlast);
- }
-
- // check if broadcast
- if (dxcallsign.startsWith("BC-")) {
- //let broadcastChannelId = dxcallsign.split("BC-")[1];
- //broadcastChannelIdCRC = crc32(broadcastChannelId)
- // .toString(16)
- // .toUpperCase();
- //dxcallsignWithID = "BC-" + broadcastChannelIdCRC;
- var tnc_command = "broadcast";
- var message_type = "broadcast_transmit";
-
- // slice uuid for reducing overhead
- uuid = uuid.slice(-4);
-
- let Data = {
- command: tnc_command,
- broadcastChannel: dxcallsign,
- data: chatmessage,
- uuid: uuid,
- };
- ipcRenderer.send("run-tnc-command", Data);
- } else {
- var message_type = "transmit";
- var file_checksum = crc32(file).toString(16).toUpperCase();
- var tnc_command = "msg";
- var data_with_attachment =
- timestamp +
- split_char +
- chatmessage +
- split_char +
- filename +
- split_char +
- filetype +
- split_char +
- file;
-
- document.getElementById("selectFilesButton").innerHTML = ``;
-
- console.log(data_with_attachment);
- let Data = {
- command: tnc_command,
- dxcallsign: dxcallsign,
- mode: 255,
- frames: 5,
- data: data_with_attachment,
- checksum: file_checksum,
- uuid: uuid,
- };
- ipcRenderer.send("run-tnc-command", Data);
- }
-
- db.post({
- _id: uuid,
- timestamp: timestamp,
- dxcallsign: dxcallsign,
- dxgrid: "null",
- msg: chatmessage,
- checksum: file_checksum,
- type: message_type,
- status: "transmit",
- attempt: 1,
- uuid: uuid,
- _attachments: {
- [filename]: {
- content_type: filetype,
- //data: btoa(file)
- data: FD.btoa_FD(file),
- },
- },
- })
- .then(function (response) {
- // handle response
- console.log("new database entry");
- console.log(response);
- })
- .catch(function (err) {
- console.log(err);
- });
- update_chat_obj_by_uuid(uuid);
-
- // clear input
- document.getElementById("chatModuleMessage").value = "";
-
- // after adding file data to our attachment variable, delete it from global
- filetype = "";
- file = "";
- filename = "";
- });
- // cleanup after transmission
- filetype = "";
- file = "";
- filename = "";
-});
-
-ipcRenderer.on("return-selected-files", (event, arg) => {
- filetype = arg.mime;
- console.log(filetype);
-
- file = arg.data;
- filename = arg.filename;
- document.getElementById("selectFilesButton").innerHTML = `
-
- New file selected
-
- `;
-});
-
-ipcRenderer.on("return-shared-folder-files", (event, arg) => {
- console.log(arg);
- sharedFolderFileList = arg.files;
-
- var tbl = document.getElementById("sharedFolderTable");
- if (tbl == undefined) return;
- tbl.innerHTML = "";
- let counter = 0;
- arg.files.forEach((file) => {
- //console.log(file["name"]);
- var row = document.createElement("tr");
-
- let id = document.createElement("td");
- let idText = document.createElement("span");
- idText.innerText = counter += 1;
- id.appendChild(idText);
- row.appendChild(id);
-
- let filename = document.createElement("td");
- let filenameText = document.createElement("span");
- filenameText.innerText = file["name"];
- filename.appendChild(filenameText);
- row.appendChild(filename);
-
- let filetype = document.createElement("td");
- let filetypeText = document.createElement("span");
- filetypeText.innerHTML = `
-
- `;
- filetype.appendChild(filetypeText);
- row.appendChild(filetype);
-
- let filesize = document.createElement("td");
- let filesizeText = document.createElement("span");
- filesizeText.innerText = formatBytes(file["size"], 2);
- filesize.appendChild(filesizeText);
- row.appendChild(filesize);
-
- tbl.appendChild(row);
- });
-});
-
-ipcRenderer.on("return-select-user-image", (event, arg) => {
- let imageFiletype = arg.mime;
- let imageFile = arg.data;
-
- imageFile = blobUtil.base64StringToBlob(imageFile, imageFiletype);
-
- var options = {
- maxSizeMB: 0.01,
- maxWidthOrHeight: 125,
- useWebWorker: false,
- };
-
- imageCompression(imageFile, options)
- .then(function (compressedFile) {
- console.log(
- "compressedFile instanceof Blob",
- compressedFile instanceof Blob,
- ); // true
- console.log(
- `compressedFile size ${compressedFile.size / 1024 / 1024} MB`,
- ); // smaller than maxSizeMB
-
- console.log(compressedFile.size);
-
- blobUtil
- .blobToBase64String(compressedFile)
- .then(function (base64String) {
- // update image
-
- document.getElementById("user_info_image").src =
- "data:" + imageFiletype + ";base64," + base64String;
- })
- .catch(function (err) {
- document.getElementById("user_info_image").src = "img/icon.png";
- });
- })
- .catch(function (error) {
- console.log(error.message);
- });
-});
-
-
-
-
-ipcRenderer.on("action-update-transmission-status", (event, arg) => {
- var data = arg["data"][0];
-
- if (data.status == "opening") return;
- if (typeof data.uuid === undefined) return;
-
- //console.log(data.status);
- if (data.uuid !== "no-uuid") {
- db.get(data.uuid, {
- attachments: true,
- })
- .then(function (doc) {
- return db.put({
- _id: doc.uuid.toString(),
- _rev: doc._rev,
- timestamp: doc.timestamp,
- dxcallsign: doc.dxcallsign,
- dxgrid: doc.dxgrid,
- msg: doc.msg,
- checksum: doc.checksum,
- type: "transmit",
- status: data.status,
- percent: data.percent,
- bytesperminute: data.bytesperminute,
- uuid: doc.uuid,
- _attachments: doc._attachments,
- });
- })
- .then(function (response) {
- update_chat_obj_by_uuid(data.uuid);
- })
- .catch(function (err) {
- console.log(err);
- console.log(data);
- });
- }
-});
-
-//Render is typing message in correct chat window
-ipcRenderer.on("action-show-feciswriting", (event, arg) => {
- //console.log("In action-show-feciswriting");
- //console.log(arg);
- let uuid = uuidv4.toString();
- let dxcallsign = arg["data"][0]["dxcallsign"];
- var new_message = `
-
-
${dxcallsign} is typing....
-
-
- `;
- var id = "chat-" + dxcallsign;
- let chatwin = document.getElementById(id);
- if (chatwin == undefined) {
- //console.log("Element not found!!!!! :(");
- return;
- }
- chatwin.insertAdjacentHTML("beforeend", new_message);
- scrollMessagesToBottom();
- let animIcon = document.getElementById("msg-" + uuid + "-icon");
- //Remove notification after about 4.5 seconds hopefully enough time before a second notification can come in
- setTimeout(function () {
- animIcon.classList = "m-1 bi bi-wifi-2";
- }, 1000);
- setTimeout(function () {
- animIcon.classList = "m-1 bi bi-wifi";
- }, 2000);
- setTimeout(function () {
- animIcon.classList = "m-1 bi bi-wifi-2";
- }, 3000);
- setTimeout(function () {
- animIcon.classList = "m-1 bi bi-wifi-1";
- }, 4000);
- setTimeout(() => {
- let feciw = document.getElementById("msg-" + uuid);
- feciw.remove();
- }, 4500);
-});
-
-ipcRenderer.on("action-new-msg-received", (event, arg) => {
- console.log(arg.data);
-
- var new_msg = arg.data;
- new_msg.forEach(function (item) {
- let obj = new Object();
-
- //handle broadcast
- if (item.fec == "broadcast") {
- console.log("BROADCAST RECEIVED");
- console.log(item);
- var transmitting_station = item.dxcallsign;
- var encoded_data = FD.atob_FD(item.data);
- var splitted_data = encoded_data.split(split_char);
- console.log(splitted_data);
- console.log(transmitting_station);
- // add callsign to message:
- var message = splitted_data[3];
- console.log(message);
- obj.timestamp = Math.floor(Date.now() / 1000);
- obj.dxcallsign = splitted_data[1];
- obj.dxgrid = "null";
- obj.uuid = splitted_data[2];
- obj.broadcast_sender = transmitting_station;
- obj.command = "msg";
- obj.checksum = "null";
- obj.msg = message;
- obj.status = "received";
- obj.snr = item.snr;
- obj.type = "broadcast_received";
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.new = 1;
- console.log(obj);
- add_obj_to_database(obj);
- update_chat_obj_by_uuid(obj.uuid);
-
- db.find({
- selector: {
- dxcallsign: obj.dxcallsign,
- },
- }).then(function (result) {
- // handle result
- console.log(result);
- });
-
- //handle ping
- } else if (item.ping == "received") {
- obj.timestamp = parseInt(item.timestamp);
- obj.dxcallsign = item.dxcallsign;
- obj.dxgrid = item.dxgrid;
- obj.uuid = item.uuid;
- obj.command = "ping";
- obj.checksum = "null";
- obj.msg = "null";
- obj.status = item.status;
- obj.hmac_signed = item.hmac_signed;
- obj.snr = item.snr;
- obj.type = "ping";
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.new = 0;
-
- add_obj_to_database(obj);
- update_chat_obj_by_uuid(obj.uuid);
- // check for messages which failed and try to transmit them
- if (config.enable_auto_retry.toUpperCase() == "TRUE") {
- checkForWaitingMessages(obj.dxcallsign);
- }
-
- // handle ping-ack
- } else if (item.ping == "acknowledge") {
- obj.timestamp = parseInt(item.timestamp);
- obj.dxcallsign = item.dxcallsign;
- obj.dxgrid = item.dxgrid;
- obj.uuid = item.uuid;
- obj.command = "ping-ack";
- obj.checksum = "null";
- obj.msg = "null";
- obj.status = item.status;
- obj.snr = item.dxsnr + "/" + item.snr;
- obj.type = "ping-ack";
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.new = 0;
- add_obj_to_database(obj);
- update_chat_obj_by_uuid(obj.uuid);
-
- // handle beacon
- } else if (item.beacon == "received") {
- obj.timestamp = parseInt(item.timestamp);
- obj.dxcallsign = item.dxcallsign;
- obj.dxgrid = item.dxgrid;
- obj.uuid = item.uuid;
- obj.command = "beacon";
- obj.checksum = "null";
- obj.msg = "null";
- obj.status = item.status;
- obj.snr = item.snr;
- obj.type = "beacon";
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.new = 0;
- add_obj_to_database(obj);
- update_chat_obj_by_uuid(obj.uuid);
- // check for messages which failed and try to transmit them
- if (config.enable_auto_retry.toUpperCase() == "TRUE") {
- checkForWaitingMessages(obj.dxcallsign);
- }
- // handle ARQ transmission
- } else if (item.arq == "transmission" && item.status == "received") {
- //var encoded_data = atob(item.data);
- //var encoded_data = Buffer.from(item.data,'base64').toString('utf-8');
- var encoded_data = FD.atob_FD(item.data);
- var splitted_data = encoded_data.split(split_char);
-
- console.log(splitted_data);
-
- if (splitted_data[1] == "msg") {
- obj.timestamp = parseInt(splitted_data[4]);
- obj.dxcallsign = item.dxcallsign;
- obj.dxgrid = item.dxgrid;
- obj.command = splitted_data[1];
- obj.checksum = splitted_data[2];
- obj.uuid = splitted_data[3];
- obj.msg = splitted_data[5];
- obj.status = "null";
- obj.snr = "null";
- obj.type = "received";
- obj.filename = splitted_data[6];
- obj.filetype = splitted_data[7];
- //obj.file = btoa(splitted_data[8]);
- obj.file = FD.btoa_FD(splitted_data[8]);
- obj.hmac_signed = item.hmac_signed;
- obj.new = 1;
- } else if (splitted_data[1] == "req" && splitted_data[2] == "0") {
- obj.uuid = uuidv4().toString();
- obj.timestamp = Math.floor(Date.now() / 1000);
- obj.dxcallsign = item.dxcallsign;
- obj.command = splitted_data[1];
- obj.type = "request";
- obj.status = "received";
- obj.snr = "null";
- obj.msg = "Request for station info";
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.hmac_signed = item.hmac_signed;
- obj.new = 0;
- if (config.enable_request_profile == "True") {
- sendUserData(item.dxcallsign);
- }
- } else if (splitted_data[1] == "req" && splitted_data[2] == "1") {
- obj.uuid = uuidv4().toString();
- obj.timestamp = Math.floor(Date.now() / 1000);
- obj.dxcallsign = item.dxcallsign;
- obj.command = splitted_data[1];
- obj.type = "request";
- obj.status = "received";
- obj.snr = "null";
- obj.msg = "Request for shared folder list";
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.hmac_signed = item.hmac_signed;
- obj.new = 0;
- if (config.enable_request_shared_folder == "True") {
- sendSharedFolderList(item.dxcallsign);
- }
- } else if (
- splitted_data[1] == "req" &&
- splitted_data[2].substring(0, 1) == "2"
- ) {
- let name = splitted_data[2].substring(1);
- //console.log("In handle req for shared folder file");
- obj.uuid = uuidv4().toString();
- obj.timestamp = Math.floor(Date.now() / 1000);
- obj.dxcallsign = item.dxcallsign;
- obj.command = splitted_data[1];
- obj.type = "request";
- obj.status = "received";
- obj.snr = "null";
- obj.msg = "Request for shared file " + name;
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.hmac_signed = item.hmac_signed;
- obj.new = 0;
- if (config.enable_request_shared_folder == "True") {
- sendSharedFolderFile(item.dxcallsign, name);
- }
- } else if (splitted_data[1] == "res-0") {
- obj.uuid = uuidv4().toString();
- obj.timestamp = Math.floor(Date.now() / 1000);
- obj.dxcallsign = item.dxcallsign;
- obj.command = splitted_data[1];
- obj.type = "response";
- obj.status = "received";
- obj.snr = "null";
- obj.msg = "Response for station info";
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.hmac_signed = item.hmac_signed;
- obj.new = 0;
- console.log(splitted_data);
- let userData = new Object();
- userData.user_info_image = splitted_data[2];
- userData.user_info_callsign = splitted_data[3];
- userData.user_info_gridsquare = splitted_data[4];
- userData.user_info_name = splitted_data[5];
- userData.user_info_age = splitted_data[6];
- userData.user_info_location = splitted_data[7];
- userData.user_info_radio = splitted_data[8];
- userData.user_info_antenna = splitted_data[9];
- userData.user_info_email = splitted_data[10];
- userData.user_info_website = splitted_data[11];
- userData.user_info_comments = splitted_data[12];
-
- addUserToDatabaseIfNotExists(userData);
- getSetUserInformation(splitted_data[3]);
- } else if (splitted_data[1] == "res-1") {
- obj.uuid = uuidv4().toString();
- obj.timestamp = Math.floor(Date.now() / 1000);
- obj.dxcallsign = item.dxcallsign;
- obj.command = splitted_data[1];
- obj.type = "response";
- obj.status = "received";
- obj.snr = "null";
- obj.msg = "Response for shared file list";
- obj.filename = "null";
- obj.filetype = "null";
- obj.file = "null";
- obj.hmac_signed = item.hmac_signed;
- obj.new = 0;
- console.log(splitted_data);
-
- let userData = new Object();
-
- userData.user_info_callsign = obj.dxcallsign;
- let filelist = JSON.parse(splitted_data[3]);
- console.log(filelist);
- userData.user_shared_folder = filelist;
- addFileListToUserDatabaseIfNotExists(userData);
- getSetUserSharedFolder(obj.dxcallsign);
-
- //getSetUserInformation(selected_callsign);
- } else if (splitted_data[1] == "res-2") {
- console.log("In received response-2");
- let sharedFileInfo = splitted_data[2].split("/", 2);
-
- obj.uuid = uuidv4().toString();
- obj.timestamp = Math.floor(Date.now() / 1000);
- obj.dxcallsign = item.dxcallsign;
- obj.command = splitted_data[1];
- obj.type = "received";
- obj.status = "received";
- obj.snr = "null";
- obj.msg = "Response for shared file download";
- obj.filename = sharedFileInfo[0];
- obj.filetype = "application/octet-stream";
- obj.file = FD.btoa_FD(sharedFileInfo[1]);
- obj.hmac_signed = item.hmac_signed;
- obj.new = 0;
- } else {
- console.log("no rule matched for handling received data!");
- }
-
- add_obj_to_database(obj);
- update_chat_obj_by_uuid(obj.uuid);
- }
- });
- //window.location = window.location;
-});
-
-// Update chat list
-update_chat = function (obj) {
- var dxcallsign = obj.dxcallsign;
- var timestamp = dateFormat.format(obj.timestamp * 1000);
- //var timestampShort = dateFormatShort.format(obj.timestamp * 1000);
- var timestampHours = dateFormatHours.format(obj.timestamp * 1000);
-
- var dxgrid = obj.dxgrid;
-
- // check if obj.attempt exists
- if (typeof obj.attempt == "undefined") {
- db.upsert(obj._id, function (doc) {
- if (!doc.attempt) {
- doc.attempt = 1;
- }
- return doc;
- });
- var attempt = 1;
- obj.attempt = attempt;
- } else {
- var attempt = obj.attempt;
- }
-
- // add percent and bytes per minute if not existing
- //console.log(obj.percent)
- if (typeof obj.percent == "undefined") {
- obj.percent = 0;
- obj.bytesperminute = 0;
- }
-
- // check if wrong status message
- if (
- obj.status == "transmitting" &&
- obj.type == "transmit" &&
- obj.percent < 100
- ) {
- var TimeDifference = new Date().getTime() / 1000 - obj.timestamp;
- if (TimeDifference > 21600) {
- //Six hours
- console.log(
- "Resetting message to failed state since in transmit status for over 6 hours:",
- );
- console.log(obj);
- db.upsert(obj._id, function (doc) {
- doc.status = "failed";
- return doc;
- });
- obj.status = "failed";
- }
- }
- // check if in transmitting status and @ 100%
- if (
- obj.status == "transmitting" &&
- obj.type == "transmit" &&
- obj.percent == 100
- ) {
- var TimeDifference = new Date().getTime() / 1000 - obj.timestamp;
- if (TimeDifference > 21600) {
- //Six hours
- console.log(
- "Resetting message to transmitted since in transmit state and at 100%:",
- );
- console.log(obj);
- db.upsert(obj._id, function (doc) {
- doc.status = "transmitted";
- return doc;
- });
- obj.status = "transmitted";
- }
- }
- if (typeof obj.new == "undefined") {
- obj.new = 0;
- }
-
- if (typeof config.max_retry_attempts == "undefined") {
- var max_retry_attempts = 3;
- } else {
- var max_retry_attempts = parseInt(config.max_retry_attempts);
- }
- //console.log(obj.msg);
- // define shortmessage
- if (obj.msg == "null" || obj.msg == "NULL") {
- var shortmsg = obj.type;
- } else {
- var shortmsg = obj.msg;
- var maxlength = 30;
- var shortmsg =
- shortmsg.length > maxlength
- ? shortmsg.substring(0, maxlength - 3) + "..."
- : shortmsg;
- }
- try {
- //console.log(Object.keys(obj._attachments)[0].length)
- if (
- typeof obj._attachments !== "undefined" &&
- Object.keys(obj._attachments)[0].length > 0
- ) {
- //var filename = obj._attachments;
- var filename = Object.keys(obj._attachments)[0];
- var filetype = filename.split(".")[1];
- var filesize = obj._attachments[filename]["length"] + " Bytes";
- if (filesize == "undefined Bytes") {
- // get filesize of new submitted data
- // not that nice....
- // we really should avoid converting back from base64 for performance reasons...
- //var filesize = Math.ceil(atob(obj._attachments[filename]["data"]).length) + "Bytes";
- var filesize =
- Math.ceil(FD.atob_FD(obj._attachments[filename]["data"]).length) +
- " Bytes";
- }
-
- // check if image, then display it
- if (filetype == "image/png" || filetype == "png") {
- var fileheader = `
-
-
- `;
- } else {
- var fileheader = `
-
-
- `;
- }
-
- var controlarea_transmit = `
-
-
-
-
-
-
- `;
-
- var controlarea_receive = `
-
-
-
-
-
-
- `;
- } else {
- var filename = "";
- var fileheader = "";
- var filetype = "text/plain";
- var controlarea_transmit = `
-
-
-
-
- `;
- var controlarea_receive = `
-
-
-
- `;
- }
- } catch (err) {
- console.log("error with database parsing...");
- console.log(err);
- }
- // CALLSIGN LIST
- if (!document.getElementById("chat-" + dxcallsign + "-list")) {
- // increment callsign counter
- callsign_counter++;
- dxcallsigns.add(dxcallsign);
- if (
- (callsign_counter == 1 && selected_callsign == "") ||
- selected_callsign == dxcallsign
- ) {
- var callsign_selected = "active show";
- //document.getElementById('chatModuleDxCall').value = dxcallsign;
- selected_callsign = dxcallsign;
- }
-
- if (dxcallsign.startsWith("BC-")) {
- var user_image =
- ' ';
- } else {
- var user_image =
- ' ';
-
- getSetUserInformation(dxcallsign);
- getSetUserSharedFolder(dxcallsign);
- }
-
- var new_callsign = `
-
-
-
-
- ${user_image}
-
-
-
-
${dxcallsign}
-
${dxgrid}
-
${timestampHours}
-
${shortmsg}
-
-
-
-
- `;
-
- document
- .getElementById("list-tab-chat")
- .insertAdjacentHTML("beforeend", new_callsign);
- var message_area = `
-
- `;
- document
- .getElementById("nav-tabContent-Chat")
- .insertAdjacentHTML("beforeend", message_area);
-
- // finally get and set user information to first selected item
- getSetUserInformation(selected_callsign);
- getSetUserSharedFolder(selected_callsign);
-
- // create eventlistener for listening on clicking on a callsign
- document
- .getElementById("chat-" + dxcallsign + "-list")
- .addEventListener("click", function () {
- //document.getElementById('chatModuleDxCall').value = dxcallsign;
- selected_callsign = dxcallsign;
- //Reset unread messages and new message indicator
- let clear = selected_callsign;
- clearUnreadMessages(clear);
- document.getElementById(
- `chat-${selected_callsign}-list-displaydxcall`,
- ).textContent = selected_callsign;
- document
- .getElementById(`chat-${selected_callsign}-list`)
- .classList.remove("list-group-item-warning");
- setTimeout(scrollMessagesToBottom, 200);
-
- //get user information
- getSetUserInformation(selected_callsign);
- getSetUserSharedFolder(selected_callsign);
- if (selected_callsign.startsWith("BC-")) {
- document
- .getElementById("chatModuleMessage")
- .setAttribute("maxlength", 16);
- //console.log("Setting max message size to 16")
- } else {
- document
- .getElementById("chatModuleMessage")
- .setAttribute("maxlength", 524288);
- //console.log("Setting max message size to big#")
- }
- });
-
- // if callsign entry already exists - update
- } else {
- // gridsquare - update only on receive
- if (obj.type !== "transmit") {
- document.getElementById("chat-" + dxcallsign + "-list-dxgrid").innerHTML =
- dxgrid;
- }
- // time
- document.getElementById("chat-" + dxcallsign + "-list-time").innerHTML =
- timestampHours;
- // short message
- document.getElementById("chat-" + dxcallsign + "-list-shortmsg").innerHTML =
- shortmsg;
- if (obj.new == 1) {
- document.getElementById(
- `chat-${obj.dxcallsign}-list-displaydxcall`,
- ).textContent = "*" + obj.dxcallsign;
- document
- .getElementById(`chat-${dxcallsign}-list`)
- .classList.add("list-group-item-warning");
- }
- }
- // APPEND MESSAGES TO CALLSIGN
-
- if (!document.getElementById("msg-" + obj._id)) {
- if (obj.type == "ping") {
- //if (obj.new == 1)
- //{
- // showOsPopUp("Ping from " + obj.dxcallsign,"You've been ping'd!");
- //}
- var new_message = `
-
-
snr: ${obj.snr} - ${timestamp}
-
- `;
- }
- if (obj.type == "ping-ack") {
- var new_message = `
-
-
Ping ack dx/mine snr: ${obj.snr} - ${timestamp}
-
- `;
- }
- if (obj.type == "beacon") {
- var new_message = `
-
-
snr: ${obj.snr} - ${timestamp}
-
- `;
- }
- if (obj.type == "request") {
- var new_message = `
-
-
${obj.msg} - ${timestamp}
-
- `;
- }
- if (obj.type == "response") {
- var new_message = `
-
-
Response - ${timestamp}
-
- `;
- }
- if (obj.type == "newchat") {
- var new_message = `
-
-
new chat opened - ${timestamp}
-
- `;
- }
-
- // CHECK FOR NEW LINE AND REPLACE WITH
- var message_html = obj.msg.replaceAll(/\n/g, " ");
-
- if (obj.type == "received") {
- if (obj.new == 1) {
- showOsPopUp("Message received from " + obj.dxcallsign, obj.msg);
- }
-
- // check if message is signed or not for adjusting icon
- if (
- typeof obj.hmac_signed !== "undefined" &&
- obj.hmac_signed !== "False"
- ) {
- console.log(hmac_signed);
- var hmac_signed = ' ';
- } else {
- var hmac_signed = ' ';
- }
-
- var new_message = `
-
-
-
-
- ${fileheader}
-
-
-
${message_html}
-
- ${timestamp}
-
-
-
-
-
-
- ${hmac_signed}
-
-
-
-
-
- ${controlarea_receive}
-
- `;
- }
-
- if (obj.type == "broadcast_received") {
- console.log(obj);
- var new_message = `
-
-
-
-
-
-
${message_html}
-
- ${timestamp}
-
-
-
-
-
- ${obj.broadcast_sender}
- dxcallsign
-
-
-
-
-
-
-
-
- `;
- }
- if (obj.type == "broadcast_transmit") {
- var new_message = `
-
-
-
-
-
-
-
-
-
${message_html}
-
- ${timestamp} -
- ${get_icon_for_state(
- obj.status,
- )}
-
-
-
- ${attempt}/${max_retry_attempts}
- retries
-
-
-
-
-
- `;
- }
-
- if (obj.type == "transmit") {
- //console.log(obj);
- //console.log('msg-' + obj._id + '-status')
-
- if (obj.status == "failed") {
- var progressbar_bg = "bg-danger";
- var percent_value = "TRANSMISSION FAILED";
- //Set to 100 so progressbar background populates
- obj.percent = 100;
- } else if (obj.status == "transmitted") {
- var progressbar_bg = "bg-success";
- var percent_value = "TRANSMITTED";
- } else {
- var progressbar_bg = "bg-primary";
- var percent_value = obj.percent + " %";
- }
-
- //Sneak in low graphics mode if so enabled for progress bars
- if (config.high_graphics.toString().toUpperCase() != "TRUE") {
- progressbar_bg += " disable-effects";
- //console.log("Low graphics enabled for chat module");
- }
-
- var new_message = `
-
- ${controlarea_transmit}
-
-
- ${fileheader}
-
-
${message_html}
-
- ${timestamp} -
- ${get_icon_for_state(
- obj.status,
- )}
-
-
-
- ${attempt}/${max_retry_attempts}
- retries
-
-
-
-
${percent_value} - ${
- obj.bytesperminute
- } Bpm
-
-
-
-
-
- `;
- }
- // CHECK CHECK CHECK --> This could be done better
- var id = "chat-" + obj.dxcallsign;
- document.getElementById(id).insertAdjacentHTML("beforeend", new_message);
-
- /* UPDATE EXISTING ELEMENTS */
- } else if (document.getElementById("msg-" + obj._id)) {
- //console.log("element already exists......");
- //console.log(obj);
-
- // console.log(obj.status)
- // console.log(obj.attempt)
-
- if (
- obj.status != "broadcast_transmit" ||
- obj.status != "broadcast_received"
- ) {
- document.getElementById("msg-" + obj._id + "-status").innerHTML =
- get_icon_for_state(obj.status);
-
- document
- .getElementById("msg-" + obj._id + "-progress")
- .setAttribute("aria-valuenow", obj.percent);
- document
- .getElementById("msg-" + obj._id + "-progress")
- .setAttribute("style", "width:" + obj.percent + "%;");
- document.getElementById(
- "msg-" + obj._id + "-progress-information",
- ).innerHTML = obj.percent + "% - " + obj.bytesperminute + " Bpm";
-
- document.getElementById("msg-" + obj._id + "-attempts").innerHTML =
- obj.attempt + "/" + max_retry_attempts;
- }
-
- if (obj.status == "transmit") {
- document.getElementById("msg-" + obj._id + "-status").innerHTML =
- get_icon_for_state(obj.status);
-
- if (typeof obj.percent !== "undefined") {
- document
- .getElementById("msg-" + obj._id + "-progress")
- .setAttribute("aria-valuenow", obj.percent);
- document
- .getElementById("msg-" + obj._id + "-progress")
- .setAttribute("style", "width:" + obj.percent + "%;");
- document.getElementById(
- "msg-" + obj._id + "-progress-information",
- ).innerHTML = obj.percent + "% - " + obj.bytesperminute + " Bpm";
- } else {
- document
- .getElementById("msg-" + obj._id + "-progress")
- .setAttribute("aria-valuenow", 0);
- document
- .getElementById("msg-" + obj._id + "-progress")
- .setAttribute("style", "width:0%;");
- document.getElementById(
- "msg-" + obj._id + "-progress-information",
- ).innerHTML = "0% - 0 Bpm";
- }
-
- document.getElementById("msg-" + obj._id + "-attempts").innerHTML =
- obj.attempt + "/" + max_retry_attempts;
- }
-
- if (obj.status == "transmitted") {
- //document.getElementById('msg-' + obj._id + '-progress').classList.remove("progress-bar-striped");
- document
- .getElementById("msg-" + obj._id + "-progress")
- .classList.remove("progress-bar-animated");
- document
- .getElementById("msg-" + obj._id + "-progress")
- .classList.remove("bg-danger");
- document
- .getElementById("msg-" + obj._id + "-progress")
- .classList.add("bg-success");
-
- document.getElementById("msg-" + obj._id + "-progress").innerHTML = "";
- document.getElementById(
- "msg-" + obj._id + "-progress-information",
- ).innerHTML = "TRANSMITTED - " + obj.bytesperminute + " Bpm";
- } else if (
- obj.status != "broadcast_transmit" ||
- obj.status != "broadcast_received"
- ) {
- document
- .getElementById("msg-" + obj._id + "-progress")
- .classList.add("progress-bar-striped");
- document
- .getElementById("msg-" + obj._id + "-progress")
- .classList.add("progress-bar-animated");
- }
-
- if (obj.status == "failed") {
- //document.getElementById('msg-' + obj._id + '-progress').classList.remove("progress-bar-striped");
- document
- .getElementById("msg-" + obj._id + "-progress")
- .classList.remove("progress-bar-animated");
- document
- .getElementById("msg-" + obj._id + "-progress")
- .classList.remove("bg-primary");
- document
- .getElementById("msg-" + obj._id + "-progress")
- .classList.add("bg-danger");
-
- console.log(
- document.getElementById("msg-" + obj._id + "-progress").classList,
- );
-
- document.getElementById(
- "msg-" + obj._id + "-progress-information",
- ).innerHTML = "TRANSMISSION FAILED - " + obj.bytesperminute + " Bpm";
- }
-
- //document.getElementById(id).className = message_class;
- }
-
- //Delete message event listener
- if (
- document.getElementById("del-msg-" + obj._id) &&
- !document
- .getElementById("del-msg-" + obj._id)
- .hasAttribute("listenerOnClick")
- ) {
- // set Attribute to determine if we already created an EventListener for this element
- document
- .getElementById("del-msg-" + obj._id)
- .setAttribute("listenerOnClick", "true");
- document
- .getElementById("del-msg-" + obj._id)
- .addEventListener("click", () => {
- db.get(obj._id, {
- attachments: true,
- })
- .then(function (doc) {
- db.remove(doc._id, doc._rev, function (err) {
- if (err) console.log("Error removing item " + err);
- });
- })
- .catch(function (err) {
- console.log(err);
- });
-
- document.getElementById("msg-" + obj._id).remove();
- document.getElementById("msg-" + obj._id + "-control-area").remove();
- console.log("Removed message " + obj._id.toString());
-
- // stop transmission if deleted message is still in progress
- if (obj.status == "transmitting") {
- let Data = {
- command: "stop_transmission",
- };
- ipcRenderer.send("run-tnc-command", Data);
- }
- });
- //scrollMessagesToBottom();
- }
-
- // CREATE SAVE TO FOLDER EVENT LISTENER
- if (
- document.getElementById("save-file-msg-" + obj._id) &&
- !document
- .getElementById("save-file-msg-" + obj._id)
- .hasAttribute("listenerOnClick")
- ) {
- // set Attribute to determine if we already created an EventListener for this element
- document
- .getElementById("save-file-msg-" + obj._id)
- .setAttribute("listenerOnClick", "true");
-
- document
- .getElementById("save-file-msg-" + obj._id)
- .addEventListener("click", () => {
- saveFileToFolder(obj._id);
- });
- }
- // CREATE RESEND MSG EVENT LISTENER
-
- // check if element exists and if we already created NOT created an event listener
- if (
- document.getElementById("retransmit-msg-" + obj._id) &&
- !document
- .getElementById("retransmit-msg-" + obj._id)
- .hasAttribute("listenerOnClick")
- ) {
- // set Attribute to determine if we already created an EventListener for this element
- document
- .getElementById("retransmit-msg-" + obj._id)
- .setAttribute("listenerOnClick", "true");
- document
- .getElementById("retransmit-msg-" + obj._id)
- .addEventListener("click", () => {
- // increment attempt
- db.upsert(obj._id, function (doc) {
- if (!doc.attempt) {
- doc.attempt = 1;
- }
- doc.attempt++;
- return doc;
- })
- .then(function (res) {
- // success, res is {rev: '1-xxx', updated: true, id: 'myDocId'}
- console.log(res);
- update_chat_obj_by_uuid(obj.uuid);
- })
- .catch(function (err) {
- // error
- console.log(err);
- });
-
- db.get(obj._id, {
- attachments: true,
- })
- .then(function (doc) {
- // handle doc
- console.log(doc);
-
- var filename = Object.keys(obj._attachments)[0];
- var filetype = filename.content_type;
-
- console.log(filename);
- console.log(filetype);
- var file = obj._attachments[filename].data;
- console.log(file);
- console.log(Object.keys(obj._attachments)[0].data);
-
- //var file = atob(obj._attachments[filename]["data"])
- db.getAttachment(obj._id, filename).then(function (data) {
- console.log(data);
- //Rewrote this part to use buffers to ensure encoding is corect -- n1qm
- var binaryString = FD.atob_FD(data);
-
- console.log(binaryString);
- var data_with_attachment =
- doc.timestamp +
- split_char +
- doc.msg +
- split_char +
- filename +
- split_char +
- filetype +
- split_char +
- binaryString;
- let Data = {
- command: "msg",
- dxcallsign: doc.dxcallsign,
- mode: 255,
- frames: 5,
- data: data_with_attachment,
- checksum: doc.checksum,
- uuid: doc.uuid,
- };
- console.log(Data);
- ipcRenderer.send("run-tnc-command", Data);
- });
- /*
- // convert blob data to binary string
- blobUtil.blobToBinaryString(data).then(function (binaryString) {
- console.log(binaryString)
- }).catch(function (err) {
- // error
- console.log(err);
- binaryString = blobUtil.arrayBufferToBinaryString(data);
-
- }).then(function(){
-
- console.log(binaryString)
- console.log(binaryString.length)
-
- var data_with_attachment = doc.timestamp + split_char + utf8.encode(doc.msg) + split_char + filename + split_char + filetype + split_char + binaryString;
- let Data = {
- command: "msg",
- dxcallsign: doc.dxcallsign,
- mode: 255,
- frames: 1,
- data: data_with_attachment,
- checksum: doc.checksum,
- uuid: doc.uuid
- };
- console.log(Data)
- ipcRenderer.send('run-tnc-command', Data);
-
- });
- });
- */
- })
- .catch(function (err) {
- console.log(err);
- });
- });
- }
- //window.location = window.location
-
- // scroll to bottom on new message
- scrollMessagesToBottom();
-};
-
-function saveFileToFolder(id) {
- db.get(id, {
- attachments: true,
- })
- .then(function (obj) {
- console.log(obj);
- console.log(Object.keys(obj._attachments)[0].content_type);
- var filename = Object.keys(obj._attachments)[0];
- var filetype = filename.content_type;
- var file = filename.data;
- console.log(file);
- console.log(filename.data);
- db.getAttachment(id, filename)
- .then(function (data) {
- // handle result
- console.log(data.length);
- //data = new Blob([data.buffer], { type: 'image/png' } /* (1) */)
- console.log(data);
- // we need to encode data because of error "an object could not be cloned"
- let Data = {
- file: data,
- filename: filename,
- filetype: filetype,
- };
- console.log(Data);
- ipcRenderer.send("save-file-to-folder", Data);
- })
- .catch(function (err) {
- console.log(err);
- return false;
- });
- })
- .catch(function (err) {
- console.log(err);
- });
-}
-
-// function for setting an ICON to the corresponding state
-function get_icon_for_state(state) {
- if (state == "transmit") {
- var status_icon = '
';
- } else if (state == "transmitting") {
- //var status_icon = '
';
- var status_icon = `
-
- `;
- } else if (state == "failed") {
- var status_icon =
- '
';
- } else if (state == "transmitted") {
- var status_icon = '
';
- } else {
- var status_icon = '
';
- }
- return status_icon;
-}
-
-update_chat_obj_by_uuid = function (uuid) {
- db.get(uuid, {
- attachments: true,
- })
- .then(function (doc) {
- update_chat(doc);
- //return doc
- })
- .catch(function (err) {
- console.log(err);
- });
-};
-
-add_obj_to_database = function (obj) {
- console.log(obj);
- db.put({
- _id: obj.uuid,
- timestamp: parseInt(obj.timestamp),
- broadcast_sender: obj.broadcast_sender,
- uuid: obj.uuid,
- dxcallsign: obj.dxcallsign,
- dxgrid: obj.dxgrid,
- msg: obj.msg,
- checksum: obj.checksum,
- type: obj.type,
- command: obj.command,
- status: obj.status,
- snr: obj.snr,
- attempt: obj.attempt,
- hmac_signed: obj.hmac_signed,
- new: obj.new,
- _attachments: {
- [obj.filename]: {
- content_type: obj.filetype,
- data: obj.file,
- },
- },
- })
- .then(function (response) {
- console.log("new database entry");
- console.log(response);
- })
- .catch(function (err) {
- console.log("already exists");
- console.log(err);
- console.log(obj);
- db.upsert(obj.uuid, function (doc) {
- doc = obj;
- return doc;
- })
- .then(function (response) {
- console.log("upsert");
- console.log(response);
- })
- .catch(function (err) {
- console.log(err);
- });
- });
-};
-/* users database functions */
-addUserToDatabaseIfNotExists = function (obj) {
- /*
- "user_info_callsign",
- "user_info_gridsquare",
- "user_info_name",
- "user_info_age",
- "user_info_location",
- "user_info_radio",
- "user_info_antenna",
- "user_info_email",
- "user_info_website",
- "user_info_comments",
-*/
- console.log(obj);
- users
- .find({
- selector: {
- user_info_callsign: obj.user_info_callsign,
- },
- })
- .then(function (result) {
- // handle result
- console.log(result);
- if (result.docs.length > 0) {
- users
- .put({
- _id: result.docs[0]._id,
- _rev: result.docs[0]._rev,
- user_info_callsign: obj.user_info_callsign,
- user_info_gridsquare: obj.user_info_gridsquare,
- user_info_name: obj.user_info_name,
- user_info_age: obj.user_info_age,
- user_info_location: obj.user_info_location,
- user_info_radio: obj.user_info_radio,
- user_info_antenna: obj.user_info_antenna,
- user_info_email: obj.user_info_email,
- user_info_website: obj.user_info_website,
- user_info_comments: obj.user_info_comments,
- user_info_image: obj.user_info_image,
- })
- .then(function (response) {
- console.log("UPDATED USER");
- console.log(response);
- console.log(obj);
- })
- .catch(function (err) {
- console.log(err);
- });
- } else {
- users
- .post({
- user_info_callsign: obj.user_info_callsign,
- user_info_gridsquare: obj.user_info_gridsquare,
- user_info_name: obj.user_info_name,
- user_info_age: obj.user_info_age,
- user_info_location: obj.user_info_location,
- user_info_radio: obj.user_info_radio,
- user_info_antenna: obj.user_info_antenna,
- user_info_email: obj.user_info_email,
- user_info_website: obj.user_info_website,
- user_info_comments: obj.user_info_comments,
- })
- .then(function (response) {
- console.log("NEW USER ADDED");
- })
- .catch(function (err) {
- console.log(err);
- });
- }
- })
- .catch(function (err) {
- console.log(err);
- });
-};
-
-addFileListToUserDatabaseIfNotExists = function (obj) {
- console.log(obj);
- users
- .find({
- selector: {
- user_info_callsign: obj.user_info_callsign,
- },
- })
- .then(function (result) {
- // handle result
- if (result.docs.length > 0) {
- users
- .put({
- _id: result.docs[0]._id,
- _rev: result.docs[0]._rev,
- user_shared_folder: obj.user_shared_folder,
- user_info_callsign: result.docs[0].user_info_callsign,
- user_info_gridsquare: result.docs[0].user_info_gridsquare,
- user_info_name: result.docs[0].user_info_name,
- user_info_age: result.docs[0].user_info_age,
- user_info_location: result.docs[0].user_info_location,
- user_info_radio: result.docs[0].user_info_radio,
- user_info_antenna: result.docs[0].user_info_antenna,
- user_info_email: result.docs[0].user_info_email,
- user_info_website: result.docs[0].user_info_website,
- user_info_comments: result.docs[0].user_info_comments,
- })
- .then(function (response) {
- console.log("File List: UPDATED USER");
- console.log(response);
- console.log(obj);
- getSetUserSharedFolder(obj.user_info_callsign);
- })
- .catch(function (err) {
- console.log(err);
- });
- } else {
- users
- .post({
- user_info_callsign: obj.user_info_callsign,
- user_shared_folder: obj.user_shared_folder,
- })
- .then(function (response) {
- console.log("File List: NEW USER ADDED");
- getSetUserSharedFolder(obj.user_info_callsign);
- })
- .catch(function (err) {
- console.log(err);
- });
- }
- })
- .catch(function (err) {
- console.log(err);
- });
-};
-
-// Scroll to bottom of message-container
-function scrollMessagesToBottom() {
- var messageBody = document.getElementById("message-container");
- messageBody.scrollTop = messageBody.scrollHeight - messageBody.clientHeight;
-}
-
-// CRC CHECKSUMS
-// https://stackoverflow.com/a/50579690
-// crc32 calculation
-//console.log(crc32('abc'));
-//var crc32=function(r){for(var a,o=[],c=0;c<256;c++){a=c;for(var f=0;f<8;f++)a=1&a?3988292384^a>>>1:a>>>1;o[c]=a}for(var n=-1,t=0;t
>>8^o[255&(n^r.charCodeAt(t))];return(-1^n)>>>0};
-//console.log(crc32('abc').toString(16).toUpperCase()); // hex
-
-var makeCRCTable = function () {
- var c;
- var crcTable = [];
- for (var n = 0; n < 256; n++) {
- c = n;
- for (var k = 0; k < 8; k++) {
- c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
- }
- crcTable[n] = c;
- }
- return crcTable;
-};
-
-var crc32 = function (str) {
- var crcTable = window.crcTable || (window.crcTable = makeCRCTable());
- var crc = 0 ^ -1;
-
- for (var i = 0; i < str.length; i++) {
- crc = (crc >>> 8) ^ crcTable[(crc ^ str.charCodeAt(i)) & 0xff];
- }
-
- return (crc ^ -1) >>> 0;
-};
-
-function returnObjFromCallsign(database, callsign) {
- return new Promise((resolve, reject) => {
- users
- .find({
- selector: {
- user_info_callsign: callsign,
- },
- })
- .then(function (result) {
- //return new Promise((resolve, reject) => {
- if (typeof result.docs[0] !== "undefined") {
- resolve(result.docs[0]);
- } else {
- reject("Promise rejected");
- }
-
- /*
- if (typeof result.docs[0] !== "undefined") {
- return result.docs[0];
-
-
-
-
- } else {
- return false;
- }
-
- */
- })
- .catch(function (err) {
- console.log(err);
- });
- });
-}
-
-function createChatIndex() {
- db.createIndex({
- index: {
- fields: [
- "timestamp",
- "uuid",
- "dxcallsign",
- "dxgrid",
- "msg",
- "checksum",
- "type",
- "command",
- "status",
- "percent",
- "attempt",
- "hmac_signed",
- "bytesperminute",
- "_attachments",
- "new",
- ],
- },
- })
- .then(function (result) {
- // handle result
- console.log(result);
- })
- .catch(function (err) {
- console.log(err);
- });
-}
-
-function createUserIndex() {
- users
- .createIndex({
- index: {
- fields: [
- "timestamp",
- "user_info_callsign",
- "user_info_gridsquare",
- "user_info_name",
- "user_info_age",
- "user_info_location",
- "user_info_radio",
- "user_info_antenna",
- "user_info_email",
- "user_info_website",
- "user_info_comments",
- "user_info_image",
- ],
- },
- })
- .then(function (result) {
- // handle result
- console.log(result);
- return true;
- })
- .catch(function (err) {
- console.log(err);
- return false;
- });
-}
-
-async function updateAllChat(clear) {
- if (clear == true) {
- filetype = "";
- file = "";
- filename = "";
- callsign_counter = 0;
- //selected_callsign = "";
- dxcallsigns.clear();
- document.getElementById("list-tab-chat").innerHTML = "";
- document.getElementById("nav-tabContent-Chat").innerHTML = "";
- //document.getElementById("list-tab-chat").childNodes.remove();
- //document.getElementById("nav-tab-content").childrenNodes.remove();
- }
- //Ensure we create an index before running db.find
- //We can't rely on the default index existing before we get here...... :'(
- await db
- .createIndex({
- index: {
- fields: [{ dxcallsign: "asc" }, { timestamp: "asc" }],
- },
- })
- .then(async function (result) {
- // handle result
- await db
- .find({
- selector: {
- $and: [
- { dxcallsign: { $exists: true } },
- { timestamp: { $exists: true } },
- { $or: chatFilter },
- ],
- //$or: chatFilter
- },
- sort: [{ dxcallsign: "asc" }, { timestamp: "asc" }],
- })
- .then(async function (result) {
- console.log(result);
- // handle result async
- //document.getElementById("blurOverlay").classList.add("bg-primary");
- console.log(result);
- if (typeof result !== "undefined") {
- for (const item of result.docs) {
- //await otherwise history will not be in chronological order
- await db
- .get(item._id, {
- attachments: true,
- })
- .then(function (item_with_attachments) {
- update_chat(item_with_attachments);
- });
- }
- }
- })
- .catch(function (err) {
- console.log(err);
- });
- })
- .catch(function (err) {
- console.log(err);
- });
- if (clear == true && dxcallsigns.has(selected_callsign) == false) {
- //Selected call sign is not visible, reset to first call sign
- let tmp = dxcallsigns.entries().next().value[0];
- selected_callsign = tmp;
- document
- .getElementById("chat-" + tmp + "-list")
- .classList.add("active", "show");
- document.getElementById("chat-" + tmp).classList.add("active", "show");
- scrollMessagesToBottom();
- }
-}
-
-function getSetUserSharedFolder(selected_callsign) {
- // TODO: This is a dirty hotfix for avoiding, this function is canceld too fast.
- //Should be fixed
- //console.log("get set user information:" + selected_callsign);
-
- if (
- selected_callsign == "" ||
- selected_callsign == null ||
- typeof selected_callsign == "undefined"
- ) {
- console.log("return triggered");
- return;
- }
-
- // disable button if broadcast
- if (selected_callsign.startsWith("BC-")) {
- document.getElementById("sharedFolderDXButton").disabled = true;
- } else {
- document.getElementById("sharedFolderDXButton").disabled = false;
- }
-
- returnObjFromCallsign(users, selected_callsign)
- .then(function (data) {
- console.log(data);
-
- if (typeof data.user_shared_folder !== "undefined") {
- console.log(data.user_shared_folder);
- // shared folder table
- var icons = [
- "aac",
- "ai",
- "bmp",
- "cs",
- "css",
- "csv",
- "doc",
- "docx",
- "exe",
- "gif",
- "heic",
- "html",
- "java",
- "jpg",
- "js",
- "json",
- "jsx",
- "key",
- "m4p",
- "md",
- "mdx",
- "mov",
- "mp3",
- "mp4",
- "otf",
- "pdf",
- "php",
- "png",
- "ppt",
- "pptx",
- "psd",
- "py",
- "raw",
- "rb",
- "sass",
- "scss",
- "sh",
- "sql",
- "svg",
- "tiff",
- "tsx",
- "ttf",
- "txt",
- "wav",
- "woff",
- "xls",
- "xlsx",
- "xml",
- "yml",
- ];
- var tbl = document.getElementById("sharedFolderTableDX");
- tbl.innerHTML = "";
- let counter = 0;
- data.user_shared_folder.forEach((file) => {
- var row = document.createElement("tr");
-
- let dxcall = selected_callsign;
- let name = file["name"];
- let type = file["extension"];
-
- if (icons.indexOf(type) == -1) {
- type = "bi-file-earmark";
- } else {
- type = "bi-filetype-" + type;
- }
-
- let id = document.createElement("td");
- let idText = document.createElement("span");
- counter += 1;
- idText.innerHTML +=
- ' ' +
- counter;
- id.appendChild(idText);
- row.appendChild(id);
-
- let filename = document.createElement("td");
- let filenameText = document.createElement("span");
- filenameText.innerText = file["name"];
- filename.appendChild(filenameText);
- row.appendChild(filename);
-
- let filetype = document.createElement("td");
- let filetypeText = document.createElement("span");
- filetypeText.innerHTML = ` `;
- filetype.appendChild(filetypeText);
- row.appendChild(filetype);
-
- let filesize = document.createElement("td");
- let filesizeText = document.createElement("span");
- filesizeText.innerText = formatBytes(file["size"], 2);
- filesize.appendChild(filesizeText);
- row.appendChild(filesize);
- id.addEventListener("click", function () {
- //console.log(name," clicked");
- sendFileReq(dxcall, name);
- });
- tbl.appendChild(row);
- });
- } else {
- document.getElementById("sharedFolderTableDX").innerHTML = "no data";
- }
- })
- .catch(function (err) {
- console.log(err);
- document.getElementById("sharedFolderTableDX").innerHTML = "no data";
- });
-}
-
-function getSetUserInformation(selected_callsign) {
- //Get user information
- //console.log("get set user information:" + selected_callsign);
-
- if (
- selected_callsign == "" ||
- selected_callsign == null ||
- typeof selected_callsign == "undefined"
- ) {
- console.log("return triggered");
- return;
- }
-
- // disable button if broadcast
- if (selected_callsign.startsWith("BC-")) {
- document.getElementById("userModalDXButton").disabled = true;
- document.getElementById("ping").disabled = true;
- } else {
- document.getElementById("userModalDXButton").disabled = false;
- document.getElementById("ping").disabled = false;
- }
-
- document.getElementById("dx_user_info_callsign").innerHTML =
- selected_callsign;
-
- returnObjFromCallsign(users, selected_callsign)
- .then(function (data) {
- console.log(data);
-
- // image
- if (typeof data.user_info_image !== "undefined") {
- try {
- console.log("try checking for image if base64 data");
- // determine if we have a base64 encoded image
- console.log(data.user_info_image);
- console.log(data.user_info_image.split(";base64,")[1]);
- // split data string by "base64" for separating image type from base64 string
- atob(data.user_info_image.split(";base64,")[1]);
-
- if (selected_callsign.startsWith("BC-")) {
- data.user_info_image = defaultGroupIcon;
- }
-
- document.getElementById("dx_user_info_image").src =
- data.user_info_image;
- document.getElementById("user-image-" + selected_callsign).src =
- data.user_info_image;
- } catch (e) {
- console.log(e);
- console.log("corrupted image data");
-
- if (selected_callsign.startsWith("BC-")) {
- var userIcon = defaultGroupIcon;
- } else {
- var userIcon = defaultUserIcon;
- }
-
- document.getElementById("user-image-" + selected_callsign).src =
- userIcon;
- document.getElementById("dx_user_info_image").src = userIcon;
- }
- } else {
- // throw error and use placeholder data
- // throw new Error("Data not available or corrupted");
- document.getElementById("dx_user_info_image").src = defaultUserIcon;
- document.getElementById("user-image-" + selected_callsign).src =
- defaultUserIcon;
- }
-
- // Callsign list elements
- document.getElementById(
- "chat-" + selected_callsign + "-list-dxgrid",
- ).innerHTML = "" + data.user_info_gridsquare + " ";
- document.getElementById("user-image-" + selected_callsign).className =
- "p-1 rounded-circle";
- document.getElementById("user-image-" + selected_callsign).style =
- "width: 60px";
-
- // DX Station tab
- document.getElementById("dx_user_info_name").innerHTML =
- data.user_info_name;
- document.getElementById("dx_user_info_age").innerHTML =
- data.user_info_age;
- document.getElementById("dx_user_info_gridsquare").innerHTML =
- data.user_info_gridsquare;
- document.getElementById("dx_user_info_location").innerHTML =
- data.user_info_location;
- document.getElementById("dx_user_info_email").innerHTML =
- data.user_info_email;
- document.getElementById("dx_user_info_website").innerHTML =
- data.user_info_website;
- document.getElementById("dx_user_info_radio").innerHTML =
- data.user_info_radio;
- document.getElementById("dx_user_info_antenna").innerHTML =
- data.user_info_antenna;
- document.getElementById("dx_user_info_comments").innerHTML =
- data.user_info_comments;
-
- document.getElementById("dx_user_info_gridsquare").className = "";
- document.getElementById("dx_user_info_name").className =
- "badge bg-secondary";
- document.getElementById("dx_user_info_age").className =
- "badge bg-secondary";
- document.getElementById("dx_user_info_gridsquare").className = "";
- document.getElementById("dx_user_info_location").className = "";
- document.getElementById("dx_user_info_email").className = "";
- document.getElementById("dx_user_info_website").className = "";
- document.getElementById("dx_user_info_radio").className = "";
- document.getElementById("dx_user_info_antenna").className = "";
- document.getElementById("dx_user_info_comments").className = "";
- })
- .catch(function (err) {
- console.log("writing user info to modal failed");
- console.log(err);
-
- if (selected_callsign.startsWith("BC-")) {
- var userIcon = defaultGroupIcon;
- } else {
- var userIcon = defaultUserIcon;
- }
-
- // Callsign list elements
- document.getElementById("user-image-" + selected_callsign).src = userIcon;
- document.getElementById("user-image-" + selected_callsign).className =
- "p-1 rounded-circle w-100";
- document.getElementById("user-image-" + selected_callsign).style =
- "height:60px";
- document.getElementById(
- "chat-" + selected_callsign + "-list-dxgrid",
- ).innerHTML = "no grid ";
-
- // DX Station tab
-
- document.getElementById("dx_user_info_image").src = defaultUserIcon;
- document.getElementById("dx_user_info_gridsquare").className =
- "placeholder col-4";
- document.getElementById("dx_user_info_name").className =
- "placeholder col-4";
- document.getElementById("dx_user_info_age").className =
- "placeholder col-2";
- document.getElementById("dx_user_info_gridsquare").className =
- "placeholder col-3";
- document.getElementById("dx_user_info_location").className =
- "placeholder col-3";
- document.getElementById("dx_user_info_email").className =
- "placeholder col-7";
- document.getElementById("dx_user_info_website").className =
- "placeholder col-7";
- document.getElementById("dx_user_info_radio").className =
- "placeholder col-4";
- document.getElementById("dx_user_info_antenna").className =
- "placeholder col-4";
- document.getElementById("dx_user_info_comments").className =
- "placeholder col-7";
- });
-}
-
-function sendSharedFolderList(dxcallsign) {
- ipcRenderer.send("read-files-in-folder", {
- folder: config.shared_folder_path,
- });
-
- console.log(sharedFolderFileList);
- let fileListWithCallsign = "";
- fileListWithCallsign += dxcallsign;
- fileListWithCallsign += split_char;
- fileListWithCallsign += JSON.stringify(sharedFolderFileList);
-
- console.log(fileListWithCallsign);
-
- ipcRenderer.send("run-tnc-command", {
- command: "responseSharedFolderList",
- dxcallsign: dxcallsign,
- folderFileList: fileListWithCallsign,
- });
-}
-
-function sendSharedFolderFile(dxcallsign, filename) {
- let filePath = path.join(config.shared_folder_path, filename);
- console.log("In function sendSharedFolderFile ", filePath);
-
- //Make sure nothing sneaky is going on
- if (!filePath.startsWith(config.shared_folder_path)) {
- console.error("File is outside of shared folder path!");
- return;
- }
-
- if (!fs.existsSync(filePath)) {
- console.warn("File doesn't seem to exist");
- return;
- }
-
- //Read file's data
- let fileData = null;
- try {
- //Has to be binary
- let data = fs.readFileSync(filePath);
- fileData = data.toString("utf-8");
- } catch (err) {
- console.log(err);
- return;
- }
-
- ipcRenderer.send("run-tnc-command", {
- command: "responseSharedFile",
- dxcallsign: dxcallsign,
- file: filename,
- filedata: fileData,
- });
-}
-
-function sendUserData(dxcallsign) {
- const userInfoFields = [
- "user_info_image",
- "user_info_callsign",
- "user_info_gridsquare",
- "user_info_name",
- "user_info_age",
- "user_info_location",
- "user_info_radio",
- "user_info_antenna",
- "user_info_email",
- "user_info_website",
- "user_info_comments",
- ];
-
- let info = "";
- userInfoFields.forEach(function (subelem) {
- if (subelem !== "user_info_image") {
- info += document.getElementById(subelem).value;
- info += split_char;
- } else {
- info += document.getElementById(subelem).src;
- info += split_char;
- }
- });
-
- console.log(info);
-
- ipcRenderer.send("run-tnc-command", {
- command: "responseUserInfo",
- dxcallsign: dxcallsign,
- userinfo: info,
- });
-}
-
-//Temporarily disable a button with timeout
-function pauseButton(btn, timems) {
- btn.disabled = true;
- var curText = btn.innerHTML;
- if (config.high_graphics.toUpperCase() == "TRUE") {
- btn.innerHTML =
- '';
- }
- setTimeout(() => {
- btn.innerHTML = curText;
- btn.disabled = false;
- }, timems);
-}
-ipcRenderer.on("update-config", (event, data) => {
- config = data;
-});
-
-ipcRenderer.on("action-update-unread-messages", (event) => {
- checkForNewMessages().then(function (count) {
- ipcRenderer.send("request-update-unread-messages-main", count);
- });
-});
-
-ipcRenderer.on("action-clean-db", (event) => {
- dbClean();
-});
-
-// https://stackoverflow.com/a/18650828
-function formatBytes(bytes, decimals = 2) {
- if (!+bytes) return "0 Bytes";
-
- const k = 1024;
- const dm = decimals < 0 ? 0 : decimals;
- const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
-
- const i = Math.floor(Math.log(bytes) / Math.log(k));
-
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
-}
-function sendFileReq(dxcall, file) {
- //console.log(file," clicked");
- ipcRenderer.send("run-tnc-command", {
- command: "requestSharedFile",
- dxcallsign: dxcall,
- file: file,
- });
-}
-
-function changeGuiDesign(design) {
- console.log(design);
- if (
- design != "default" &&
- design != "default_light" &&
- design != "default_dark" &&
- design != "default_auto"
- ) {
- var theme_path =
- "../node_modules/bootswatch/dist/" + design + "/bootstrap.min.css";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
- } else if (design == "default" || design == "default_light") {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
- document.documentElement.setAttribute("data-bs-theme", "light");
- } else if (design == "default_dark") {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
- document.querySelector("html").setAttribute("data-bs-theme", "dark");
- } else if (design == "default_auto") {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
-
- // https://stackoverflow.com/a/57795495
- // check if dark mode or light mode used in OS
- if (
- window.matchMedia &&
- window.matchMedia("(prefers-color-scheme: dark)").matches
- ) {
- // dark mode
- document.documentElement.setAttribute("data-bs-theme", "dark");
- } else {
- document.documentElement.setAttribute("data-bs-theme", "light");
- }
-
- // also register event listener for automatic change
- window
- .matchMedia("(prefers-color-scheme: dark)")
- .addEventListener("change", (event) => {
- let newColorScheme = event.matches ? "dark" : "light";
- if (newColorScheme == "dark") {
- document.documentElement.setAttribute("data-bs-theme", "dark");
- } else {
- document.documentElement.setAttribute("data-bs-theme", "light");
- }
- });
- } else {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
- document.documentElement.setAttribute("data-bs-theme", "light");
- }
-
- //update path to css file
- document.getElementById("bootstrap_theme").href = escape(theme_path);
-}
-
-function checkForWaitingMessages(dxcall) {
- db.find({
- selector: {
- dxcallsign: dxcall,
- type: "transmit",
- status: "failed",
- //attempt: { $lt: parseInt(config.max_retry_attempts) }
- },
- })
- .then(function (result) {
- console.log(
- "Found " + result.docs.length + " messages waiting for " + dxcall,
- );
- // handle result
- if (result.docs.length > 0) {
- // only want to process the first available item object, then return
- // this ensures, we are only sending one message at once
-
- if (typeof result.docs[0].attempt == "undefined") {
- db.upsert(result.docs[0]._id, function (doc) {
- if (!doc.attempt) {
- doc.attempt = 1;
- }
- doc.attempt++;
- return doc;
- });
- console.log("old message found - adding attempt field");
- result.docs[0].attempt = 1;
- }
-
- if (result.docs[0].attempt < config.max_retry_attempts) {
- console.log("RESENDING MESSAGE TRIGGERED BY BEACON OR PING");
- console.log(result.docs[0]);
- document
- .getElementById("retransmit-msg-" + result.docs[0]._id)
- .click();
- } else {
- console.log("max retries reached...can't auto repeat");
- document
- .getElementById("msg-" + result.docs[0]._id + "-attempts-badge")
- .classList.remove("bg-primary");
- document
- .getElementById("msg-" + result.docs[0]._id + "-attempts-badge")
- .classList.add("bg-danger");
- }
- return;
- } else {
- //console.log("nope");
- }
- })
- .catch(function (err) {
- console.log(err);
- });
-}
-
-async function checkForNewMessages() {
- var newmsgs;
- await db
- .find({
- selector: {
- new: { $eq: 1 },
- },
- limit: 1,
- })
- .then(function (result) {
- if (result.docs.length > 0) newmsgs = true;
- else newmsgs = false;
- })
- .catch(function (err) {
- console.log(err);
- });
- return newmsgs;
-}
-
-function clearUnreadMessages(dxcall) {
- //console.log(dxcall);
- //Selector of dxcall and new $eq: 1 isn't working, don't know why
- //For now parse all messages of callsign to clear new flag
- db.find({
- //{
- selector:
- //$and:[
- { dxcallsign: dxcall }, //, {new: { $gte: 1}}
- //]
- // }
- })
- .then(function (result) {
- //console.log(result);
- //console.log ("New messages count to clear for " + dxcall + ": " + result.docs.length)
- result.docs.forEach(function (item) {
- if (item.new == 1) {
- db.upsert(item._id, function (doc) {
- doc.new = 0;
- //console.log("Clearing new on _id " + item._id);
- return doc;
- });
- }
- });
- })
- .catch(function (err) {
- console.log(err);
- });
-
-
-}
-
-//Have the operating system show a notification popup
-function showOsPopUp(title, message) {
- if (config.enable_sys_notification == 0) return;
- const NOTIFICATION_TITLE = title;
- const NOTIFICATION_BODY = message;
- new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY });
-}
-
-//Function to clean old beacons and optimize database
-async function dbClean() {
- //Only keep the most x latest days of beacons
- let beaconKeep = 7;
- let itemCount = 0;
- let timestampPurge = Math.floor(
- (Date.now() - beaconKeep * 24 * 60 * 60 * 1000) / 1000,
- );
- if (
- confirm(
- "Delete beacons and pings older than " +
- beaconKeep +
- " days and compact database?",
- )
- ) {
- } else {
- ipcRenderer.send("request-update-dbclean-spinner");
- return;
- }
-
- //Items to purge from database
- var purgeFilter = [
- { type: "beacon" },
- { type: "ping-ack" },
- { type: "ping" },
- ];
-
- await db
- .find({
- selector: {
- $and: [{ timestamp: { $lt: timestampPurge } }, { $or: purgeFilter }],
- },
- })
- .then(async function (result) {
- //console.log("Purging " + result.docs.length + " beacons received before " + timestampPurge);
- itemCount = result.docs.length;
- result.docs.forEach(async function (item) {
- await db
- .get(item._id)
- .then(async function (doc) {
- await db.remove(doc);
- })
- .catch(function (err) {
- console.log(err);
- });
- });
- })
- .catch(function (err) {
- console.log(err);
- });
-
- //Compact database
- await db.compact();
- window.alert(
- "Database maintenance is complete. " +
- itemCount +
- " items removed from database. It's recommended you now restart the GUI.",
- );
- ipcRenderer.send("request-update-dbclean-spinner");
-}
diff --git a/gui/preload-log.js b/gui/preload-log.js
deleted file mode 100644
index 9e2bcbc2..00000000
--- a/gui/preload-log.js
+++ /dev/null
@@ -1,186 +0,0 @@
-const path = require("path");
-const { ipcRenderer } = require("electron");
-
-// https://stackoverflow.com/a/26227660
-var appDataFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Application Support"
- : process.env.HOME + "/.config");
-var configFolder = path.join(appDataFolder, "FreeDATA");
-var configPath = path.join(configFolder, "config.json");
-const config = require(configPath);
-
-// WINDOW LISTENER
-window.addEventListener("DOMContentLoaded", () => {
- document
- .getElementById("enable_filter_info")
- .addEventListener("click", () => {
- if (document.getElementById("enable_filter_info").checked) {
- display_class("table-info", true);
- } else {
- display_class("table-info", false);
- }
- });
-
- document
- .getElementById("enable_filter_debug")
- .addEventListener("click", () => {
- if (document.getElementById("enable_filter_debug").checked) {
- display_class("table-debug", true);
- } else {
- display_class("table-debug", false);
- }
- });
-
- document
- .getElementById("enable_filter_warning")
- .addEventListener("click", () => {
- if (document.getElementById("enable_filter_warning").checked) {
- display_class("table-warning", true);
- } else {
- display_class("table-warning", false);
- }
- });
-
- document
- .getElementById("enable_filter_error")
- .addEventListener("click", () => {
- if (document.getElementById("enable_filter_error").checked) {
- display_class("table-danger", true);
- } else {
- display_class("table-danger", false);
- }
- });
-});
-
-function display_class(class_name, state) {
- var collection = document.getElementsByClassName(class_name);
- console.log(collection);
- for (let i = 0; i < collection.length; i++) {
- if (state == true) {
- collection[i].style.display = "table-row";
- } else {
- collection[i].style.display = "None";
- }
- }
-}
-
-ipcRenderer.on("action-update-log", (event, arg) => {
- var entry = arg.entry;
-
- // remove ANSI characters from string, caused by color logging
- // https://stackoverflow.com/a/29497680
- entry = entry.replace(
- /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
- "",
- );
-
- var tbl = document.getElementById("log");
- var row = document.createElement("tr");
-
- var timestamp = document.createElement("td");
- var timestampText = document.createElement("span");
-
- //datetime = new Date();
- //timestampText.innerText = datetime.toISOString();
- timestampText.innerText = entry.slice(0, 19);
- timestamp.appendChild(timestampText);
-
- var type = document.createElement("td");
- var typeText = document.createElement("span");
- // typeText.innerText = entry.slice(10, 30).match(/[\[](.*)[^\]]/g);
- console.log(entry.match(/\[[^\]]+\]/g));
-
- try {
- typeText.innerText = entry.match(/\[[^\]]+\]/g)[0];
- } catch (e) {
- typeText.innerText = "-";
- }
-
- // let res = str.match(/[\[](.*)[^\]]/g);
-
- type.appendChild(typeText);
-
- var area = document.createElement("td");
- var areaText = document.createElement("span");
- //areaText.innerText = entry.slice(10, 50).match(/[\] \[](.*)[^\]]/g);
- //areaText.innerText = entry.match(/\[[^\]]+\]/g)[1];
-
- try {
- areaText.innerText = entry.match(/\[[^\]]+\]/g)[1];
- } catch (e) {
- areaText.innerText = "-";
- }
- area.appendChild(areaText);
-
- var logEntry = document.createElement("td");
- var logEntryText = document.createElement("span");
- try {
- logEntryText.innerText = entry.split("]")[2];
- } catch (e) {
- logEntryText.innerText = "-";
- }
- logEntry.appendChild(logEntryText);
-
- row.appendChild(timestamp);
- row.appendChild(type);
- row.appendChild(area);
- row.appendChild(logEntry);
-
- //row.classList.add("table-blablubb");
- /*
- if (logEntryText.innerText.includes('ALSA lib pcm')) {
- row.classList.add("table-secondary");
- }
- */
- if (typeText.innerText.includes("info")) {
- row.classList.add("table-info");
- }
- if (typeText.innerText.includes("debug")) {
- row.classList.add("table-secondary");
- }
-
- if (typeText.innerText.includes("warning")) {
- row.classList.add("table-warning");
- }
-
- if (typeText.innerText.includes("error")) {
- row.classList.add("table-danger");
- }
-
- if (document.getElementById("enable_filter_info").checked) {
- row.style.display = "table-row";
- display_class("table-info", true);
- } else {
- row.style.display = "None";
- display_class("table-info", false);
- }
- if (document.getElementById("enable_filter_debug").checked) {
- row.style.display = "table-row";
- display_class("table-secondary", true);
- } else {
- row.style.display = "None";
- display_class("table-secondary", false);
- }
- if (document.getElementById("enable_filter_warning").checked) {
- row.style.display = "table-row";
- display_class("table-warning", true);
- } else {
- row.style.display = "None";
- display_class("table-warning", false);
- }
- if (document.getElementById("enable_filter_error").checked) {
- row.style.display = "table-row";
- display_class("table-danger", true);
- } else {
- row.style.display = "None";
- display_class("table-danger", false);
- }
-
- tbl.appendChild(row);
-
- // scroll to bottom of page
- // https://stackoverflow.com/a/11715670
- window.scrollTo(0, document.body.scrollHeight);
-});
diff --git a/gui/preload-main.js b/gui/preload-main.js
deleted file mode 100644
index f6640361..00000000
--- a/gui/preload-main.js
+++ /dev/null
@@ -1,3861 +0,0 @@
-const path = require("path");
-const { ipcRenderer, shell, clipboard } = require("electron");
-const exec = require("child_process").spawn;
-const sock = require("./sock.js");
-const daemon = require("./daemon.js");
-
-
-require("./preload-chat.js");
-require("./preload-mesh.js");
-require("./preload-log.js");
-
-
-
-const fs = require("fs");
-const FD = require("./freedata");
-const {
- locatorToLatLng,
- distance,
- bearingDistance,
- latLngToLocator,
-} = require("qth-locator");
-
-const { v4: uuidv4 } = require("uuid");
-
-const os = require("os");
-
-// split character used for appending additional data to files
-const split_char = "\0;";
-
-// https://stackoverflow.com/a/26227660
-var appDataFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Application Support"
- : process.env.HOME + "/.config");
-var configFolder = path.join(appDataFolder, "FreeDATA");
-var configPath = path.join(configFolder, "config.json");
-var config = require(configPath);
-
-const contrib = [
- "DK5SM",
- "DL4IAZ",
- "DB1UJ",
- "EI3HIB",
- "VK5DGR",
- "EI7IG",
- "N2KIQ",
- "KT4WO",
- "DF7MH",
- "G0HWW",
- "N1QM",
- "LA3QMA",
-];
-
-//let elements = document.querySelectorAll('[id^="hamlib_"]'); // get all elements starting with...
-const hamlib_elements = [
- "hamlib_deviceid",
- "hamlib_deviceport",
- "hamlib_stop_bits",
- "hamlib_data_bits",
- "hamlib_handshake",
- "hamlib_serialspeed",
- "hamlib_dtrstate",
- "hamlib_pttprotocol",
- "hamlib_ptt_port",
- "hamlib_dcd",
- "hamlib_rigctld_port",
- "hamlib_rigctld_ip",
- "hamlib_rigctld_path",
- "hamlib_rigctld_server_port",
- "hamlib_rigctld_custom_args",
-];
-
-// SET dbfs LEVEL GLOBAL
-// this is an attempt of reducing CPU LOAD
-// we are going to check if we have unequal values before we start calculating again
-var dbfs_level_raw = 0;
-var noise_level_raw = 0;
-
-//Global version variable
-var appVer = null;
-
-//Track the number of times TNC has been started
-//So that warning is shown when using auto start and 2nd start
-//if hamlib is not running
-var tncStartCount = 0;
-
-// START INTERVALL COMMAND EXECUTION FOR STATES
-//setInterval(sock.getRxBuffer, 1000);
-
-// WINDOW LISTENER
-window.addEventListener("DOMContentLoaded", () => {
- // save frequency event listener
- document.getElementById("saveFrequency").addEventListener("click", () => {
- var freq = document.getElementById("newFrequency").value;
- console.log(freq);
- let Data = {
- type: "set",
- command: "frequency",
- frequency: freq,
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- // enter button for input field
- document
- .getElementById("newFrequency")
- .addEventListener("keypress", function (event) {
- if (event.key === "Enter") {
- event.preventDefault();
- document.getElementById("saveFrequency").click();
- }
- });
-
- // save mode event listener
- document.getElementById("saveModePKTUSB").addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "mode",
- mode: "PKTUSB",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
- // save mode event listener
- document.getElementById("saveModeDIGU").addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "mode",
- mode: "DIGU",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- // save mode event listener
- document.getElementById("saveModeDIGL").addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "mode",
- mode: "DIGL",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- // save mode event listener
- document.getElementById("saveModeUSB").addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "mode",
- mode: "USB",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- // save mode event listener
- document.getElementById("saveModeLSB").addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "mode",
- mode: "LSB",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- // save mode event listener
- document.getElementById("saveModeAM").addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "mode",
- mode: "AM",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- // save mode event listener
- document.getElementById("saveModeFM").addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "mode",
- mode: "FM",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- // start stop audio recording event listener
- document
- .getElementById("startStopRecording")
- .addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "record_audio",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- document
- .getElementById("received_files_folder")
- .addEventListener("click", () => {
- ipcRenderer.send("get-folder-path", {
- title: "Title",
- action: "return-folder-paths-received_files_folder",
- });
-
- ipcRenderer.on(
- "return-folder-paths-received_files_folder",
- (event, data) => {
- document.getElementById("received_files_folder").value =
- data.path.filePaths[0];
- config.received_files_folder = data.path.filePaths[0];
- FD.saveConfig(config, configPath);
-
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- },
- );
- });
-
- document
- .getElementById("shared_folder_path")
- .addEventListener("click", () => {
- ipcRenderer.send("get-folder-path", {
- title: "Title",
- action: "return-folder-paths-shared_folder_path",
- });
-
- ipcRenderer.on(
- "return-folder-paths-shared_folder_path",
- (event, data) => {
- document.getElementById("shared_folder_path").value =
- data.path.filePaths[0];
- config.shared_folder_path = data.path.filePaths[0];
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- },
- );
- });
-
- document
- .getElementById("openReceivedFilesFolder")
- .addEventListener("click", () => {
- ipcRenderer.send("open-folder", {
- path: config.received_files_folder,
- });
- });
-
- /*
- // ENABLE BOOTSTRAP POPOVERS EVERYWHERE
- // https://getbootstrap.com/docs/5.0/components/popovers/#example-enable-popovers-everywhere
- var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
- var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
- return new bootstrap.Popover(popoverTriggerEl)
- })
-*/
-
- // ENABLE TOOLTIPS EVERYWHERE
- // https://getbootstrap.com/docs/5.1/components/tooltips/
- var tooltipTriggerList = [].slice.call(
- document.querySelectorAll('[data-bs-toggle="tooltip"]'),
- );
- var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
- return new bootstrap.Tooltip(tooltipTriggerEl);
- });
-
- // LOAD SETTINGS
-
- // load settings by function
- loadSettings(hamlib_elements);
-
- document.getElementById("tnc_adress").value = config.tnc_host;
- document.getElementById("tnc_port").value = config.tnc_port;
-
- callsign_and_ssid = config.mycall.split("-");
- callsign = callsign_and_ssid[0];
- ssid = callsign_and_ssid[1];
-
- document.getElementById("myCall").value = callsign;
- //document.title = document.title + ' - Call: ' + config.mycall;
- updateTitle();
-
- document.getElementById("myCallSSID").value = ssid;
- document.getElementById("myGrid").value = config.mygrid;
-
- // hamlib settings
- document.getElementById("hamlib_deviceid").value = config.hamlib_deviceid;
-
- document.getElementById("hamlib_rigctld_ip").value = config.hamlib_rigctld_ip;
- document.getElementById("hamlib_rigctld_port").value =
- config.hamlib_rigctld_port;
- document.getElementById("tci_ip").value = config.tci_ip;
- document.getElementById("tci_port").value = config.tci_port;
-
- document.getElementById("hamlib_rigctld_path").value =
- config.hamlib_rigctld_path;
- document.getElementById("hamlib_rigctld_server_port").value =
- config.hamlib_rigctld_server_port;
-
- // running this in try catch for setting default value in case of wrong beacon intervals
- // https://stackoverflow.com/a/69293164
- console.log(config.beacon_interval);
- let selectElement = document.getElementById("beaconInterval");
- let optionValues = [...selectElement.options].map((o) => o.value);
- console.log(optionValues);
- if (optionValues.includes(config.beacon_interval)) {
- document.getElementById("beaconInterval").value = config.beacon_interval;
- } else {
- document.getElementById("beaconInterval").value = "300";
- }
-
- document.getElementById("scatterSwitch").value = config.enable_scatter;
- document.getElementById("fftSwitch").value = config.enable_fft;
-
- document.getElementById("received_files_folder").value =
- config.received_files_folder;
-
- if (config.enable_scatter == "True") {
- document.getElementById("scatterSwitch").checked = true;
- } else {
- document.getElementById("scatterSwitch").checked = false;
- }
-
- document.getElementById("shared_folder_path").value =
- config.shared_folder_path;
-
- if (config.enable_auto_retry == "True") {
- document.getElementById("enable_auto_retry").checked = true;
- } else {
- document.getElementById("enable_auto_retry").checked = false;
- }
-
- document.getElementById("max_retry_attempts").value =
- config.max_retry_attempts;
-
- if (config.enable_request_profile == "True") {
- document.getElementById("enable_request_profile").checked = true;
- } else {
- document.getElementById("enable_request_profile").checked = false;
- }
- if (config.enable_request_shared_folder == "True") {
- document.getElementById("enable_request_shared_folder").checked = true;
- } else {
- document.getElementById("enable_request_shared_folder").checked = false;
- }
-
- if (config.enable_is_writing == "True") {
- document.getElementById("enable_is_writing").checked = true;
- } else {
- document.getElementById("enable_is_writing").checked = false;
- }
-
- if (config.enable_fft == "True") {
- document.getElementById("fftSwitch").checked = true;
- } else {
- document.getElementById("fftSwitch").checked = false;
- }
-
- if (config.low_bandwidth_mode == "True") {
- document.getElementById("250HzModeSwitch").checked = true;
- } else {
- document.getElementById("250HzModeSwitch").checked = false;
- }
-
- if (config.high_graphics == "True") {
- document.getElementById("GraphicsSwitch").checked = true;
- } else {
- document.getElementById("GraphicsSwitch").checked = false;
- }
-
- if (config.enable_fsk == "True") {
- document.getElementById("fskModeSwitch").checked = true;
- } else {
- document.getElementById("fskModeSwitch").checked = false;
- }
-
- if (config.respond_to_cq == "True") {
- document.getElementById("respondCQSwitch").checked = true;
- } else {
- document.getElementById("respondCQSwitch").checked = false;
- }
-
- if (config.enable_explorer == "True") {
- document.getElementById("ExplorerSwitch").checked = true;
- } else {
- document.getElementById("ExplorerSwitch").checked = false;
- }
-
- if (config.explorer_stats.toLowerCase() == "true") {
- document.getElementById("ExplorerStatsSwitch").checked = true;
- } else {
- document.getElementById("ExplorerStatsSwitch").checked = false;
- }
-
- if (config.auto_tune == "True") {
- document.getElementById("autoTuneSwitch").checked = true;
- } else {
- document.getElementById("autoTuneSwitch").checked = false;
- }
-
- if (config.auto_start == 1) {
- document.getElementById("AutoStartSwitch").checked = true;
- } else {
- document.getElementById("AutoStartSwitch").checked = false;
- }
-
- if (config.enable_sys_notification == 1) {
- document.getElementById("NotificationSwitch").checked = true;
- } else {
- document.getElementById("NotificationSwitch").checked = false;
- }
-
- if (config.enable_mesh_features.toLowerCase() == "true") {
- document.getElementById("list-mesh-list").style.visibility = "visible";
- document.getElementById("list-mesh-list").style.display = "block";
- document.getElementById("enableMeshSwitch").checked = true;
- } else {
- document.getElementById("list-mesh-list").style.visibility = "hidden";
- document.getElementById("list-mesh-list").style.display = "none";
- document.getElementById("enableMeshSwitch").checked = false;
- }
-
- // theme selector
- changeGuiDesign(config.theme);
-
- // Update channel selector
- document.getElementById("update_channel_selector").value =
- config.update_channel;
- document.getElementById("updater_channel").innerHTML = escape(
- config.update_channel,
- );
-
- // Update tuning range fmin fmax
- document.getElementById("tuning_range_fmin").value = config.tuning_range_fmin;
- document.getElementById("tuning_range_fmax").value = config.tuning_range_fmax;
-
- //Update TX delay
- document.getElementById("tx_delay").value = config.tx_delay;
-
- // Update TX Audio Level
- document.getElementById("audioLevelTXvalue").innerHTML = parseInt(
- config.tx_audio_level,
- );
- document.getElementById("audioLevelTX").value = parseInt(
- config.tx_audio_level,
- );
-
- // Update RX Buffer Size
- document.getElementById("rx_buffer_size").value = config.rx_buffer_size;
-
- if (config.spectrum == "waterfall") {
- document.getElementById("waterfall-scatter-switch1").checked = true;
- document.getElementById("waterfall-scatter-switch2").checked = false;
- document.getElementById("waterfall-scatter-switch3").checked = false;
-
- document.getElementById("waterfall").style.visibility = "visible";
- document.getElementById("waterfall").style.height = "100%";
- document.getElementById("waterfall").style.display = "block";
-
- document.getElementById("scatter").style.height = "0px";
- document.getElementById("scatter").style.visibility = "hidden";
- document.getElementById("scatter").style.display = "none";
-
- document.getElementById("chart").style.height = "0px";
- document.getElementById("chart").style.visibility = "hidden";
- document.getElementById("chart").style.display = "none";
- } else if (config.spectrum == "scatter") {
- document.getElementById("waterfall-scatter-switch1").checked = false;
- document.getElementById("waterfall-scatter-switch2").checked = true;
- document.getElementById("waterfall-scatter-switch3").checked = false;
-
- document.getElementById("waterfall").style.visibility = "hidden";
- document.getElementById("waterfall").style.height = "0px";
- document.getElementById("waterfall").style.display = "none";
-
- document.getElementById("scatter").style.height = "100%";
- document.getElementById("scatter").style.visibility = "visible";
- document.getElementById("scatter").style.display = "block";
-
- document.getElementById("chart").style.visibility = "hidden";
- document.getElementById("chart").style.height = "0px";
- document.getElementById("chart").style.display = "none";
- } else {
- document.getElementById("waterfall-scatter-switch1").checked = false;
- document.getElementById("waterfall-scatter-switch2").checked = false;
- document.getElementById("waterfall-scatter-switch3").checked = true;
-
- document.getElementById("waterfall").style.visibility = "hidden";
- document.getElementById("waterfall").style.height = "0px";
- document.getElementById("waterfall").style.display = "none";
-
- document.getElementById("scatter").style.height = "0px";
- document.getElementById("scatter").style.visibility = "hidden";
- document.getElementById("scatter").style.display = "none";
-
- document.getElementById("chart").style.visibility = "visible";
- document.getElementById("chart").style.height = "100%";
- document.getElementById("chart").style.display = "block";
- }
-
- // radio control element
- if (config.radiocontrol == "rigctld") {
- document.getElementById("radio-control-switch-disabled").checked = false;
- document.getElementById("radio-control-switch-rigctld").checked = true;
- document.getElementById("radio-control-switch-tci").checked = false;
-
- document.getElementById("radio-control-disabled").style.visibility =
- "hidden";
- document.getElementById("radio-control-disabled").style.display = "none";
-
- document.getElementById("radio-control-tci").style.display = "none";
- document.getElementById("radio-control-tci").style.visibility = "hidden";
-
- document.getElementById("radio-control-help").style.visibility = "hidden";
- document.getElementById("radio-control-help").style.display = "none";
-
- document.getElementById("radio-control-rigctld").style.visibility =
- "visible";
- document.getElementById("radio-control-rigctld").style.display = "block";
- } else if (config.radiocontrol == "tci") {
- document.getElementById("radio-control-switch-disabled").checked = false;
- document.getElementById("radio-control-switch-rigctld").checked = false;
- document.getElementById("radio-control-switch-tci").checked = true;
-
- document.getElementById("radio-control-disabled").style.visibility =
- "hidden";
- document.getElementById("radio-control-disabled").style.display = "none";
-
- document.getElementById("radio-control-help").style.visibility = "hidden";
- document.getElementById("radio-control-help").style.display = "none";
- document.getElementById("radio-control-rigctld").style.visibility =
- "hidden";
- document.getElementById("radio-control-rigctld").style.display = "none";
-
- document.getElementById("radio-control-tci").style.visibility = "visible";
- document.getElementById("radio-control-tci").style.display = "block";
- } else {
- document.getElementById("radio-control-switch-disabled").checked = true;
- document.getElementById("radio-control-switch-rigctld").checked = false;
- document.getElementById("radio-control-switch-tci").checked = false;
-
- document.getElementById("radio-control-help").style.display = "none";
- document.getElementById("radio-control-help").style.visibility = "hidden";
-
- document.getElementById("radio-control-tci").style.display = "none";
- document.getElementById("radio-control-tci").style.visibility = "hidden";
-
- document.getElementById("radio-control-rigctld").style.visibility =
- "hidden";
- document.getElementById("radio-control-rigctld").style.display = "none";
- }
-
- // remote tnc
- if (config.tnclocation == "remote") {
- document.getElementById("local-remote-switch1").checked = false;
- document.getElementById("local-remote-switch2").checked = true;
- document.getElementById("remote-tnc-field").style.visibility = "visible";
- toggleClass("remote-tnc-field", "d-none", false);
- } else {
- document.getElementById("local-remote-switch1").checked = true;
- document.getElementById("local-remote-switch2").checked = false;
- document.getElementById("remote-tnc-field").style.visibility = "hidden";
- toggleClass("remote-tnc-field", "d-none", true);
- }
-
- // Create spectrum object on canvas with ID "waterfall"
- global.spectrum = new Spectrum("waterfall", {
- spectrumPercent: 0,
- wf_rows: 192, //Assuming 1 row = 1 pixe1, 192 is the height of the spectrum container
- });
-
- //Set waterfalltheme
- document.getElementById("wftheme_selector").value = config.wftheme;
- spectrum.setColorMap(config.wftheme);
-
- document.getElementById("list-info-list").addEventListener("click", () => {
- document.getElementById("aboutVersion").innerText = appVer;
- let maxcol = 3;
- let col = 2;
- let shuffled = contrib
- .map((value) => ({ value, sort: Math.random() }))
- .sort((a, b) => a.sort - b.sort)
- .map(({ value }) => value);
- let list = "DJ2LS ";
- let list2 = "";
- let list3 = "";
- shuffled.forEach((element) => {
- switch (col) {
- case 1:
- list += "" + element + " ";
- break;
- case 2:
- list2 += "" + element + " ";
- break;
- case 3:
- list3 += "" + element + " ";
- break;
- }
- col = col + 1;
- if (col > maxcol) {
- col = 1;
- }
- });
- //list+="";
- divContrib.innerHTML = "";
- divContrib2.innerHTML = "";
- divContrib3.innerHTML = "";
- //console.log(shuffled)
- });
-
- // on click radio control toggle view
- // disabled
- document
- .getElementById("radio-control-switch-disabled")
- .addEventListener("click", () => {
- //document.getElementById("hamlib_info_field").innerHTML =
- // "Disables TNC rig control";
-
- document.getElementById("radio-control-disabled").style.display = "block";
- document.getElementById("radio-control-disabled").style.visibility =
- "visible";
- document.getElementById("radio-control-tci").style.display = "none";
- document.getElementById("radio-control-tci").style.visibility = "hidden";
-
- document.getElementById("radio-control-help").style.display = "none";
- document.getElementById("radio-control-help").style.visibility = "hidden";
-
- document.getElementById("radio-control-rigctld").style.visibility =
- "hidden";
- document.getElementById("radio-control-rigctld").style.display = "none";
-
- config.radiocontrol = "disabled";
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // // radio settings 'rigctld' event listener
- document
- .getElementById("radio-control-switch-rigctld")
- .addEventListener("click", () => {
- //document.getElementById("hamlib_info_field").innerHTML =
- // "Edit your rigctld settings and start and stop rigctld .";
-
- document.getElementById("radio-control-disabled").style.display = "none";
- document.getElementById("radio-control-disabled").style.visibility =
- "hidden";
-
- document.getElementById("radio-control-help").style.display = "none";
- document.getElementById("radio-control-help").style.visibility = "hidden";
-
- document.getElementById("radio-control-tci").style.display = "none";
- document.getElementById("radio-control-tci").style.visibility = "hidden";
-
- document.getElementById("radio-control-rigctld").style.visibility =
- "visible";
- document.getElementById("radio-control-rigctld").style.display = "block";
-
- config.radiocontrol = "rigctld";
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // // radio settings 'rigctld' event listener
- document
- .getElementById("radio-control-switch-tci")
- .addEventListener("click", () => {
- //document.getElementById("hamlib_info_field").innerHTML =
- // "Edit your rigctld settings and start and stop rigctld .";
-
- document.getElementById("radio-control-disabled").style.display = "none";
- document.getElementById("radio-control-disabled").style.visibility =
- "hidden";
-
- document.getElementById("radio-control-rigctld").style.display = "none";
- document.getElementById("radio-control-rigctld").style.visibility =
- "hidden";
-
- document.getElementById("radio-control-help").style.display = "none";
- document.getElementById("radio-control-help").style.visibility = "hidden";
-
- document.getElementById("radio-control-tci").style.visibility = "visible";
- document.getElementById("radio-control-tci").style.display = "block";
-
- config.radiocontrol = "tci";
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- document
- .getElementById("btnHamlibCopyCommand")
- .addEventListener("click", () => {
- hamlib_params();
- let rigctld = document.getElementById("hamlib_rigctld_path").value;
-
- //Escape spaces in executable file
- switch (os.platform().toLowerCase()) {
- case "darwin":
- case "linux":
- rigctld = rigctld.replace(" ", "\\ ");
- break;
- case "win32":
- case "win64":
- if (rigctld.indexOf(" ") > -1) rigctld = '"' + rigctld + '"';
- break;
- default:
- console.log("Unhandled OS Platform: ", os.platform());
- break;
- }
-
- rigctld +=
- " " + document.getElementById("hamlib_rigctld_command").value + " -vv";
- document.getElementById("btnHamlibCopyCommandBi").classList =
- "bi bi-clipboard2-check-fill";
- clipboard.writeText(rigctld);
-
- setTimeout(function () {
- document.getElementById("btnHamlibCopyCommandBi").classList =
- "bi bi-clipboard";
- }, 2000);
- });
-
- document
- .getElementById("hamlib_rigctld_path")
- .addEventListener("click", () => {
- ipcRenderer.send("get-file-path", {
- title: "Title",
- action: "return-file-path-hamlib_rigctld_path",
- });
-
- ipcRenderer.on("return-file-path-hamlib_rigctld_path", (event, data) => {
- rigctldPath = data.path.filePaths[0];
- document.getElementById("hamlib_rigctld_path").value = rigctldPath;
- config.hamlib_rigctld_path = rigctldPath;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- hamlib_params();
- });
- });
-
- // radio settings 'hamlib_rigctld_server_port' event listener
- document
- .getElementById("hamlib_rigctld_server_port")
- .addEventListener("change", () => {
- config.hamlib_rigctld_server_port = document.getElementById(
- "hamlib_rigctld_server_port",
- ).value;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- hamlib_params();
- });
-
- // hamlib bulk event listener for saving settings
- hamlib_elements.forEach(function (elem) {
- try {
- document.getElementById(elem).addEventListener("change", function () {
- config[elem] = document.getElementById(elem).value;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- console.log(config);
- hamlib_params();
- });
- } catch (e) {
- console.log(e);
- console.log(elem);
- }
- });
-
- document
- .getElementById("hamlib_rigctld_start")
- .addEventListener("click", () => {
- var rigctldPath = document.getElementById("hamlib_rigctld_path").value;
- var paramList = hamlib_params();
-
- let Data = {
- path: rigctldPath,
- parameters: paramList,
- };
- ipcRenderer.send("request-start-rigctld", Data);
- });
-
- hamlib_params = function () {
- var paramList = [];
-
- // hamlib stopbits setting
- if (document.getElementById("hamlib_deviceid").value !== "-- ignore --") {
- var hamlib_deviceid = document.getElementById("hamlib_deviceid").value;
- paramList = paramList.concat("--model=" + hamlib_deviceid);
- }
-
- // hamlib deviceport setting
- if (document.getElementById("hamlib_deviceport").value !== "ignore") {
- var hamlib_deviceport =
- document.getElementById("hamlib_deviceport").value;
- paramList = paramList.concat("--rig-file=" + hamlib_deviceport);
- }
-
- // hamlib serialspeed setting
- if (document.getElementById("hamlib_serialspeed").value !== "ignore") {
- var hamlib_serialspeed =
- document.getElementById("hamlib_serialspeed").value;
- paramList = paramList.concat("--serial-speed=" + hamlib_serialspeed);
- }
-
- // hamlib databits setting
- if (document.getElementById("hamlib_data_bits").value !== "ignore") {
- var hamlib_data_bits = document.getElementById("hamlib_data_bits").value;
- paramList = paramList.concat("--set-conf=data_bits=" + hamlib_data_bits);
- }
-
- // hamlib stopbits setting
- if (document.getElementById("hamlib_stop_bits").value !== "ignore") {
- var hamlib_stop_bits = document.getElementById("hamlib_stop_bits").value;
- paramList = paramList.concat("--set-conf=stop_bits=" + hamlib_stop_bits);
- }
-
- // hamlib handshake setting
- if (document.getElementById("hamlib_handshake").value !== "ignore") {
- var hamlib_handshake = document.getElementById("hamlib_handshake").value;
- paramList = paramList.concat(
- "--set-conf=serial_handshake=" + hamlib_handshake,
- );
- }
-
- // hamlib dcd setting
- if (document.getElementById("hamlib_dcd").value !== "ignore") {
- var hamlib_dcd = document.getElementById("hamlib_dcd").value;
- paramList = paramList.concat("--dcd-type=" + hamlib_dcd);
- }
-
- // hamlib ptt port
- if (document.getElementById("hamlib_ptt_port").value !== "ignore") {
- var hamlib_ptt_port = document.getElementById("hamlib_ptt_port").value;
- paramList = paramList.concat("--ptt-file=" + hamlib_ptt_port);
- }
-
- // hamlib ptt type
- if (document.getElementById("hamlib_pttprotocol").value !== "ignore") {
- var hamlib_ptt_type = document.getElementById("hamlib_pttprotocol").value;
- paramList = paramList.concat("--ptt-type=" + hamlib_ptt_type);
- }
-
- // hamlib dtr state
- if (document.getElementById("hamlib_dtrstate").value !== "ignore") {
- var hamlib_dtrstate = document.getElementById("hamlib_dtrstate").value;
- paramList = paramList.concat("--set-conf=dtr_state=" + hamlib_dtrstate);
- }
-
- var hamlib_rigctld_server_port = document.getElementById(
- "hamlib_rigctld_server_port",
- ).value;
- paramList = paramList.concat("--port=" + hamlib_rigctld_server_port);
-
- //Custom rigctld arguments to pass to rigctld
- var hamlib_rigctld_custom_args = document.getElementById(
- "hamlib_rigctld_custom_args",
- ).value;
- paramList = paramList.concat(hamlib_rigctld_custom_args);
-
- document.getElementById("hamlib_rigctld_command").value =
- paramList.join(" "); // join removes the commas
-
- console.log(paramList);
- //console.log(rigctldPath);
- return paramList;
- };
-
- document
- .getElementById("hamlib_rigctld_stop")
- .addEventListener("click", () => {
- ipcRenderer.send("request-stop-rigctld", {
- path: "123",
- parameters: "--version",
- });
- });
-
- // on click waterfall scatter toggle view
- // waterfall
- document
- .getElementById("waterfall-scatter-switch1")
- .addEventListener("click", () => {
- document.getElementById("chart").style.visibility = "hidden";
- document.getElementById("chart").style.display = "none";
- document.getElementById("chart").style.height = "0px";
-
- document.getElementById("scatter").style.height = "0px";
- document.getElementById("scatter").style.display = "none";
- document.getElementById("scatter").style.visibility = "hidden";
-
- document.getElementById("waterfall").style.display = "block";
- document.getElementById("waterfall").style.visibility = "visible";
- document.getElementById("waterfall").style.height = "100%";
-
- config.spectrum = "waterfall";
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
- // scatter
- document
- .getElementById("waterfall-scatter-switch2")
- .addEventListener("click", () => {
- document.getElementById("scatter").style.display = "block";
- document.getElementById("scatter").style.visibility = "visible";
- document.getElementById("scatter").style.height = "100%";
-
- document.getElementById("waterfall").style.visibility = "hidden";
- document.getElementById("waterfall").style.height = "0px";
- document.getElementById("waterfall").style.display = "none";
-
- document.getElementById("chart").style.visibility = "hidden";
- document.getElementById("chart").style.height = "0px";
- document.getElementById("chart").style.display = "none";
-
- config.spectrum = "scatter";
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
- // chart
- document
- .getElementById("waterfall-scatter-switch3")
- .addEventListener("click", () => {
- document.getElementById("waterfall").style.visibility = "hidden";
- document.getElementById("waterfall").style.height = "0px";
- document.getElementById("waterfall").style.display = "none";
-
- document.getElementById("scatter").style.height = "0px";
- document.getElementById("scatter").style.visibility = "hidden";
- document.getElementById("scatter").style.display = "none";
-
- document.getElementById("chart").style.height = "100%";
- document.getElementById("chart").style.display = "block";
- document.getElementById("chart").style.visibility = "visible";
-
- config.spectrum = "chart";
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // on click remote tnc toggle view
- document
- .getElementById("local-remote-switch1")
- .addEventListener("click", () => {
- document.getElementById("local-remote-switch1").checked = true;
- document.getElementById("local-remote-switch2").checked = false;
- document.getElementById("remote-tnc-field").style.visibility = "hidden";
- config.tnclocation = "localhost";
- toggleClass("remote-tnc-field", "d-none", true);
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
- document
- .getElementById("local-remote-switch2")
- .addEventListener("click", () => {
- document.getElementById("local-remote-switch1").checked = false;
- document.getElementById("local-remote-switch2").checked = true;
- document.getElementById("remote-tnc-field").style.visibility = "visible";
- config.tnclocation = "remote";
- toggleClass("remote-tnc-field", "d-none", false);
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // on change ping callsign
- document.getElementById("dxCall").addEventListener("change", () => {
- document.getElementById("dataModalDxCall").value =
- document.getElementById("dxCall").value;
- });
- // on change ping callsign
- document.getElementById("dataModalDxCall").addEventListener("change", () => {
- document.getElementById("dxCall").value =
- document.getElementById("dataModalDxCall").value;
- });
-
- // on change port and host
- document.getElementById("tnc_adress").addEventListener("change", () => {
- console.log(document.getElementById("tnc_adress").value);
- config.tnc_host = document.getElementById("tnc_adress").value;
- config.daemon_host = document.getElementById("tnc_adress").value;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- let Data = {
- port: document.getElementById("tnc_port").value,
- adress: document.getElementById("tnc_adress").value,
- };
- ipcRenderer.send("request-update-tnc-ip", Data);
-
- Data = {
- port: parseInt(document.getElementById("tnc_port").value) + 1,
- adress: document.getElementById("tnc_adress").value,
- };
- ipcRenderer.send("request-update-daemon-ip", Data);
- });
-
- // on change tnc port
- document.getElementById("tnc_port").addEventListener("change", () => {
- config.tnc_port = document.getElementById("tnc_port").value;
- config.daemon_port =
- parseInt(document.getElementById("tnc_port").value) + 1;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
-
- let Data = {
- port: document.getElementById("tnc_port").value,
- adress: document.getElementById("tnc_adress").value,
- };
- ipcRenderer.send("request-update-tnc-ip", Data);
-
- Data = {
- port: parseInt(document.getElementById("tnc_port").value) + 1,
- adress: document.getElementById("tnc_adress").value,
- };
- ipcRenderer.send("request-update-daemon-ip", Data);
- });
-
- // on change audio TX Level
- document.getElementById("audioLevelTX").addEventListener("change", () => {
- var tx_audio_level = parseInt(
- document.getElementById("audioLevelTX").value,
- );
- document.getElementById("audioLevelTXvalue").innerHTML = tx_audio_level;
- config.tx_audio_level = tx_audio_level;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
-
- let Data = {
- command: "set_tx_audio_level",
- tx_audio_level: tx_audio_level,
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
- document.getElementById("sendTestFrame").addEventListener("click", () => {
- let Data = {
- type: "set",
- command: "send_test_frame",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
- // saveMyCall button clicked
- document.getElementById("myCall").addEventListener("input", () => {
- callsign = document.getElementById("myCall").value;
- ssid = document.getElementById("myCallSSID").value;
- callsign_ssid = callsign.toUpperCase() + "-" + ssid;
- config.mycall = callsign_ssid;
- // split document title by looking for Call then split and update it
- //var documentTitle = document.title.split('Call:')
- //document.title = documentTitle[0] + 'Call: ' + callsign_ssid;
- updateTitle(callsign_ssid);
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- daemon.saveMyCall(callsign_ssid);
- });
-
- // saveMyGrid button clicked
- document.getElementById("myGrid").addEventListener("input", () => {
- grid = document.getElementById("myGrid").value;
- config.mygrid = grid;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- daemon.saveMyGrid(grid);
- });
-
- // startPing button clicked
- document.getElementById("sendPing").addEventListener("click", () => {
- var dxcallsign = document.getElementById("dxCall").value.toUpperCase();
- if (dxcallsign == "" || dxcallsign == null || dxcallsign == undefined)
- return;
- pauseButton(document.getElementById("sendPing"), 2000);
- sock.sendPing(dxcallsign);
- });
-
- // dataModalstartPing button clicked
- document.getElementById("dataModalSendPing").addEventListener("click", () => {
- var dxcallsign = document.getElementById("dataModalDxCall").value;
- dxcallsign = dxcallsign.toUpperCase();
- sock.sendPing(dxcallsign);
- });
-
- // close app, update and restart
- document
- .getElementById("update_and_install")
- .addEventListener("click", () => {
- ipcRenderer.send("request-restart-and-install");
- });
-
- /*disabled because it's causing confusion TODO: remove entire code some day
- // open arq session
- document.getElementById("openARQSession").addEventListener("click", () => {
- var dxcallsign = document.getElementById("dataModalDxCall").value;
- dxcallsign = dxcallsign.toUpperCase();
- sock.connectARQ(dxcallsign);
- });
-
- // close arq session
- document.getElementById("closeARQSession").addEventListener("click", () => {
- sock.disconnectARQ();
- });
-*/
- // sendCQ button clicked
- document.getElementById("sendCQ").addEventListener("click", () => {
- pauseButton(document.getElementById("sendCQ"), 2000);
- sock.sendCQ();
- });
-
- // Start beacon button clicked
- document.getElementById("startBeacon").addEventListener("click", () => {
- let bcn = document.getElementById("startBeacon");
- bcn.disabled = true;
- interval = document.getElementById("beaconInterval").value;
- //Use class list to determine state of beacon, secondary == off
- if (bcn.className.toLowerCase().indexOf("secondary") > 0) {
- //Stopped; let us start it
- sock.startBeacon(interval);
- } else {
- sock.stopBeacon();
- }
- config.beacon_interval = interval;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- bcn.disabled = false;
- });
-
- // enable_auto_retry Switch clicked
- document.getElementById("enable_auto_retry").addEventListener("click", () => {
- console.log(document.getElementById("enable_auto_retry").checked);
- if (document.getElementById("enable_auto_retry").checked == true) {
- config.enable_auto_retry = "True";
- } else {
- config.enable_auto_retry = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // max_retry_attempts Switch clicked
- document
- .getElementById("max_retry_attempts")
- .addEventListener("change", () => {
- console.log(document.getElementById("max_retry_attempts").value);
- config.max_retry_attempts =
- document.getElementById("max_retry_attempts").value;
-
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // sendscatter Switch clicked
- document.getElementById("scatterSwitch").addEventListener("click", () => {
- console.log(document.getElementById("scatterSwitch").checked);
- if (document.getElementById("scatterSwitch").checked == true) {
- config.enable_scatter = "True";
- } else {
- config.enable_scatter = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // sendfft Switch clicked
- document.getElementById("fftSwitch").addEventListener("click", () => {
- if (document.getElementById("fftSwitch").checked == true) {
- config.enable_fft = "True";
- } else {
- config.enable_fft = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // enable 500z Switch clicked
- document.getElementById("250HzModeSwitch").addEventListener("click", () => {
- if (document.getElementById("250HzModeSwitch").checked == true) {
- config.low_bandwidth_mode = "True";
- } else {
- config.low_bandwidth_mode = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // enable response to cq clicked
- document.getElementById("respondCQSwitch").addEventListener("click", () => {
- if (document.getElementById("respondCQSwitch").checked == true) {
- config.respond_to_cq = "True";
- } else {
- config.respond_to_cq = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // enable explorer Switch clicked
- document.getElementById("ExplorerSwitch").addEventListener("click", () => {
- if (document.getElementById("ExplorerSwitch").checked == true) {
- config.enable_explorer = "True";
- } else {
- config.enable_explorer = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
- // enable explorer stats Switch clicked
- document
- .getElementById("ExplorerStatsSwitch")
- .addEventListener("click", () => {
- if (document.getElementById("ExplorerStatsSwitch").checked == true) {
- config.explorer_stats = "True";
- } else {
- config.explorer_stats = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
- // enable autotune Switch clicked
- document.getElementById("autoTuneSwitch").addEventListener("click", () => {
- if (document.getElementById("autoTuneSwitch").checked == true) {
- config.auto_tune = "True";
- } else {
- config.auto_tune = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- //Handle change of fancy graphics
- document.getElementById("GraphicsSwitch").addEventListener("click", () => {
- if (document.getElementById("GraphicsSwitch").checked == true) {
- config.high_graphics = "True";
- } else {
- config.high_graphics = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- set_CPU_mode();
- });
-
- //Handle change of Auto-start settings
- document.getElementById("AutoStartSwitch").addEventListener("click", () => {
- if (document.getElementById("AutoStartSwitch").checked == true) {
- config.auto_start = 1;
- } else {
- config.auto_start = 0;
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- //Handle change of Notification settings
- document
- .getElementById("NotificationSwitch")
- .addEventListener("click", () => {
- if (document.getElementById("NotificationSwitch").checked == true) {
- config.enable_sys_notification = 1;
- } else {
- config.enable_sys_notification = 0;
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // enable fsk Switch clicked
- document.getElementById("fskModeSwitch").addEventListener("click", () => {
- if (document.getElementById("fskModeSwitch").checked == true) {
- config.enable_fsk = "True";
- } else {
- config.enable_fsk = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // enable MESH Switch clicked
- document.getElementById("enableMeshSwitch").addEventListener("click", () => {
- if (document.getElementById("enableMeshSwitch").checked == true) {
- config.enable_mesh_features = "True";
- document.getElementById("list-mesh-list").style.visibility = "visible";
- document.getElementById("list-mesh-list").style.display = "block";
- } else {
- config.enable_mesh_features = "False";
- document.getElementById("list-mesh-list").style.visibility = "hidden";
- document.getElementById("list-mesh-list").style.display = "none";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // enable is writing switch clicked
- document.getElementById("enable_is_writing").addEventListener("click", () => {
- if (document.getElementById("enable_is_writing").checked == true) {
- config.enable_is_writing = "True";
- } else {
- config.enable_is_writing = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // enable enable_request_shared_folder switch clicked
- document
- .getElementById("enable_request_shared_folder")
- .addEventListener("click", () => {
- if (
- document.getElementById("enable_request_shared_folder").checked == true
- ) {
- config.enable_request_shared_folder = "True";
- } else {
- config.enable_request_shared_folder = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- //Update file list after setting change
- ipcRenderer.send("read-files-in-folder", {
- folder: config.shared_folder_path.toString(),
- });
- });
-
- // enable enable_request_profile switch clicked
- document
- .getElementById("enable_request_profile")
- .addEventListener("click", () => {
- if (document.getElementById("enable_request_profile").checked == true) {
- config.enable_request_profile = "True";
- } else {
- config.enable_request_profile = "False";
- }
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // Tuning range clicked
- document.getElementById("tuning_range_fmin").addEventListener("click", () => {
- var tuning_range_fmin = document.getElementById("tuning_range_fmin").value;
- config.tuning_range_fmin = tuning_range_fmin;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- document.getElementById("tuning_range_fmax").addEventListener("click", () => {
- var tuning_range_fmax = document.getElementById("tuning_range_fmax").value;
- config.tuning_range_fmax = tuning_range_fmax;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- document.getElementById("tx_delay").addEventListener("click", () => {
- var tx_delay = document.getElementById("tx_delay").value;
- config.tx_delay = tx_delay;
- FD.saveConfig(config, configPath);
- });
-
- // Theme selector clicked
-
- document.getElementById("theme_selector").addEventListener("change", () => {
- /*
- var theme = document.getElementById("theme_selector").value;
- if (theme != "default") {
- var theme_path =
- "../node_modules/bootswatch/dist/" + theme + "/bootstrap.min.css";
- } else {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- }
-*/
- var theme = document.getElementById("theme_selector").value;
- changeGuiDesign(theme);
- config.theme = theme;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // Waterfall theme selector changed
- document.getElementById("wftheme_selector").addEventListener("change", () => {
- var wftheme = document.getElementById("wftheme_selector").value;
- spectrum.setColorMap(wftheme);
- config.wftheme = wftheme;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // Update channel selector changed
- document
- .getElementById("update_channel_selector")
- .addEventListener("change", () => {
- config.update_channel = document.getElementById(
- "update_channel_selector",
- ).value;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- console.log("Autoupdate channel changed to ", config.update_channel);
- });
-
- // rx buffer size selector clicked
- document.getElementById("rx_buffer_size").addEventListener("click", () => {
- var rx_buffer_size = document.getElementById("rx_buffer_size").value;
- config.rx_buffer_size = rx_buffer_size;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- //screen size
- window.addEventListener("resize", () => {
- config.screen_height = window.innerHeight;
- config.screen_width = window.innerWidth;
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
- });
-
- // Explorer button clicked
- document.getElementById("openExplorer").addEventListener("click", () => {
- shell.openExternal(
- "https://explorer.freedata.app/?myCall=" +
- document.getElementById("myCall").value,
- );
- });
-
- // Stats button clicked
- document.getElementById("btnStats").addEventListener("click", () => {
- shell.openExternal("https://statistics.freedata.app");
- });
- // GH Link clicked
- document.getElementById("fdWww").addEventListener("click", () => {
- shell.openExternal("https://freedata.app");
- });
- // GH Link clicked
- document.getElementById("ghUrl").addEventListener("click", () => {
- shell.openExternal("https://github.com/DJ2LS/FreeDATA");
- });
- // Wiki Link clicked
- document.getElementById("wikiUrl").addEventListener("click", () => {
- shell.openExternal("https://wiki.freedata.app");
- });
-
- // Discord Link clicked
- document.getElementById("discordUrl").addEventListener("click", () => {
- shell.openExternal("https://discord.freedata.app/");
- });
-
- // startTNC button clicked
- document.getElementById("startTNC").addEventListener("click", () => {
- tncStartCount++;
- var tuning_range_fmin = document.getElementById("tuning_range_fmin").value;
- var tuning_range_fmax = document.getElementById("tuning_range_fmax").value;
-
- var rigctld_ip = document.getElementById("hamlib_rigctld_ip").value;
- var rigctld_port = document.getElementById("hamlib_rigctld_port").value;
-
- var tci_ip = document.getElementById("tci_ip").value;
- var tci_port = document.getElementById("tci_port").value;
-
- var hamlib_rigctld_server_port = document.getElementById(
- "hamlib_rigctld_server_port",
- ).value;
-
- var deviceid = document.getElementById("hamlib_deviceid").value;
- var deviceport = document.getElementById("hamlib_deviceport").value;
- var serialspeed = document.getElementById("hamlib_serialspeed").value;
- var pttprotocol = document.getElementById("hamlib_pttprotocol").value;
- var hamlib_dcd = document.getElementById("hamlib_dcd").value;
-
- var mycall = document.getElementById("myCall").value;
- var ssid = document.getElementById("myCallSSID").value;
- callsign_ssid = mycall.toUpperCase() + "-" + ssid;
-
- var mygrid = document.getElementById("myGrid").value;
-
- var rx_audio = document.getElementById("audio_input_selectbox").value;
- var tx_audio = document.getElementById("audio_output_selectbox").value;
-
- var pttport = document.getElementById("hamlib_ptt_port").value;
- var data_bits = document.getElementById("hamlib_data_bits").value;
- var stop_bits = document.getElementById("hamlib_stop_bits").value;
- var handshake = document.getElementById("hamlib_handshake").value;
- var tx_delay = document.getElementById("tx_delay").value;
-
- if (document.getElementById("enableMeshSwitch").checked == true) {
- var enable_mesh_features = "True";
- document.getElementById("list-mesh-list").style.visibility = "visible";
- document.getElementById("list-mesh-list").style.display = "block";
- } else {
- var enable_mesh_features = "False";
- document.getElementById("list-mesh-list").style.visibility = "hidden";
- document.getElementById("list-mesh-list").style.display = "none";
- }
-
- if (document.getElementById("scatterSwitch").checked == true) {
- var enable_scatter = "True";
- } else {
- var enable_scatter = "False";
- }
-
- if (document.getElementById("fftSwitch").checked == true) {
- var enable_fft = "True";
- } else {
- var enable_fft = "False";
- }
-
- if (document.getElementById("250HzModeSwitch").checked == true) {
- var low_bandwidth_mode = "True";
- } else {
- var low_bandwidth_mode = "False";
- }
-
- if (document.getElementById("fskModeSwitch").checked == true) {
- var enable_fsk = "True";
- } else {
- var enable_fsk = "False";
- }
-
- if (document.getElementById("respondCQSwitch").checked == true) {
- var respond_to_cq = "True";
- } else {
- var respond_to_cq = "False";
- }
-
- if (document.getElementById("ExplorerSwitch").checked == true) {
- var enable_explorer = "True";
- } else {
- var enable_explorer = "False";
- }
-
- if (document.getElementById("ExplorerStatsSwitch").checked == true) {
- var explorer_stats = "True";
- } else {
- var explorer_stats = "False";
- }
-
- if (document.getElementById("autoTuneSwitch").checked == true) {
- var auto_tune = "True";
- } else {
- var auto_tune = "False";
- }
- // loop through audio device list and select
- for (
- i = 0;
- i < document.getElementById("audio_input_selectbox").length;
- i++
- ) {
- device = document.getElementById("audio_input_selectbox")[i];
-
- if (device.value == rx_audio) {
- console.log(device.text);
- config.rx_audio = device.text;
- }
- }
-
- // loop through audio device list and select
- for (
- i = 0;
- i < document.getElementById("audio_output_selectbox").length;
- i++
- ) {
- device = document.getElementById("audio_output_selectbox")[i];
-
- if (device.value == tx_audio) {
- console.log(device.text);
- config.tx_audio = device.text;
- }
- }
-
- if (document.getElementById("radio-control-switch-rigctld").checked) {
- var radiocontrol = "rigctld";
- } else if (document.getElementById("radio-control-switch-tci").checked) {
- var radiocontrol = "tci";
- } else {
- var radiocontrol = "disabled";
- }
-
- var tx_audio_level = document.getElementById("audioLevelTX").value;
- var rx_buffer_size = document.getElementById("rx_buffer_size").value;
- config.radiocontrol = radiocontrol;
- config.mycall = callsign_ssid;
- config.mygrid = mygrid;
- config.hamlib_deviceid = deviceid;
- config.hamlib_deviceport = deviceport;
- config.hamlib_serialspeed = serialspeed;
- config.hamlib_pttprotocol = pttprotocol;
- config.hamlib_ptt_port = pttport;
- config.hamlib_data_bits = data_bits;
- config.hamlib_stop_bits = stop_bits;
- config.hamlib_handshake = handshake;
- config.hamlib_dcd = hamlib_dcd;
- config.hamlib_rigctld_port = rigctld_port;
- config.hamlib_rigctld_ip = rigctld_ip;
- config.hamlib_rigctld_server_port = hamlib_rigctld_server_port;
- config.enable_scatter = enable_scatter;
- config.enable_fft = enable_fft;
- config.enable_fsk = enable_fsk;
- config.low_bandwidth_mode = low_bandwidth_mode;
- config.tx_audio_level = tx_audio_level;
- config.respond_to_cq = respond_to_cq;
- config.rx_buffer_size = rx_buffer_size;
- config.enable_explorer = enable_explorer;
- config.explorer_stats = explorer_stats;
- config.auto_tune = auto_tune;
- config.tx_delay = tx_delay;
- config.tci_ip = tci_ip;
- config.tci_port = tci_port;
- config.enable_mesh_features = enable_mesh_features;
-
- //fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
- FD.saveConfig(config, configPath);
-
- //Display a message if hamlib control is enabled and not running
- if (
- config.radiocontrol == "rigctld" &&
- rigctldActive == false &&
- (config.auto_start == 0 || tncStartCount > 1)
- ) {
- if (
- !window.confirm(
- "Rig control is set to hamlib/rigctl, but it doesn't appear to be running.\n\nPlease start rigctld (start button in Rig Control area), or use rigctl mode 'none'. If you're having issues starting rigctld please review the Hamlib tab in settings.\n\nClick OK to continue or cancel to abort.",
- )
- ) {
- return;
- }
- }
-
- daemon.startTNC(
- callsign_ssid,
- mygrid,
- rx_audio,
- tx_audio,
- radiocontrol,
- deviceid,
- deviceport,
- pttprotocol,
- pttport,
- serialspeed,
- data_bits,
- stop_bits,
- handshake,
- rigctld_ip,
- rigctld_port,
- enable_fft,
- enable_scatter,
- low_bandwidth_mode,
- tuning_range_fmin,
- tuning_range_fmax,
- enable_fsk,
- tx_audio_level,
- respond_to_cq,
- rx_buffer_size,
- enable_explorer,
- explorer_stats,
- auto_tune,
- tx_delay,
- tci_ip,
- tci_port,
- enable_mesh_features,
- );
- });
-
-
- // stopTNC button clicked
- document.getElementById("stopTNC").addEventListener("click", () => {
- if (!confirm("Stop the TNC?")) return;
-
- daemon.stopTNC();
- });
-
- // btnCleanDB button clicked
- document.getElementById("btnCleanDB").addEventListener("click", () => {
- document.getElementById("divCleanDBSpinner").classList.remove("invisible");
- ipcRenderer.send("request-clean-db");
- });
-
- // TEST HAMLIB
- document.getElementById("testHamlib").addEventListener("click", () => {
- var data_bits = document.getElementById("hamlib_data_bits").value;
- var stop_bits = document.getElementById("hamlib_stop_bits").value;
- var handshake = document.getElementById("hamlib_handshake").value;
- var pttport = document.getElementById("hamlib_ptt_port").value;
-
- var rigctld_ip = document.getElementById("hamlib_rigctld_ip").value;
- var rigctld_port = document.getElementById("hamlib_rigctld_port").value;
-
- var deviceid = document.getElementById("hamlib_deviceid").value;
- var deviceport = document.getElementById("hamlib_deviceport").value;
- var serialspeed = document.getElementById("hamlib_serialspeed").value;
- var pttprotocol = document.getElementById("hamlib_pttprotocol").value;
-
- if (document.getElementById("radio-control-switch-disabled").checked) {
- var radiocontrol = "disabled";
- } else {
- var radiocontrol = "rigctld";
- }
-
- daemon.testHamlib(
- radiocontrol,
- deviceid,
- deviceport,
- serialspeed,
- pttprotocol,
- pttport,
- data_bits,
- stop_bits,
- handshake,
- rigctld_ip,
- rigctld_port,
- );
- });
-
- // START TRANSMISSION
- document.getElementById("startTransmission").addEventListener("click", () => {
- var fileList = document.getElementById("dataModalFile").files;
- console.log(fileList);
- var reader = new FileReader();
- reader.readAsBinaryString(fileList[0]);
- //reader.readAsDataURL(fileList[0]);
-
- reader.onload = function (e) {
- // binary data
-
- var data = e.target.result;
- console.log(data);
-
- let Data = {
- command: "send_file",
- dxcallsign: document
- .getElementById("dataModalDxCall")
- .value.toUpperCase(),
- mode: document.getElementById("datamode").value,
- frames: document.getElementById("framesperburst").value,
- filetype: fileList[0].type,
- filename: fileList[0].name,
- data: data,
- checksum: "123123123",
- };
- // only send command if dxcallsign entered and we have a file selected
- if (document.getElementById("dataModalDxCall").value.length > 0) {
- ipcRenderer.send("run-tnc-command", Data);
- }
- };
- reader.onerror = function (e) {
- // error occurred
- console.log("Error : " + e.type);
- };
- });
- // STOP TRANSMISSION
- document.getElementById("stopTransmission").addEventListener("click", () => {
- let Data = {
- command: "stop_transmission",
- };
- ipcRenderer.send("run-tnc-command", Data);
- });
-
- // STOP TRANSMISSION AND CONNECRTION
- document
- .getElementById("stop_transmission_connection")
- .addEventListener("click", () => {
- let Data = {
- command: "stop_transmission",
- };
- ipcRenderer.send("run-tnc-command", Data);
- sock.disconnectARQ();
- });
-
-
-
- document.getElementById("thTime").addEventListener("click", () => {
- if (hslLastSort == 0 && hslLastSortDir == "asc") hslLastSortDir = "desc";
- else hslLastSortDir = "asc";
- sorthslTable(0);
- resetSortIcon();
- });
- document.getElementById("thFreq").addEventListener("click", () => {
- if (hslLastSort == 1 && hslLastSortDir == "asc") hslLastSortDir = "desc";
- else hslLastSortDir = "asc";
- sorthslTable(1);
- resetSortIcon();
- });
- document.getElementById("thDxcall").addEventListener("click", () => {
- if (hslLastSort == 3 && hslLastSortDir == "asc") hslLastSortDir = "desc";
- else hslLastSortDir = "asc";
- sorthslTable(3);
- resetSortIcon();
- });
- document.getElementById("thDxgrid").addEventListener("click", () => {
- if (hslLastSort == 4 && hslLastSortDir == "asc") hslLastSortDir = "desc";
- else hslLastSortDir = "asc";
- sorthslTable(4);
- resetSortIcon();
- });
- document.getElementById("thDist").addEventListener("click", () => {
- if (hslLastSort == 5 && hslLastSortDir == "asc") hslLastSortDir = "desc";
- else hslLastSortDir = "asc";
- sorthslTable(5);
- resetSortIcon();
- });
- document.getElementById("thType").addEventListener("click", () => {
- if (hslLastSort == 6 && hslLastSortDir == "asc") hslLastSortDir = "desc";
- else hslLastSortDir = "asc";
- sorthslTable(6);
- resetSortIcon();
- });
- document.getElementById("thSnr").addEventListener("click", () => {
- if (hslLastSort == 7 && hslLastSortDir == "asc") hslLastSortDir = "desc";
- else hslLastSortDir = "asc";
- sorthslTable(7);
- resetSortIcon();
- });
-
- autostart_rigctld();
-});
-//End of domcontentloaded
-
-function resetSortIcon() {
- document.getElementById("hslSort").remove();
- let headers = document.querySelectorAll(
- "#tblHeardStationList > thead > tr > th",
- );
- if (hslLastSortDir == "desc") text = "bi-sort-up";
- else text = "bi-sort-down";
- const sicon = document.createElement("i");
- sicon.id = "hslSort";
- sicon.classList.add("bi", text);
- headers[hslLastSort].prepend(sicon);
-}
-
-function connectedStation(data) {
- if (typeof data.dxcallsign == "undefined") {
- return;
- }
- if (
- !(typeof data.arq == "undefined") &&
- data.arq.toLowerCase() == "session"
- ) {
- var prefix = "w/ ";
- } else {
- switch (data.irs) {
- case "True":
- //We are receiving station
- var prefix = "de ";
- break;
- case "False":
- //We are sending station
- var prefix = "to ";
- break;
- default:
- //Shouldn't happen
- console.trace("No data.irs data in tnc-message");
- var prefix = "";
- break;
- }
- }
- document.getElementById("txtConnectedWith").textContent =
- prefix + data.dxcallsign;
-}
-
-//Called by chat to turn off db clean spinner
-ipcRenderer.on("action-update-dbclean-spinner", () => {
- document.getElementById("divCleanDBSpinner").classList.add("invisible");
-});
-//Listen for events caused by tnc 'tnc-message' rx
-ipcRenderer.on("action-update-reception-status", (event, arg) => {
- var data = arg["data"][0];
- var txprog = document.getElementById("transmission_progress");
- ipcRenderer.send("request-show-electron-progressbar", data.percent);
- txprog.setAttribute("aria-valuenow", data.percent);
- txprog.setAttribute("style", "width:" + data.percent + "%;");
-
- // SET TIME LEFT UNTIL FINIHED
- if (typeof data.finished == "undefined") {
- var time_left = "time left: estimating";
- } else {
- var arq_seconds_until_finish = data.finished;
- var hours = Math.floor(arq_seconds_until_finish / 3600);
- var minutes = Math.floor((arq_seconds_until_finish % 3600) / 60);
- var seconds = arq_seconds_until_finish % 60;
- if (hours < 0) {
- hours = 0;
- }
- if (minutes < 0) {
- minutes = 0;
- }
- if (seconds < 0) {
- seconds = 0;
- }
- if (hours > 0) {
- time_left =
- "time left: ~" +
- hours.toString().padStart(2, "0") +
- ":" +
- minutes.toString().padStart(2, "0") +
- "." +
- seconds.toString().padStart(2, "0");
- } else {
- time_left =
- "time left: ~" +
- minutes.toString().padStart(2, "0") +
- "." +
- seconds.toString().padStart(2, "0");
- }
- }
- var time_left = "" + time_left + " || Speed/min: ";
-
- // SET BYTES PER MINUTE
-
- if (typeof data.bytesperminute == "undefined") {
- var arq_bytes_per_minute = 0;
- } else {
- var arq_bytes_per_minute = data.bytesperminute;
- }
-
- // SET BYTES PER MINUTE COMPRESSED
- var compress = data.compression;
- if (isNaN(compress)) {
- compress = 1;
- }
- var arq_bytes_per_minute_compressed = Math.round(
- arq_bytes_per_minute * compress,
- );
- console.log(arq_bytes_per_minute);
- time_left +=
- formatBytes(arq_bytes_per_minute, 1) +
- " (comp: " +
- formatBytes(arq_bytes_per_minute_compressed, 1) +
- ") ";
-
- document.getElementById("transmission_timeleft").innerHTML = time_left;
- connectedStation(data);
-});
-
-//Listen for events caused by tnc 'tnc-message's tx
-ipcRenderer.on("action-update-transmission-status", (event, arg) => {
- var data = arg["data"][0];
- var txprog = document.getElementById("transmission_progress");
- ipcRenderer.send("request-show-electron-progressbar", data.percent);
- txprog.setAttribute("aria-valuenow", data.percent);
- txprog.setAttribute("style", "width:" + data.percent + "%;");
-
- // SET TIME LEFT UNTIL FINIHED
- if (typeof data.finished == "undefined") {
- var time_left = "time left: estimating";
- } else {
- var arq_seconds_until_finish = data.finished;
- var hours = Math.floor(arq_seconds_until_finish / 3600);
- var minutes = Math.floor((arq_seconds_until_finish % 3600) / 60);
- var seconds = arq_seconds_until_finish % 60;
- if (hours < 0) {
- hours = 0;
- }
- if (minutes < 0) {
- minutes = 0;
- }
- if (seconds < 0) {
- seconds = 0;
- }
- if (hours > 0) {
- time_left =
- "time left: ~" +
- hours.toString().padStart(2, "0") +
- ":" +
- minutes.toString().padStart(2, "0") +
- "." +
- seconds.toString().padStart(2, "0");
- } else {
- time_left =
- "time left: ~" +
- minutes.toString().padStart(2, "0") +
- "." +
- seconds.toString().padStart(2, "0");
- }
- }
- var time_left = "" + time_left + " || Speed/min: ";
-
- // SET BYTES PER MINUTE
- if (typeof data.bytesperminute == "undefined") {
- var arq_bytes_per_minute = 0;
- } else {
- var arq_bytes_per_minute = data.bytesperminute;
- }
-
- // SET BYTES PER MINUTE COMPRESSED
- var compress = data.compression;
- if (isNaN(compress)) {
- compress = 1;
- }
- var arq_bytes_per_minute_compressed = Math.round(
- arq_bytes_per_minute * compress,
- );
-
- time_left +=
- formatBytes(arq_bytes_per_minute, 1) +
- " (comp: " +
- formatBytes(arq_bytes_per_minute_compressed, 1) +
- ") ";
- document.getElementById("transmission_timeleft").innerHTML = time_left;
- connectedStation(data);
-});
-
-//Just some stuff I want to experiment with - n1qm
-//https://gist.github.com/senseisimple/002cdba344de92748695a371cef0176a
-function signal_quality_perc_quad(rssi, perfect_rssi = 10, worst_rssi = -150) {
- nominal_rssi = perfect_rssi - worst_rssi;
- signal_quality =
- (100 * (perfect_rssi - worst_rssi) * (perfect_rssi - worst_rssi) -
- (perfect_rssi - rssi) *
- (15 * (perfect_rssi - worst_rssi) + 62 * (perfect_rssi - rssi))) /
- ((perfect_rssi - worst_rssi) * (perfect_rssi - worst_rssi));
-
- if (signal_quality > 100) {
- signal_quality = 100;
- } else if (signal_quality < 1) {
- signal_quality = 0;
- }
- return Math.ceil(signal_quality);
-}
-
-var lastHeard = "";
-var checkForNewMessageWait = 85;
-
-ipcRenderer.on("action-update-tnc-state", (event, arg) => {
- //check for new messages
- if (checkForNewMessageWait >= 100) {
- //This is very expensive
- ipcRenderer.send("request-update-unread-messages");
- checkForNewMessageWait = -1;
- }
- checkForNewMessageWait++;
- // update FFT only if data available
- if (typeof arg.fft !== "undefined" && arg.fft !== "[]") {
- try {
- var array = JSON.parse("[" + arg.fft + "]");
- spectrum.addData(array[0]);
- } catch (e) {
- console.log(e);
- }
- }
-
- if (typeof arg.mycallsign !== "undefined") {
- updateTitle(arg.mycallsign);
- }
-
- // update mygrid information with data from tnc
- if (typeof arg.mygrid !== "undefined") {
- document.getElementById("myGrid").value = arg.mygrid;
- }
-
- // DATA STATE
- global.rxBufferLengthTnc = arg.rx_buffer_length;
-
- // START OF SCATTER CHART
- if (typeof arg.scatter == "undefined") {
- var scatterSize = 0;
- } else {
- var scatterSize = arg.scatter.length;
- }
-
- if (scatterSize > 0 && global.scatterData != newScatterData) {
- const scatterConfig = {
- plugins: {
- legend: {
- display: false,
- },
- tooltip: {
- enabled: false,
- },
- annotation: {
- annotations: {
- line1: {
- type: "line",
- yMin: 0,
- yMax: 0,
- borderColor: "rgb(255, 99, 132)",
- borderWidth: 2,
- },
- line2: {
- type: "line",
- xMin: 0,
- xMax: 0,
- borderColor: "rgb(255, 99, 132)",
- borderWidth: 2,
- },
- },
- },
- },
- animations: false,
- scales: {
- x: {
- type: "linear",
- position: "bottom",
- display: true,
- min: -80,
- max: 80,
- ticks: {
- display: false,
- },
- },
- y: {
- display: true,
- min: -80,
- max: 80,
- ticks: {
- display: false,
- },
- },
- },
- };
- var scatterData = arg.scatter;
- var newScatterData = {
- datasets: [
- {
- //label: 'constellation diagram',
- data: scatterData,
- options: scatterConfig,
- backgroundColor: "rgb(255, 99, 132)",
- },
- ],
- };
-
- global.scatterData = newScatterData;
-
- if (typeof global.scatterChart == "undefined") {
- var scatterCtx = document.getElementById("scatter").getContext("2d");
- global.scatterChart = new Chart(scatterCtx, {
- type: "scatter",
- data: global.scatterData,
- options: scatterConfig,
- });
- } else {
- global.scatterChart.data = global.scatterData;
- global.scatterChart.update();
- }
- }
- // END OF SCATTER CHART
-
- // START OF SPEED CHART
- var speedDataTime = [];
-
- if (typeof arg.speed_list == "undefined") {
- var speed_listSize = 0;
- } else {
- var speed_listSize = arg.speed_list.length;
- }
-
- for (var i = 0; i < speed_listSize; i++) {
- var timestamp = arg.speed_list[i].timestamp * 1000;
- var h = new Date(timestamp).getHours();
- var m = new Date(timestamp).getMinutes();
- var s = new Date(timestamp).getSeconds();
- var time = h + ":" + m + ":" + s;
- speedDataTime.push(time);
- }
-
- var speedDataBpm = [];
- for (var i = 0; i < speed_listSize; i++) {
- speedDataBpm.push(arg.speed_list[i].bpm);
- }
-
- var speedDataSnr = [];
- for (var i = 0; i < speed_listSize; i++) {
- let snr = NaN;
- if (arg.speed_list[i].snr !== 0) {
- snr = arg.speed_list[i].snr;
- } else {
- snr = NaN;
- }
- speedDataSnr.push(snr);
- }
-
- var speedChartConfig = {
- type: "line",
- };
-
- // https://www.chartjs.org/docs/latest/samples/line/segments.html
- const skipped = (speedCtx, value) =>
- speedCtx.p0.skip || speedCtx.p1.skip ? value : undefined;
- const down = (speedCtx, value) =>
- speedCtx.p0.parsed.y > speedCtx.p1.parsed.y ? value : undefined;
-
- var newSpeedData = {
- labels: speedDataTime,
- datasets: [
- {
- type: "line",
- label: "SNR[dB]",
- data: speedDataSnr,
- borderColor: "rgb(75, 192, 192, 1.0)",
- pointRadius: 1,
- segment: {
- borderColor: (speedCtx) =>
- skipped(speedCtx, "rgb(0,0,0,0.4)") ||
- down(speedCtx, "rgb(192,75,75)"),
- borderDash: (speedCtx) => skipped(speedCtx, [3, 3]),
- },
- spanGaps: true,
- backgroundColor: "rgba(75, 192, 192, 0.2)",
- order: 1,
- yAxisID: "SNR",
- },
- {
- type: "bar",
- label: "Speed[bpm]",
- data: speedDataBpm,
- borderColor: "rgb(120, 100, 120, 1.0)",
- backgroundColor: "rgba(120, 100, 120, 0.2)",
- order: 0,
- yAxisID: "SPEED",
- },
- ],
- };
-
- var speedChartOptions = {
- responsive: true,
- animations: true,
- cubicInterpolationMode: "monotone",
- tension: 0.4,
- scales: {
- SNR: {
- type: "linear",
- ticks: { beginAtZero: false, color: "rgb(255, 99, 132)" },
- position: "right",
- },
- SPEED: {
- type: "linear",
- ticks: { beginAtZero: false, color: "rgb(120, 100, 120)" },
- position: "left",
- grid: {
- drawOnChartArea: false, // only want the grid lines for one axis to show up
- },
- },
- x: { ticks: { beginAtZero: true } },
- },
- };
-
- if (typeof global.speedChart == "undefined") {
- var speedCtx = document.getElementById("chart").getContext("2d");
- global.speedChart = new Chart(speedCtx, {
- data: newSpeedData,
- options: speedChartOptions,
- });
- } else {
- if (speedDataSnr.length > 0) {
- global.speedChart.data = newSpeedData;
- global.speedChart.update();
- }
- }
- // END OF SPEED CHART
-
- // PTT STATE
- switch (arg.ptt_state) {
- case "True":
- document.getElementById("ptt_state").className =
- "btn btn-sm btn-danger me-1";
- break;
- case "False":
- document.getElementById("ptt_state").className =
- "btn btn-sm btn-success me-1";
- break;
- default:
- document.getElementById("ptt_state").className =
- "btn btn-sm btn-secondary me-1";
- break;
- }
-
- // AUDIO RECORDING
- if (arg.audio_recording == "True") {
- document.getElementById("startStopRecording").textContent = "Stop Rec";
- } else {
- document.getElementById("startStopRecording").textContent = "Record";
- }
- //CHANNEL CODEC2 BUSY STATE
- if (arg.is_codec2_traffic == "True") {
- document.getElementById("c2_busy").className = "btn btn-sm btn-success";
- } else {
- document.getElementById("c2_busy").className =
- "btn btn-sm btn-outline-secondary";
- }
- // CHANNEL BUSY STATE
- switch (arg.channel_busy) {
- case "True":
- document.getElementById("channel_busy").className =
- "btn btn-sm btn-danger";
- break;
- case "False":
- document.getElementById("channel_busy").className =
- "btn btn-sm btn-success";
- break;
- default:
- document.getElementById("channel_busy").className =
- "btn btn-sm btn-secondary";
- break;
- }
-
- // BUSY STATE
- switch (arg.busy_state) {
- case "BUSY":
- document.getElementById("busy_state").className =
- "btn btn-sm btn-danger me-1";
- //Seems to be no longer user accessible
- //document.getElementById("startTransmission").disabled = true;
- break;
- case "IDLE":
- document.getElementById("busy_state").className =
- "btn btn-sm btn-success me-1";
- break;
- default:
- document.getElementById("busy_state").className =
- "btn btn-sm btn-secondary me-1";
- //Seems to be no longer user accessible
- //document.getElementById("startTransmission").disabled = true;
- break;
- }
-
- // ARQ STATE
- switch (arg.arq_state) {
- case "True":
- document.getElementById("arq_state").className =
- "btn btn-sm btn-warning me-1";
- //Seems to be no longer user accessible
- //document.getElementById("startTransmission").disabled = false;
- break;
- default:
- document.getElementById("arq_state").className =
- "btn btn-sm btn-secondary me-1";
- //Seems to be no longer user accessible
- //document.getElementById("startTransmission").disabled = false;
- break;
- }
-
- // ARQ SESSION
- switch (arg.arq_session) {
- case "True":
- document.getElementById("arq_session").className =
- "btn btn-sm btn-warning me-1";
- break;
- default:
- document.getElementById("arq_session").className =
- "btn btn-sm btn-secondary me-1";
- break;
- }
-
- if (arg.arq_state == "True" || arg.arq_session == "True") {
- document.getElementById("spnConnectedWith").className =
- "bi bi-chat-fill text-success me-1";
- } else {
- document.getElementById("spnConnectedWith").className = "bi bi-chat-fill";
- ipcRenderer.send("request-clear-chat-connected");
- }
-
- // HAMLIB STATUS
- if (arg.hamlib_status == "connected") {
- document.getElementById("rigctld_state").className =
- "btn btn-success btn-sm me-1";
- } else {
- document.getElementById("rigctld_state").className =
- "btn btn-secondary btn-sm me-1";
- }
-
- // BEACON
- switch (arg.beacon_state) {
- case "True":
- document.getElementById("startBeacon").className =
- "btn btn-sm btn-success ms-1";
- if (document.getElementById("beaconInterval").disabled == false) {
- document.getElementById("beaconInterval").disabled = true;
- }
- break;
- default:
- document.getElementById("startBeacon").className =
- "btn btn-sm btn-outline-secondary ms-1";
- if (document.getElementById("beaconInterval").disabled == true) {
- document.getElementById("beaconInterval").disabled = false;
- }
- break;
- }
- // dbfs
- // https://www.moellerstudios.org/converting-amplitude-representations/
- if (
- arg.dbfs_level.length != 0 &&
- !isNaN(arg.dbfs_level) &&
- dbfs_level_raw != arg.dbfs_level
- ) {
- dbfs_level_raw = arg.dbfs_level;
- dbfs_level = Math.pow(10, arg.dbfs_level / 20) * 100;
-
- document.getElementById("dbfs_level_value").textContent =
- Math.round(arg.dbfs_level) + " dBFS (Audio Level)";
- var dbfscntrl = document.getElementById("dbfs_level");
- dbfscntrl.setAttribute("aria-valuenow", dbfs_level);
- dbfscntrl.style = "width:" + dbfs_level + "%;";
- //dbfscntrl.setAttribute("style", "width:" + dbfs_level + "%;");
- }
-
- // noise / strength
- // https://www.moellerstudios.org/converting-amplitude-representations/
- if (
- arg.strength != 0 &&
- !isNaN(arg.strength) &&
- noise_level_raw != arg.strength
- ) {
- //console.log(arg.strength);
- noise_level_raw = arg.strength;
- noise_level = Math.pow(10, arg.strength / 20) * 100;
-
- document.getElementById("noise_level_value").textContent =
- Math.round(arg.strength) + " dB (S-Meter)";
- var noisecntrl = document.getElementById("noise_level");
- noisecntrl.setAttribute("aria-valuenow", noise_level);
- noisecntrl.style = "width:" + noise_level + "%;";
- //noisecntrl.setAttribute("style", "width:" + noise_level + "%;");
- }
-
- // SET FREQUENCY
- // https://stackoverflow.com/a/2901298
- var freq = arg.frequency.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
- document.getElementById("frequency").textContent = freq;
- //document.getElementById("newFrequency").value = arg.frequency;
-
- // SET MODE
- document.getElementById("mode").textContent = arg.mode;
-
- // SET bandwidth
- document.getElementById("bandwidth").textContent = arg.bandwidth;
-
- // SET SPEED LEVEL
- switch (arg.speed_level) {
- case "0":
- document.getElementById("speed_level").className = "bi bi-reception-1";
- break;
- case "1":
- document.getElementById("speed_level").className = "bi bi-reception-2";
- break;
- case "2":
- document.getElementById("speed_level").className = "bi bi-reception-3";
- break;
- default:
- document.getElementById("speed_level").className = "bi bi-reception-4";
- break;
- }
-
- // SET TOTAL BYTES
- if (typeof arg.total_bytes == "undefined") {
- var total_bytes = 0;
- } else {
- var total_bytes = arg.total_bytes;
- }
- document.getElementById("total_bytes").textContent = total_bytes;
-
- //Check if heard station list has changed
- if (
- typeof arg.stations != "undefined" &&
- arg.stations.length > 0 &&
- JSON.stringify(arg.stations) != lastHeard
- ) {
- //console.log("Updating last heard stations");
- lastHeard = JSON.stringify(arg.stations);
- updateHeardStations(arg);
- }
-});
-
-function updateHeardStations(arg) {
- // UPDATE HEARD STATIONS
-
- var tbl = document.getElementById("heardstations");
- tbl.innerHTML = "";
-
- if (typeof arg.stations == "undefined") {
- var heardStationsLength = 0;
- } else {
- var heardStationsLength = arg.stations.length;
- }
-
- for (i = 0; i < heardStationsLength; i++) {
- // first we update the PING window
- if (
- arg.stations[i]["dxcallsign"] ==
- document.getElementById("dxCall").value.toUpperCase()
- ) {
- var dxGrid = arg.stations[i]["dxgrid"];
- var myGrid = document.getElementById("myGrid").value;
- try {
- var dist = parseInt(distance(myGrid, dxGrid)) + " km";
- document.getElementById("dataModalPingDistance").textContent = dist;
- } catch {
- document.getElementById("dataModalPingDistance").textContent = "---";
- }
- document.getElementById("dataModalPingDB").textContent =
- arg.stations[i]["snr"];
- }
-
- // now we update the heard stations list
- var row = document.createElement("tr");
- //https://stackoverflow.com/q/51421470
-
- //https://stackoverflow.com/a/847196
- timestampRaw = arg.stations[i]["timestamp"];
-
- var datetime = new Date(timestampRaw * 1000).toLocaleString(
- navigator.language,
- {
- hourCycle: "h23",
- year: "numeric",
- month: "2-digit",
- day: "2-digit",
- hour: "2-digit",
- minute: "2-digit",
- second: "2-digit",
- },
- );
- //var hours = date.getHours();
- //var minutes = "0" + date.getMinutes();
- //var seconds = "0" + date.getSeconds();
- //var datetime = hours + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
-
- var timestamp = document.createElement("td");
- var timestampText = document.createElement("span");
- timestampText.innerText = datetime;
- timestamp.appendChild(timestampText);
-
- var frequency = document.createElement("td");
- var frequencyText = document.createElement("span");
- frequencyText.innerText = arg.stations[i]["frequency"];
- frequency.appendChild(frequencyText);
-
- var dxCall = document.createElement("td");
- var dxCallText = document.createElement("span");
- dxCallText.innerText = arg.stations[i]["dxcallsign"];
- let dxCallTextCall = dxCallText.innerText;
- let dxCallTextShort = dxCallTextCall.split("-", 1)[0];
- row.addEventListener("click", function () {
- document.getElementById("dxCall").value = dxCallTextCall;
- });
- dxCall.appendChild(dxCallText);
-
- var dxGrid = document.createElement("td");
- var dxGridText = document.createElement("span");
- dxGridText.innerText = arg.stations[i]["dxgrid"];
- dxGrid.appendChild(dxGridText);
-
- var gridDistance = document.createElement("td");
- var gridDistanceText = document.createElement("span");
-
- try {
- if (arg.stations[i]["dxgrid"].toString() != "------") {
- gridDistanceText.innerText =
- parseInt(
- distance(
- document.getElementById("myGrid").value,
- arg.stations[i]["dxgrid"],
- ),
- ) + " km";
- } else {
- gridDistanceText.innerText = "---";
- }
- } catch {
- gridDistanceText.innerText = "---";
- }
- gridDistance.appendChild(gridDistanceText);
-
- var dataType = document.createElement("td");
- var dataTypeText = document.createElement("span");
- dataTypeText.innerText = arg.stations[i]["datatype"];
- dataType.appendChild(dataTypeText);
-
- switch (dataTypeText.innerText) {
- case "CQ CQ CQ":
- dataTypeText.textContent = "CQ CQ";
- row.classList.add("table-success");
- break;
- case "DATA-CHANNEL":
- dataTypeText.innerHTML =
- ' ';
- row.classList.add("table-warning");
- break;
- case "BEACON":
- dataTypeText.textContent = "BCN";
- row.classList.add("table-light");
- break;
- case "PING":
- row.classList.add("table-info");
- break;
- case "PING-ACK":
- row.classList.add("table-primary");
- break;
- case "SESSION-HB":
- dataTypeText.innerHTML =
- ' ';
- //dataType.appendChild(dataTypeText);
- break;
- }
- var snr = document.createElement("td");
- var snrText = document.createElement("span");
- snrText.innerText = arg.stations[i]["snr"];
- snr.appendChild(snrText);
-
- var offset = document.createElement("td");
- var offsetText = " ";
- if (contrib.indexOf(dxCallTextShort) >= 0) {
- var offsetText =
- ' ';
- } else {
- if (dxCallTextShort == "DJ2LS") {
- var offsetText =
- ' ';
- }
- }
- offset.innerHTML = offsetText;
-
- row.appendChild(timestamp);
- row.appendChild(frequency);
- row.appendChild(offset);
- row.appendChild(dxCall);
- row.appendChild(dxGrid);
- row.appendChild(gridDistance);
- row.appendChild(dataType);
- row.appendChild(snr);
-
- tbl.appendChild(row);
- }
- sorthslTable(hslLastSort);
-}
-
-var populateSerial = false;
-ipcRenderer.on("action-update-daemon-state", (event, arg) => {
- /*
- // deactivetd RAM und CPU view so we dont get errors. We need to find a new place for this feature
- // RAM
- document.getElementById("progressbar_ram").setAttribute("aria-valuenow", arg.ram_usage)
- document.getElementById("progressbar_ram").setAttribute("style", "width:" + arg.ram_usage + "%;")
- document.getElementById("progressbar_ram_value").innerHTML = arg.ram_usage + "%"
-
- // CPU
- document.getElementById("progressbar_cpu").setAttribute("aria-valuenow", arg.cpu_usage)
- document.getElementById("progressbar_cpu").setAttribute("style", "width:" + arg.cpu_usage + "%;")
- document.getElementById("progressbar_cpu_value").innerHTML = arg.cpu_usage + "%"
- */
- /*
- document.getElementById("ram_load").innerHTML = arg.ram_usage + "%"
- document.getElementById("cpu_load").innerHTML = arg.cpu_usage + "%"
- */
- // OPERATING SYSTEM
- //document.getElementById("operating_system").innerHTML = "OS " + os.type()
-
- /*
- // PYTHON VERSION
- document.getElementById("python_version").innerHTML = "Python " + arg.python_version
- document.getElementById("python_version").className = "btn btn-sm btn-success";
- */
- /*
- // HAMLIB VERSION
- document.getElementById("hamlib_version").innerHTML = "Hamlib " + arg.hamlib_version
- document.getElementById("hamlib_version").className = "btn btn-sm btn-success";
- */
- /*
- // NODE VERSION
- document.getElementById("node_version").innerHTML = "Node " + process.version
- document.getElementById("node_version").className = "btn btn-sm btn-success";
- */
-
- if (arg.tnc_running_state != "stopped" && populateSerial == true) return;
- // UPDATE SERIAL DEVICES
- if (
- document.getElementById("hamlib_deviceport").length !=
- arg.serial_devices.length
- ) {
- document.getElementById("hamlib_deviceport").innerHTML = "";
- var ignore = document.createElement("option");
- ignore.text = "-- ignore --";
- ignore.value = "ignore";
- document.getElementById("hamlib_deviceport").add(ignore);
- for (i = 0; i < arg.serial_devices.length; i++) {
- var option = document.createElement("option");
- option.text =
- arg.serial_devices[i]["port"] +
- " -- " +
- arg.serial_devices[i]["description"];
- option.value = arg.serial_devices[i]["port"];
- document.getElementById("hamlib_deviceport").add(option);
- }
- // set device from config if available
- document.getElementById("hamlib_deviceport").value =
- config.hamlib_deviceport;
- }
-
- if (
- document.getElementById("hamlib_ptt_port").length !=
- arg.serial_devices.length
- ) {
- document.getElementById("hamlib_ptt_port").innerHTML = "";
- var ignore = document.createElement("option");
- ignore.text = "-- ignore --";
- ignore.value = "ignore";
- document.getElementById("hamlib_ptt_port").add(ignore);
- for (i = 0; i < arg.serial_devices.length; i++) {
- var option = document.createElement("option");
- option.text =
- arg.serial_devices[i]["port"] +
- " -- " +
- arg.serial_devices[i]["description"];
- option.value = arg.serial_devices[i]["port"];
- document.getElementById("hamlib_ptt_port").add(option);
- }
- // set device from config if available
- document.getElementById("hamlib_ptt_port").value = config.hamlib_ptt_port;
- }
- //Serial devices are updated on first pass
- populateSerial = true;
- if (arg.tnc_running_state != "stopped") return;
-
- // UPDATE AUDIO INPUT
- if (
- document.getElementById("audio_input_selectbox").length !=
- arg.input_devices.length
- ) {
- document.getElementById("audio_input_selectbox").innerHTML = "";
- for (i = 0; i < arg.input_devices.length; i++) {
- var option = document.createElement("option");
- option.text = arg.input_devices[i]["name"];
- option.value = arg.input_devices[i]["id"];
- // set device from config if available
-
- if (config.rx_audio == option.text) {
- option.setAttribute("selected", true);
- }
- document.getElementById("audio_input_selectbox").add(option);
- }
- }
-
- // UPDATE AUDIO OUTPUT
- if (
- document.getElementById("audio_output_selectbox").length !=
- arg.output_devices.length
- ) {
- document.getElementById("audio_output_selectbox").innerHTML = "";
- for (i = 0; i < arg.output_devices.length; i++) {
- var option = document.createElement("option");
- option.text = arg.output_devices[i]["name"];
- option.value = arg.output_devices[i]["id"];
- // set device from config if available
- if (config.tx_audio == option.text) {
- option.setAttribute("selected", true);
- }
- document.getElementById("audio_output_selectbox").add(option);
- }
- }
- //Once audio devices are populated, try starting TNC if it hasn't been started yet in this session
- //and if autostart is enabled
- if (tncStartCount <= 0) autostart_tnc();
-});
-
-// ACTION UPDATE HAMLIB TEST
-ipcRenderer.on("action-update-hamlib-test", (event, arg) => {
- console.log(arg.hamlib_result);
- if (arg.hamlib_result == "SUCCESS") {
- document.getElementById("testHamlib").className = "btn btn-sm btn-success";
- // BUTTON HAS BEEN REMOVED
- //document.getElementById("testHamlibAdvanced").className = "btn btn-sm btn-success";
- }
- if (arg.hamlib_result == "NOSUCCESS") {
- document.getElementById("testHamlib").className = "btn btn-sm btn-warning";
- // BUTTON HAS BEEN REMOVED
- //document.getElementById("testHamlibAdvanced").className = "btn btn-sm btn-warning";
- }
- if (arg.hamlib_result == "FAILED") {
- document.getElementById("testHamlib").className = "btn btn-sm btn-danger";
- // BUTTON HAS BEEN REMOVED
- //document.getElementById("testHamlibAdvanced").className = "btn btn-sm btn-danger";
- }
-});
-
-ipcRenderer.on("action-update-daemon-connection", (event, arg) => {
- if (arg.daemon_connection == "open") {
- document.getElementById("daemon_connection_state").className =
- "btn btn-success";
- //document.getElementById("blurdiv").style.webkitFilter = "blur(0px)";
- }
- if (arg.daemon_connection == "opening") {
- document.getElementById("daemon_connection_state").className =
- "btn btn-warning";
- //document.getElementById("blurdiv").style.webkitFilter = "blur(10px)";
- }
- if (arg.daemon_connection == "closed") {
- document.getElementById("daemon_connection_state").className =
- "btn btn-danger";
- //document.getElementById("blurdiv").style.webkitFilter = "blur(10px)";
- }
-});
-
-ipcRenderer.on("action-update-tnc-connection", (event, arg) => {
- if (arg.tnc_connection == "open") {
- /*
- document.getElementById('hamlib_deviceid').disabled = true;
- document.getElementById('hamlib_deviceport').disabled = true;
- document.getElementById('testHamlib').disabled = true;
- document.getElementById('hamlib_ptt_protocol').disabled = true;
- document.getElementById('audio_input_selectbox').disabled = true;
- document.getElementById('audio_output_selectbox').disabled = true;
- //document.getElementById('stopTNC').disabled = false;
- document.getElementById('startTNC').disabled = true;
- document.getElementById('dxCall').disabled = false;
- document.getElementById("hamlib_serialspeed").disabled = true;
- document.getElementById("openDataModule").disabled = false;
- */
-
- // collapse settings screen
- var collapseFirstRow = new bootstrap.Collapse(
- document.getElementById("collapseFirstRow"),
- { toggle: false },
- );
- collapseFirstRow.hide();
- var collapseSecondRow = new bootstrap.Collapse(
- document.getElementById("collapseSecondRow"),
- { toggle: false },
- );
- collapseSecondRow.hide();
- var collapseThirdRow = new bootstrap.Collapse(
- document.getElementById("collapseThirdRow"),
- { toggle: false },
- );
- collapseThirdRow.show();
- var collapseFourthRow = new bootstrap.Collapse(
- document.getElementById("collapseFourthRow"),
- { toggle: false },
- );
- collapseFourthRow.show();
-
- //Set tuning for fancy graphics mode (high/low CPU)
- set_CPU_mode();
-
- //GUI will auto connect to TNC if already running, if that is the case increment start count if 0
- if (tncStartCount == 0) tncStartCount++;
- } else {
- /*
- document.getElementById('hamlib_deviceid').disabled = false;
- document.getElementById('hamlib_deviceport').disabled = false;
- document.getElementById('testHamlib').disabled = false;
- document.getElementById('hamlib_ptt_protocol').disabled = false;
- document.getElementById('audio_input_selectbox').disabled = false;
- document.getElementById('audio_output_selectbox').disabled = false;
- //document.getElementById('stopTNC').disabled = true;
- document.getElementById('startTNC').disabled = false;
- document.getElementById('dxCall').disabled = true;
- document.getElementById("hamlib_serialspeed").disabled = false;
- document.getElementById("openDataModule").disabled = true;
- */
- // collapse settings screen
- var collapseFirstRow = new bootstrap.Collapse(
- document.getElementById("collapseFirstRow"),
- { toggle: false },
- );
- collapseFirstRow.show();
- var collapseSecondRow = new bootstrap.Collapse(
- document.getElementById("collapseSecondRow"),
- { toggle: false },
- );
- collapseSecondRow.show();
- var collapseThirdRow = new bootstrap.Collapse(
- document.getElementById("collapseThirdRow"),
- { toggle: false },
- );
- collapseThirdRow.hide();
- var collapseFourthRow = new bootstrap.Collapse(
- document.getElementById("collapseFourthRow"),
- { toggle: false },
- );
- collapseFourthRow.hide();
- }
-});
-
-ipcRenderer.on("action-update-rx-buffer", (event, arg) => {
- var data = arg.data["data"];
-
- var tbl = document.getElementById("rx-data");
- document.getElementById("rx-data").innerHTML = "";
-
- for (i = 0; i < arg.data.length; i++) {
- // first we update the PING window
- if (
- arg.data[i]["dxcallsign"] ==
- document.getElementById("dxCall").value.toUpperCase()
- ) {
- /*
- // if we are sending data without doing a ping before, we don't have a grid locator available. This could be a future feature for the TNC!
- if(arg.data[i]['DXGRID'] != ''){
- document.getElementById("pingDistance").innerHTML = arg.stations[i]['DXGRID']
- }
- */
- //document.getElementById("pingDB").innerHTML = arg.stations[i]['snr'];
- document.getElementById("dataModalPingDB").innerHTML =
- arg.stations[i]["snr"];
- }
-
- // now we update the received files list
-
- var row = document.createElement("tr");
- //https://stackoverflow.com/q/51421470
-
- //https://stackoverflow.com/a/847196
- timestampRaw = arg.data[i]["timestamp"];
- var date = new Date(timestampRaw * 1000);
- var hours = date.getHours();
- var minutes = "0" + date.getMinutes();
- var seconds = "0" + date.getSeconds();
- var datetime = hours + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
-
- var timestamp = document.createElement("td");
- var timestampText = document.createElement("span");
- timestampText.innerText = datetime;
- timestamp.appendChild(timestampText);
-
- var dxCall = document.createElement("td");
- var dxCallText = document.createElement("span");
- dxCallText.innerText = arg.data[i]["dxcallsign"];
- dxCall.appendChild(dxCallText);
-
- /*
- var dxGrid = document.createElement("td");
- var dxGridText = document.createElement('span');
- dxGridText.innerText = arg.data[i]['DXGRID']
- dxGrid.appendChild(dxGridText);
- */
-
- console.log(arg.data);
-
- var encoded_data = FD.atob_FD(arg.data[i]["data"]);
- var splitted_data = encoded_data.split(split_char);
- console.log(splitted_data);
-
- var fileName = document.createElement("td");
- var fileNameText = document.createElement("span");
- //var fileNameString = arg.data[i]['data'][0]['fn'];
- var fileNameString = splitted_data[1];
-
- fileNameText.innerText = fileNameString;
- fileName.appendChild(fileNameText);
-
- row.appendChild(timestamp);
- row.appendChild(dxCall);
- // row.appendChild(dxGrid);
- row.appendChild(fileName);
- tbl.appendChild(row);
-
- // https://stackoverflow.com/a/26227660
- //var appDataFolder = process.env.HOME;
- //console.log("appDataFolder:" + appDataFolder);
- //var applicationFolder = path.join(appDataFolder, "FreeDATA");
- //console.log(applicationFolder);
- //var receivedFilesFolder = path.join(applicationFolder, "receivedFiles");
- var receivedFilesFolder = path.join(config.received_files_folder);
-
- console.log("receivedFilesFolder: " + receivedFilesFolder);
- // Creates receivedFiles folder if not exists
- // https://stackoverflow.com/a/13544465
- fs.mkdir(
- receivedFilesFolder,
- {
- recursive: true,
- },
- function (err) {
- console.log(err);
- },
- );
-
- // write file to data folder
- ////var base64String = arg.data[i]['data'][0]['d']
- // remove header from base64 String
- // https://www.codeblocq.com/2016/04/Convert-a-base64-string-to-a-file-in-Node/
- ////var base64Data = base64String.split(';base64,').pop()
- //write data to file
- var base64Data = splitted_data[4];
- var receivedFile = path.join(receivedFilesFolder, fileNameString);
- console.log(receivedFile);
-
- require("fs").writeFile(receivedFile, base64Data, "binary", function (err) {
- //require("fs").writeFile(receivedFile, base64Data, 'base64', function(err) {
- console.log(err);
- });
- }
-});
-ipcRenderer.on("run-tnc-command-fec-iswriting", (event) => {
- //console.log("Sending sendFecIsWriting");
- sock.sendFecIsWriting(config.mycall);
-});
-
-//Change background color of RF Chat button if new messages are available
-ipcRenderer.on("action-update-unread-messages-main", (event, data) => {
- //Do something
- if (data == true) {
- document.getElementById("list-messages-list").classList.add("bg-warning");
- document.getElementById("list-messages-list").classList.remove("bg-secondary");
- } else {
- document.getElementById("list-messages-list").classList.remove("bg-warning");
- document.getElementById("list-messages-list").classList.add("bg-secondary");
- }
-});
-
-ipcRenderer.on("run-tnc-command", (event, arg) => {
- if (arg.command == "save_my_call") {
- sock.saveMyCall(arg.callsign);
- }
- if (arg.command == "save_my_grid") {
- sock.saveMyGrid(arg.grid);
- }
- if (arg.command == "ping") {
- sock.sendPing(arg.dxcallsign);
- }
-
- if (arg.command == "send_file") {
- sock.sendFile(
- arg.dxcallsign,
- arg.mode,
- arg.frames,
- arg.filename,
- arg.filetype,
- arg.data,
- arg.checksum,
- );
- }
- if (arg.command == "msg") {
- sock.sendMessage(
- arg.dxcallsign,
- arg.mode,
- arg.frames,
- arg.data,
- arg.checksum,
- arg.uuid,
- arg.command,
- );
- }
- if (arg.command == "broadcast") {
- sock.sendBroadcastChannel(arg.broadcastChannel, arg.data, arg.uuid);
- }
- if (arg.command == "stop_transmission") {
- sock.stopTransmission();
- }
- if (arg.command == "set_tx_audio_level") {
- sock.setTxAudioLevel(arg.tx_audio_level);
- }
- if (arg.command == "record_audio") {
- sock.record_audio();
- }
- if (arg.command == "send_test_frame") {
- sock.sendTestFrame();
- }
-
- if (arg.command == "frequency") {
- sock.set_frequency(arg.frequency);
- }
-
- if (arg.command == "mode") {
- sock.set_mode(arg.mode);
- }
-
- if (arg.command == "requestUserInfo") {
- sock.sendRequestInfo(arg.dxcallsign);
- }
-
- if (arg.command == "requestSharedFolderList") {
- sock.sendRequestSharedFolderList(arg.dxcallsign);
- }
-
- if (arg.command == "requestSharedFile") {
- sock.sendRequestSharedFile(arg.dxcallsign, arg.file);
- }
-
- // responses
- if (arg.command == "responseUserInfo") {
- sock.sendResponseInfo(arg.dxcallsign, arg.userinfo);
- }
-
- if (arg.command == "responseSharedFolderList") {
- sock.sendResponseSharedFolderList(arg.dxcallsign, arg.folderFileList);
- }
- if (arg.command == "responseSharedFile") {
- sock.sendResponseSharedFile(arg.dxcallsign, arg.file, arg.filedata);
- }
-
- if (arg.command == "mesh_ping") {
- sock.sendMeshPing(arg.dxcallsign);
- }
-});
-
-// IPC ACTION FOR AUTO UPDATER
-ipcRenderer.on("action-updater", (event, arg) => {
- if (arg.status == "download-progress") {
- var progressinfo =
- "(" +
- Math.round(arg.progress.transferred / 1024) +
- "kB /" +
- Math.round(arg.progress.total / 1024) +
- "kB)" +
- " @ " +
- Math.round(arg.progress.bytesPerSecond / 1024) +
- "kByte/s";
- document.getElementById("UpdateProgressInfo").innerHTML = progressinfo;
-
- document
- .getElementById("UpdateProgressBar")
- .setAttribute("aria-valuenow", arg.progress.percent);
- document
- .getElementById("UpdateProgressBar")
- .setAttribute("style", "width:" + arg.progress.percent + "%;");
- }
-
- if (arg.status == "checking-for-update") {
- //document.title = document.title + ' - v' + arg.version;
- updateTitle(
- config.myCall,
- config.tnc_host,
- config.tnc_port,
- " -v " + arg.version,
- );
- document.getElementById("updater_status").innerHTML =
- ' ';
-
- document.getElementById("updater_status").className =
- "btn btn-secondary btn-sm";
- document.getElementById("update_and_install").style.display = "none";
- }
- if (arg.status == "update-downloaded") {
- document.getElementById("update_and_install").removeAttribute("style");
- document.getElementById("updater_status").innerHTML =
- ' ';
- document.getElementById("updater_status").className =
- "btn btn-success btn-sm";
-
- // HERE WE NEED TO RUN THIS SOMEHOW...
- //mainLog.info('quit application and install update');
- //autoUpdater.quitAndInstall();
- }
- if (arg.status == "update-not-available") {
- document.getElementById("updater_status").innerHTML =
- ' ';
- document.getElementById("updater_status").className =
- "btn btn-success btn-sm";
- document.getElementById("update_and_install").style.display = "none";
- }
- if (arg.status == "update-available") {
- document.getElementById("updater_status").innerHTML =
- ' ';
- document.getElementById("updater_status").className =
- "btn btn-warning btn-sm";
- document.getElementById("update_and_install").style.display = "none";
- }
-
- if (arg.status == "error") {
- document.getElementById("updater_status").innerHTML =
- ' ';
- document.getElementById("updater_status").className =
- "btn btn-danger btn-sm";
- document.getElementById("update_and_install").style.display = "none";
- }
-});
-
-// ----------- INFO MODAL ACTIONS -------------------------------
-
-// CQ TRANSMITTING
-ipcRenderer.on("action-show-cq-toast-transmitting", (event, data) => {
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content = "transmitting cq"),
- (duration = 5000),
- );
-});
-// fec iswriting received
-ipcRenderer.on("action-show-fec-toast-iswriting", (event, data) => {
- let dxcallsign = data["data"][0]["dxcallsign"];
- let content = `${dxcallsign} is typing`;
- displayToast(
- (type = "success"),
- (icon = "bi-pencil-fill"),
- (content = content),
- (duration = 5000),
- );
-});
-// CQ RECEIVED
-ipcRenderer.on("action-show-cq-toast-received", (event, data) => {
- let dxcallsign = data["data"][0]["dxcallsign"];
- let dxgrid = data["data"][0]["dxgrid"];
- let content = `cq from ${dxcallsign} (${dxgrid})`;
- showOsPopUp("CQ from " + dxcallsign, "Say hello!");
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content = content),
- (duration = 5000),
- );
-});
-
-// QRV TRANSMITTING
-ipcRenderer.on("action-show-qrv-toast-transmitting", (event, data) => {
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content = "transmitting qrv"),
- (duration = 5000),
- );
-});
-
-// QRV RECEIVED
-ipcRenderer.on("action-show-qrv-toast-received", (event, data) => {
- console.log(data["data"][0]);
- let dxcallsign = data["data"][0]["dxcallsign"];
- let dxgrid = data["data"][0]["dxgrid"];
- let content = `received qrv from ${dxcallsign} (${dxgrid})`;
-
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content = content),
- (duration = 5000),
- );
-});
-
-// BEACON TRANSMITTING
-ipcRenderer.on("action-show-beacon-toast-transmitting", (event, data) => {
- displayToast(
- (type = "info"),
- (icon = "bi-broadcast"),
- (content = "transmitting beacon"),
- (duration = 5000),
- );
-});
-
-// BEACON RECEIVED
-ipcRenderer.on("action-show-beacon-toast-received", (event, data) => {
- console.log(data["data"][0]);
- let dxcallsign = data["data"][0]["dxcallsign"];
- let dxgrid = data["data"][0]["dxgrid"];
- let content = `beacon from ${dxcallsign} (${dxgrid})`;
- displayToast(
- (type = "info"),
- (icon = "bi-broadcast"),
- (content = content),
- (duration = 5000),
- );
-});
-
-// PING TRANSMITTING
-ipcRenderer.on("action-show-ping-toast-transmitting", (event, data) => {
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content = "transmitting ping"),
- (duration = 5000),
- );
-});
-
-// PING RECEIVED
-ipcRenderer.on("action-show-ping-toast-received", (event, data) => {
- console.log(data["data"][0]);
- let dxcallsign = data["data"][0]["dxcallsign"];
- let content = `ping from ${dxcallsign} `;
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content = content),
- (duration = 5000),
- );
-});
-
-// PING RECEIVED ACK
-ipcRenderer.on("action-show-ping-toast-received-ack", (event, data) => {
- console.log(data["data"][0]);
- let dxcallsign = data["data"][0]["dxcallsign"];
- let dxgrid = data["data"][0]["dxgrid"];
- let content = `ping ACK from ${dxcallsign} (${dxgrid})`;
- displayToast(
- (type = "success"),
- (icon = "bi-check"),
- (content = content),
- (duration = 5000),
- );
-});
-
-// DATA CHANNEL OPENING TOAST
-ipcRenderer.on("action-show-arq-toast-datachannel-opening", (event, data) => {
- console.log(data["data"][0]);
- let dxcallsign = data["data"][0]["dxcallsign"];
- let content = `opening datachannel with ${dxcallsign} `;
- displayToast(
- (type = "secondary"),
- (icon = "bi-arrow-left-right"),
- (content = content),
- (duration = 5000),
- );
-});
-
-// DATA CHANNEL WAITING TOAST
-ipcRenderer.on("action-show-arq-toast-datachannel-waiting", (event, data) => {
- displayToast(
- (type = "warning"),
- (icon = "bi-smartwatch"),
- (content = "channel busy - waiting..."),
- (duration = 5000),
- );
-});
-
-// DATA CHANNEL OPEN TOAST
-ipcRenderer.on("action-show-arq-toast-datachannel-open", (event, data) => {
- displayToast(
- (type = "success"),
- (icon = "bi-arrow-left-right"),
- (content = "datachannel open"),
- (duration = 5000),
- );
-});
-
-// DATA CHANNEL RECEIVED OPENER TOAST
-ipcRenderer.on(
- "action-show-arq-toast-datachannel-received-opener",
- (event, data) => {
- console.log(data["data"][0]);
- let dxcallsign = data["data"][0]["dxcallsign"];
- let content = `datachannel requested by ${dxcallsign} `;
- displayToast(
- (type = "success"),
- (icon = "bi-arrow-left-right"),
- (content = content),
- (duration = 5000),
- );
- },
-);
-
-// ARQ TRANSMISSION FAILED
-// TODO: use for both - transmitting and receiving --> we need to change the IDs
-ipcRenderer.on("action-show-arq-toast-transmission-failed", (event, data) => {
- displayToast(
- (type = "danger"),
- (icon = "bi-arrow-left-right"),
- (content = "transmission failed"),
- (duration = 5000),
- );
-});
-
-// ARQ TRANSMISSION FAILED (Version mismatch)
-ipcRenderer.on(
- "action-show-arq-toast-transmission-failed-ver",
- (event, data) => {
- displayToast(
- (type = "danger"),
- (icon = "bi-broadcast"),
- (content = "protocol version missmatch"),
- (duration = 5000),
- );
- },
-);
-
-// ARQ TRANSMISSION STOPPED
-// TODO: RENAME ID -- WRONG
-ipcRenderer.on("action-show-arq-toast-transmission-stopped", (event, data) => {
- displayToast(
- (type = "success"),
- (icon = "bi-arrow-left-right"),
- (content = "transmission stopped"),
- (duration = 5000),
- );
-});
-
-// ARQ TRANSMISSION FAILED
-// TODO: USE FOR TX AND RX
-ipcRenderer.on("action-show-arq-toast-transmission-failed", (event, data) => {
- displayToast(
- (type = "danger"),
- (icon = "bi-broadcast"),
- (content = "arq transmission failed"),
- (duration = 5000),
- );
-});
-
-// ARQ TRANSMISSION TRANSMITTED
-ipcRenderer.on(
- "action-show-arq-toast-transmission-transmitted",
- (event, data) => {
- console.log(data["data"][0]);
- //let content = `received cq from ${dxcallsign} (${dxgrid})`;
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content = "data transmitted"),
- (duration = 5000),
- );
- },
-);
-
-// ARQ TRANSMISSION TRANSMITTING
-ipcRenderer.on(
- "action-show-arq-toast-transmission-transmitting",
- (event, data) => {
- var irs_snr = data["data"][0].irs_snr;
-
- if (irs_snr <= 0) {
- displayToast(
- (type = "warning"),
- (icon = "bi-broadcast"),
- (content = "low link margin: " + irs_snr + " dB "),
- (duration = 5000),
- );
- } else if (irs_snr > 0 && irs_snr <= 5) {
- displayToast(
- (type = "warning"),
- (icon = "bi-broadcast"),
- (content = "medium link margin: " + irs_snr + " dB "),
- (duration = 5000),
- );
- } else if (irs_snr > 5 && irs_snr < 12.7) {
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content = "high link margin: " + irs_snr + " dB "),
- (duration = 5000),
- );
- } else if (irs_snr >= 12.7) {
- displayToast(
- (type = "success"),
- (icon = "bi-broadcast"),
- (content =
- "very high link margin: " + irs_snr + " dB "),
- (duration = 5000),
- );
- } else {
- //displayToast(type='info', icon='bi-broadcast', content='no snr information', duration=5000);
- }
- },
-);
-
-// ARQ TRANSMISSION RECEIVED
-ipcRenderer.on("action-show-arq-toast-transmission-received", (event, data) => {
- console.log(data["data"][0]);
- displayToast(
- (type = "success"),
- (icon = "bi-check-circle"),
- (content = "all data received"),
- (duration = 5000),
- );
-});
-
-// ARQ TRANSMISSION RECEIVING
-ipcRenderer.on(
- "action-show-arq-toast-transmission-receiving",
- (event, data) => {
- displayToast(
- (type = "primary"),
- (icon = "bi-arrow-left-right"),
- (content = "session receiving"),
- (duration = 5000),
- );
- },
-);
-
-// ARQ SESSION CONNECTING
-ipcRenderer.on("action-show-arq-toast-session-connecting", (event, data) => {
- displayToast(
- (type = "primary"),
- (icon = "bi-arrow-left-right"),
- (content = "connecting..."),
- (duration = 5000),
- );
-});
-
-// ARQ SESSION CONNECTED
-ipcRenderer.on("action-show-arq-toast-session-connected", (event, data) => {
- displayToast(
- (type = "success"),
- (icon = "bi-arrow-left-right"),
- (content = "session connected"),
- (duration = 5000),
- );
-});
-
-// ARQ SESSION CONNECTED
-ipcRenderer.on("action-show-arq-toast-session-waiting", (event, data) => {
- displayToast(
- (type = "warning"),
- (icon = "bi-smartwatch"),
- (content = "session waiting..."),
- (duration = 5000),
- );
-});
-
-// ARQ SESSION CLOSE
-ipcRenderer.on("action-show-arq-toast-session-close", (event, data) => {
- displayToast(
- (type = "warning"),
- (icon = "bi-arrow-left-right"),
- (content = "session close"),
- (duration = 5000),
- );
-});
-
-// ARQ SESSION FAILED
-ipcRenderer.on("action-show-arq-toast-session-failed", (event, data) => {
- displayToast(
- (type = "danger"),
- (icon = "bi-arrow-left-right"),
- (content = "session failed"),
- (duration = 5000),
- );
-});
-
-// enable or disable a setting by given switch and element
-// not used at this time
-function enable_setting(enable_switch, enable_object) {
- if (document.getElementById(enable_switch).checked) {
- config[enable_switch] = true;
- document
- .getElementById(enable_object)
- .removeAttribute("disabled", "disabled");
- } else {
- config[enable_switch] = false;
- document.getElementById(enable_object).setAttribute("disabled", "disabled");
- }
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
-}
-
-// enable or disable a setting switch
-// not used at this time
-function set_setting_switch(setting_switch, enable_object, state) {
- document.getElementById(setting_switch).checked = state;
- enable_setting(setting_switch, enable_object);
-}
-
-var rigctldActive = false;
-setInterval(checkRigctld, 500);
-function checkRigctld() {
- var rigctld_ip = document.getElementById("hamlib_rigctld_ip").value;
- var rigctld_port = document.getElementById("hamlib_rigctld_port").value;
-
- let Data = {
- ip: rigctld_ip,
- port: rigctld_port,
- };
-
- //Prevents an error on startup if hamlib settings aren't populated yet
- if (rigctld_port.length > 0 && rigctld_ip.length > 0) {
- ipcRenderer.send("request-check-rigctld", Data);
- }
-}
-
-ipcRenderer.on("action-check-rigctld", (event, data) => {
- document.getElementById("hamlib_rigctld_status").value = data["state"];
- rigctldActive = data["active"];
- if (data["active"] == true) {
- document.getElementById("hamlib_rigctld_stop").disabled = false;
- document.getElementById("hamlib_rigctld_start").disabled = true;
- document.getElementById("testHamlib").disabled = false;
- } else {
- document.getElementById("hamlib_rigctld_stop").disabled = true;
- document.getElementById("hamlib_rigctld_start").disabled = false;
- document.getElementById("testHamlib").disabled = true;
- }
-});
-
-ipcRenderer.on("action-set-app-version", (event, data) => {
- appVer = data;
-});
-
-function updateTitle(
- mycall = config.mycall,
- tnc = config.tnc_host,
- tncport = config.tnc_port,
- appender = "",
-) {
- //Multiple consecutive spaces get converted to a single space
- var title =
- "FreeDATA " +
- appVer +
- " - Call: " +
- mycall +
- " - TNC: " +
- tnc +
- ":" +
- tncport +
- appender;
- if (title != document.title) {
- document.title = title;
- }
-}
-
-//Set force to true to ensure a class is present on a control, otherwise set to false to ensure it isn't present
-function toggleClass(control, classToToggle, force) {
- var cntrl = document.getElementById(control);
- if (cntrl == undefined) {
- console.log("toggle class: unknown control: ", control);
- return;
- }
- var activeClasses = cntrl.className;
- //var oldactive = activeClasses;
- if (force == true && activeClasses.indexOf(classToToggle) >= 0) {
- return;
- }
- if (force == false && activeClasses.indexOf(classToToggle) == -1) {
- return;
- }
- if (force == true) {
- activeClasses += " " + classToToggle;
- } else {
- activeClasses = activeClasses.replace(classToToggle, "");
- }
- activeClasses = activeClasses.replace(" ", " ").trim();
- cntrl.className = activeClasses;
- //console.log(control," toggleClass; force: ", force, "class: " ,classToToggle, " in: '" ,oldactive, "' out: '",activeClasses,"'");
-}
-function set_CPU_mode() {
- if (config.high_graphics.toUpperCase() == "FALSE") {
- toggleClass("dbfs_level", "disable-effects", true);
- toggleClass("dbfs_level", "progress-bar-striped", false);
- toggleClass("noise_level", "disable-effects", true);
- toggleClass("noise_level", "progress-bar-striped", false);
- toggleClass("waterfall", "disable-effects", true);
- toggleClass("transmission_progress", "disable-effects", true);
- toggleClass("transmission_progress", "progress-bar-striped", false);
- } else {
- toggleClass("dbfs_level", "disable-effects", false);
- toggleClass("dbfs_level", "progress-bar-striped", true);
- toggleClass("noise_level", "disable-effects", false);
- toggleClass("noise_level", "progress-bar-striped", true);
- toggleClass("waterfall", "disable-effects", false);
- toggleClass("transmission_progress", "disable-effects", false);
- toggleClass("transmission_progress", "progress-bar-striped", true);
- }
-}
-//Temporarily disable a button with timeout
-function pauseButton(btn, timems) {
- btn.disabled = true;
- var curText = btn.innerHTML;
- if (config.high_graphics.toUpperCase() == "TRUE") {
- btn.innerHTML =
- '';
- }
- setTimeout(() => {
- btn.innerHTML = curText;
- btn.disabled = false;
- }, timems);
-}
-//https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript
-function formatBytes(bytes, decimals = 1) {
- if (!+bytes) return "0 Bytes";
-
- const k = 1024;
- const dm = decimals < 0 ? 0 : decimals;
- const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
-
- const i = Math.floor(Math.log(bytes) / Math.log(k));
-
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
-}
-
-// display toast
-function displayToast(
- type = "primary",
- icon = "bi-info",
- content = "default",
- duration = 5000,
-) {
- mainToastContainer = document.getElementById("mainToastContainer");
-
- let randomID = uuidv4();
- let toastCode = `
-
- `;
-
- // insert toast to toast container
- mainToastContainer.insertAdjacentHTML("beforeend", toastCode);
-
- // register toast
- let toastHTMLElement = document.getElementById(randomID);
- let toast = bootstrap.Toast.getOrCreateInstance(toastHTMLElement); // Returns a Bootstrap toast instance
- toast._config.delay = duration;
-
- // show toast
- toast.show();
-
- //register event listener if toast is hidden
- toastHTMLElement.addEventListener("hidden.bs.toast", () => {
- // remove eventListener
- toastHTMLElement.removeEventListener("hidden.bs.toast", this);
- // remove toast
- toastHTMLElement.remove();
- });
-}
-
-function loadSettings(elements) {
- elements.forEach(function (id) {
- let element = document.getElementById(id);
-
- if (element.tagName === "SELECT") {
- element.value = config[id];
-
- // add selected value
- for (var i = 0, j = element.options.length; i < j; ++i) {
- if (element.options[i].innerHTML === config[id]) {
- element.selectedIndex = i;
- break;
- }
- }
- } else if (element.tagName === "INPUT" && element.type === "text") {
- element.value = config[id];
- } else if (element.tagName === "INPUT" && element.type === "radio") {
- element.value = config[id];
-
- if (config[id] === "True") {
- element.checked = true;
- } else {
- element.checked = false;
- }
- } else {
- console.log("nothing matched....");
- }
- });
- ipcRenderer.on("update-config", (event, data) => {
- config = data;
- });
-}
-
-function changeGuiDesign(design) {
- if (
- design != "default" &&
- design != "default_light" &&
- design != "default_dark" &&
- design != "default_auto"
- ) {
- var theme_path =
- "../node_modules/bootswatch/dist/" + design + "/bootstrap.min.css";
- document.getElementById("theme_selector").value = design;
- document.getElementById("bootstrap_theme").href = escape(theme_path);
- } else if (design == "default" || design == "default_light") {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- document.getElementById("theme_selector").value = "default_light";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
-
- document.documentElement.setAttribute("data-bs-theme", "light");
- } else if (design == "default_dark") {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- document.getElementById("theme_selector").value = "default_dark";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
-
- document.querySelector("html").setAttribute("data-bs-theme", "dark");
- } else if (design == "default_auto") {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- document.getElementById("theme_selector").value = "default_auto";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
-
- // https://stackoverflow.com/a/57795495
- // check if dark mode or light mode used in OS
- if (
- window.matchMedia &&
- window.matchMedia("(prefers-color-scheme: dark)").matches
- ) {
- // dark mode
- document.documentElement.setAttribute("data-bs-theme", "dark");
- } else {
- document.documentElement.setAttribute("data-bs-theme", "light");
- }
-
- // also register event listener for automatic change
- window
- .matchMedia("(prefers-color-scheme: dark)")
- .addEventListener("change", (event) => {
- let newColorScheme = event.matches ? "dark" : "light";
- if (newColorScheme == "dark") {
- document.documentElement.setAttribute("data-bs-theme", "dark");
- } else {
- document.documentElement.setAttribute("data-bs-theme", "light");
- }
- });
- } else {
- var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
- document.getElementById("theme_selector").value = "default_light";
- document.getElementById("bootstrap_theme").href = escape(theme_path);
-
- document.documentElement.setAttribute("data-bs-theme", "light");
- }
-
- //update path to css file
- document.getElementById("bootstrap_theme").href = escape(theme_path);
-}
-
-var hslLastSort = 0;
-var hslLastSortDir = "desc";
-
-//https://www.w3schools.com/howto/howto_js_sort_table.asp
-function sorthslTable(n) {
- hslLastSort = n;
- var table,
- rows,
- switching,
- i,
- x,
- y,
- shouldSwitch,
- dir,
- switchcount = 0;
- table = document.getElementById("tblHeardStationList");
- switching = true;
- // Set the sorting direction to ascending:
- //hslLastSortDir = "asc";
- /* Make a loop that will continue until
- no switching has been done: */
- while (switching) {
- // Start by saying: no switching is done:
- switching = false;
- rows = table.rows;
- /* Loop through all table rows (except the
- first, which contains table headers): */
- for (i = 1; i < rows.length - 1; i++) {
- // Start by saying there should be no switching:
- shouldSwitch = false;
- /* Get the two elements you want to compare,
- one from current row and one from the next: */
- x = rows[i].getElementsByTagName("TD")[n];
- y = rows[i + 1].getElementsByTagName("TD")[n];
- /* Check if the two rows should switch place,
- based on the direction, asc or desc: */
- if (hslLastSortDir == "asc") {
- if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
- // If so, mark as a switch and break the loop:
- shouldSwitch = true;
- break;
- }
- } else if (hslLastSortDir == "desc") {
- if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
- // If so, mark as a switch and break the loop:
- shouldSwitch = true;
- break;
- }
- }
- }
- if (shouldSwitch) {
- /* If a switch has been marked, make the switch
- and mark that a switch has been done: */
- rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
- switching = true;
- // Each time a switch is done, increase this count by 1:
- switchcount++;
- }
- }
-}
-
-function autostart_rigctld() {
- if (config.auto_start == 1) {
- //Start rigctld if radiocontrol is in correct mode and is not active
- if (config.radiocontrol == "rigctld" && rigctldActive == false) {
- //console.log("Autostarting rigctld");
- document.getElementById("hamlib_rigctld_start").click();
- }
- }
-}
-function autostart_tnc() {
- if (config.auto_start == 1) {
- //Now start TNC
- document.getElementById("startTNC").click();
- }
-}
-
-//Have the operating system show a notification popup
-function showOsPopUp(title, message) {
- if (config.enable_sys_notification == 0) return;
- const NOTIFICATION_TITLE = title;
- const NOTIFICATION_BODY = message;
- new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY });
-}
diff --git a/gui/preload-mesh.js b/gui/preload-mesh.js
deleted file mode 100644
index 6035b058..00000000
--- a/gui/preload-mesh.js
+++ /dev/null
@@ -1,231 +0,0 @@
-const path = require("path");
-const { ipcRenderer } = require("electron");
-
-// https://stackoverflow.com/a/26227660
-var appDataFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Application Support"
- : process.env.HOME + "/.config");
-var configFolder = path.join(appDataFolder, "FreeDATA");
-var configPath = path.join(configFolder, "config.json");
-const config = require(configPath);
-
-var callsignPath = path.join(configFolder, "callsigns.json");
-const callsigns = require(callsignPath);
-
-// WINDOW LISTENER
-window.addEventListener("DOMContentLoaded", () => {
- // startPing button clicked
- document
- .getElementById("transmit_mesh_ping")
- .addEventListener("click", () => {
- var dxcallsign = document
- .getElementById("dxCallMesh")
- .value.toUpperCase();
- if (dxcallsign == "" || dxcallsign == null || dxcallsign == undefined)
- return;
- //pauseButton(document.getElementById("transmit_mesh_ping"), 2000);
- ipcRenderer.send("run-tnc-command", {
- command: "mesh_ping",
- dxcallsign: dxcallsign,
- });
- });
-});
-
-ipcRenderer.on("action-update-mesh-table", (event, arg) => {
- var routes = arg.routing_table;
-
- if (typeof routes == "undefined") {
- return;
- }
-
- var tbl = document.getElementById("mesh-table");
- if (tbl !== null) {
- tbl.innerHTML = "";
- }
-
- for (i = 0; i < routes.length; i++) {
- var row = document.createElement("tr");
- var datetime = new Date(routes[i]["timestamp"] * 1000).toLocaleString(
- navigator.language,
- {
- hourCycle: "h23",
- year: "numeric",
- month: "2-digit",
- day: "2-digit",
- hour: "2-digit",
- minute: "2-digit",
- second: "2-digit",
- },
- );
- var timestamp = document.createElement("td");
- var timestampText = document.createElement("span");
- timestampText.innerText = datetime;
- timestamp.appendChild(timestampText);
-
- var dxcall = document.createElement("td");
- var dxcallText = document.createElement("span");
- dxcallText.innerText = routes[i]["dxcall"];
-
- // check for callsign in callsign list, else use checksum
- for (let call in callsigns) {
- if (callsigns[call] == routes[i]["dxcall"]) {
- dxcallText.innerText += " (" + call + ")";
- continue;
- }
- }
- dxcall.appendChild(dxcallText);
-
- var router = document.createElement("td");
- var routerText = document.createElement("span");
- routerText.innerText = routes[i]["router"];
-
- // check for callsign in callsign list, else use checksum
- for (let call in callsigns) {
- if (callsigns[call] == routes[i]["router"]) {
- routerText.innerHTML += `${call} `;
- continue;
- }
- }
- router.appendChild(routerText);
-
- var hops = document.createElement("td");
- var hopsText = document.createElement("span");
- hopsText.innerText = routes[i]["hops"];
- hops.appendChild(hopsText);
-
- var score = document.createElement("td");
- var scoreText = document.createElement("span");
- scoreText.innerText = routes[i]["score"];
- score.appendChild(scoreText);
-
- var snr = document.createElement("td");
- var snrText = document.createElement("span");
- snrText.innerText = routes[i]["snr"];
- snr.appendChild(snrText);
-
- row.appendChild(timestamp);
- row.appendChild(dxcall);
- row.appendChild(router);
- row.appendChild(hops);
- row.appendChild(score);
- row.appendChild(snr);
-
- tbl.appendChild(row);
- }
- /*-------------------------------------------*/
- var routes = arg.mesh_signalling_table;
-
- //console.log(routes);
- if (typeof routes == "undefined") {
- return;
- }
-
- var tbl = document.getElementById("mesh-signalling-table");
- if (tbl !== null) {
- tbl.innerHTML = "";
- }
-
- for (i = 0; i < routes.length; i++) {
- var row = document.createElement("tr");
- var datetime = new Date(routes[i]["timestamp"] * 1000).toLocaleString(
- navigator.language,
- {
- hourCycle: "h23",
- year: "numeric",
- month: "2-digit",
- day: "2-digit",
- hour: "2-digit",
- minute: "2-digit",
- second: "2-digit",
- },
- );
- var timestamp = document.createElement("td");
- var timestampText = document.createElement("span");
- timestampText.innerText = datetime;
- timestamp.appendChild(timestampText);
-
- var destination = document.createElement("td");
- var destinationText = document.createElement("span");
- destinationText.innerText = routes[i]["destination"];
- // check for callsign in callsign list, else use checksum
- for (let call in callsigns) {
- if (callsigns[call] == routes[i]["destination"]) {
- destinationText.innerHTML += `${call} `;
- continue;
- }
- }
- destination.appendChild(destinationText);
-
- var origin = document.createElement("td");
- var originText = document.createElement("span");
- originText.innerText = routes[i]["origin"];
- // check for callsign in callsign list, else use checksum
- for (let call in callsigns) {
- if (callsigns[call] == routes[i]["origin"]) {
- originText.innerHTML += `${call} `;
- continue;
- }
- }
-
- origin.appendChild(originText);
-
- var frametype = document.createElement("td");
- var frametypeText = document.createElement("span");
- frametypeText.innerText = routes[i]["frametype"];
- frametype.appendChild(frametypeText);
-
- var payload = document.createElement("td");
- var payloadText = document.createElement("span");
- payloadText.innerText = routes[i]["payload"];
- payload.appendChild(payloadText);
-
- var attempt = document.createElement("td");
- var attemptText = document.createElement("span");
- attemptText.innerText = routes[i]["attempt"];
- attempt.appendChild(attemptText);
-
- var status = document.createElement("td");
- var statusText = document.createElement("span");
- //statusText.innerText = routes[i]["status"];
- switch (routes[i]["status"]) {
- case "acknowledged":
- var status_icon = ' ';
- var status_color = "bg-success";
- break;
- case "acknowledging":
- var status_icon = ' ';
- var status_color = "bg-warning";
- break;
- case "forwarding":
- var status_icon = ' ';
- var status_color = "bg-secondary";
- break;
- case "awaiting_ack":
- var status_icon = ' ';
- var status_color = "bg-info";
- break;
- default:
- var status_icon = ' ';
- var status_color = "bg-primary";
- break;
- }
-
- statusText.innerHTML = `
- ${status_icon}
- ${routes[i]["status"]}
- `;
- status.appendChild(statusText);
-
- row.appendChild(timestamp);
- row.appendChild(destination);
- row.appendChild(origin);
- row.appendChild(frametype);
- row.appendChild(payload);
- row.appendChild(attempt);
- row.appendChild(status);
-
- tbl.appendChild(row);
- }
-});
diff --git a/gui/src/img/icon_cube_border.png b/gui/public/icon_cube_border.png
similarity index 100%
rename from gui/src/img/icon_cube_border.png
rename to gui/public/icon_cube_border.png
diff --git a/gui_vue/setup.md b/gui/setup.md
similarity index 100%
rename from gui_vue/setup.md
rename to gui/setup.md
diff --git a/gui/sock.js b/gui/sock.js
deleted file mode 100644
index 50fbb724..00000000
--- a/gui/sock.js
+++ /dev/null
@@ -1,939 +0,0 @@
-var net = require("net");
-const path = require("path");
-const { ipcRenderer } = require("electron");
-const FD = require("./freedata");
-const log = require("electron-log");
-const socketLog = log.scope("tnc");
-//const utf8 = require("utf8");
-
-// https://stackoverflow.com/a/26227660
-var appDataFolder =
- process.env.APPDATA ||
- (process.platform == "darwin"
- ? process.env.HOME + "/Library/Application Support"
- : process.env.HOME + "/.config");
-var configFolder = path.join(appDataFolder, "FreeDATA");
-var configPath = path.join(configFolder, "config.json");
-const config = require(configPath);
-
-var client = new net.Socket();
-var socketchunk = ""; // Current message, per connection.
-
-// split character
-const split_char = "\0;\1;";
-
-// globals for getting new data only if available so we are saving bandwidth
-var rxBufferLengthTnc = 0;
-var rxBufferLengthGui = 0;
-//var rxMsgBufferLengthTnc = 0;
-//var rxMsgBufferLengthGui = 0;
-
-// global to keep track of TNC connection error emissions
-var tncShowConnectStateError = 1;
-
-// global for storing ip information
-var tnc_port = config.tnc_port;
-var tnc_host = config.tnc_host;
-
-// network connection Timeout
-setTimeout(connectTNC, 2000);
-
-function connectTNC() {
- //exports.connectTNC = function(){
- //socketLog.info('connecting to TNC...')
-
- //clear message buffer after reconnecting or initial connection
- socketchunk = "";
-
- if (config.tnclocation == "localhost") {
- client.connect(3000, "127.0.0.1");
- } else {
- client.connect(tnc_port, tnc_host);
- }
-}
-
-client.on("connect", function (data) {
- socketLog.info("TNC connection established");
- let Data = {
- busy_state: "-",
- arq_state: "-",
- //channel_state: "-",
- frequency: "-",
- mode: "-",
- bandwidth: "-",
- dbfs_level: 0,
- };
- ipcRenderer.send("request-update-tnc-state", Data);
-
- // also update tnc connection state
- ipcRenderer.send("request-update-tnc-connection", {
- tnc_connection: client.readyState,
- });
-
- tncShowConnectStateError = 1;
-});
-
-client.on("error", function (data) {
- if (tncShowConnectStateError == 1) {
- socketLog.error("TNC connection error");
- tncShowConnectStateError = 0;
- }
- setTimeout(connectTNC, 500);
- client.destroy();
- let Data = {
- tnc_connection: client.readyState,
- busy_state: "-",
- arq_state: "-",
- //channel_state: "-",
- frequency: "-",
- mode: "-",
- bandwidth: "-",
- dbfs_level: 0,
- };
- ipcRenderer.send("request-update-tnc-state", Data);
- ipcRenderer.send("request-update-tnc-connection", {
- tnc_connection: client.readyState,
- });
-});
-
-/*
-client.on('close', function(data) {
- socketLog.info(' TNC connection closed');
- setTimeout(connectTNC, 2000)
-});
-*/
-
-client.on("end", function (data) {
- socketLog.info("TNC connection ended");
- ipcRenderer.send("request-update-tnc-connection", {
- tnc_connection: client.readyState,
- });
- client.destroy();
-
- setTimeout(connectTNC, 500);
-});
-
-writeTncCommand = function (command) {
- //socketLog.info(command)
- // we use the writingCommand function to update our TCPIP state because we are calling this function a lot
- // if socket opened, we are able to run commands
-
- if (client.readyState == "open") {
- client.write(command + "\n");
- }
-
- if (client.readyState == "closed") {
- socketLog.info("CLOSED!");
- }
-
- if (client.readyState == "opening") {
- socketLog.info("connecting to TNC...");
- }
-};
-
-client.on("data", function (socketdata) {
- ipcRenderer.send("request-update-tnc-connection", {
- tnc_connection: client.readyState,
- });
-
- /*
- inspired by:
- stackoverflow.com questions 9070700 nodejs-net-createserver-large-amount-of-data-coming-in
- */
-
- socketdata = socketdata.toString("utf8"); // convert data to string
- socketchunk += socketdata; // append data to buffer so we can stick long data together
-
- // check if we received begin and end of json data
- if (socketchunk.startsWith('{"') && socketchunk.endsWith('"}\n')) {
- var data = "";
-
- // split data into chunks if we received multiple commands
- socketchunk = socketchunk.split("\n");
- //don't think this is needed anymore
- //data = JSON.parse(socketchunk[0])
-
- // search for empty entries in socketchunk and remove them
- for (i = 0; i < socketchunk.length; i++) {
- if (socketchunk[i] === "") {
- socketchunk.splice(i, 1);
- }
- }
-
- //iterate through socketchunks array to execute multiple commands in row
- for (i = 0; i < socketchunk.length; i++) {
- //check if data is not empty
- if (socketchunk[i].length > 0) {
- //try to parse JSON
- try {
- data = JSON.parse(socketchunk[i]);
- } catch (e) {
- socketLog.info("Throwing away data!!!!\n" + e); // "SyntaxError
- //socketLog.info(e); // "SyntaxError
- socketLog.info(socketchunk[i]);
- socketchunk = "";
- //If we're here, I don't think we want to process any data that may be in data variable
- continue;
- }
- }
-
- if (data["command"] == "tnc_state") {
- //socketLog.info(data)
- // set length of RX Buffer to global variable
- rxBufferLengthTnc = data["rx_buffer_length"];
- //rxMsgBufferLengthTnc = data["rx_msg_buffer_length"];
-
- let Data = {
- mycallsign: data["mycallsign"],
- mygrid: data["mygrid"],
- ptt_state: data["ptt_state"],
- busy_state: data["tnc_state"],
- arq_state: data["arq_state"],
- arq_session: data["arq_session"],
- //channel_state: data['CHANNEL_STATE'],
- frequency: data["frequency"],
- speed_level: data["speed_level"],
- mode: data["mode"],
- bandwidth: data["bandwidth"],
- dbfs_level: data["audio_dbfs"],
- fft: data["fft"],
- channel_busy: data["channel_busy"],
- channel_busy_slot: data["channel_busy_slot"],
- scatter: data["scatter"],
- info: data["info"],
- rx_buffer_length: data["rx_buffer_length"],
- rx_msg_buffer_length: data["rx_msg_buffer_length"],
- tx_n_max_retries: data["tx_n_max_retries"],
- arq_tx_n_frames_per_burst: data["arq_tx_n_frames_per_burst"],
- arq_tx_n_bursts: data["arq_tx_n_bursts"],
- arq_tx_n_current_arq_frame: data["arq_tx_n_current_arq_frame"],
- arq_tx_n_total_arq_frames: data["arq_tx_n_total_arq_frames"],
- arq_rx_frame_n_bursts: data["arq_rx_frame_n_bursts"],
- arq_rx_n_current_arq_frame: data["arq_rx_n_current_arq_frame"],
- arq_n_arq_frames_per_data_frame:
- data["arq_n_arq_frames_per_data_frame"],
- arq_bytes_per_minute: data["arq_bytes_per_minute"],
- arq_seconds_until_finish: data["arq_seconds_until_finish"],
- arq_compression_factor: data["arq_compression_factor"],
- total_bytes: data["total_bytes"],
- arq_transmission_percent: data["arq_transmission_percent"],
- stations: data["stations"],
- routing_table: data["routing_table"],
- mesh_signalling_table: data["mesh_signalling_table"],
- beacon_state: data["beacon_state"],
- hamlib_status: data["hamlib_status"],
- listen: data["listen"],
- audio_recording: data["audio_recording"],
- speed_list: data["speed_list"],
- strength: data["strength"],
- is_codec2_traffic: data["is_codec2_traffic"],
- //speed_table: [{"bpm" : 5200, "snr": -3, "timestamp":1673555399},{"bpm" : 2315, "snr": 12, "timestamp":1673555500}],
- };
-
- ipcRenderer.send("request-update-tnc-state", Data);
- //continue to next for loop iteration, nothing else needs to be done here
- continue;
- }
-
- // ----------- catch tnc messages START -----------
- if (data["freedata"] == "tnc-message") {
- switch (data["fec"]) {
- case "is_writing":
- // RX'd FECiswriting
- ipcRenderer.send("request-show-fec-toast-iswriting", {
- data: [data],
- });
- break;
-
- case "broadcast":
- // RX'd FEC BROADCAST
- var encoded_data = FD.atob_FD(data["data"]);
- var splitted_data = encoded_data.split(split_char);
- var messageArray = [];
- if (splitted_data[0] == "m") {
- messageArray.push(data);
- console.log(data);
- }
-
- let Messages = {
- data: messageArray,
- };
- ipcRenderer.send("request-new-msg-received", Messages);
- break;
- }
-
- switch (data["cq"]) {
- case "transmitting":
- // CQ TRANSMITTING
- ipcRenderer.send("request-show-cq-toast-transmitting", {
- data: [data],
- });
- break;
-
- case "received":
- // CQ RECEIVED
- ipcRenderer.send("request-show-cq-toast-received", {
- data: [data],
- });
- break;
- }
-
- switch (data["qrv"]) {
- case "transmitting":
- // QRV TRANSMITTING
- ipcRenderer.send("request-show-qrv-toast-transmitting", {
- data: [data],
- });
- break;
-
- case "received":
- // QRV RECEIVED
- ipcRenderer.send("request-show-qrv-toast-received", {
- data: [data],
- });
- break;
- }
-
- switch (data["beacon"]) {
- case "transmitting":
- // BEACON TRANSMITTING
- ipcRenderer.send("request-show-beacon-toast-transmitting", {
- data: [data],
- });
- break;
-
- case "received":
- // BEACON RECEIVED
- ipcRenderer.send("request-show-beacon-toast-received", {
- data: [data],
- });
- ipcRenderer.send("request-new-msg-received", { data: [data] });
- break;
- }
-
- switch (data["ping"]) {
- case "transmitting":
- // PING TRANSMITTING
- ipcRenderer.send("request-show-ping-toast-transmitting", {
- data: [data],
- });
- break;
-
- case "received":
- // PING RECEIVED
- ipcRenderer.send("request-show-ping-toast-received", {
- data: [data],
- });
- ipcRenderer.send("request-new-msg-received", { data: [data] });
- break;
-
- case "acknowledge":
- // PING ACKNOWLEDGE
- ipcRenderer.send("request-show-ping-toast-received-ack", {
- data: [data],
- });
- ipcRenderer.send("request-new-msg-received", { data: [data] });
- break;
- }
-
- // ARQ SESSION && freedata == tnc-message
- if (data["arq"] == "session") {
- switch (data["status"]) {
- case "connecting":
- // ARQ Open
- ipcRenderer.send("request-show-arq-toast-session-connecting", {
- data: [data],
- });
- break;
-
- case "connected":
- // ARQ Opening
- ipcRenderer.send("request-show-arq-toast-session-connected", {
- data: [data],
- });
- break;
-
- case "waiting":
- // ARQ Opening
- ipcRenderer.send("request-show-arq-toast-session-waiting", {
- data: [data],
- });
- break;
-
- case "close":
- // ARQ Closing
- ipcRenderer.send("request-show-arq-toast-session-close", {
- data: [data],
- });
- break;
-
- case "failed":
- // ARQ Failed
- ipcRenderer.send("request-show-arq-toast-session-failed", {
- data: [data],
- });
- break;
- }
- }
- // ARQ TRANSMISSION && freedata == tnc-message
- if (data["arq"] == "transmission") {
- switch (data["status"]) {
- case "opened":
- // ARQ Open
- ipcRenderer.send("request-show-arq-toast-datachannel-opened", {
- data: [data],
- });
- break;
-
- case "opening":
- // ARQ Opening IRS/ISS
- if (data["irs"] == "False") {
- ipcRenderer.send("request-show-arq-toast-datachannel-opening", {
- data: [data],
- });
- ipcRenderer.send("request-update-transmission-status", {
- data: [data],
- });
- } else {
- ipcRenderer.send(
- "request-show-arq-toast-datachannel-received-opener",
- { data: [data] },
- );
- ipcRenderer.send("request-update-reception-status", {
- data: [data],
- });
- }
-
- break;
-
- case "waiting":
- // ARQ waiting
- ipcRenderer.send("request-show-arq-toast-datachannel-waiting", {
- data: [data],
- });
- break;
-
- case "receiving":
- // ARQ RX
- ipcRenderer.send("request-update-reception-status", {
- data: [data],
- });
- break;
-
- case "failed":
- // ARQ TX Failed
- if (data["reason"] == "protocol version missmatch") {
- ipcRenderer.send(
- "request-show-arq-toast-transmission-failed-ver",
- { data: [data] },
- );
- } else {
- ipcRenderer.send("request-show-arq-toast-transmission-failed", {
- data: [data],
- });
- }
- switch (data["irs"]) {
- case "True":
- ipcRenderer.send("request-update-reception-status", {
- data: [data],
- });
- break;
- default:
- ipcRenderer.send("request-update-transmission-status", {
- data: [data],
- });
- break;
- }
- break;
-
- case "received":
- // ARQ Received
- ipcRenderer.send("request-show-arq-toast-transmission-received", {
- data: [data],
- });
-
- ipcRenderer.send("request-update-reception-status", {
- data: [data],
- });
-
- dataArray = [];
- messageArray = [];
-
- socketLog.info(data);
- // we need to encode here to do a deep check for checking if file or message
- //var encoded_data = atob(data['data'])
- var encoded_data = FD.atob_FD(data["data"]);
- var splitted_data = encoded_data.split(split_char);
-
- if (splitted_data[0] == "f") {
- dataArray.push(data);
- }
-
- if (splitted_data[0] == "m") {
- messageArray.push(data);
- console.log(data);
- }
-
- rxBufferLengthGui = dataArray.length;
- let Files = {
- data: dataArray,
- };
- ipcRenderer.send("request-update-rx-buffer", Files);
- ipcRenderer.send("request-new-msg-received", Files);
-
- //rxMsgBufferLengthGui = messageArray.length;
- let Messages = {
- data: messageArray,
- };
- ipcRenderer.send("request-new-msg-received", Messages);
- break;
-
- case "transmitting":
- // ARQ transmitting
- ipcRenderer.send(
- "request-show-arq-toast-transmission-transmitting",
- { data: [data] },
- );
- ipcRenderer.send("request-update-transmission-status", {
- data: [data],
- });
- break;
-
- case "transmitted":
- // ARQ transmitted
- ipcRenderer.send(
- "request-show-arq-toast-transmission-transmitted",
- { data: [data] },
- );
- ipcRenderer.send("request-update-transmission-status", {
- data: [data],
- });
- break;
- }
- }
- }
-
- // ----------- catch tnc info messages END -----------
-
- // if we manually checking for the rx buffer we are getting an array of multiple data
- if (data["command"] == "rx_buffer") {
- socketLog.info(data);
- // iterate through buffer list and sort it to file or message array
- dataArray = [];
- messageArray = [];
-
- for (i = 0; i < data["data-array"].length; i++) {
- try {
- // we need to encode here to do a deep check for checking if file or message
- //var encoded_data = atob(data['data-array'][i]['data'])
- var encoded_data = FD.atob_FD(data["data-array"][i]["data"]);
- var splitted_data = encoded_data.split(split_char);
-
- if (splitted_data[0] == "f") {
- dataArray.push(data["data-array"][i]);
- }
-
- if (splitted_data[0] == "m") {
- messageArray.push(data["data-array"][i]);
- }
- } catch (e) {
- socketLog.info(e);
- }
- }
-
- rxBufferLengthGui = dataArray.length;
- let Files = {
- data: dataArray,
- };
- ipcRenderer.send("request-update-rx-buffer", Files);
-
- //rxMsgBufferLengthGui = messageArray.length;
- let Messages = {
- data: messageArray,
- };
- //ipcRenderer.send('request-update-rx-msg-buffer', Messages);
- ipcRenderer.send("request-new-msg-received", Messages);
- }
- }
-
- //finally delete message buffer
- socketchunk = "";
- }
-});
-
-function hexToBytes(hex) {
- for (var bytes = [], c = 0; c < hex.length; c += 2)
- bytes.push(parseInt(hex.substr(c, 2), 16));
- return bytes;
-}
-
-//Get TNC State
-exports.getTncState = function () {
- command = '{"type" : "get", "command" : "tnc_state"}';
- writeTncCommand(command);
-};
-
-//Get DATA State
-exports.getDataState = function () {
- command = '{"type" : "get", "command" : "data_state"}';
- //writeTncCommand(command)
-};
-
-// Send Ping
-exports.sendPing = function (dxcallsign) {
- command =
- '{"type" : "ping", "command" : "ping", "dxcallsign" : "' +
- dxcallsign +
- '"}';
- writeTncCommand(command);
-};
-
-// Send Mesh Ping
-exports.sendMeshPing = function (dxcallsign) {
- command =
- '{"type" : "mesh", "command" : "ping", "dxcallsign" : "' +
- dxcallsign +
- '"}';
- writeTncCommand(command);
-};
-
-// Send CQ
-exports.sendCQ = function () {
- command = '{"type" : "broadcast", "command" : "cqcqcq"}';
- writeTncCommand(command);
-};
-
-// Set AUDIO Level
-exports.setTxAudioLevel = function (value) {
- command =
- '{"type" : "set", "command" : "tx_audio_level", "value" : "' + value + '"}';
- writeTncCommand(command);
-};
-
-// Send File
-exports.sendFile = function (
- dxcallsign,
- mode,
- frames,
- filename,
- filetype,
- data,
- checksum,
-) {
- socketLog.info(data);
- socketLog.info(filetype);
- socketLog.info(filename);
-
- var datatype = "f";
-
- data =
- datatype +
- split_char +
- filename +
- split_char +
- filetype +
- split_char +
- checksum +
- split_char +
- data;
- socketLog.info(data);
- //socketLog.info(btoa(data))
- //Btoa / atob will not work with charsets > 8 bits (i.e. the emojis); should probably move away from using it
- //TODO: Will need to update anyother occurences and throughly test
- //data = btoa(data)
- data = FD.btoa_FD(data);
-
- command =
- '{"type" : "arq", "command" : "send_raw", "parameter" : [{"dxcallsign" : "' +
- dxcallsign +
- '", "mode" : "' +
- mode +
- '", "n_frames" : "' +
- frames +
- '", "data" : "' +
- data +
- '"}]}';
- writeTncCommand(command);
-};
-
-// Send Message
-exports.sendMessage = function (
- dxcallsign,
- mode,
- frames,
- data,
- checksum,
- uuid,
- command,
-) {
- data = FD.btoa_FD(
- "m" +
- split_char +
- command +
- split_char +
- checksum +
- split_char +
- uuid +
- split_char +
- data,
- );
- command =
- '{"type" : "arq", "command" : "send_raw", "uuid" : "' +
- uuid +
- '", "parameter" : [{"dxcallsign" : "' +
- dxcallsign +
- '", "mode" : "' +
- mode +
- '", "n_frames" : "' +
- frames +
- '", "data" : "' +
- data +
- '", "attempts": "10"}]}';
- socketLog.info(command);
- socketLog.info("-------------------------------------");
- writeTncCommand(command);
-};
-
-// Send Request message
-//It would be then „m + split + request + split + request-type“
-function sendRequest(dxcallsign, mode, frames, data, command) {
- data = FD.btoa_FD("m" + split_char + command + split_char + data);
- command =
- '{"type" : "arq", "command" : "send_raw", "parameter" : [{"dxcallsign" : "' +
- dxcallsign +
- '", "mode" : "' +
- mode +
- '", "n_frames" : "' +
- frames +
- '", "data" : "' +
- data +
- '", "attempts": "10"}]}';
- socketLog.info(command);
- socketLog.info("--------------REQ--------------------");
- writeTncCommand(command);
-}
-
-// Send Response message
-//It would be then „m + split + request + split + request-type“
-function sendResponse(dxcallsign, mode, frames, data, command) {
- data = FD.btoa_FD("m" + split_char + command + split_char + data);
- command =
- '{"type" : "arq", "command" : "send_raw", "parameter" : [{"dxcallsign" : "' +
- dxcallsign +
- '", "mode" : "' +
- mode +
- '", "n_frames" : "' +
- frames +
- '", "data" : "' +
- data +
- '", "attempts": "10"}]}';
- socketLog.info(command);
- socketLog.info("--------------RES--------------------");
- writeTncCommand(command);
-}
-
-//Send station info request
-exports.sendRequestInfo = function (dxcallsign) {
- //Command 0 = user/station information
- //Command 1 = shared folder list
- //Command 2 = shared file transfer
- sendRequest(dxcallsign, 255, 1, "0", "req");
-};
-
-//Send shared folder file list request
-exports.sendRequestSharedFolderList = function (dxcallsign) {
- //Command 0 = user/station information
- //Command 1 = shared folder list
- //Command 2 = shared file transfer
- sendRequest(dxcallsign, 255, 1, "1", "req");
-};
-
-//Send shared file request
-exports.sendRequestSharedFile = function (dxcallsign, file) {
- //Command 0 = user/station information
- //Command 1 = shared folder list
- //Command 2 = shared file transfer
- sendRequest(dxcallsign, 255, 1, "2" + file, "req");
-};
-
-//Send station info response
-exports.sendResponseInfo = function (dxcallsign, userinfo) {
- //Command 0 = user/station information
- //Command 1 = shared folder list
- //Command 2 = shared file transfer
- sendResponse(dxcallsign, 255, 1, userinfo, "res-0");
-};
-
-//Send shared folder response
-exports.sendResponseSharedFolderList = function (dxcallsign, sharedFolderList) {
- //Command 0 = user/station information
- //Command 1 = shared folder list
- //Command 2 = shared file transfer
- sendResponse(dxcallsign, 255, 1, sharedFolderList, "res-1");
-};
-
-//Send shared file response
-exports.sendResponseSharedFile = function (
- dxcallsign,
- sharedFile,
- sharedFileData,
-) {
- console.log(
- "In sendResponseSharedFile",
- dxcallsign,
- sharedFile,
- sharedFileData,
- );
- //Command 0 = user/station information
- //Command 1 = shared folder list
- //Command 2 = shared file transfer
- sendResponse(dxcallsign, 255, 1, sharedFile + "/" + sharedFileData, "res-2");
-};
-
-//STOP TRANSMISSION
-exports.stopTransmission = function () {
- command = '{"type" : "arq", "command": "stop_transmission"}';
- writeTncCommand(command);
-};
-
-// Get RX BUffer
-exports.getRxBuffer = function () {
- command = '{"type" : "get", "command" : "rx_buffer"}';
-
- // call command only if new data arrived
- if (rxBufferLengthGui != rxBufferLengthTnc) {
- writeTncCommand(command);
- }
-};
-
-// START BEACON
-exports.startBeacon = function (interval) {
- command =
- '{"type" : "broadcast", "command" : "start_beacon", "parameter": "' +
- interval +
- '"}';
- writeTncCommand(command);
-};
-
-// STOP BEACON
-exports.stopBeacon = function () {
- command = '{"type" : "broadcast", "command" : "stop_beacon"}';
- writeTncCommand(command);
-};
-
-// OPEN ARQ SESSION
-exports.connectARQ = function (dxcallsign) {
- command =
- '{"type" : "arq", "command" : "connect", "dxcallsign": "' +
- dxcallsign +
- '", "attempts": "10"}';
- writeTncCommand(command);
-};
-
-// CLOSE ARQ SESSION
-exports.disconnectARQ = function () {
- command = '{"type" : "arq", "command" : "disconnect"}';
- writeTncCommand(command);
-};
-
-// SEND TEST FRAME
-exports.sendTestFrame = function () {
- command = '{"type" : "set", "command" : "send_test_frame"}';
- writeTncCommand(command);
-};
-
-// SEND FEC
-exports.sendFEC = function (mode, payload) {
- command =
- '{"type" : "fec", "command" : "transmit", "mode" : "' +
- mode +
- '", "payload" : "' +
- payload +
- '"}';
- writeTncCommand(command);
-};
-
-// SEND FEC IS WRITING
-exports.sendFecIsWriting = function (mycallsign) {
- command =
- '{"type" : "fec", "command" : "transmit_is_writing", "mycallsign" : "' +
- mycallsign +
- '"}';
- writeTncCommand(command);
-};
-
-// SEND FEC TO BROADCASTCHANNEL
-exports.sendBroadcastChannel = function (channel, data_out, uuid) {
- let checksum = "";
- let command = "";
- let data = FD.btoa_FD(
- "m" +
- split_char +
- channel +
- //split_char +
- //checksum +
- split_char +
- uuid +
- split_char +
- data_out,
- );
- console.log(data.length);
- let payload = data;
- command =
- '{"type" : "fec", "command" : "transmit", "mode": "datac4", "wakeup": "True", "payload" : "' +
- payload +
- '"}';
- writeTncCommand(command);
-};
-
-// RECORD AUDIO
-exports.record_audio = function () {
- command = '{"type" : "set", "command" : "record_audio"}';
- writeTncCommand(command);
-};
-
-// SET FREQUENCY
-exports.set_frequency = function (frequency) {
- command =
- '{"type" : "set", "command" : "frequency", "frequency": ' + frequency + "}";
- writeTncCommand(command);
-};
-
-// SET MODE
-exports.set_mode = function (mode) {
- command = '{"type" : "set", "command" : "mode", "mode": "' + mode + '"}';
- console.log(command);
- writeTncCommand(command);
-};
-
-ipcRenderer.on("action-update-tnc-ip", (event, arg) => {
- client.destroy();
- let Data = {
- busy_state: "-",
- arq_state: "-",
- //channel_state: "-",
- frequency: "-",
- mode: "-",
- bandwidth: "-",
- dbfs_level: 0,
- };
- ipcRenderer.send("request-update-tnc-state", Data);
- tnc_port = arg.port;
- tnc_host = arg.adress;
- connectTNC();
-});
-
-// https://stackoverflow.com/a/50579690
-// crc32 calculation
-//console.log(crc32('abc'));
-//console.log(crc32('abc').toString(16).toUpperCase()); // hex
-var crc32 = function (r) {
- for (var a, o = [], c = 0; c < 256; c++) {
- a = c;
- for (var f = 0; f < 8; f++) a = 1 & a ? 3988292384 ^ (a >>> 1) : a >>> 1;
- o[c] = a;
- }
- for (var n = -1, t = 0; t < r.length; t++)
- n = (n >>> 8) ^ o[255 & (n ^ r.charCodeAt(t))];
- return (-1 ^ n) >>> 0;
-};
diff --git a/gui_vue/src/App.vue b/gui/src/App.vue
similarity index 100%
rename from gui_vue/src/App.vue
rename to gui/src/App.vue
diff --git a/gui/src/waterfall/LICENSE b/gui/src/assets/waterfall/LICENSE
similarity index 100%
rename from gui/src/waterfall/LICENSE
rename to gui/src/assets/waterfall/LICENSE
diff --git a/gui/src/waterfall/README.rst b/gui/src/assets/waterfall/README.rst
similarity index 100%
rename from gui/src/waterfall/README.rst
rename to gui/src/assets/waterfall/README.rst
diff --git a/gui/src/waterfall/colormap.js b/gui/src/assets/waterfall/colormap.js
similarity index 100%
rename from gui/src/waterfall/colormap.js
rename to gui/src/assets/waterfall/colormap.js
diff --git a/gui/src/waterfall/index.html b/gui/src/assets/waterfall/index.html
similarity index 100%
rename from gui/src/waterfall/index.html
rename to gui/src/assets/waterfall/index.html
diff --git a/gui/src/waterfall/make_colormap.py b/gui/src/assets/waterfall/make_colormap.py
similarity index 100%
rename from gui/src/waterfall/make_colormap.py
rename to gui/src/assets/waterfall/make_colormap.py
diff --git a/gui/src/waterfall/script.js b/gui/src/assets/waterfall/script.js
similarity index 100%
rename from gui/src/waterfall/script.js
rename to gui/src/assets/waterfall/script.js
diff --git a/gui/src/waterfall/server.py b/gui/src/assets/waterfall/server.py
similarity index 100%
rename from gui/src/waterfall/server.py
rename to gui/src/assets/waterfall/server.py
diff --git a/gui_vue/src/assets/waterfall/spectrum.js b/gui/src/assets/waterfall/spectrum.js
similarity index 100%
rename from gui_vue/src/assets/waterfall/spectrum.js
rename to gui/src/assets/waterfall/spectrum.js
diff --git a/gui/src/waterfall/waterfall.css b/gui/src/assets/waterfall/waterfall.css
similarity index 100%
rename from gui/src/waterfall/waterfall.css
rename to gui/src/assets/waterfall/waterfall.css
diff --git a/gui_vue/src/components/chat.vue b/gui/src/components/chat.vue
similarity index 100%
rename from gui_vue/src/components/chat.vue
rename to gui/src/components/chat.vue
diff --git a/gui_vue/src/components/chat_conversations.vue b/gui/src/components/chat_conversations.vue
similarity index 100%
rename from gui_vue/src/components/chat_conversations.vue
rename to gui/src/components/chat_conversations.vue
diff --git a/gui_vue/src/components/chat_messages.vue b/gui/src/components/chat_messages.vue
similarity index 100%
rename from gui_vue/src/components/chat_messages.vue
rename to gui/src/components/chat_messages.vue
diff --git a/gui_vue/src/components/chat_messages_action_menu.vue b/gui/src/components/chat_messages_action_menu.vue
similarity index 100%
rename from gui_vue/src/components/chat_messages_action_menu.vue
rename to gui/src/components/chat_messages_action_menu.vue
diff --git a/gui_vue/src/components/chat_messages_broadcast_received.vue b/gui/src/components/chat_messages_broadcast_received.vue
similarity index 100%
rename from gui_vue/src/components/chat_messages_broadcast_received.vue
rename to gui/src/components/chat_messages_broadcast_received.vue
diff --git a/gui_vue/src/components/chat_messages_broadcast_sent.vue b/gui/src/components/chat_messages_broadcast_sent.vue
similarity index 100%
rename from gui_vue/src/components/chat_messages_broadcast_sent.vue
rename to gui/src/components/chat_messages_broadcast_sent.vue
diff --git a/gui_vue/src/components/chat_messages_received.vue b/gui/src/components/chat_messages_received.vue
similarity index 100%
rename from gui_vue/src/components/chat_messages_received.vue
rename to gui/src/components/chat_messages_received.vue
diff --git a/gui_vue/src/components/chat_messages_sent.vue b/gui/src/components/chat_messages_sent.vue
similarity index 100%
rename from gui_vue/src/components/chat_messages_sent.vue
rename to gui/src/components/chat_messages_sent.vue
diff --git a/gui_vue/src/components/chat_navbar.vue b/gui/src/components/chat_navbar.vue
similarity index 100%
rename from gui_vue/src/components/chat_navbar.vue
rename to gui/src/components/chat_navbar.vue
diff --git a/gui_vue/src/components/chat_new_message.vue b/gui/src/components/chat_new_message.vue
similarity index 100%
rename from gui_vue/src/components/chat_new_message.vue
rename to gui/src/components/chat_new_message.vue
diff --git a/gui_vue/src/components/main.vue b/gui/src/components/main.vue
similarity index 100%
rename from gui_vue/src/components/main.vue
rename to gui/src/components/main.vue
diff --git a/gui_vue/src/components/main_active_audio_level.vue b/gui/src/components/main_active_audio_level.vue
similarity index 100%
rename from gui_vue/src/components/main_active_audio_level.vue
rename to gui/src/components/main_active_audio_level.vue
diff --git a/gui_vue/src/components/main_active_broadcasts.vue b/gui/src/components/main_active_broadcasts.vue
similarity index 100%
rename from gui_vue/src/components/main_active_broadcasts.vue
rename to gui/src/components/main_active_broadcasts.vue
diff --git a/gui_vue/src/components/main_active_heard_stations.vue b/gui/src/components/main_active_heard_stations.vue
similarity index 100%
rename from gui_vue/src/components/main_active_heard_stations.vue
rename to gui/src/components/main_active_heard_stations.vue
diff --git a/gui_vue/src/components/main_active_rig_control.vue b/gui/src/components/main_active_rig_control.vue
similarity index 100%
rename from gui_vue/src/components/main_active_rig_control.vue
rename to gui/src/components/main_active_rig_control.vue
diff --git a/gui_vue/src/components/main_active_stats.vue b/gui/src/components/main_active_stats.vue
similarity index 100%
rename from gui_vue/src/components/main_active_stats.vue
rename to gui/src/components/main_active_stats.vue
diff --git a/gui_vue/src/components/main_audio.vue b/gui/src/components/main_audio.vue
similarity index 100%
rename from gui_vue/src/components/main_audio.vue
rename to gui/src/components/main_audio.vue
diff --git a/gui_vue/src/components/main_footer_navbar.vue b/gui/src/components/main_footer_navbar.vue
similarity index 100%
rename from gui_vue/src/components/main_footer_navbar.vue
rename to gui/src/components/main_footer_navbar.vue
diff --git a/gui_vue/src/components/main_modals.vue b/gui/src/components/main_modals.vue
similarity index 100%
rename from gui_vue/src/components/main_modals.vue
rename to gui/src/components/main_modals.vue
diff --git a/gui_vue/src/components/main_my_station.vue b/gui/src/components/main_my_station.vue
similarity index 100%
rename from gui_vue/src/components/main_my_station.vue
rename to gui/src/components/main_my_station.vue
diff --git a/gui_vue/src/components/main_rig_control.vue b/gui/src/components/main_rig_control.vue
similarity index 100%
rename from gui_vue/src/components/main_rig_control.vue
rename to gui/src/components/main_rig_control.vue
diff --git a/gui_vue/src/components/main_top_navbar.vue b/gui/src/components/main_top_navbar.vue
similarity index 100%
rename from gui_vue/src/components/main_top_navbar.vue
rename to gui/src/components/main_top_navbar.vue
diff --git a/gui_vue/src/components/main_updater.vue b/gui/src/components/main_updater.vue
similarity index 100%
rename from gui_vue/src/components/main_updater.vue
rename to gui/src/components/main_updater.vue
diff --git a/gui_vue/src/components/settings.vue b/gui/src/components/settings.vue
similarity index 100%
rename from gui_vue/src/components/settings.vue
rename to gui/src/components/settings.vue
diff --git a/gui_vue/src/components/settings_chat.vue b/gui/src/components/settings_chat.vue
similarity index 100%
rename from gui_vue/src/components/settings_chat.vue
rename to gui/src/components/settings_chat.vue
diff --git a/gui_vue/src/components/settings_exp.vue b/gui/src/components/settings_exp.vue
similarity index 100%
rename from gui_vue/src/components/settings_exp.vue
rename to gui/src/components/settings_exp.vue
diff --git a/gui_vue/src/components/settings_gui.vue b/gui/src/components/settings_gui.vue
similarity index 100%
rename from gui_vue/src/components/settings_gui.vue
rename to gui/src/components/settings_gui.vue
diff --git a/gui_vue/src/components/settings_hamlib.vue b/gui/src/components/settings_hamlib.vue
similarity index 100%
rename from gui_vue/src/components/settings_hamlib.vue
rename to gui/src/components/settings_hamlib.vue
diff --git a/gui_vue/src/components/settings_modem.vue b/gui/src/components/settings_modem.vue
similarity index 100%
rename from gui_vue/src/components/settings_modem.vue
rename to gui/src/components/settings_modem.vue
diff --git a/gui_vue/src/components/settings_web.vue b/gui/src/components/settings_web.vue
similarity index 100%
rename from gui_vue/src/components/settings_web.vue
rename to gui/src/components/settings_web.vue
diff --git a/gui/src/hamlib-list.html b/gui/src/hamlib-list.html
deleted file mode 100644
index 50be5469..00000000
--- a/gui/src/hamlib-list.html
+++ /dev/null
@@ -1,261 +0,0 @@
-Hamlib Dummy
-Hamlib NET rigctl
-FLRig FLRig
-TRXManager TRXManager 5.7.630+
-Hamlib Dummy No VFO
-Yaesu FT-847
-Yaesu FT-1000D
-Yaesu MARK-V FT-1000MP
-Yaesu FT-747GX
-Yaesu FT-757GX
-Yaesu FT-757GXII
-Yaesu FT-767GX
-Yaesu FT-736R
-Yaesu FT-840
-Yaesu FT-900
-Yaesu FT-920
-Yaesu FT-890
-Yaesu FT-990
-Yaesu FRG-100
-Yaesu FRG-9600
-Yaesu FRG-8800
-Yaesu FT-817
-Yaesu FT-100
-Yaesu FT-857
-Yaesu FT-897
-Yaesu FT-1000MP
-Yaesu MARK-V Field FT-1000MP
-Yaesu VR-5000
-Yaesu FT-450
-Yaesu FT-950
-Yaesu FT-2000
-Yaesu FTDX-9000
-Yaesu FT-980
-Yaesu FTDX-5000
-Vertex Standard VX-1700
-Yaesu FTDX-1200
-Yaesu FT-991
-Yaesu FT-891
-Yaesu FTDX-3000
-Yaesu FT-847UNI
-Yaesu FT-600
-Yaesu FTDX-101D
-Yaesu FT-818
-Yaesu FTDX-10
-Yaesu FT-897D
-Yaesu FTDX-101MP
-Kenwood TS-50S
-Kenwood TS-440S
-Kenwood TS-450S
-Kenwood TS-570D
-Kenwood TS-690S
-Kenwood TS-711
-Kenwood TS-790
-Kenwood TS-811
-Kenwood TS-850
-Kenwood TS-870S
-Kenwood TS-940S
-Kenwood TS-950S
-Kenwood TS-950SDX
-Kenwood TS-2000
-Kenwood R-5000
-Kenwood TS-570S
-Kenwood TH-D7A
-Kenwood TH-F6A
-Kenwood TH-F7E
-Elecraft K2
-Kenwood TS-930
-Kenwood TH-G71
-Kenwood TS-680S
-Kenwood TS-140S
-Kenwood TM-D700
-Kenwood TM-V7
-Kenwood TS-480
-Elecraft K3
-Kenwood TRC-80
-Kenwood TS-590S
-SigFox Transfox
-Kenwood TH-D72A
-Kenwood TM-D710(G)
-FlexRadio 6xxx
-Kenwood TS-590SG
-Elecraft XG3
-Kenwood TS-990s
-OpenHPSDR PiHPSDR
-Kenwood TS-890S
-Kenwood TH-D74
-Elecraft K3S
-Elecraft KX2
-Elecraft KX3
-Hilberling PT-8000A
-Elecraft K4
-FlexRadio/ANAN PowerSDR/Thetis
-Malachite DSP
-Icom IC-1275
-Icom IC-271
-Icom IC-275
-Icom IC-471
-Icom IC-475
-Icom IC-706
-Icom IC-706MkII
-Icom IC-706MkIIG
-Icom IC-707
-Icom IC-718
-Icom IC-725
-Icom IC-726
-Icom IC-728
-Icom IC-729
-Icom IC-735
-Icom IC-736
-Icom IC-737
-Icom IC-738
-Icom IC-746
-Icom IC-751
-Icom IC-756
-Icom IC-756PRO
-Icom IC-761
-Icom IC-765
-Icom IC-775
-Icom IC-781
-Icom IC-820H
-Icom IC-821H
-Icom IC-970
-Icom IC-R10
-Icom IC-R71
-Icom IC-R72
-Icom IC-R75
-Icom IC-R7000
-Icom IC-R7100
-Icom ICR-8500
-Icom IC-R9000
-Icom IC-910
-Icom IC-78
-Icom IC-746PRO
-Icom IC-756PROII
-Ten-Tec Omni VI Plus
-Optoelectronics OptoScan535
-Optoelectronics OptoScan456
-Icom IC ID-1
-Icom IC-703
-Icom IC-7800
-Icom IC-756PROIII
-Icom IC-R20
-Icom IC-7000
-Icom IC-7200
-Icom IC-7700
-Icom IC-7600
-Ten-Tec Delta II
-Icom IC-92D
-Icom IC-R9500
-Icom IC-7410
-Icom IC-9100
-Icom IC-RX7
-Icom IC-7100
-Icom ID-5100
-Icom IC-2730
-Icom IC-7300
-Microtelecom Perseus
-Icom IC-785x
-Xeigu X108G
-Icom IC-R6
-Icom IC-7610
-Icom IC-R8600
-Icom IC-R30
-Icom IC-9700
-Icom ID-4100
-Icom ID-31
-Icom ID-51
-Icom IC-705
-Icom IC-PCR1000
-Icom IC-PCR100
-Icom IC-PCR1500
-Icom IC-PCR2500
-AOR AR8200
-AOR AR8000
-AOR AR7030
-AOR AR5000
-AOR AR3030
-AOR AR3000A
-AOR AR2700
-AOR AR8600
-AOR AR5000A
-AOR AR7030 Plus
-AOR SR2200
-JRC NRD-525
-JRC NRD-535D
-JRC NRD-545 DSP
-Uniden BC780xlt
-Uniden BC245xlt
-Uniden BC895xlt
-Radio Shack PRO-2052
-Uniden BC250D
-Uniden BCD-396T
-Uniden BCD-996T
-Uniden BC898T
-Drake R-8A
-Drake R-8B
-Lowe HF-235
-Racal RA6790/GM
-Racal RA3702
-Watkins-Johnson WJ-8888
-Skanti TRP8000
-Skanti TRP 8255 S R
-Winradio WR-1000
-Winradio WR-1500
-Winradio WR-1550
-Winradio WR-3100
-Winradio WR-3150
-Winradio WR-3500
-Winradio WR-3700
-Winradio WR-G313
-Ten-Tec TT-550
-Ten-Tec TT-538 Jupiter
-Ten-Tec RX-320
-Ten-Tec RX-340
-Ten-Tec RX-350
-Ten-Tec TT-516 Argonaut V
-Ten-Tec TT-565 Orion
-Ten-Tec TT-585 Paragon
-Ten-Tec TT-588 Omni VII
-Ten-Tec RX-331
-Ten-Tec TT-599 Eagle
-Alinco DX-77
-Alinco DX-SR8
-Kachina 505DSP
-TAPR DSP-10
-Flex-radio SDR-1000
-DTTS Microwave Society DttSP IPC
-DTTS Microwave Society DttSP UDP
-RFT EKD-500
-Elektor Elektor 3/04
-SAT-Schneider DRT1
-Coding Technologies Digital World Traveller
-AmQRP DDS-60
-Elektor Elektor SDR-USB
-mRS miniVNA
-SoftRock Si570 AVR-USB
-KTH-SDR kit Si570 PIC-USB
-FiFi FiFi-SDR
-AMSAT-UK FUNcube Dongle
-N2ADR HiQSDR
-Funkamateur FA-SDR
-AE9RB Si570 Peaberry V1
-AE9RB Si570 Peaberry V2
-AMSAT-UK FUNcube Dongle Pro+
-HobbyPCB RS-HFIQ
-Video4Linux SW/FM radio
-Video4Linux2 SW/FM radio
-Rohde&Schwarz ESMC
-Rohde&Schwarz EB200
-Rohde&Schwarz XK2100
-Philips/Simoco PRM8060
-ADAT www.adat.ch ADT-200A
-Icom IC-M700PRO
-Icom IC-M802
-Icom IC-M710
-Icom IC-M803
-Dorji DRA818V
-Dorji DRA818U
-Barrett 2050
-Barrett 950
-ELAD FDM-DUO
diff --git a/gui/src/img/favicon.png b/gui/src/img/favicon.png
deleted file mode 100644
index c6b23789..00000000
Binary files a/gui/src/img/favicon.png and /dev/null differ
diff --git a/gui/src/img/icon.png b/gui/src/img/icon.png
deleted file mode 100644
index 2e346c91..00000000
Binary files a/gui/src/img/icon.png and /dev/null differ
diff --git a/gui/src/index.html b/gui/src/index.html
deleted file mode 100644
index c4a9d050..00000000
--- a/gui/src/index.html
+++ /dev/null
@@ -1,4946 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- FreeDATA by DJ2LS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Start tnc
-
-
-
- Stop tnc
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TNC will not utilize rig control and features will be
- limited. While functional; it is recommended to configure
- hamlib.
-
-
-
-
-
-
-
-
-
- VOX: Use rig control mode 'none'
-
- HAMLIB locally: configure in settings, then
- start/stop service.
-
- HAMLIB remotely: Enter IP/Port, connection
- happens automatically.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ...
-
-
- ...
-
-
- Changelog
-
-
- Install & Restart
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- dBFS (Audio Level)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ping
-
-
-
-
- Call CQ
-
-
-
- Toggle beacon
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Time
-
- Frequency
-
- DXCall
- DXGrid
- Distance
- Type
- SNR (rx/dx)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Routes
-
-
- Signaling
-
-
- Actions
-
-
-
-
-
-
-
-
-
-
-
- Timestamp
- DXCall
- Router
- Hops
- Score
- SNR
-
-
-
-
-
-
-
-
-
-
-
-
-
- Timestamp
- Destination
- Origin
- Frametype
- Payload
- Attempt
- Status
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
FreeDATA -
-
-
-
-
-
Special thanks to
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ping
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Save & Close
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
- ( )
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Request user data (about 20kBytes!)
-
-
-
- Close
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Please restart the TNC
- after changing settings!
-
-
-
-
-
-
-
-
-
-
-
- GUI
-
-
-
-
- Chat
-
-
-
-
- Hamlib
-
-
-
-
- TNC
-
-
-
-
- Web
-
-
-
-
- Exp
-
-
-
-
-
-
-
-
- GUI theme
-
- Default (light)
- Default (dark)
- Default (auto)
- Cerulean
- Cosmo
- Cyborg
- Darkly
- Flatly
- Journal
- Litera
- Lumen
- Lux
- Materia
- Minty
- Morhp
- Pulse
- Quartz
- Sandstone
- Simplex
- Sketchy
- Slate
- Solar
- Spacelab
- Superhero
- United
- Vapor
- Yeti
- Zephyr
-
-
-
- Waterfall theme
-
- Default
- Turbo
- Fosphor
- Inferno
- Magma
- Jet
- Binary
-
-
-
-
- Received files folder
-
-
-
- Update channel
-
- stable
- beta
- alpha
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Shared folder path
-
-
-
-
-
-
- message retry attempts
-
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-
-
-
-
-
-
-
-
- Rigctld path
-
-
-
- Rigctld server port
-
-
-
-
-
- Radio model
-
-
-
- -- ignore --
- Kenwood TS480
- Hamlib Dummy
- Hamlib NET rigctl
- FLRig FLRig
- TRXManager TRXManager 5.7.630+
- Hamlib Dummy No VFO
- Yaesu FT-847
- Yaesu FT-1000D
- Yaesu MARK-V FT-1000MP
- Yaesu FT-747GX
- Yaesu FT-757GX
- Yaesu FT-757GXII
- Yaesu FT-767GX
- Yaesu FT-736R
- Yaesu FT-840
- Yaesu FT-900
- Yaesu FT-920
- Yaesu FT-890
- Yaesu FT-990
- Yaesu FRG-100
- Yaesu FRG-9600
- Yaesu FRG-8800
- Yaesu FT-817
- Yaesu FT-100
- Yaesu FT-857
- Yaesu FT-897
- Yaesu FT-1000MP
- Yaesu MARK-V Field FT-1000MP
- Yaesu VR-5000
- Yaesu FT-450
- Yaesu FT-950
- Yaesu FT-2000
- Yaesu FTDX-9000
- Yaesu FT-980
- Yaesu FTDX-5000
- Vertex Standard VX-1700
- Yaesu FTDX-1200
- Yaesu FT-991
- Yaesu FT-891
- Yaesu FTDX-3000
- Yaesu FT-847UNI
- Yaesu FT-600
- Yaesu FTDX-101D
- Yaesu FT-818
- Yaesu FTDX-10
- Yaesu FT-897D
- Yaesu FTDX-101MP
- Kenwood TS-50S
- Kenwood TS-440S
- Kenwood TS-450S
- Kenwood TS-570D
- Kenwood TS-690S
- Kenwood TS-711
- Kenwood TS-790
- Kenwood TS-811
- Kenwood TS-850
- Kenwood TS-870S
- Kenwood TS-940S
- Kenwood TS-950S
- Kenwood TS-950SDX
- Kenwood TS-2000
- Kenwood R-5000
- Kenwood TS-570S
- Kenwood TH-D7A
- Kenwood TH-F6A
- Kenwood TH-F7E
- Elecraft K2
- Kenwood TS-930
- Kenwood TH-G71
- Kenwood TS-680S
- Kenwood TS-140S
- Kenwood TM-D700
- Kenwood TM-V7
- Kenwood TS-480
- Elecraft K3
- Kenwood TRC-80
- Kenwood TS-590S
- SigFox Transfox
- Kenwood TH-D72A
- Kenwood TM-D710(G)
- FlexRadio 6xxx
- Kenwood TS-590SG
- Elecraft XG3
- Kenwood TS-990s
- OpenHPSDR PiHPSDR
- Kenwood TS-890S
- Kenwood TH-D74
- Elecraft K3S
- Elecraft KX2
- Elecraft KX3
- Hilberling PT-8000A
- Elecraft K4
- FlexRadio/ANAN PowerSDR/Thetis
- Malachite DSP
- Icom IC-1275
- Icom IC-271
- Icom IC-275
- Icom IC-471
- Icom IC-475
- Icom IC-706
- Icom IC-706MkII
- Icom IC-706MkIIG
- Icom IC-707
- Icom IC-718
- Icom IC-725
- Icom IC-726
- Icom IC-728
- Icom IC-729
- Icom IC-735
- Icom IC-736
- Icom IC-737
- Icom IC-738
- Icom IC-746
- Icom IC-751
- Icom IC-756
- Icom IC-756PRO
- Icom IC-761
- Icom IC-765
- Icom IC-775
- Icom IC-781
- Icom IC-820H
- Icom IC-821H
- Icom IC-970
- Icom IC-R10
- Icom IC-R71
- Icom IC-R72
- Icom IC-R75
- Icom IC-R7000
- Icom IC-R7100
- Icom ICR-8500
- Icom IC-R9000
- Icom IC-910
- Icom IC-78
- Icom IC-746PRO
- Icom IC-756PROII
- Ten-Tec Omni VI Plus
- Optoelectronics OptoScan535
- Optoelectronics OptoScan456
- Icom IC ID-1
- Icom IC-703
- Icom IC-7800
- Icom IC-756PROIII
- Icom IC-R20
- Icom IC-7000
- Icom IC-7200
- Icom IC-7700
- Icom IC-7600
- Ten-Tec Delta II
- Icom IC-92D
- Icom IC-R9500
- Icom IC-7410
- Icom IC-9100
- Icom IC-RX7
- Icom IC-7100
- Icom ID-5100
- Icom IC-2730
- Icom IC-7300
- Microtelecom Perseus
- Icom IC-785x
- Xeigu X108G
- Icom IC-R6
- Icom IC-7610
- Icom IC-R8600
- Icom IC-R30
- Icom IC-9700
- Icom ID-4100
- Icom ID-31
- Icom ID-51
- Icom IC-705
- Icom IC-PCR1000
- Icom IC-PCR100
- Icom IC-PCR1500
- Icom IC-PCR2500
- AOR AR8200
- AOR AR8000
- AOR AR7030
- AOR AR5000
- AOR AR3030
- AOR AR3000A
- AOR AR2700
- AOR AR8600
- AOR AR5000A
- AOR AR7030 Plus
- AOR SR2200
- JRC NRD-525
- JRC NRD-535D
- JRC NRD-545 DSP
- Uniden BC780xlt
- Uniden BC245xlt
- Uniden BC895xlt
- Radio Shack PRO-2052
- Uniden BC250D
- Uniden BCD-396T
- Uniden BCD-996T
- Uniden BC898T
- Drake R-8A
- Drake R-8B
- Lowe HF-235
- Racal RA6790/GM
- Racal RA3702
- Watkins-Johnson WJ-8888
- Skanti TRP8000
- Skanti TRP 8255 S R
- Winradio WR-1000
- Winradio WR-1500
- Winradio WR-1550
- Winradio WR-3100
- Winradio WR-3150
- Winradio WR-3500
- Winradio WR-3700
- Winradio WR-G313
- Ten-Tec TT-550
- Ten-Tec TT-538 Jupiter
- Ten-Tec RX-320
- Ten-Tec RX-340
- Ten-Tec RX-350
- Ten-Tec TT-516 Argonaut V
- Ten-Tec TT-565 Orion
- Ten-Tec TT-585 Paragon
- Ten-Tec TT-588 Omni VII
- Ten-Tec RX-331
- Ten-Tec TT-599 Eagle
- Alinco DX-77
- Alinco DX-SR8
- Kachina 505DSP
- TAPR DSP-10
- Flex-radio SDR-1000
-
- DTTS Microwave Society DttSP IPC
-
-
- DTTS Microwave Society DttSP UDP
-
- RFT EKD-500
- Elektor Elektor 3/04
- SAT-Schneider DRT1
-
- Coding Technologies Digital World Traveller
-
- AmQRP DDS-60
- Elektor Elektor SDR-USB
- mRS miniVNA
- SoftRock Si570 AVR-USB
- KTH-SDR kit Si570 PIC-USB
- FiFi FiFi-SDR
- AMSAT-UK FUNcube Dongle
- N2ADR HiQSDR
- Funkamateur FA-SDR
- AE9RB Si570 Peaberry V1
- AE9RB Si570 Peaberry V2
- AMSAT-UK FUNcube Dongle Pro+
- HobbyPCB RS-HFIQ
- Video4Linux SW/FM radio
- Video4Linux2 SW/FM radio
- Rohde&Schwarz ESMC
- Rohde&Schwarz EB200
- Rohde&Schwarz XK2100
- Philips/Simoco PRM8060
- ADAT www.adat.ch ADT-200A
- Icom IC-M700PRO
- Icom IC-M802
- Icom IC-M710
- Icom IC-M803
- Dorji DRA818V
- Dorji DRA818U
- Barrett 2050
- Barrett 950
- ELAD FDM-DUO
-
-
-
-
- Device port
-
-
-
-
-
-
-
- Serial speed
-
-
- -- ignore --
- 1200
- 2400
- 4800
- 9600
- 14400
- 19200
- 28800
- 38400
- 57600
- 115200
-
-
-
- Data bits
-
-
- -- ignore --
- 7
- 8
-
-
-
- Stop bits
-
-
- -- ignore --
- 1
- 2
-
-
-
- Serial handshake
-
-
- -- ignore --
- None (Default)
-
-
-
-
- PTT device port
-
- -- ignore --
-
-
-
- PTT type
-
-
- -- ignore --
- NONE
- RIG
- USB
- Serial RTS
- Rig PARALLEL
- Rig MICDATA
- Rig CM108
-
-
-
- DCD
-
-
- -- ignore --
- NONE
- RIG/CAT
- DSR
- CTS
- CD
- PARALLEL
-
-
-
- DTR
-
-
- -- ignore --
- OFF
- ON
-
-
-
- Rigctld command
-
-
-
-
-
-
- Rigctld custom arguments
-
-
-
-
-
-
-
-
-
-
- TX delay in ms
-
- 0
- 50
- 100
- 150
- 200
- 250
- 300
- 350
- 400
- 450
- 500
- 550
- 600
- 650
- 700
- 750
- 800
- 850
- 900
- 950
- 1000
-
-
-
-
- Tuning range
- fmin
-
- -50.0
- -100.0
- -150.0
- -200.0
- -250.0
-
- fmax
-
- 50.0
- 100.0
- 150.0
- 200.0
- 250.0
-
-
-
- Beacon interval
-
- 60 secs
- 90 secs
- 2 mins
- 5 mins
- 10 mins
- 15 mins
- 30 mins
- 60 mins
-
-
-
-
-
-
-
- RX buffer size
-
-
- 1
- 2
- 4
- 8
- 16
- 32
- 64
- 128
- 256
- 512
- 1024
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- These options may
- not work and are for experienced users only!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ---
-
- ------
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/gui_vue/src/js/chatHandler.ts b/gui/src/js/chatHandler.ts
similarity index 100%
rename from gui_vue/src/js/chatHandler.ts
rename to gui/src/js/chatHandler.ts
diff --git a/gui_vue/src/js/daemon.ts b/gui/src/js/daemon.ts
similarity index 100%
rename from gui_vue/src/js/daemon.ts
rename to gui/src/js/daemon.ts
diff --git a/gui_vue/src/js/deprecated_preload-chat.js b/gui/src/js/deprecated_preload-chat.js
similarity index 100%
rename from gui_vue/src/js/deprecated_preload-chat.js
rename to gui/src/js/deprecated_preload-chat.js
diff --git a/gui_vue/src/js/deprecated_preload-log.js b/gui/src/js/deprecated_preload-log.js
similarity index 100%
rename from gui_vue/src/js/deprecated_preload-log.js
rename to gui/src/js/deprecated_preload-log.js
diff --git a/gui_vue/src/js/deprecated_preload-main.js b/gui/src/js/deprecated_preload-main.js
similarity index 100%
rename from gui_vue/src/js/deprecated_preload-main.js
rename to gui/src/js/deprecated_preload-main.js
diff --git a/gui_vue/src/js/deprecated_preload-mesh.js b/gui/src/js/deprecated_preload-mesh.js
similarity index 100%
rename from gui_vue/src/js/deprecated_preload-mesh.js
rename to gui/src/js/deprecated_preload-mesh.js
diff --git a/gui_vue/src/js/freedata.ts b/gui/src/js/freedata.ts
similarity index 100%
rename from gui_vue/src/js/freedata.ts
rename to gui/src/js/freedata.ts
diff --git a/gui_vue/src/js/popupHandler.ts b/gui/src/js/popupHandler.ts
similarity index 100%
rename from gui_vue/src/js/popupHandler.ts
rename to gui/src/js/popupHandler.ts
diff --git a/gui_vue/src/js/settingsHandler.ts b/gui/src/js/settingsHandler.ts
similarity index 100%
rename from gui_vue/src/js/settingsHandler.ts
rename to gui/src/js/settingsHandler.ts
diff --git a/gui_vue/src/js/sock.js b/gui/src/js/sock.js
similarity index 100%
rename from gui_vue/src/js/sock.js
rename to gui/src/js/sock.js
diff --git a/gui_vue/src/js/waterfallHandler.js b/gui/src/js/waterfallHandler.js
similarity index 100%
rename from gui_vue/src/js/waterfallHandler.js
rename to gui/src/js/waterfallHandler.js
diff --git a/gui_vue/src/main.ts b/gui/src/main.ts
similarity index 100%
rename from gui_vue/src/main.ts
rename to gui/src/main.ts
diff --git a/gui_vue/src/scss/styles.scss b/gui/src/scss/styles.scss
similarity index 100%
rename from gui_vue/src/scss/styles.scss
rename to gui/src/scss/styles.scss
diff --git a/gui/src/splash.html b/gui/src/splash.html
deleted file mode 100644
index fa3735af..00000000
--- a/gui/src/splash.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/gui_vue/src/store/audioStore.js b/gui/src/store/audioStore.js
similarity index 100%
rename from gui_vue/src/store/audioStore.js
rename to gui/src/store/audioStore.js
diff --git a/gui_vue/src/store/chatStore.js b/gui/src/store/chatStore.js
similarity index 100%
rename from gui_vue/src/store/chatStore.js
rename to gui/src/store/chatStore.js
diff --git a/gui_vue/src/store/index.js b/gui/src/store/index.js
similarity index 100%
rename from gui_vue/src/store/index.js
rename to gui/src/store/index.js
diff --git a/gui_vue/src/store/settingsStore.js b/gui/src/store/settingsStore.js
similarity index 100%
rename from gui_vue/src/store/settingsStore.js
rename to gui/src/store/settingsStore.js
diff --git a/gui_vue/src/store/stateStore.js b/gui/src/store/stateStore.js
similarity index 100%
rename from gui_vue/src/store/stateStore.js
rename to gui/src/store/stateStore.js
diff --git a/gui_vue/src/style.css b/gui/src/style.css
similarity index 100%
rename from gui_vue/src/style.css
rename to gui/src/style.css
diff --git a/gui/src/styles.css b/gui/src/styles.css
index 1fc88516..79ba714b 100644
--- a/gui/src/styles.css
+++ b/gui/src/styles.css
@@ -107,3 +107,11 @@ https://stackoverflow.com/a/9622873
[data-bs-theme="dark"] {
/* default dark theme mods */
}
+.modal-backdrop {
+ background-color: transparent;
+}
+
+.modal-backdrop.in {
+ filter: alpha(opacity=10);
+ opacity: .1
+}
diff --git a/gui_vue/src/vite-env.d.ts b/gui/src/vite-env.d.ts
similarity index 100%
rename from gui_vue/src/vite-env.d.ts
rename to gui/src/vite-env.d.ts
diff --git a/gui/src/waterfall/spectrogram.js b/gui/src/waterfall/spectrogram.js
deleted file mode 100644
index 669432b5..00000000
--- a/gui/src/waterfall/spectrogram.js
+++ /dev/null
@@ -1,607 +0,0 @@
-/*=============================================================
- Filename: Spectrogram-1v00.js
-
- JavaScript graphics functions to draw Spectrograms.
-
- Date Description By
- -------|-------------------------------------------------|---
- 12Nov18 First beta ARC
- 17Nov18 Added offset into data buffer ARC
- 08May19 this.imageURL URL added
- bugfix: fixed isNaN test
- Changed sgStart, sgStop to start, stop
- Added options object to constructors ARC
- 10May19 Enabled Left to Right as well as Top to Bottom ARC
- 11May19 Added RasterscanSVG ARC
- 12May19 Added blnkline for horizontal ratser scans ARC
- 13May19 Eliminated unneccessary putImageData ARC
- 14May19 Removed toDataURL, not used drawImage is better
- bugfix: SVG RHC names swapped ARC
- 02Jun19 bugfix: startOfs not honored in horizontalNewLine ARC
- 03Jun19 Flipped the SVG and RHC names for waterfalls ARC
- 04Jun19 Unflip SVG and RHC for horizontal mode ARC
- Swap "SVG" & "RHC" strings to match fn names ARC
- 05Jun19 bugfix: WaterfallSVG scrolling wrong way ARC
- 10Jun19 bugfix: support lineRate=0 for static display
- bugfix: ipBufPtr must be a ptr to a ptr ARC
- 11Jun19 Make ipBuffers an Array of Arrays, if lineRate=0
- use all buffers else use only ipBuffer[0] ARC
- 13Jun19 Use Waterfall and Rasterscan plus direction
- Use Boolean rater than string compare ARC
- 16Jun19 Use const and let ARC
- 20Jun19 Change order of parameters ARC
- 21Jun19 Add setLineRate method ARC
- 06Jul19 Released as Rev 1v00 ARC
- ==============================================================*/
-
-var Waterfall, Rasterscan;
-
-(function () {
- Waterfall = function (ipBufAry, w, h, dir, options) {
- var direction = typeof dir === "string" ? dir.toLowerCase() : "down";
-
- switch (direction) {
- case "up":
- return new Spectrogram(ipBufAry, w, h, "WF", false, true, options);
- case "down":
- default:
- return new Spectrogram(ipBufAry, w, h, "WF", true, true, options);
- case "left":
- return new Spectrogram(ipBufAry, w, h, "WF", false, false, options);
- case "right":
- return new Spectrogram(ipBufAry, w, h, "WF", true, false, options);
- }
- };
-
- Rasterscan = function (ipBufAry, w, h, dir, options) {
- const direction = typeof dir === "string" ? dir.toLowerCase() : "down";
-
- switch (direction) {
- case "up":
- return new Spectrogram(ipBufAry, w, h, "RS", true, true, options);
- case "down":
- default:
- return new Spectrogram(ipBufAry, w, h, "RS", false, true, options);
- case "left":
- return new Spectrogram(ipBufAry, w, h, "RS", false, false, options);
- case "right":
- return new Spectrogram(ipBufAry, w, h, "RS", true, false, options);
- }
- };
-
- function Spectrogram(ipBufAry, w, h, sgMode, rhc, vert, options) {
- const opt = typeof options === "object" ? options : {}; // avoid undeclared object errors
- let offScreenCtx; // offscreen canvas drawing context
- const pxPerLine = w || 200;
- const lines = h || 200;
- let lineRate = 30; // requested line rate for dynamic waterfalls
- let interval = 0; // msec
- let startOfs = 0;
- const lineBuf = new ArrayBuffer(pxPerLine * 4); // 1 line
- const lineBuf8 = new Uint8ClampedArray(lineBuf);
- const lineImgData = new ImageData(lineBuf8, pxPerLine, 1); // 1 line of canvas pixels
- let pageImgData; // lines * pxPerLine of canvas pixels
- let ipBuf8; // map input data to 0..255 unsigned bytes
- const blankBuf = new ArrayBuffer(pxPerLine * 4); // 1 line
- const blankBuf8 = new Uint8ClampedArray(blankBuf);
- const blankImgData = new ImageData(blankBuf8, pxPerLine, 1); // 1 line of canvas pixels
- const clearBuf = new ArrayBuffer(pxPerLine * lines * 4); // fills with 0s ie. rgba 0,0,0,0 = transparent
- const clearBuf8 = new Uint8ClampedArray(clearBuf);
- let clearImgData;
- let nextLine = 0;
- let timerID = null;
- let running = false;
- let sgTime = 0;
- let sgStartTime = 0;
-
- // Matlab Jet ref: stackoverflow.com grayscale-to-red-green-blue-matlab-jet-color-scale
- let colMap = [
- [0, 0, 128, 255],
- [0, 0, 131, 255],
- [0, 0, 135, 255],
- [0, 0, 139, 255],
- [0, 0, 143, 255],
- [0, 0, 147, 255],
- [0, 0, 151, 255],
- [0, 0, 155, 255],
- [0, 0, 159, 255],
- [0, 0, 163, 255],
- [0, 0, 167, 255],
- [0, 0, 171, 255],
- [0, 0, 175, 255],
- [0, 0, 179, 255],
- [0, 0, 183, 255],
- [0, 0, 187, 255],
- [0, 0, 191, 255],
- [0, 0, 195, 255],
- [0, 0, 199, 255],
- [0, 0, 203, 255],
- [0, 0, 207, 255],
- [0, 0, 211, 255],
- [0, 0, 215, 255],
- [0, 0, 219, 255],
- [0, 0, 223, 255],
- [0, 0, 227, 255],
- [0, 0, 231, 255],
- [0, 0, 235, 255],
- [0, 0, 239, 255],
- [0, 0, 243, 255],
- [0, 0, 247, 255],
- [0, 0, 251, 255],
- [0, 0, 255, 255],
- [0, 4, 255, 255],
- [0, 8, 255, 255],
- [0, 12, 255, 255],
- [0, 16, 255, 255],
- [0, 20, 255, 255],
- [0, 24, 255, 255],
- [0, 28, 255, 255],
- [0, 32, 255, 255],
- [0, 36, 255, 255],
- [0, 40, 255, 255],
- [0, 44, 255, 255],
- [0, 48, 255, 255],
- [0, 52, 255, 255],
- [0, 56, 255, 255],
- [0, 60, 255, 255],
- [0, 64, 255, 255],
- [0, 68, 255, 255],
- [0, 72, 255, 255],
- [0, 76, 255, 255],
- [0, 80, 255, 255],
- [0, 84, 255, 255],
- [0, 88, 255, 255],
- [0, 92, 255, 255],
- [0, 96, 255, 255],
- [0, 100, 255, 255],
- [0, 104, 255, 255],
- [0, 108, 255, 255],
- [0, 112, 255, 255],
- [0, 116, 255, 255],
- [0, 120, 255, 255],
- [0, 124, 255, 255],
- [0, 128, 255, 255],
- [0, 131, 255, 255],
- [0, 135, 255, 255],
- [0, 139, 255, 255],
- [0, 143, 255, 255],
- [0, 147, 255, 255],
- [0, 151, 255, 255],
- [0, 155, 255, 255],
- [0, 159, 255, 255],
- [0, 163, 255, 255],
- [0, 167, 255, 255],
- [0, 171, 255, 255],
- [0, 175, 255, 255],
- [0, 179, 255, 255],
- [0, 183, 255, 255],
- [0, 187, 255, 255],
- [0, 191, 255, 255],
- [0, 195, 255, 255],
- [0, 199, 255, 255],
- [0, 203, 255, 255],
- [0, 207, 255, 255],
- [0, 211, 255, 255],
- [0, 215, 255, 255],
- [0, 219, 255, 255],
- [0, 223, 255, 255],
- [0, 227, 255, 255],
- [0, 231, 255, 255],
- [0, 235, 255, 255],
- [0, 239, 255, 255],
- [0, 243, 255, 255],
- [0, 247, 255, 255],
- [0, 251, 255, 255],
- [0, 255, 255, 255],
- [4, 255, 251, 255],
- [8, 255, 247, 255],
- [12, 255, 243, 255],
- [16, 255, 239, 255],
- [20, 255, 235, 255],
- [24, 255, 231, 255],
- [28, 255, 227, 255],
- [32, 255, 223, 255],
- [36, 255, 219, 255],
- [40, 255, 215, 255],
- [44, 255, 211, 255],
- [48, 255, 207, 255],
- [52, 255, 203, 255],
- [56, 255, 199, 255],
- [60, 255, 195, 255],
- [64, 255, 191, 255],
- [68, 255, 187, 255],
- [72, 255, 183, 255],
- [76, 255, 179, 255],
- [80, 255, 175, 255],
- [84, 255, 171, 255],
- [88, 255, 167, 255],
- [92, 255, 163, 255],
- [96, 255, 159, 255],
- [100, 255, 155, 255],
- [104, 255, 151, 255],
- [108, 255, 147, 255],
- [112, 255, 143, 255],
- [116, 255, 139, 255],
- [120, 255, 135, 255],
- [124, 255, 131, 255],
- [128, 255, 128, 255],
- [131, 255, 124, 255],
- [135, 255, 120, 255],
- [139, 255, 116, 255],
- [143, 255, 112, 255],
- [147, 255, 108, 255],
- [151, 255, 104, 255],
- [155, 255, 100, 255],
- [159, 255, 96, 255],
- [163, 255, 92, 255],
- [167, 255, 88, 255],
- [171, 255, 84, 255],
- [175, 255, 80, 255],
- [179, 255, 76, 255],
- [183, 255, 72, 255],
- [187, 255, 68, 255],
- [191, 255, 64, 255],
- [195, 255, 60, 255],
- [199, 255, 56, 255],
- [203, 255, 52, 255],
- [207, 255, 48, 255],
- [211, 255, 44, 255],
- [215, 255, 40, 255],
- [219, 255, 36, 255],
- [223, 255, 32, 255],
- [227, 255, 28, 255],
- [231, 255, 24, 255],
- [235, 255, 20, 255],
- [239, 255, 16, 255],
- [243, 255, 12, 255],
- [247, 255, 8, 255],
- [251, 255, 4, 255],
- [255, 255, 0, 255],
- [255, 251, 0, 255],
- [255, 247, 0, 255],
- [255, 243, 0, 255],
- [255, 239, 0, 255],
- [255, 235, 0, 255],
- [255, 231, 0, 255],
- [255, 227, 0, 255],
- [255, 223, 0, 255],
- [255, 219, 0, 255],
- [255, 215, 0, 255],
- [255, 211, 0, 255],
- [255, 207, 0, 255],
- [255, 203, 0, 255],
- [255, 199, 0, 255],
- [255, 195, 0, 255],
- [255, 191, 0, 255],
- [255, 187, 0, 255],
- [255, 183, 0, 255],
- [255, 179, 0, 255],
- [255, 175, 0, 255],
- [255, 171, 0, 255],
- [255, 167, 0, 255],
- [255, 163, 0, 255],
- [255, 159, 0, 255],
- [255, 155, 0, 255],
- [255, 151, 0, 255],
- [255, 147, 0, 255],
- [255, 143, 0, 255],
- [255, 139, 0, 255],
- [255, 135, 0, 255],
- [255, 131, 0, 255],
- [255, 128, 0, 255],
- [255, 124, 0, 255],
- [255, 120, 0, 255],
- [255, 116, 0, 255],
- [255, 112, 0, 255],
- [255, 108, 0, 255],
- [255, 104, 0, 255],
- [255, 100, 0, 255],
- [255, 96, 0, 255],
- [255, 92, 0, 255],
- [255, 88, 0, 255],
- [255, 84, 0, 255],
- [255, 80, 0, 255],
- [255, 76, 0, 255],
- [255, 72, 0, 255],
- [255, 68, 0, 255],
- [255, 64, 0, 255],
- [255, 60, 0, 255],
- [255, 56, 0, 255],
- [255, 52, 0, 255],
- [255, 48, 0, 255],
- [255, 44, 0, 255],
- [255, 40, 0, 255],
- [255, 36, 0, 255],
- [255, 32, 0, 255],
- [255, 28, 0, 255],
- [255, 24, 0, 255],
- [255, 20, 0, 255],
- [255, 16, 0, 255],
- [255, 12, 0, 255],
- [255, 8, 0, 255],
- [255, 4, 0, 255],
- [255, 0, 0, 255],
- [251, 0, 0, 255],
- [247, 0, 0, 255],
- [243, 0, 0, 255],
- [239, 0, 0, 255],
- [235, 0, 0, 255],
- [231, 0, 0, 255],
- [227, 0, 0, 255],
- [223, 0, 0, 255],
- [219, 0, 0, 255],
- [215, 0, 0, 255],
- [211, 0, 0, 255],
- [207, 0, 0, 255],
- [203, 0, 0, 255],
- [199, 0, 0, 255],
- [195, 0, 0, 255],
- [191, 0, 0, 255],
- [187, 0, 0, 255],
- [183, 0, 0, 255],
- [179, 0, 0, 255],
- [175, 0, 0, 255],
- [171, 0, 0, 255],
- [167, 0, 0, 255],
- [163, 0, 0, 255],
- [159, 0, 0, 255],
- [155, 0, 0, 255],
- [151, 0, 0, 255],
- [147, 0, 0, 255],
- [143, 0, 0, 255],
- [139, 0, 0, 255],
- [135, 0, 0, 255],
- [131, 0, 0, 255],
- [0, 0, 0, 0],
- ];
-
- function incrLine() {
- if ((vert && !rhc) || (!vert && rhc)) {
- nextLine++;
- if (nextLine >= lines) {
- nextLine = 0;
- }
- } else {
- nextLine--;
- if (nextLine < 0) {
- nextLine = lines - 1;
- }
- }
- }
-
- function updateWaterfall() {
- // update dynamic waterfalls at a fixed rate
- let sgDiff;
-
- // grab latest line of data, write it to off screen buffer, inc 'nextLine'
- sgNewLine();
- // loop to write data data at the desired rate, data is being updated asynchronously
- // ref for accurate timeout: http://www.sitepoint.com/creating-accurate-timers-in-javascript
- sgTime += interval;
- sgDiff = Date.now() - sgStartTime - sgTime;
- if (running) {
- timerID = setTimeout(updateWaterfall, interval - sgDiff);
- }
- }
-
- function sgSetLineRate(newRate) {
- if (isNaN(newRate) || newRate > 50 || newRate < 0) {
- console.error("invalid line rate [0 <= lineRate < 50 lines/sec]");
- // don't change the lineRate;
- } else if (newRate === 0) {
- // static (one pass) raster
- lineRate = 0;
- } else {
- lineRate = newRate;
- interval = 1000 / lineRate; // msec
- }
- }
-
- this.setLineRate = sgSetLineRate;
-
- function setProperty(propertyName, value) {
- if (typeof propertyName !== "string" || value === undefined) {
- // null is OK, forces default
- return;
- }
- switch (propertyName.toLowerCase()) {
- case "linerate":
- sgSetLineRate(value); // setLine does checks for number etc
- break;
- case "startbin":
- if (!isNaN(value) && value > 0) {
- startOfs = value;
- }
- break;
- case "onscreenparentid":
- if (typeof value === "string" && document.getElementById(value)) {
- demoCvsId = value;
- }
- break;
- case "colormap":
- if (
- Array.isArray(value) &&
- Array.isArray(value[0]) &&
- value[0].length == 4
- ) {
- colMap = value; // value must be an array of 4 element arrays to get here
- if (colMap.length < 256) {
- // fill out the remaining colors with last color
- for (let i = colMap.length; i < 256; i++) {
- colMap[i] = colMap[colMap.length - 1];
- }
- }
- }
- break;
- default:
- break;
- }
- }
-
- function verticalNewLine() {
- let tmpImgData, ipBuf8;
-
- if (sgMode == "WF") {
- if (rhc) {
- // shift the current display down 1 line, oldest line drops off
- tmpImgData = offScreenCtx.getImageData(0, 0, pxPerLine, lines - 1);
- offScreenCtx.putImageData(tmpImgData, 0, 1);
- } else {
- // shift the current display up 1 line, oldest line drops off
- tmpImgData = offScreenCtx.getImageData(0, 1, pxPerLine, lines - 1);
- offScreenCtx.putImageData(tmpImgData, 0, 0);
- }
- }
- ipBuf8 = Uint8ClampedArray.from(ipBufAry[0]);
- for (
- let sigVal, rgba, opIdx = 0, ipIdx = startOfs;
- ipIdx < pxPerLine + startOfs;
- opIdx += 4, ipIdx++
- ) {
- sigVal = ipBuf8[ipIdx] || 0; // if input line too short add zeros
- rgba = colMap[sigVal]; // array of rgba values
- // byte reverse so number aa bb gg rr
- lineBuf8[opIdx] = rgba[0]; // red
- lineBuf8[opIdx + 1] = rgba[1]; // green
- lineBuf8[opIdx + 2] = rgba[2]; // blue
- lineBuf8[opIdx + 3] = rgba[3]; // alpha
- }
- offScreenCtx.putImageData(lineImgData, 0, nextLine);
- if (sgMode === "RS") {
- incrLine();
- // if not static draw a white line in front of the current line to indicate new data point
- if (lineRate) {
- offScreenCtx.putImageData(blankImgData, 0, nextLine);
- }
- }
- }
-
- function horizontalNewLine() {
- let tmpImgData, ipBuf8;
-
- if (sgMode == "WF") {
- if (rhc) {
- // shift the current display right 1 line, oldest line drops off
- tmpImgData = offScreenCtx.getImageData(0, 0, lines - 1, pxPerLine);
- offScreenCtx.putImageData(tmpImgData, 1, 0);
- } else {
- // shift the current display left 1 line, oldest line drops off
- tmpImgData = offScreenCtx.getImageData(1, 0, lines - 1, pxPerLine);
- offScreenCtx.putImageData(tmpImgData, 0, 0);
- }
- }
- // refresh the page image (it was just shifted)
- pageImgData = offScreenCtx.getImageData(0, 0, lines, pxPerLine);
- if (ipBufAry[0].constructor !== Uint8Array) {
- ipBuf8 = Uint8ClampedArray.from(ipBufAry[0]); // clamp input values to 0..255 range
- } else {
- ipBuf8 = ipBufAry[0]; // conversion already done
- }
-
- for (let sigVal, rgba, opIdx, ipIdx = 0; ipIdx < pxPerLine; ipIdx++) {
- sigVal = ipBuf8[ipIdx + startOfs] || 0; // if input line too short add zeros
- rgba = colMap[sigVal]; // array of rgba values
- opIdx = 4 * ((pxPerLine - ipIdx - 1) * lines + nextLine);
- // byte reverse so number aa bb gg rr
- pageImgData.data[opIdx] = rgba[0]; // red
- pageImgData.data[opIdx + 1] = rgba[1]; // green
- pageImgData.data[opIdx + 2] = rgba[2]; // blue
- pageImgData.data[opIdx + 3] = rgba[3]; // alpha
- }
- if (sgMode === "RS") {
- incrLine();
- // if not draw a white line in front of the current line to indicate new data point
- if (lineRate) {
- for (let j = 0; j < pxPerLine; j++) {
- if (rhc) {
- opIdx = 4 * (j * lines + nextLine);
- } else {
- opIdx = 4 * ((pxPerLine - j - 1) * lines + nextLine);
- }
- // byte reverse so number aa bb gg rr
- pageImgData.data[opIdx] = 255; // red
- pageImgData.data[opIdx + 1] = 255; // green
- pageImgData.data[opIdx + 2] = 255; // blue
- pageImgData.data[opIdx + 3] = 255; // alpha
- }
- }
- }
- offScreenCtx.putImageData(pageImgData, 0, 0);
- }
-
- const sgNewLine = vert ? verticalNewLine : horizontalNewLine; // function pointers
-
- //===== set all the options ================
- for (let prop in opt) {
- // check that this is opt's own property, not inherited from prototype
- if (opt.hasOwnProperty(prop)) {
- setProperty(prop, opt[prop]);
- }
- }
-
- // ===== now make the exposed properties and methods ===============
- this.newLine = sgNewLine;
-
- this.offScreenCvs = document.createElement("canvas");
- if (vert) {
- this.offScreenCvs.setAttribute("width", pxPerLine); // reset canvas pixels width
- this.offScreenCvs.setAttribute("height", lines); // don't use style for this
- clearImgData = new ImageData(clearBuf8, pxPerLine, lines);
- } // data written in columns
- else {
- this.offScreenCvs.setAttribute("width", lines); // reset canvas pixels width
- this.offScreenCvs.setAttribute("height", pxPerLine); // don't use style for this
- clearImgData = new ImageData(clearBuf8, lines, pxPerLine);
- }
- offScreenCtx = this.offScreenCvs.getContext("2d");
-
- this.clear = function () {
- offScreenCtx.putImageData(clearImgData, 0, 0);
- };
-
- this.start = function () {
- sgStartTime = Date.now();
- sgTime = 0;
- running = true;
- updateWaterfall(); // start the update loop
- };
-
- this.stop = function () {
- running = false;
- if (timerID) {
- clearTimeout(timerID);
- }
- // reset where the next line is to be written
- if (sgMode === "RS") {
- if (vert) {
- nextLine = rhc ? lines - 1 : 0;
- } else {
- nextLine = rhc ? 0 : lines - 1;
- }
- } // WF
- else {
- nextLine = rhc ? 0 : lines - 1;
- }
- };
-
- // make a white line, it will show the input line for RS displays
- blankBuf8.fill(255);
- // make a full canvas of the color map 0 values
- for (let i = 0; i < pxPerLine * lines * 4; i += 4) {
- // byte reverse so number aa bb gg rr
- clearBuf8[i] = colMap[0][0]; // red
- clearBuf8[i + 1] = colMap[0][1]; // green
- clearBuf8[i + 2] = colMap[0][2]; // blue
- clearBuf8[i + 3] = colMap[0][3]; // alpha
- }
- // for diagnostics only
- if (typeof demoCvsId == "string") {
- document.getElementById(demoCvsId).appendChild(this.offScreenCvs);
- }
- // initialize the direction and first line position
- this.stop();
-
- // everything is set
- // if dynamic, wait for the start or newLine methods to be called
- }
-})();
diff --git a/gui/src/waterfall/spectrum.js b/gui/src/waterfall/spectrum.js
deleted file mode 100644
index f3976bd9..00000000
--- a/gui/src/waterfall/spectrum.js
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (c) 2019 Jeppe Ledet-Pedersen
- * This software is released under the MIT license.
- * See the LICENSE file for further details.
- */
-
-"use strict";
-
-Spectrum.prototype.squeeze = function (value, out_min, out_max) {
- if (value <= this.min_db) return out_min;
- else if (value >= this.max_db) return out_max;
- else
- return Math.round(
- ((value - this.min_db) / (this.max_db - this.min_db)) * out_max
- );
-};
-
-Spectrum.prototype.rowToImageData = function (bins) {
- for (var i = 0; i < this.imagedata.data.length; i += 4) {
- var cindex = this.squeeze(bins[i / 4], 0, 255);
- var color = this.colormap[cindex];
- this.imagedata.data[i + 0] = color[0];
- this.imagedata.data[i + 1] = color[1];
- this.imagedata.data[i + 2] = color[2];
- this.imagedata.data[i + 3] = 255;
- }
-};
-
-Spectrum.prototype.addWaterfallRow = function (bins) {
- // Shift waterfall 1 row down
- this.ctx_wf.drawImage(
- this.ctx_wf.canvas,
- 0,
- 0,
- this.wf_size,
- this.wf_rows - 1,
- 0,
- 1,
- this.wf_size,
- this.wf_rows - 1
- );
-
- // Draw new line on waterfall canvas
- this.rowToImageData(bins);
- this.ctx_wf.putImageData(this.imagedata, 0, 0);
-
- var width = this.ctx.canvas.width;
- var height = this.ctx.canvas.height;
-
- // Copy scaled FFT canvas to screen. Only copy the number of rows that will
- // fit in waterfall area to avoid vertical scaling.
- this.ctx.imageSmoothingEnabled = false;
- var rows = Math.min(this.wf_rows, height - this.spectrumHeight);
- this.ctx.drawImage(
- this.ctx_wf.canvas,
- 0,
- 0,
- this.wf_size,
- rows,
- 0,
- this.spectrumHeight,
- width,
- height - this.spectrumHeight
- );
-};
-
-Spectrum.prototype.drawFFT = function (bins) {
- this.ctx.beginPath();
- this.ctx.moveTo(-1, this.spectrumHeight + 1);
- for (var i = 0; i < bins.length; i++) {
- var y = this.spectrumHeight - this.squeeze(bins[i], 0, this.spectrumHeight);
- if (y > this.spectrumHeight - 1) y = this.spectrumHeight + 1; // Hide underflow
- if (y < 0) y = 0;
- if (i == 0) this.ctx.lineTo(-1, y);
- this.ctx.lineTo(i, y);
- if (i == bins.length - 1) this.ctx.lineTo(this.wf_size + 1, y);
- }
- this.ctx.lineTo(this.wf_size + 1, this.spectrumHeight + 1);
- this.ctx.strokeStyle = "#fefefe";
- this.ctx.stroke();
-};
-
-//Spectrum.prototype.drawSpectrum = function(bins) {
-Spectrum.prototype.drawSpectrum = function () {
- var width = this.ctx.canvas.width;
- var height = this.ctx.canvas.height;
-
- // Modification by DJ2LS
- // Draw bandwidth lines
- // TODO: Math not correct. But a first attempt
- // it seems position is more or less equal to frequenzy by factor 10
- // eg. position 150 == 1500Hz
- /*
- // CENTER LINE
- this.ctx_wf.beginPath();
- this.ctx_wf.moveTo(150,0);
- this.ctx_wf.lineTo(150, height);
- this.ctx_wf.lineWidth = 1;
- this.ctx_wf.strokeStyle = '#8C8C8C';
- this.ctx_wf.stroke()
- */
-
- // 586Hz and 1700Hz LINES
- var linePositionLow = 121.6; //150 - bandwith/20
- var linePositionHigh = 178.4; //150 + bandwidth/20
- var linePositionLow2 = 65; //150 - bandwith/20
- var linePositionHigh2 = 235; //150 + bandwith/20
- this.ctx_wf.beginPath();
- this.ctx_wf.moveTo(linePositionLow, 0);
- this.ctx_wf.lineTo(linePositionLow, height);
- this.ctx_wf.moveTo(linePositionHigh, 0);
- this.ctx_wf.lineTo(linePositionHigh, height);
- this.ctx_wf.moveTo(linePositionLow2, 0);
- this.ctx_wf.lineTo(linePositionLow2, height);
- this.ctx_wf.moveTo(linePositionHigh2, 0);
- this.ctx_wf.lineTo(linePositionHigh2, height);
- this.ctx_wf.lineWidth = 1;
- this.ctx_wf.strokeStyle = "#C3C3C3";
- this.ctx_wf.stroke();
-
- // ---- END OF MODIFICATION ------
-
- // Fill with black
- this.ctx.fillStyle = "white";
- this.ctx.fillRect(0, 0, width, height);
-
- //Commenting out the remainder of this code, it's not needed and unused as of 6.9.11 and saves three if statements
- return;
- /*
- // FFT averaging
- if (this.averaging > 0) {
- if (!this.binsAverage || this.binsAverage.length != bins.length) {
- this.binsAverage = Array.from(bins);
- } else {
- for (var i = 0; i < bins.length; i++) {
- this.binsAverage[i] += this.alpha * (bins[i] - this.binsAverage[i]);
- }
- }
- bins = this.binsAverage;
- }
-
- // Max hold
- if (this.maxHold) {
- if (!this.binsMax || this.binsMax.length != bins.length) {
- this.binsMax = Array.from(bins);
- } else {
- for (var i = 0; i < bins.length; i++) {
- if (bins[i] > this.binsMax[i]) {
- this.binsMax[i] = bins[i];
- } else {
- // Decay
- this.binsMax[i] = 1.0025 * this.binsMax[i];
- }
- }
- }
- }
-
- // Do not draw anything if spectrum is not visible
- if (this.ctx_axes.canvas.height < 1)
- return;
-
- // Scale for FFT
- this.ctx.save();
- this.ctx.scale(width / this.wf_size, 1);
-
- // Draw maxhold
- if (this.maxHold)
- this.drawFFT(this.binsMax);
-
- // Draw FFT bins
- this.drawFFT(bins);
-
- // Restore scale
- this.ctx.restore();
-
- // Fill scaled path
- this.ctx.fillStyle = this.gradient;
- this.ctx.fill();
-
- // Copy axes from offscreen canvas
- this.ctx.drawImage(this.ctx_axes.canvas, 0, 0);
- */
-};
-
-//Allow setting colormap
-Spectrum.prototype.setColorMap = function (index) {
- this.colormap = colormaps[index];
-};
-
-Spectrum.prototype.updateAxes = function () {
- var width = this.ctx_axes.canvas.width;
- var height = this.ctx_axes.canvas.height;
-
- // Clear axes canvas
- this.ctx_axes.clearRect(0, 0, width, height);
-
- // Draw axes
- this.ctx_axes.font = "12px sans-serif";
- this.ctx_axes.fillStyle = "white";
- this.ctx_axes.textBaseline = "middle";
-
- this.ctx_axes.textAlign = "left";
- var step = 10;
- for (var i = this.min_db + 10; i <= this.max_db - 10; i += step) {
- var y = height - this.squeeze(i, 0, height);
- this.ctx_axes.fillText(i, 5, y);
-
- this.ctx_axes.beginPath();
- this.ctx_axes.moveTo(20, y);
- this.ctx_axes.lineTo(width, y);
- this.ctx_axes.strokeStyle = "rgba(200, 200, 200, 0.10)";
- this.ctx_axes.stroke();
- }
-
- this.ctx_axes.textBaseline = "bottom";
- for (var i = 0; i < 11; i++) {
- var x = Math.round(width / 10) * i;
-
- if (this.spanHz > 0) {
- var adjust = 0;
- if (i == 0) {
- this.ctx_axes.textAlign = "left";
- adjust = 3;
- } else if (i == 10) {
- this.ctx_axes.textAlign = "right";
- adjust = -3;
- } else {
- this.ctx_axes.textAlign = "center";
- }
-
- var freq = this.centerHz + (this.spanHz / 10) * (i - 5);
- if (this.centerHz + this.spanHz > 1e6) freq = freq / 1e6 + "M";
- else if (this.centerHz + this.spanHz > 1e3) freq = freq / 1e3 + "k";
- this.ctx_axes.fillText(freq, x + adjust, height - 3);
- }
-
- this.ctx_axes.beginPath();
- this.ctx_axes.moveTo(x, 0);
- this.ctx_axes.lineTo(x, height);
- this.ctx_axes.strokeStyle = "rgba(200, 200, 200, 0.10)";
- this.ctx_axes.stroke();
- }
-};
-
-Spectrum.prototype.addData = function (data) {
- if (!this.paused) {
- if (data.length != this.wf_size) {
- this.wf_size = data.length;
- this.ctx_wf.canvas.width = data.length;
- this.ctx_wf.fillStyle = "white";
- this.ctx_wf.fillRect(0, 0, this.wf.width, this.wf.height);
- this.imagedata = this.ctx_wf.createImageData(data.length, 1);
- }
- //this.drawSpectrum(data);
- this.drawSpectrum();
- this.addWaterfallRow(data);
- this.resize();
- }
-};
-
-Spectrum.prototype.updateSpectrumRatio = function () {
- this.spectrumHeight = Math.round(
- (this.canvas.height * this.spectrumPercent) / 100.0
- );
-
- this.gradient = this.ctx.createLinearGradient(0, 0, 0, this.spectrumHeight);
- for (var i = 0; i < this.colormap.length; i++) {
- var c = this.colormap[this.colormap.length - 1 - i];
- this.gradient.addColorStop(
- i / this.colormap.length,
- "rgba(" + c[0] + "," + c[1] + "," + c[2] + ", 1.0)"
- );
- }
-};
-
-Spectrum.prototype.resize = function () {
- var width = this.canvas.clientWidth;
- var height = this.canvas.clientHeight;
-
- if (this.canvas.width != width || this.canvas.height != height) {
- this.canvas.width = width;
- this.canvas.height = height;
- this.updateSpectrumRatio();
- }
-
- if (this.axes.width != width || this.axes.height != this.spectrumHeight) {
- this.axes.width = width;
- this.axes.height = this.spectrumHeight;
- this.updateAxes();
- }
-};
-
-Spectrum.prototype.setSpectrumPercent = function (percent) {
- if (percent >= 0 && percent <= 100) {
- this.spectrumPercent = percent;
- this.updateSpectrumRatio();
- }
-};
-
-Spectrum.prototype.incrementSpectrumPercent = function () {
- if (this.spectrumPercent + this.spectrumPercentStep <= 100) {
- this.setSpectrumPercent(this.spectrumPercent + this.spectrumPercentStep);
- }
-};
-
-Spectrum.prototype.decrementSpectrumPercent = function () {
- if (this.spectrumPercent - this.spectrumPercentStep >= 0) {
- this.setSpectrumPercent(this.spectrumPercent - this.spectrumPercentStep);
- }
-};
-
-Spectrum.prototype.toggleColor = function () {
- this.colorindex++;
- if (this.colorindex >= colormaps.length) this.colorindex = 0;
- this.colormap = colormaps[this.colorindex];
- this.updateSpectrumRatio();
-};
-
-Spectrum.prototype.setRange = function (min_db, max_db) {
- this.min_db = min_db;
- this.max_db = max_db;
- this.updateAxes();
-};
-
-Spectrum.prototype.rangeUp = function () {
- this.setRange(this.min_db - 5, this.max_db - 5);
-};
-
-Spectrum.prototype.rangeDown = function () {
- this.setRange(this.min_db + 5, this.max_db + 5);
-};
-
-Spectrum.prototype.rangeIncrease = function () {
- this.setRange(this.min_db - 5, this.max_db + 5);
-};
-
-Spectrum.prototype.rangeDecrease = function () {
- if (this.max_db - this.min_db > 10)
- this.setRange(this.min_db + 5, this.max_db - 5);
-};
-
-Spectrum.prototype.setCenterHz = function (hz) {
- this.centerHz = hz;
- this.updateAxes();
-};
-
-Spectrum.prototype.setSpanHz = function (hz) {
- this.spanHz = hz;
- this.updateAxes();
-};
-
-Spectrum.prototype.setAveraging = function (num) {
- if (num >= 0) {
- this.averaging = num;
- this.alpha = 2 / (this.averaging + 1);
- }
-};
-
-Spectrum.prototype.incrementAveraging = function () {
- this.setAveraging(this.averaging + 1);
-};
-
-Spectrum.prototype.decrementAveraging = function () {
- if (this.averaging > 0) {
- this.setAveraging(this.averaging - 1);
- }
-};
-
-Spectrum.prototype.setPaused = function (paused) {
- this.paused = paused;
-};
-
-Spectrum.prototype.togglePaused = function () {
- this.setPaused(!this.paused);
-};
-
-Spectrum.prototype.setMaxHold = function (maxhold) {
- this.maxHold = maxhold;
- this.binsMax = undefined;
-};
-
-Spectrum.prototype.toggleMaxHold = function () {
- this.setMaxHold(!this.maxHold);
-};
-
-Spectrum.prototype.toggleFullscreen = function () {
- if (!this.fullscreen) {
- if (this.canvas.requestFullscreen) {
- this.canvas.requestFullscreen();
- } else if (this.canvas.mozRequestFullScreen) {
- this.canvas.mozRequestFullScreen();
- } else if (this.canvas.webkitRequestFullscreen) {
- this.canvas.webkitRequestFullscreen();
- } else if (this.canvas.msRequestFullscreen) {
- this.canvas.msRequestFullscreen();
- }
- this.fullscreen = true;
- } else {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- }
- this.fullscreen = false;
- }
-};
-
-Spectrum.prototype.onKeypress = function (e) {
- if (e.key == " ") {
- this.togglePaused();
- } else if (e.key == "f") {
- this.toggleFullscreen();
- } else if (e.key == "c") {
- this.toggleColor();
- } else if (e.key == "ArrowUp") {
- this.rangeUp();
- } else if (e.key == "ArrowDown") {
- this.rangeDown();
- } else if (e.key == "ArrowLeft") {
- this.rangeDecrease();
- } else if (e.key == "ArrowRight") {
- this.rangeIncrease();
- } else if (e.key == "s") {
- this.incrementSpectrumPercent();
- } else if (e.key == "w") {
- this.decrementSpectrumPercent();
- } else if (e.key == "+") {
- this.incrementAveraging();
- } else if (e.key == "-") {
- this.decrementAveraging();
- } else if (e.key == "m") {
- this.toggleMaxHold();
- }
-};
-
-function Spectrum(id, options) {
- // Handle options
- this.centerHz = options && options.centerHz ? options.centerHz : 1500;
- this.spanHz = options && options.spanHz ? options.spanHz : 0;
- this.wf_size = options && options.wf_size ? options.wf_size : 0;
- this.wf_rows = options && options.wf_rows ? options.wf_rows : 1024;
- this.spectrumPercent =
- options && options.spectrumPercent ? options.spectrumPercent : 0;
- this.spectrumPercentStep =
- options && options.spectrumPercentStep ? options.spectrumPercentStep : 0;
- this.averaging = options && options.averaging ? options.averaging : 0;
- this.maxHold = options && options.maxHold ? options.maxHold : false;
-
- // Setup state
- this.paused = false;
- this.fullscreen = false;
- this.min_db = 0;
- this.max_db = 70;
- this.spectrumHeight = 0;
-
- // Colors
- this.colorindex = 0;
- this.colormap = colormaps[2];
-
- // Create main canvas and adjust dimensions to match actual
- this.canvas = document.getElementById(id);
- this.canvas.height = this.canvas.clientHeight;
- this.canvas.width = this.canvas.clientWidth;
- this.ctx = this.canvas.getContext("2d");
- this.ctx.fillStyle = "white";
- this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
-
- // Create offscreen canvas for axes
- this.axes = document.createElement("canvas");
- this.axes.height = 1; // Updated later
- this.axes.width = this.canvas.width;
- this.ctx_axes = this.axes.getContext("2d");
-
- // Create offscreen canvas for waterfall
- this.wf = document.createElement("canvas");
- this.wf.height = this.wf_rows;
- this.wf.width = this.wf_size;
- this.ctx_wf = this.wf.getContext("2d");
-
- // Trigger first render
- this.setAveraging(this.averaging);
- this.updateSpectrumRatio();
- this.resize();
-}
diff --git a/gui_vue/tsconfig.json b/gui/tsconfig.json
similarity index 100%
rename from gui_vue/tsconfig.json
rename to gui/tsconfig.json
diff --git a/gui_vue/tsconfig.node.json b/gui/tsconfig.node.json
similarity index 100%
rename from gui_vue/tsconfig.node.json
rename to gui/tsconfig.node.json
diff --git a/gui_vue/vite.config.ts b/gui/vite.config.ts
similarity index 100%
rename from gui_vue/vite.config.ts
rename to gui/vite.config.ts
diff --git a/gui_vue/build/entitlements.plist b/gui_vue/build/entitlements.plist
deleted file mode 100644
index 983f1099..00000000
--- a/gui_vue/build/entitlements.plist
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- com.apple.security.cs.allow-jit
-
- com.apple.security.cs.allow-unsigned-executable-memory
-
- com.apple.security.cs.disable-library-validation
-
- com.apple.security.cs.disable-executable-page-protection
-
- com.apple.security.automation.apple-events
-
-
-
\ No newline at end of file
diff --git a/gui_vue/build/icon.png b/gui_vue/build/icon.png
deleted file mode 100644
index 2e346c91..00000000
Binary files a/gui_vue/build/icon.png and /dev/null differ
diff --git a/gui_vue/package.json b/gui_vue/package.json
deleted file mode 100644
index 4deaaf3c..00000000
--- a/gui_vue/package.json
+++ /dev/null
@@ -1,82 +0,0 @@
-{
- "name": "FreeDATA",
- "description": "FreeDATA ",
- "private": true,
- "version": "0.11.0-alpha",
- "main": "dist-electron/main/index.js",
- "scripts": {
- "start": "git pull && npm i && vite",
- "dev": "vite",
- "check" : "vue-tsc --noEmit",
- "build": "vue-tsc --noEmit && vite build && electron-builder",
- "preview": "vite preview",
- "lint": "eslint --ext .js,.vue src",
- "lint-fix": "eslint --ext .js,.vue --fix src"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/DJ2LS/FreeDATA.git"
- },
- "keywords": [
- "TNC",
- "GUI",
- "FreeDATA",
- "codec2"
- ],
- "author": "DJ2LS",
- "license": "GPL-3.0",
- "bugs": {
- "url": "https://github.com/DJ2LS/FreeDATA/issues"
- },
- "homepage": "https://freedata.app",
- "dependencies": {
- "@electron/notarize": "^2.1.0",
- "@vueuse/electron": "^10.4.1",
- "blob-util": "^2.0.2",
- "bootstrap": "^5.3.1",
- "bootstrap-icons": "^1.10.5",
- "bootswatch": "^5.3.1",
- "browser-image-compression": "^2.0.2",
- "chart.js": "^4.3.3",
- "chartjs-plugin-annotation": "^3.0.1",
- "electron-builder-notarize": "^1.5.1",
- "electron-log": "^4.4.8",
- "electron-updater": "^6.1.4",
- "emoji-picker-element": "^1.18.3",
- "emoji-picker-element-data": "^1.4.0",
- "file-saver": "^2.0.5",
- "mime": "^3.0.0",
- "pinia": "^2.1.6",
- "pouchdb": "^8.0.1",
- "pouchdb-browser": "^8.0.1",
- "pouchdb-find": "^8.0.1",
- "pouchdb-upsert": "^2.2.0",
- "qth-locator": "^2.1.0",
- "sass": "^1.66.1",
- "socket.io": "^4.7.2",
- "uuid": "^9.0.0",
- "vue": "^3.3.4",
- "vue-chartjs": "^5.2.0",
- "vuemoji-picker": "^0.2.0"
- },
- "devDependencies": {
- "@typescript-eslint/eslint-plugin": "^6.7.4",
- "@vitejs/plugin-vue": "^4.4.0",
- "electron": "^27.0.0",
- "electron-builder": "^24.6.3",
- "eslint": "^8.50.0",
- "eslint-config-prettier": "^9.0.0",
- "eslint-config-standard-with-typescript": "^39.1.0",
- "eslint-plugin-import": "^2.28.1",
- "eslint-plugin-n": "^16.1.0",
- "eslint-plugin-prettier": "^5.0.0",
- "eslint-plugin-promise": "^6.1.1",
- "eslint-plugin-vue": "^9.17.0",
- "typescript": "^5.2.2",
- "vite": "^4.3.2",
- "vite-plugin-electron": "^0.14.0",
- "vite-plugin-electron-renderer": "^0.14.5",
- "vue": "^3.3.4",
- "vue-tsc": "^1.4.2"
- }
-}
diff --git a/gui_vue/public/icon_cube_border.png b/gui_vue/public/icon_cube_border.png
deleted file mode 100644
index 2e346c91..00000000
Binary files a/gui_vue/public/icon_cube_border.png and /dev/null differ
diff --git a/gui_vue/src/assets/waterfall/LICENSE b/gui_vue/src/assets/waterfall/LICENSE
deleted file mode 100644
index 4aa300f4..00000000
--- a/gui_vue/src/assets/waterfall/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 Jeppe Ledet-Pedersen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/gui_vue/src/assets/waterfall/README.rst b/gui_vue/src/assets/waterfall/README.rst
deleted file mode 100644
index 5a474733..00000000
--- a/gui_vue/src/assets/waterfall/README.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-********************************
-HTML Canvas/WebSockets Waterfall
-********************************
-
-This is a small experiment to create a waterfall plot with HTML Canvas and WebSockets to stream live FFT data from an SDR:
-
-.. image:: img/waterfall.png
-
-``spectrum.js`` contains the main JavaScript source code for the plot, while ``colormap.js`` contains colormaps generated using ``make_colormap.py``.
-
-``index.html``, ``style.css``, ``script.js`` contain an example page that receives FFT data on a WebSocket and plots it on the waterfall plot.
-
-``server.py`` contains a example `Bottle `_ and `gevent-websocket `_ server that broadcasts FFT data to connected clients. The FFT data is generated using `GNU radio `_ using a USRP but it should be fairly easy to change it to a different SDR.
diff --git a/gui_vue/src/assets/waterfall/colormap.js b/gui_vue/src/assets/waterfall/colormap.js
deleted file mode 100644
index a7e5ac5c..00000000
--- a/gui_vue/src/assets/waterfall/colormap.js
+++ /dev/null
@@ -1,1807 +0,0 @@
-var turbo = [
- [48, 18, 59],
- [50, 21, 67],
- [51, 24, 74],
- [52, 27, 81],
- [53, 30, 88],
- [54, 33, 95],
- [55, 36, 102],
- [56, 39, 109],
- [57, 42, 115],
- [58, 45, 121],
- [59, 47, 128],
- [60, 50, 134],
- [61, 53, 139],
- [62, 56, 145],
- [63, 59, 151],
- [63, 62, 156],
- [64, 64, 162],
- [65, 67, 167],
- [65, 70, 172],
- [66, 73, 177],
- [66, 75, 181],
- [67, 78, 186],
- [68, 81, 191],
- [68, 84, 195],
- [68, 86, 199],
- [69, 89, 203],
- [69, 92, 207],
- [69, 94, 211],
- [70, 97, 214],
- [70, 100, 218],
- [70, 102, 221],
- [70, 105, 224],
- [70, 107, 227],
- [71, 110, 230],
- [71, 113, 233],
- [71, 115, 235],
- [71, 118, 238],
- [71, 120, 240],
- [71, 123, 242],
- [70, 125, 244],
- [70, 128, 246],
- [70, 130, 248],
- [70, 133, 250],
- [70, 135, 251],
- [69, 138, 252],
- [69, 140, 253],
- [68, 143, 254],
- [67, 145, 254],
- [66, 148, 255],
- [65, 150, 255],
- [64, 153, 255],
- [62, 155, 254],
- [61, 158, 254],
- [59, 160, 253],
- [58, 163, 252],
- [56, 165, 251],
- [55, 168, 250],
- [53, 171, 248],
- [51, 173, 247],
- [49, 175, 245],
- [47, 178, 244],
- [46, 180, 242],
- [44, 183, 240],
- [42, 185, 238],
- [40, 188, 235],
- [39, 190, 233],
- [37, 192, 231],
- [35, 195, 228],
- [34, 197, 226],
- [32, 199, 223],
- [31, 201, 221],
- [30, 203, 218],
- [28, 205, 216],
- [27, 208, 213],
- [26, 210, 210],
- [26, 212, 208],
- [25, 213, 205],
- [24, 215, 202],
- [24, 217, 200],
- [24, 219, 197],
- [24, 221, 194],
- [24, 222, 192],
- [24, 224, 189],
- [25, 226, 187],
- [25, 227, 185],
- [26, 228, 182],
- [28, 230, 180],
- [29, 231, 178],
- [31, 233, 175],
- [32, 234, 172],
- [34, 235, 170],
- [37, 236, 167],
- [39, 238, 164],
- [42, 239, 161],
- [44, 240, 158],
- [47, 241, 155],
- [50, 242, 152],
- [53, 243, 148],
- [56, 244, 145],
- [60, 245, 142],
- [63, 246, 138],
- [67, 247, 135],
- [70, 248, 132],
- [74, 248, 128],
- [78, 249, 125],
- [82, 250, 122],
- [85, 250, 118],
- [89, 251, 115],
- [93, 252, 111],
- [97, 252, 108],
- [101, 253, 105],
- [105, 253, 102],
- [109, 254, 98],
- [113, 254, 95],
- [117, 254, 92],
- [121, 254, 89],
- [125, 255, 86],
- [128, 255, 83],
- [132, 255, 81],
- [136, 255, 78],
- [139, 255, 75],
- [143, 255, 73],
- [146, 255, 71],
- [150, 254, 68],
- [153, 254, 66],
- [156, 254, 64],
- [159, 253, 63],
- [161, 253, 61],
- [164, 252, 60],
- [167, 252, 58],
- [169, 251, 57],
- [172, 251, 56],
- [175, 250, 55],
- [177, 249, 54],
- [180, 248, 54],
- [183, 247, 53],
- [185, 246, 53],
- [188, 245, 52],
- [190, 244, 52],
- [193, 243, 52],
- [195, 241, 52],
- [198, 240, 52],
- [200, 239, 52],
- [203, 237, 52],
- [205, 236, 52],
- [208, 234, 52],
- [210, 233, 53],
- [212, 231, 53],
- [215, 229, 53],
- [217, 228, 54],
- [219, 226, 54],
- [221, 224, 55],
- [223, 223, 55],
- [225, 221, 55],
- [227, 219, 56],
- [229, 217, 56],
- [231, 215, 57],
- [233, 213, 57],
- [235, 211, 57],
- [236, 209, 58],
- [238, 207, 58],
- [239, 205, 58],
- [241, 203, 58],
- [242, 201, 58],
- [244, 199, 58],
- [245, 197, 58],
- [246, 195, 58],
- [247, 193, 58],
- [248, 190, 57],
- [249, 188, 57],
- [250, 186, 57],
- [251, 184, 56],
- [251, 182, 55],
- [252, 179, 54],
- [252, 177, 54],
- [253, 174, 53],
- [253, 172, 52],
- [254, 169, 51],
- [254, 167, 50],
- [254, 164, 49],
- [254, 161, 48],
- [254, 158, 47],
- [254, 155, 45],
- [254, 153, 44],
- [254, 150, 43],
- [254, 147, 42],
- [254, 144, 41],
- [253, 141, 39],
- [253, 138, 38],
- [252, 135, 37],
- [252, 132, 35],
- [251, 129, 34],
- [251, 126, 33],
- [250, 123, 31],
- [249, 120, 30],
- [249, 117, 29],
- [248, 114, 28],
- [247, 111, 26],
- [246, 108, 25],
- [245, 105, 24],
- [244, 102, 23],
- [243, 99, 21],
- [242, 96, 20],
- [241, 93, 19],
- [240, 91, 18],
- [239, 88, 17],
- [237, 85, 16],
- [236, 83, 15],
- [235, 80, 14],
- [234, 78, 13],
- [232, 75, 12],
- [231, 73, 12],
- [229, 71, 11],
- [228, 69, 10],
- [226, 67, 10],
- [225, 65, 9],
- [223, 63, 8],
- [221, 61, 8],
- [220, 59, 7],
- [218, 57, 7],
- [216, 55, 6],
- [214, 53, 6],
- [212, 51, 5],
- [210, 49, 5],
- [208, 47, 5],
- [206, 45, 4],
- [204, 43, 4],
- [202, 42, 4],
- [200, 40, 3],
- [197, 38, 3],
- [195, 37, 3],
- [193, 35, 2],
- [190, 33, 2],
- [188, 32, 2],
- [185, 30, 2],
- [183, 29, 2],
- [180, 27, 1],
- [178, 26, 1],
- [175, 24, 1],
- [172, 23, 1],
- [169, 22, 1],
- [167, 20, 1],
- [164, 19, 1],
- [161, 18, 1],
- [158, 16, 1],
- [155, 15, 1],
- [152, 14, 1],
- [149, 13, 1],
- [146, 11, 1],
- [142, 10, 1],
- [139, 9, 2],
- [136, 8, 2],
- [133, 7, 2],
- [129, 6, 2],
- [126, 5, 2],
- [122, 4, 3],
-];
-var fosphor = [
- [6, 0, 13],
- [7, 0, 14],
- [7, 0, 15],
- [7, 0, 16],
- [7, 0, 17],
- [7, 0, 18],
- [7, 0, 18],
- [7, 0, 19],
- [7, 0, 20],
- [7, 0, 21],
- [7, 0, 22],
- [7, 0, 23],
- [7, 0, 24],
- [7, 0, 25],
- [7, 0, 26],
- [6, 0, 27],
- [6, 0, 28],
- [6, 0, 29],
- [5, 0, 30],
- [5, 0, 31],
- [5, 0, 32],
- [4, 0, 33],
- [4, 0, 34],
- [3, 0, 35],
- [3, 0, 36],
- [2, 0, 36],
- [2, 0, 37],
- [1, 0, 38],
- [0, 0, 39],
- [0, 0, 40],
- [0, 1, 41],
- [0, 2, 42],
- [0, 3, 43],
- [0, 4, 44],
- [0, 5, 45],
- [0, 5, 46],
- [0, 6, 47],
- [0, 7, 48],
- [0, 8, 49],
- [0, 9, 50],
- [0, 10, 51],
- [0, 12, 52],
- [0, 13, 53],
- [0, 14, 54],
- [0, 15, 55],
- [0, 16, 56],
- [0, 18, 56],
- [0, 19, 57],
- [0, 20, 58],
- [0, 22, 59],
- [0, 23, 60],
- [0, 24, 61],
- [0, 26, 62],
- [0, 27, 63],
- [0, 29, 64],
- [0, 31, 65],
- [0, 32, 66],
- [0, 34, 67],
- [0, 36, 68],
- [0, 37, 69],
- [0, 39, 70],
- [0, 41, 71],
- [0, 43, 72],
- [0, 44, 73],
- [0, 46, 74],
- [0, 48, 74],
- [0, 50, 75],
- [0, 52, 76],
- [0, 54, 77],
- [0, 56, 78],
- [0, 58, 79],
- [0, 60, 80],
- [0, 63, 81],
- [0, 65, 82],
- [0, 67, 83],
- [0, 69, 84],
- [0, 71, 85],
- [0, 74, 86],
- [0, 76, 87],
- [0, 79, 88],
- [0, 81, 89],
- [0, 83, 90],
- [0, 86, 91],
- [0, 88, 92],
- [0, 91, 93],
- [0, 94, 94],
- [0, 94, 93],
- [0, 95, 92],
- [0, 96, 91],
- [0, 97, 90],
- [0, 98, 90],
- [0, 99, 89],
- [0, 100, 88],
- [0, 101, 87],
- [0, 102, 86],
- [0, 103, 85],
- [0, 104, 84],
- [0, 105, 83],
- [0, 106, 82],
- [0, 107, 80],
- [0, 108, 79],
- [0, 109, 78],
- [0, 110, 77],
- [0, 111, 75],
- [0, 112, 74],
- [0, 112, 73],
- [0, 113, 71],
- [0, 114, 70],
- [0, 115, 69],
- [0, 116, 67],
- [0, 117, 66],
- [0, 118, 64],
- [0, 119, 62],
- [0, 120, 61],
- [0, 121, 59],
- [0, 122, 57],
- [0, 123, 56],
- [0, 124, 54],
- [0, 125, 52],
- [0, 126, 50],
- [0, 127, 48],
- [0, 128, 47],
- [0, 129, 45],
- [0, 130, 43],
- [0, 131, 41],
- [0, 132, 39],
- [0, 132, 37],
- [0, 133, 35],
- [0, 134, 32],
- [0, 135, 30],
- [0, 136, 28],
- [0, 137, 26],
- [0, 138, 24],
- [0, 139, 21],
- [0, 140, 19],
- [0, 141, 17],
- [0, 142, 14],
- [0, 143, 12],
- [0, 144, 9],
- [0, 145, 7],
- [0, 146, 4],
- [0, 147, 2],
- [1, 148, 0],
- [3, 149, 0],
- [6, 150, 0],
- [9, 150, 0],
- [12, 151, 0],
- [14, 152, 0],
- [17, 153, 0],
- [20, 154, 0],
- [23, 155, 0],
- [26, 156, 0],
- [29, 157, 0],
- [32, 158, 0],
- [35, 159, 0],
- [38, 160, 0],
- [41, 161, 0],
- [44, 162, 0],
- [47, 163, 0],
- [50, 164, 0],
- [53, 165, 0],
- [57, 166, 0],
- [60, 167, 0],
- [63, 168, 0],
- [66, 169, 0],
- [70, 170, 0],
- [73, 170, 0],
- [77, 171, 0],
- [80, 172, 0],
- [84, 173, 0],
- [87, 174, 0],
- [91, 175, 0],
- [94, 176, 0],
- [98, 177, 0],
- [102, 178, 0],
- [105, 179, 0],
- [109, 180, 0],
- [113, 181, 0],
- [117, 182, 0],
- [120, 183, 0],
- [124, 184, 0],
- [128, 185, 0],
- [132, 186, 0],
- [136, 187, 0],
- [140, 188, 0],
- [144, 188, 0],
- [148, 189, 0],
- [152, 190, 0],
- [156, 191, 0],
- [161, 192, 0],
- [165, 193, 0],
- [169, 194, 0],
- [173, 195, 0],
- [178, 196, 0],
- [182, 197, 0],
- [186, 198, 0],
- [191, 199, 0],
- [195, 200, 0],
- [200, 201, 0],
- [202, 199, 0],
- [203, 197, 0],
- [204, 194, 0],
- [205, 191, 0],
- [206, 189, 0],
- [207, 186, 0],
- [208, 183, 0],
- [208, 180, 0],
- [209, 177, 0],
- [210, 174, 0],
- [211, 172, 0],
- [212, 169, 0],
- [213, 166, 0],
- [214, 163, 0],
- [215, 159, 0],
- [216, 156, 0],
- [217, 153, 0],
- [218, 150, 0],
- [219, 147, 0],
- [220, 144, 0],
- [221, 140, 0],
- [222, 137, 0],
- [223, 134, 0],
- [224, 130, 0],
- [225, 127, 0],
- [226, 123, 0],
- [226, 120, 0],
- [227, 116, 0],
- [228, 113, 0],
- [229, 109, 0],
- [230, 106, 0],
- [231, 102, 0],
- [232, 98, 0],
- [233, 95, 0],
- [234, 91, 0],
- [235, 87, 0],
- [236, 83, 0],
- [237, 79, 0],
- [238, 76, 0],
- [239, 72, 0],
- [240, 68, 0],
- [241, 64, 0],
- [242, 60, 0],
- [243, 56, 0],
- [244, 52, 0],
- [245, 47, 0],
- [246, 43, 0],
- [246, 39, 0],
- [247, 35, 0],
- [248, 31, 0],
- [249, 26, 0],
- [250, 22, 0],
- [251, 18, 0],
- [252, 13, 0],
- [253, 9, 0],
- [254, 4, 0],
- [255, 0, 0],
-];
-var viridis = [
- [68, 1, 84],
- [68, 2, 86],
- [69, 4, 87],
- [69, 5, 89],
- [70, 7, 90],
- [70, 8, 92],
- [70, 10, 93],
- [70, 11, 94],
- [71, 13, 96],
- [71, 14, 97],
- [71, 16, 99],
- [71, 17, 100],
- [71, 19, 101],
- [72, 20, 103],
- [72, 22, 104],
- [72, 23, 105],
- [72, 24, 106],
- [72, 26, 108],
- [72, 27, 109],
- [72, 28, 110],
- [72, 29, 111],
- [72, 31, 112],
- [72, 32, 113],
- [72, 33, 115],
- [72, 35, 116],
- [72, 36, 117],
- [72, 37, 118],
- [72, 38, 119],
- [72, 40, 120],
- [72, 41, 121],
- [71, 42, 122],
- [71, 44, 122],
- [71, 45, 123],
- [71, 46, 124],
- [71, 47, 125],
- [70, 48, 126],
- [70, 50, 126],
- [70, 51, 127],
- [70, 52, 128],
- [69, 53, 129],
- [69, 55, 129],
- [69, 56, 130],
- [68, 57, 131],
- [68, 58, 131],
- [68, 59, 132],
- [67, 61, 132],
- [67, 62, 133],
- [66, 63, 133],
- [66, 64, 134],
- [66, 65, 134],
- [65, 66, 135],
- [65, 68, 135],
- [64, 69, 136],
- [64, 70, 136],
- [63, 71, 136],
- [63, 72, 137],
- [62, 73, 137],
- [62, 74, 137],
- [62, 76, 138],
- [61, 77, 138],
- [61, 78, 138],
- [60, 79, 138],
- [60, 80, 139],
- [59, 81, 139],
- [59, 82, 139],
- [58, 83, 139],
- [58, 84, 140],
- [57, 85, 140],
- [57, 86, 140],
- [56, 88, 140],
- [56, 89, 140],
- [55, 90, 140],
- [55, 91, 141],
- [54, 92, 141],
- [54, 93, 141],
- [53, 94, 141],
- [53, 95, 141],
- [52, 96, 141],
- [52, 97, 141],
- [51, 98, 141],
- [51, 99, 141],
- [50, 100, 142],
- [50, 101, 142],
- [49, 102, 142],
- [49, 103, 142],
- [49, 104, 142],
- [48, 105, 142],
- [48, 106, 142],
- [47, 107, 142],
- [47, 108, 142],
- [46, 109, 142],
- [46, 110, 142],
- [46, 111, 142],
- [45, 112, 142],
- [45, 113, 142],
- [44, 113, 142],
- [44, 114, 142],
- [44, 115, 142],
- [43, 116, 142],
- [43, 117, 142],
- [42, 118, 142],
- [42, 119, 142],
- [42, 120, 142],
- [41, 121, 142],
- [41, 122, 142],
- [41, 123, 142],
- [40, 124, 142],
- [40, 125, 142],
- [39, 126, 142],
- [39, 127, 142],
- [39, 128, 142],
- [38, 129, 142],
- [38, 130, 142],
- [38, 130, 142],
- [37, 131, 142],
- [37, 132, 142],
- [37, 133, 142],
- [36, 134, 142],
- [36, 135, 142],
- [35, 136, 142],
- [35, 137, 142],
- [35, 138, 141],
- [34, 139, 141],
- [34, 140, 141],
- [34, 141, 141],
- [33, 142, 141],
- [33, 143, 141],
- [33, 144, 141],
- [33, 145, 140],
- [32, 146, 140],
- [32, 146, 140],
- [32, 147, 140],
- [31, 148, 140],
- [31, 149, 139],
- [31, 150, 139],
- [31, 151, 139],
- [31, 152, 139],
- [31, 153, 138],
- [31, 154, 138],
- [30, 155, 138],
- [30, 156, 137],
- [30, 157, 137],
- [31, 158, 137],
- [31, 159, 136],
- [31, 160, 136],
- [31, 161, 136],
- [31, 161, 135],
- [31, 162, 135],
- [32, 163, 134],
- [32, 164, 134],
- [33, 165, 133],
- [33, 166, 133],
- [34, 167, 133],
- [34, 168, 132],
- [35, 169, 131],
- [36, 170, 131],
- [37, 171, 130],
- [37, 172, 130],
- [38, 173, 129],
- [39, 173, 129],
- [40, 174, 128],
- [41, 175, 127],
- [42, 176, 127],
- [44, 177, 126],
- [45, 178, 125],
- [46, 179, 124],
- [47, 180, 124],
- [49, 181, 123],
- [50, 182, 122],
- [52, 182, 121],
- [53, 183, 121],
- [55, 184, 120],
- [56, 185, 119],
- [58, 186, 118],
- [59, 187, 117],
- [61, 188, 116],
- [63, 188, 115],
- [64, 189, 114],
- [66, 190, 113],
- [68, 191, 112],
- [70, 192, 111],
- [72, 193, 110],
- [74, 193, 109],
- [76, 194, 108],
- [78, 195, 107],
- [80, 196, 106],
- [82, 197, 105],
- [84, 197, 104],
- [86, 198, 103],
- [88, 199, 101],
- [90, 200, 100],
- [92, 200, 99],
- [94, 201, 98],
- [96, 202, 96],
- [99, 203, 95],
- [101, 203, 94],
- [103, 204, 92],
- [105, 205, 91],
- [108, 205, 90],
- [110, 206, 88],
- [112, 207, 87],
- [115, 208, 86],
- [117, 208, 84],
- [119, 209, 83],
- [122, 209, 81],
- [124, 210, 80],
- [127, 211, 78],
- [129, 211, 77],
- [132, 212, 75],
- [134, 213, 73],
- [137, 213, 72],
- [139, 214, 70],
- [142, 214, 69],
- [144, 215, 67],
- [147, 215, 65],
- [149, 216, 64],
- [152, 216, 62],
- [155, 217, 60],
- [157, 217, 59],
- [160, 218, 57],
- [162, 218, 55],
- [165, 219, 54],
- [168, 219, 52],
- [170, 220, 50],
- [173, 220, 48],
- [176, 221, 47],
- [178, 221, 45],
- [181, 222, 43],
- [184, 222, 41],
- [186, 222, 40],
- [189, 223, 38],
- [192, 223, 37],
- [194, 223, 35],
- [197, 224, 33],
- [200, 224, 32],
- [202, 225, 31],
- [205, 225, 29],
- [208, 225, 28],
- [210, 226, 27],
- [213, 226, 26],
- [216, 226, 25],
- [218, 227, 25],
- [221, 227, 24],
- [223, 227, 24],
- [226, 228, 24],
- [229, 228, 25],
- [231, 228, 25],
- [234, 229, 26],
- [236, 229, 27],
- [239, 229, 28],
- [241, 229, 29],
- [244, 230, 30],
- [246, 230, 32],
- [248, 230, 33],
- [251, 231, 35],
- [253, 231, 37],
-];
-var inferno = [
- [0, 0, 4],
- [1, 0, 5],
- [1, 1, 6],
- [1, 1, 8],
- [2, 1, 10],
- [2, 2, 12],
- [2, 2, 14],
- [3, 2, 16],
- [4, 3, 18],
- [4, 3, 20],
- [5, 4, 23],
- [6, 4, 25],
- [7, 5, 27],
- [8, 5, 29],
- [9, 6, 31],
- [10, 7, 34],
- [11, 7, 36],
- [12, 8, 38],
- [13, 8, 41],
- [14, 9, 43],
- [16, 9, 45],
- [17, 10, 48],
- [18, 10, 50],
- [20, 11, 52],
- [21, 11, 55],
- [22, 11, 57],
- [24, 12, 60],
- [25, 12, 62],
- [27, 12, 65],
- [28, 12, 67],
- [30, 12, 69],
- [31, 12, 72],
- [33, 12, 74],
- [35, 12, 76],
- [36, 12, 79],
- [38, 12, 81],
- [40, 11, 83],
- [41, 11, 85],
- [43, 11, 87],
- [45, 11, 89],
- [47, 10, 91],
- [49, 10, 92],
- [50, 10, 94],
- [52, 10, 95],
- [54, 9, 97],
- [56, 9, 98],
- [57, 9, 99],
- [59, 9, 100],
- [61, 9, 101],
- [62, 9, 102],
- [64, 10, 103],
- [66, 10, 104],
- [68, 10, 104],
- [69, 10, 105],
- [71, 11, 106],
- [73, 11, 106],
- [74, 12, 107],
- [76, 12, 107],
- [77, 13, 108],
- [79, 13, 108],
- [81, 14, 108],
- [82, 14, 109],
- [84, 15, 109],
- [85, 15, 109],
- [87, 16, 110],
- [89, 16, 110],
- [90, 17, 110],
- [92, 18, 110],
- [93, 18, 110],
- [95, 19, 110],
- [97, 19, 110],
- [98, 20, 110],
- [100, 21, 110],
- [101, 21, 110],
- [103, 22, 110],
- [105, 22, 110],
- [106, 23, 110],
- [108, 24, 110],
- [109, 24, 110],
- [111, 25, 110],
- [113, 25, 110],
- [114, 26, 110],
- [116, 26, 110],
- [117, 27, 110],
- [119, 28, 109],
- [120, 28, 109],
- [122, 29, 109],
- [124, 29, 109],
- [125, 30, 109],
- [127, 30, 108],
- [128, 31, 108],
- [130, 32, 108],
- [132, 32, 107],
- [133, 33, 107],
- [135, 33, 107],
- [136, 34, 106],
- [138, 34, 106],
- [140, 35, 105],
- [141, 35, 105],
- [143, 36, 105],
- [144, 37, 104],
- [146, 37, 104],
- [147, 38, 103],
- [149, 38, 103],
- [151, 39, 102],
- [152, 39, 102],
- [154, 40, 101],
- [155, 41, 100],
- [157, 41, 100],
- [159, 42, 99],
- [160, 42, 99],
- [162, 43, 98],
- [163, 44, 97],
- [165, 44, 96],
- [166, 45, 96],
- [168, 46, 95],
- [169, 46, 94],
- [171, 47, 94],
- [173, 48, 93],
- [174, 48, 92],
- [176, 49, 91],
- [177, 50, 90],
- [179, 50, 90],
- [180, 51, 89],
- [182, 52, 88],
- [183, 53, 87],
- [185, 53, 86],
- [186, 54, 85],
- [188, 55, 84],
- [189, 56, 83],
- [191, 57, 82],
- [192, 58, 81],
- [193, 58, 80],
- [195, 59, 79],
- [196, 60, 78],
- [198, 61, 77],
- [199, 62, 76],
- [200, 63, 75],
- [202, 64, 74],
- [203, 65, 73],
- [204, 66, 72],
- [206, 67, 71],
- [207, 68, 70],
- [208, 69, 69],
- [210, 70, 68],
- [211, 71, 67],
- [212, 72, 66],
- [213, 74, 65],
- [215, 75, 63],
- [216, 76, 62],
- [217, 77, 61],
- [218, 78, 60],
- [219, 80, 59],
- [221, 81, 58],
- [222, 82, 56],
- [223, 83, 55],
- [224, 85, 54],
- [225, 86, 53],
- [226, 87, 52],
- [227, 89, 51],
- [228, 90, 49],
- [229, 92, 48],
- [230, 93, 47],
- [231, 94, 46],
- [232, 96, 45],
- [233, 97, 43],
- [234, 99, 42],
- [235, 100, 41],
- [235, 102, 40],
- [236, 103, 38],
- [237, 105, 37],
- [238, 106, 36],
- [239, 108, 35],
- [239, 110, 33],
- [240, 111, 32],
- [241, 113, 31],
- [241, 115, 29],
- [242, 116, 28],
- [243, 118, 27],
- [243, 120, 25],
- [244, 121, 24],
- [245, 123, 23],
- [245, 125, 21],
- [246, 126, 20],
- [246, 128, 19],
- [247, 130, 18],
- [247, 132, 16],
- [248, 133, 15],
- [248, 135, 14],
- [248, 137, 12],
- [249, 139, 11],
- [249, 140, 10],
- [249, 142, 9],
- [250, 144, 8],
- [250, 146, 7],
- [250, 148, 7],
- [251, 150, 6],
- [251, 151, 6],
- [251, 153, 6],
- [251, 155, 6],
- [251, 157, 7],
- [252, 159, 7],
- [252, 161, 8],
- [252, 163, 9],
- [252, 165, 10],
- [252, 166, 12],
- [252, 168, 13],
- [252, 170, 15],
- [252, 172, 17],
- [252, 174, 18],
- [252, 176, 20],
- [252, 178, 22],
- [252, 180, 24],
- [251, 182, 26],
- [251, 184, 29],
- [251, 186, 31],
- [251, 188, 33],
- [251, 190, 35],
- [250, 192, 38],
- [250, 194, 40],
- [250, 196, 42],
- [250, 198, 45],
- [249, 199, 47],
- [249, 201, 50],
- [249, 203, 53],
- [248, 205, 55],
- [248, 207, 58],
- [247, 209, 61],
- [247, 211, 64],
- [246, 213, 67],
- [246, 215, 70],
- [245, 217, 73],
- [245, 219, 76],
- [244, 221, 79],
- [244, 223, 83],
- [244, 225, 86],
- [243, 227, 90],
- [243, 229, 93],
- [242, 230, 97],
- [242, 232, 101],
- [242, 234, 105],
- [241, 236, 109],
- [241, 237, 113],
- [241, 239, 117],
- [241, 241, 121],
- [242, 242, 125],
- [242, 244, 130],
- [243, 245, 134],
- [243, 246, 138],
- [244, 248, 142],
- [245, 249, 146],
- [246, 250, 150],
- [248, 251, 154],
- [249, 252, 157],
- [250, 253, 161],
- [252, 255, 164],
-];
-var magma = [
- [0, 0, 4],
- [1, 0, 5],
- [1, 1, 6],
- [1, 1, 8],
- [2, 1, 9],
- [2, 2, 11],
- [2, 2, 13],
- [3, 3, 15],
- [3, 3, 18],
- [4, 4, 20],
- [5, 4, 22],
- [6, 5, 24],
- [6, 5, 26],
- [7, 6, 28],
- [8, 7, 30],
- [9, 7, 32],
- [10, 8, 34],
- [11, 9, 36],
- [12, 9, 38],
- [13, 10, 41],
- [14, 11, 43],
- [16, 11, 45],
- [17, 12, 47],
- [18, 13, 49],
- [19, 13, 52],
- [20, 14, 54],
- [21, 14, 56],
- [22, 15, 59],
- [24, 15, 61],
- [25, 16, 63],
- [26, 16, 66],
- [28, 16, 68],
- [29, 17, 71],
- [30, 17, 73],
- [32, 17, 75],
- [33, 17, 78],
- [34, 17, 80],
- [36, 18, 83],
- [37, 18, 85],
- [39, 18, 88],
- [41, 17, 90],
- [42, 17, 92],
- [44, 17, 95],
- [45, 17, 97],
- [47, 17, 99],
- [49, 17, 101],
- [51, 16, 103],
- [52, 16, 105],
- [54, 16, 107],
- [56, 16, 108],
- [57, 15, 110],
- [59, 15, 112],
- [61, 15, 113],
- [63, 15, 114],
- [64, 15, 116],
- [66, 15, 117],
- [68, 15, 118],
- [69, 16, 119],
- [71, 16, 120],
- [73, 16, 120],
- [74, 16, 121],
- [76, 17, 122],
- [78, 17, 123],
- [79, 18, 123],
- [81, 18, 124],
- [82, 19, 124],
- [84, 19, 125],
- [86, 20, 125],
- [87, 21, 126],
- [89, 21, 126],
- [90, 22, 126],
- [92, 22, 127],
- [93, 23, 127],
- [95, 24, 127],
- [96, 24, 128],
- [98, 25, 128],
- [100, 26, 128],
- [101, 26, 128],
- [103, 27, 128],
- [104, 28, 129],
- [106, 28, 129],
- [107, 29, 129],
- [109, 29, 129],
- [110, 30, 129],
- [112, 31, 129],
- [114, 31, 129],
- [115, 32, 129],
- [117, 33, 129],
- [118, 33, 129],
- [120, 34, 129],
- [121, 34, 130],
- [123, 35, 130],
- [124, 35, 130],
- [126, 36, 130],
- [128, 37, 130],
- [129, 37, 129],
- [131, 38, 129],
- [132, 38, 129],
- [134, 39, 129],
- [136, 39, 129],
- [137, 40, 129],
- [139, 41, 129],
- [140, 41, 129],
- [142, 42, 129],
- [144, 42, 129],
- [145, 43, 129],
- [147, 43, 128],
- [148, 44, 128],
- [150, 44, 128],
- [152, 45, 128],
- [153, 45, 128],
- [155, 46, 127],
- [156, 46, 127],
- [158, 47, 127],
- [160, 47, 127],
- [161, 48, 126],
- [163, 48, 126],
- [165, 49, 126],
- [166, 49, 125],
- [168, 50, 125],
- [170, 51, 125],
- [171, 51, 124],
- [173, 52, 124],
- [174, 52, 123],
- [176, 53, 123],
- [178, 53, 123],
- [179, 54, 122],
- [181, 54, 122],
- [183, 55, 121],
- [184, 55, 121],
- [186, 56, 120],
- [188, 57, 120],
- [189, 57, 119],
- [191, 58, 119],
- [192, 58, 118],
- [194, 59, 117],
- [196, 60, 117],
- [197, 60, 116],
- [199, 61, 115],
- [200, 62, 115],
- [202, 62, 114],
- [204, 63, 113],
- [205, 64, 113],
- [207, 64, 112],
- [208, 65, 111],
- [210, 66, 111],
- [211, 67, 110],
- [213, 68, 109],
- [214, 69, 108],
- [216, 69, 108],
- [217, 70, 107],
- [219, 71, 106],
- [220, 72, 105],
- [222, 73, 104],
- [223, 74, 104],
- [224, 76, 103],
- [226, 77, 102],
- [227, 78, 101],
- [228, 79, 100],
- [229, 80, 100],
- [231, 82, 99],
- [232, 83, 98],
- [233, 84, 98],
- [234, 86, 97],
- [235, 87, 96],
- [236, 88, 96],
- [237, 90, 95],
- [238, 91, 94],
- [239, 93, 94],
- [240, 95, 94],
- [241, 96, 93],
- [242, 98, 93],
- [242, 100, 92],
- [243, 101, 92],
- [244, 103, 92],
- [244, 105, 92],
- [245, 107, 92],
- [246, 108, 92],
- [246, 110, 92],
- [247, 112, 92],
- [247, 114, 92],
- [248, 116, 92],
- [248, 118, 92],
- [249, 120, 93],
- [249, 121, 93],
- [249, 123, 93],
- [250, 125, 94],
- [250, 127, 94],
- [250, 129, 95],
- [251, 131, 95],
- [251, 133, 96],
- [251, 135, 97],
- [252, 137, 97],
- [252, 138, 98],
- [252, 140, 99],
- [252, 142, 100],
- [252, 144, 101],
- [253, 146, 102],
- [253, 148, 103],
- [253, 150, 104],
- [253, 152, 105],
- [253, 154, 106],
- [253, 155, 107],
- [254, 157, 108],
- [254, 159, 109],
- [254, 161, 110],
- [254, 163, 111],
- [254, 165, 113],
- [254, 167, 114],
- [254, 169, 115],
- [254, 170, 116],
- [254, 172, 118],
- [254, 174, 119],
- [254, 176, 120],
- [254, 178, 122],
- [254, 180, 123],
- [254, 182, 124],
- [254, 183, 126],
- [254, 185, 127],
- [254, 187, 129],
- [254, 189, 130],
- [254, 191, 132],
- [254, 193, 133],
- [254, 194, 135],
- [254, 196, 136],
- [254, 198, 138],
- [254, 200, 140],
- [254, 202, 141],
- [254, 204, 143],
- [254, 205, 144],
- [254, 207, 146],
- [254, 209, 148],
- [254, 211, 149],
- [254, 213, 151],
- [254, 215, 153],
- [254, 216, 154],
- [253, 218, 156],
- [253, 220, 158],
- [253, 222, 160],
- [253, 224, 161],
- [253, 226, 163],
- [253, 227, 165],
- [253, 229, 167],
- [253, 231, 169],
- [253, 233, 170],
- [253, 235, 172],
- [252, 236, 174],
- [252, 238, 176],
- [252, 240, 178],
- [252, 242, 180],
- [252, 244, 182],
- [252, 246, 184],
- [252, 247, 185],
- [252, 249, 187],
- [252, 251, 189],
- [252, 253, 191],
-];
-var jet = [
- [0, 0, 128],
- [0, 0, 132],
- [0, 0, 137],
- [0, 0, 141],
- [0, 0, 146],
- [0, 0, 150],
- [0, 0, 155],
- [0, 0, 159],
- [0, 0, 164],
- [0, 0, 168],
- [0, 0, 173],
- [0, 0, 178],
- [0, 0, 182],
- [0, 0, 187],
- [0, 0, 191],
- [0, 0, 196],
- [0, 0, 200],
- [0, 0, 205],
- [0, 0, 209],
- [0, 0, 214],
- [0, 0, 218],
- [0, 0, 223],
- [0, 0, 227],
- [0, 0, 232],
- [0, 0, 237],
- [0, 0, 241],
- [0, 0, 246],
- [0, 0, 250],
- [0, 0, 255],
- [0, 0, 255],
- [0, 0, 255],
- [0, 0, 255],
- [0, 0, 255],
- [0, 4, 255],
- [0, 8, 255],
- [0, 12, 255],
- [0, 16, 255],
- [0, 20, 255],
- [0, 24, 255],
- [0, 28, 255],
- [0, 32, 255],
- [0, 36, 255],
- [0, 40, 255],
- [0, 44, 255],
- [0, 48, 255],
- [0, 52, 255],
- [0, 56, 255],
- [0, 60, 255],
- [0, 64, 255],
- [0, 68, 255],
- [0, 72, 255],
- [0, 76, 255],
- [0, 80, 255],
- [0, 84, 255],
- [0, 88, 255],
- [0, 92, 255],
- [0, 96, 255],
- [0, 100, 255],
- [0, 104, 255],
- [0, 108, 255],
- [0, 112, 255],
- [0, 116, 255],
- [0, 120, 255],
- [0, 124, 255],
- [0, 128, 255],
- [0, 132, 255],
- [0, 136, 255],
- [0, 140, 255],
- [0, 144, 255],
- [0, 148, 255],
- [0, 152, 255],
- [0, 156, 255],
- [0, 160, 255],
- [0, 164, 255],
- [0, 168, 255],
- [0, 172, 255],
- [0, 176, 255],
- [0, 180, 255],
- [0, 184, 255],
- [0, 188, 255],
- [0, 192, 255],
- [0, 196, 255],
- [0, 200, 255],
- [0, 204, 255],
- [0, 208, 255],
- [0, 212, 255],
- [0, 216, 255],
- [0, 220, 254],
- [0, 224, 251],
- [0, 228, 248],
- [2, 232, 244],
- [6, 236, 241],
- [9, 240, 238],
- [12, 244, 235],
- [15, 248, 231],
- [19, 252, 228],
- [22, 255, 225],
- [25, 255, 222],
- [28, 255, 219],
- [31, 255, 215],
- [35, 255, 212],
- [38, 255, 209],
- [41, 255, 206],
- [44, 255, 202],
- [48, 255, 199],
- [51, 255, 196],
- [54, 255, 193],
- [57, 255, 190],
- [60, 255, 186],
- [64, 255, 183],
- [67, 255, 180],
- [70, 255, 177],
- [73, 255, 173],
- [77, 255, 170],
- [80, 255, 167],
- [83, 255, 164],
- [86, 255, 160],
- [90, 255, 157],
- [93, 255, 154],
- [96, 255, 151],
- [99, 255, 148],
- [102, 255, 144],
- [106, 255, 141],
- [109, 255, 138],
- [112, 255, 135],
- [115, 255, 131],
- [119, 255, 128],
- [122, 255, 125],
- [125, 255, 122],
- [128, 255, 119],
- [131, 255, 115],
- [135, 255, 112],
- [138, 255, 109],
- [141, 255, 106],
- [144, 255, 102],
- [148, 255, 99],
- [151, 255, 96],
- [154, 255, 93],
- [157, 255, 90],
- [160, 255, 86],
- [164, 255, 83],
- [167, 255, 80],
- [170, 255, 77],
- [173, 255, 73],
- [177, 255, 70],
- [180, 255, 67],
- [183, 255, 64],
- [186, 255, 60],
- [190, 255, 57],
- [193, 255, 54],
- [196, 255, 51],
- [199, 255, 48],
- [202, 255, 44],
- [206, 255, 41],
- [209, 255, 38],
- [212, 255, 35],
- [215, 255, 31],
- [219, 255, 28],
- [222, 255, 25],
- [225, 255, 22],
- [228, 255, 19],
- [231, 255, 15],
- [235, 255, 12],
- [238, 255, 9],
- [241, 252, 6],
- [244, 248, 2],
- [248, 245, 0],
- [251, 241, 0],
- [254, 237, 0],
- [255, 234, 0],
- [255, 230, 0],
- [255, 226, 0],
- [255, 222, 0],
- [255, 219, 0],
- [255, 215, 0],
- [255, 211, 0],
- [255, 208, 0],
- [255, 204, 0],
- [255, 200, 0],
- [255, 196, 0],
- [255, 193, 0],
- [255, 189, 0],
- [255, 185, 0],
- [255, 182, 0],
- [255, 178, 0],
- [255, 174, 0],
- [255, 171, 0],
- [255, 167, 0],
- [255, 163, 0],
- [255, 159, 0],
- [255, 156, 0],
- [255, 152, 0],
- [255, 148, 0],
- [255, 145, 0],
- [255, 141, 0],
- [255, 137, 0],
- [255, 134, 0],
- [255, 130, 0],
- [255, 126, 0],
- [255, 122, 0],
- [255, 119, 0],
- [255, 115, 0],
- [255, 111, 0],
- [255, 108, 0],
- [255, 104, 0],
- [255, 100, 0],
- [255, 96, 0],
- [255, 93, 0],
- [255, 89, 0],
- [255, 85, 0],
- [255, 82, 0],
- [255, 78, 0],
- [255, 74, 0],
- [255, 71, 0],
- [255, 67, 0],
- [255, 63, 0],
- [255, 59, 0],
- [255, 56, 0],
- [255, 52, 0],
- [255, 48, 0],
- [255, 45, 0],
- [255, 41, 0],
- [255, 37, 0],
- [255, 34, 0],
- [255, 30, 0],
- [255, 26, 0],
- [255, 22, 0],
- [255, 19, 0],
- [250, 15, 0],
- [246, 11, 0],
- [241, 8, 0],
- [237, 4, 0],
- [232, 0, 0],
- [228, 0, 0],
- [223, 0, 0],
- [218, 0, 0],
- [214, 0, 0],
- [209, 0, 0],
- [205, 0, 0],
- [200, 0, 0],
- [196, 0, 0],
- [191, 0, 0],
- [187, 0, 0],
- [182, 0, 0],
- [178, 0, 0],
- [173, 0, 0],
- [168, 0, 0],
- [164, 0, 0],
- [159, 0, 0],
- [155, 0, 0],
- [150, 0, 0],
- [146, 0, 0],
- [141, 0, 0],
- [137, 0, 0],
- [132, 0, 0],
- [128, 0, 0],
-];
-var binary = [
- [255, 255, 255],
- [254, 254, 254],
- [253, 253, 253],
- [252, 252, 252],
- [251, 251, 251],
- [250, 250, 250],
- [249, 249, 249],
- [248, 248, 248],
- [247, 247, 247],
- [246, 246, 246],
- [245, 245, 245],
- [244, 244, 244],
- [243, 243, 243],
- [242, 242, 242],
- [241, 241, 241],
- [240, 240, 240],
- [239, 239, 239],
- [238, 238, 238],
- [237, 237, 237],
- [236, 236, 236],
- [235, 235, 235],
- [234, 234, 234],
- [233, 233, 233],
- [232, 232, 232],
- [231, 231, 231],
- [230, 230, 230],
- [229, 229, 229],
- [228, 228, 228],
- [227, 227, 227],
- [226, 226, 226],
- [225, 225, 225],
- [224, 224, 224],
- [223, 223, 223],
- [222, 222, 222],
- [221, 221, 221],
- [220, 220, 220],
- [219, 219, 219],
- [218, 218, 218],
- [217, 217, 217],
- [216, 216, 216],
- [215, 215, 215],
- [214, 214, 214],
- [213, 213, 213],
- [212, 212, 212],
- [211, 211, 211],
- [210, 210, 210],
- [209, 209, 209],
- [208, 208, 208],
- [207, 207, 207],
- [206, 206, 206],
- [205, 205, 205],
- [204, 204, 204],
- [203, 203, 203],
- [202, 202, 202],
- [201, 201, 201],
- [200, 200, 200],
- [199, 199, 199],
- [198, 198, 198],
- [197, 197, 197],
- [196, 196, 196],
- [195, 195, 195],
- [194, 194, 194],
- [193, 193, 193],
- [192, 192, 192],
- [191, 191, 191],
- [190, 190, 190],
- [189, 189, 189],
- [188, 188, 188],
- [187, 187, 187],
- [186, 186, 186],
- [185, 185, 185],
- [184, 184, 184],
- [183, 183, 183],
- [182, 182, 182],
- [181, 181, 181],
- [180, 180, 180],
- [179, 179, 179],
- [178, 178, 178],
- [177, 177, 177],
- [176, 176, 176],
- [175, 175, 175],
- [174, 174, 174],
- [173, 173, 173],
- [172, 172, 172],
- [171, 171, 171],
- [170, 170, 170],
- [169, 169, 169],
- [168, 168, 168],
- [167, 167, 167],
- [166, 166, 166],
- [165, 165, 165],
- [164, 164, 164],
- [163, 163, 163],
- [162, 162, 162],
- [161, 161, 161],
- [160, 160, 160],
- [159, 159, 159],
- [158, 158, 158],
- [157, 157, 157],
- [156, 156, 156],
- [155, 155, 155],
- [154, 154, 154],
- [153, 153, 153],
- [152, 152, 152],
- [151, 151, 151],
- [150, 150, 150],
- [149, 149, 149],
- [148, 148, 148],
- [147, 147, 147],
- [146, 146, 146],
- [145, 145, 145],
- [144, 144, 144],
- [143, 143, 143],
- [142, 142, 142],
- [141, 141, 141],
- [140, 140, 140],
- [139, 139, 139],
- [138, 138, 138],
- [137, 137, 137],
- [136, 136, 136],
- [135, 135, 135],
- [134, 134, 134],
- [133, 133, 133],
- [132, 132, 132],
- [131, 131, 131],
- [130, 130, 130],
- [129, 129, 129],
- [128, 128, 128],
- [127, 127, 127],
- [126, 126, 126],
- [125, 125, 125],
- [124, 124, 124],
- [123, 123, 123],
- [122, 122, 122],
- [121, 121, 121],
- [120, 120, 120],
- [119, 119, 119],
- [118, 118, 118],
- [117, 117, 117],
- [116, 116, 116],
- [115, 115, 115],
- [114, 114, 114],
- [113, 113, 113],
- [112, 112, 112],
- [111, 111, 111],
- [110, 110, 110],
- [109, 109, 109],
- [108, 108, 108],
- [107, 107, 107],
- [106, 106, 106],
- [105, 105, 105],
- [104, 104, 104],
- [103, 103, 103],
- [102, 102, 102],
- [101, 101, 101],
- [100, 100, 100],
- [99, 99, 99],
- [98, 98, 98],
- [97, 97, 97],
- [96, 96, 96],
- [95, 95, 95],
- [94, 94, 94],
- [93, 93, 93],
- [92, 92, 92],
- [91, 91, 91],
- [90, 90, 90],
- [89, 89, 89],
- [88, 88, 88],
- [87, 87, 87],
- [86, 86, 86],
- [85, 85, 85],
- [84, 84, 84],
- [83, 83, 83],
- [82, 82, 82],
- [81, 81, 81],
- [80, 80, 80],
- [79, 79, 79],
- [78, 78, 78],
- [77, 77, 77],
- [76, 76, 76],
- [75, 75, 75],
- [74, 74, 74],
- [73, 73, 73],
- [72, 72, 72],
- [71, 71, 71],
- [70, 70, 70],
- [69, 69, 69],
- [68, 68, 68],
- [67, 67, 67],
- [66, 66, 66],
- [65, 65, 65],
- [64, 64, 64],
- [63, 63, 63],
- [62, 62, 62],
- [61, 61, 61],
- [60, 60, 60],
- [59, 59, 59],
- [58, 58, 58],
- [57, 57, 57],
- [56, 56, 56],
- [55, 55, 55],
- [54, 54, 54],
- [53, 53, 53],
- [52, 52, 52],
- [51, 51, 51],
- [50, 50, 50],
- [49, 49, 49],
- [48, 48, 48],
- [47, 47, 47],
- [46, 46, 46],
- [45, 45, 45],
- [44, 44, 44],
- [43, 43, 43],
- [42, 42, 42],
- [41, 41, 41],
- [40, 40, 40],
- [39, 39, 39],
- [38, 38, 38],
- [37, 37, 37],
- [36, 36, 36],
- [35, 35, 35],
- [34, 34, 34],
- [33, 33, 33],
- [32, 32, 32],
- [31, 31, 31],
- [30, 30, 30],
- [29, 29, 29],
- [28, 28, 28],
- [27, 27, 27],
- [26, 26, 26],
- [25, 25, 25],
- [24, 24, 24],
- [23, 23, 23],
- [22, 22, 22],
- [21, 21, 21],
- [20, 20, 20],
- [19, 19, 19],
- [18, 18, 18],
- [17, 17, 17],
- [16, 16, 16],
- [15, 15, 15],
- [14, 14, 14],
- [13, 13, 13],
- [12, 12, 12],
- [11, 11, 11],
- [10, 10, 10],
- [9, 9, 9],
- [8, 8, 8],
- [7, 7, 7],
- [6, 6, 6],
- [5, 5, 5],
- [4, 4, 4],
- [3, 3, 3],
- [2, 2, 2],
- [1, 1, 1],
- [0, 0, 0],
-];
-var colormaps = [turbo, fosphor, viridis, inferno, magma, jet, binary];
diff --git a/gui_vue/src/assets/waterfall/index.html b/gui_vue/src/assets/waterfall/index.html
deleted file mode 100644
index 46cd68aa..00000000
--- a/gui_vue/src/assets/waterfall/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
- Spectrum Plot
-
-
-
-
-
-
-
-
-
-
diff --git a/gui_vue/src/assets/waterfall/make_colormap.py b/gui_vue/src/assets/waterfall/make_colormap.py
deleted file mode 100644
index 784559ee..00000000
--- a/gui_vue/src/assets/waterfall/make_colormap.py
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env python
-
-import matplotlib.pyplot as plt
-
-colormaps = ('viridis', 'inferno', 'magma', 'jet', 'binary')
-for c in colormaps:
- cmap_name = c
- cmap = plt.get_cmap(cmap_name)
-
- colors = [[int(round(255 * x)) for x in cmap(i)[:3]] for i in range(256)]
- print(f'var {c} = {colors}')
-
-print(f'var colormaps = [{", ".join(colormaps)}];')
diff --git a/gui_vue/src/assets/waterfall/script.js b/gui_vue/src/assets/waterfall/script.js
deleted file mode 100644
index c9196b2a..00000000
--- a/gui_vue/src/assets/waterfall/script.js
+++ /dev/null
@@ -1,62 +0,0 @@
-"use strict";
-/*
-function connectWebSocket(spectrum) {
-// var ws = new WebSocket("ws://" + window.location.host + "/websocket");
- var ws = new WebSocket("ws://192.168.178.163:3000");
-
-
- ws.onopen = function(evt) {
- console.log("connected!");
- }
- ws.onclose = function(evt) {
- console.log("closed");
- setTimeout(function() {
- connectWebSocket(spectrum);
- }, 1000);
- }
- ws.onerror = function(evt) {
- console.log("error: " + evt.message);
- }
- ws.onmessage = function (evt) {
- var data = JSON.parse(evt.data);
- if (data.s) {
- spectrum.addData(data.s);
- } else {
- if (data.center) {
- spectrum.setCenterHz(data.center);
- }
- if (data.span) {
- spectrum.setSpanHz(data.span);
- }
- }
- }
-}
-*/
-
-function main() {
- // Create spectrum object on canvas with ID "waterfall"
- var spectrum = new Spectrum("waterfall", {
- spectrumPercent: 20,
- });
-
- // Connect to websocket
- //connectWebSocket(spectrum);
-
- //spectrum.setCenterHz("2000");
- //spectrum.setSpanHz("1");
-
- /*
-for (var i = 0; i < 1000; i++) {
- var randomstring = Math.floor(Math.random())
- spectrum.addData(randomstring.toString());
- // more statements
-}
-*/
-
- // Bind keypress handler
- window.addEventListener("keydown", function (e) {
- spectrum.onKeypress(e);
- });
-}
-
-window.onload = main;
diff --git a/gui_vue/src/assets/waterfall/server.py b/gui_vue/src/assets/waterfall/server.py
deleted file mode 100644
index a6402bc2..00000000
--- a/gui_vue/src/assets/waterfall/server.py
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2019 Jeppe Ledet-Pedersen
-# This software is released under the MIT license.
-# See the LICENSE file for further details.
-
-import sys
-import json
-import argparse
-
-from gnuradio import gr
-from gnuradio import uhd
-from gnuradio.fft import logpwrfft
-
-import numpy as np
-
-from gevent.pywsgi import WSGIServer
-from geventwebsocket import WebSocketError
-from geventwebsocket.handler import WebSocketHandler
-
-from bottle import request, Bottle, abort, static_file
-
-
-app = Bottle()
-connections = set()
-opts = {}
-
-
-@app.route('/websocket')
-def handle_websocket():
- wsock = request.environ.get('wsgi.websocket')
- if not wsock:
- abort(400, 'Expected WebSocket request.')
-
- connections.add(wsock)
-
- # Send center frequency and span
- wsock.send(json.dumps(opts))
-
- while True:
- try:
- wsock.receive()
- except WebSocketError:
- break
-
- connections.remove(wsock)
-
-
-@app.route('/')
-def index():
- return static_file('index.html', root='.')
-
-
-@app.route('/')
-def static(filename):
- return static_file(filename, root='.')
-
-
-class fft_broadcast_sink(gr.sync_block):
- def __init__(self, fft_size):
- gr.sync_block.__init__(self,
- name="plotter",
- in_sig=[(np.float32, fft_size)],
- out_sig=[])
-
- def work(self, input_items, output_items):
- ninput_items = len(input_items[0])
-
- for bins in input_items[0]:
- p = np.around(bins).astype(int)
- p = np.fft.fftshift(p)
- for c in connections.copy():
- try:
- c.send(json.dumps({'s': p.tolist()}, separators=(',', ':')))
- except Exception:
- connections.remove(c)
-
- self.consume(0, ninput_items)
-
- return 0
-
-
-class fft_receiver(gr.top_block):
- def __init__(self, samp_rate, freq, gain, fft_size, framerate):
- gr.top_block.__init__(self, "Top Block")
-
- self.usrp = uhd.usrp_source(
- ",".join(("", "")),
- uhd.stream_args(
- cpu_format="fc32",
- channels=range(1),
- ),
- )
- self.usrp.set_samp_rate(samp_rate)
- self.usrp.set_center_freq(freq, 0)
- self.usrp.set_gain(gain, 0)
-
- self.fft = logpwrfft.logpwrfft_c(
- sample_rate=samp_rate,
- fft_size=fft_size,
- ref_scale=1,
- frame_rate=framerate,
- avg_alpha=1,
- average=False,
- )
- self.fft_broadcast = fft_broadcast_sink(fft_size)
-
- self.connect((self.fft, 0), (self.fft_broadcast, 0))
- self.connect((self.usrp, 0), (self.fft, 0))
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('-s', '--sample-rate', type=float, default=40e6)
- parser.add_argument('-f', '--frequency', type=float, default=940e6)
- parser.add_argument('-g', '--gain', type=float, default=40)
- parser.add_argument('-n', '--fft-size', type=int, default=4096)
- parser.add_argument('-r', '--frame-rate', type=int, default=25)
-
- args = parser.parse_args()
-
- if gr.enable_realtime_scheduling() != gr.RT_OK or 0:
- print("Error: failed to enable real-time scheduling.")
-
- tb = fft_receiver(
- samp_rate=args.sample_rate,
- freq=args.frequency,
- gain=args.gain,
- fft_size=args.fft_size,
- framerate=args.frame_rate
- )
- tb.start()
-
- opts['center'] = args.frequency
- opts['span'] = args.sample_rate
-
- server = WSGIServer(("0.0.0.0", 8000), app,
- handler_class=WebSocketHandler)
- try:
- server.serve_forever()
- except Exception:
- sys.exit(0)
-
- tb.stop()
- tb.wait()
-
-
-if __name__ == '__main__':
- main()
diff --git a/gui_vue/src/assets/waterfall/waterfall.css b/gui_vue/src/assets/waterfall/waterfall.css
deleted file mode 100644
index 8885bbdb..00000000
--- a/gui_vue/src/assets/waterfall/waterfall.css
+++ /dev/null
@@ -1,12 +0,0 @@
-html,
-body {
- width: 100%;
- height: 100%;
- margin: 0px;
-}
-
-#waterfall {
- display: block;
- width: 100%;
- height: 100%;
-}
diff --git a/gui_vue/src/styles.css b/gui_vue/src/styles.css
deleted file mode 100644
index 79ba714b..00000000
--- a/gui_vue/src/styles.css
+++ /dev/null
@@ -1,117 +0,0 @@
-/* disable scrolling in main window */
-body {
- padding-right: 0px !important;
- overflow-y: hidden !important;
- overflow-x: hidden !important;
-}
-
-/*Progress bars with centered text*/
-.progress {
- position: relative;
- transform: translateZ(0);
-}
-
-.progress span {
- position: absolute;
- display: block;
- width: 100%;
- color: black;
-}
-
-/* smooth scrolling */
-html {
- scroll-behavior: smooth;
-}
-
-/* hide scrollbar in callsign list */
-#callsignlist::-webkit-scrollbar {
- display: none;
-}
-
-#chatModuleMessage {
- resize: none;
-}
-
-#expand_textarea_label {
- border: 0;
- padding: 1px;
-}
-
-/* fixed border table header */
-.tableFixHead {
- overflow: auto;
- height: 90vh;
-}
-.tableFixHead thead th {
- position: sticky;
- top: 0;
- z-index: 1;
-}
-table {
- border-collapse: collapse;
- width: 100%;
-}
-th,
-td {
- padding: 8px 16px;
-}
-
-th {
- background: #eee;
-}
-
-/* ------ emoji picker customization --------- */
-.picker {
- border-radius: 10px;
-}
-
-/* force gpu usage
-https://stackoverflow.com/questions/13176746/css-keyframe-animation-cpu-usage-is-high-should-it-be-this-way/13293044#13293044
-*/
-
-.force-gpu {
- transform: translateZ(0);
- -webkit-transform: translateZ(0);
- -ms-transform: translateZ(0);
- will-change: transform;
-}
-
-/* force disable transition effects
-https://stackoverflow.com/a/9622873
-*/
-.disable-effects {
- -webkit-transition: none;
- -moz-transition: none;
- -ms-transition: none;
- -o-transition: none;
- transition: none;
-}
-
-/* image overlay */
-
-.image-overlay:hover {
- opacity: 0.75 !important;
- transition: 0.5s;
-}
-
-/* theme area */
-
-/* default light theme mods */
-[data-bs-theme="light"] {
- .card-header {
- background-color: var(--bs-card-cap-bg);
- /*--bs-card-cap-bg: rgba(var(--bs-body-color-rgb), 0.3);*/
- }
-}
-/* default dark theme mods */
-[data-bs-theme="dark"] {
- /* default dark theme mods */
-}
-.modal-backdrop {
- background-color: transparent;
-}
-
-.modal-backdrop.in {
- filter: alpha(opacity=10);
- opacity: .1
-}