Merge pull request #334 from DJ2LS/ls-gui

This commit is contained in:
DJ2LS 2023-01-28 09:18:16 +01:00 committed by GitHub
commit d4138da879
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 538 additions and 269 deletions

View file

@ -16,8 +16,10 @@ const mainLog = log.scope('main');
const daemonProcessLog = log.scope('freedata-daemon'); const daemonProcessLog = log.scope('freedata-daemon');
const mime = require('mime'); const mime = require('mime');
const net = require('net'); const net = require('net');
//Useful for debugging event emitter memory leaks
//require('events').EventEmitter.defaultMaxListeners = 10;
//process.traceProcessWarnings=true;
const sysInfo = log.scope('system information'); const sysInfo = log.scope('system information');
sysInfo.info("SYSTEM INFORMATION ----------------------------- "); sysInfo.info("SYSTEM INFORMATION ----------------------------- ");
sysInfo.info("APP VERSION : " + app.getVersion()); sysInfo.info("APP VERSION : " + app.getVersion());
@ -93,7 +95,8 @@ const configDefaultSettings = '{\
"respond_to_cq" : "True",\ "respond_to_cq" : "True",\
"rx_buffer_size" : "16", \ "rx_buffer_size" : "16", \
"enable_explorer" : "False", \ "enable_explorer" : "False", \
"wftheme": 2 \ "wftheme": 2, \
"high_graphics" : "True"\
}'; }';
if (!fs.existsSync(configPath)) { if (!fs.existsSync(configPath)) {
@ -206,7 +209,7 @@ function createWindow() {
}) })
// hide menu bar // hide menu bar
win.setMenuBarVisibility(false) win.setMenuBarVisibility(false)
//open dev tools //open dev tools
/*win.webContents.openDevTools({ /*win.webContents.openDevTools({
mode: 'undocked', mode: 'undocked',
@ -316,111 +319,84 @@ app.whenReady().then(() => {
win.show(); win.show();
}, 3000); }, 3000);
// start daemon by checking os //Generate daemon binary path
mainLog.info('Starting freedata-daemon binary'); var daemonPath = "";
switch (os.platform().toLowerCase()){
if(os.platform()=='darwin'){ case "darwin":
daemonProcess = spawn(path.join(process.resourcesPath, 'tnc', 'freedata-daemon'), [], case "linux":
{ daemonPath = path.join(process.resourcesPath, 'tnc', 'freedata-daemon')
cwd: path.join(process.resourcesPath, 'tnc'),
}); break;
} case "win32":
case "win64":
/* daemonPath = path.join(process.resourcesPath, 'tnc', 'freedata-daemon.exe')
process.resourcesPath --> break;
/tmp/.mount_FreeDAUQYfKb/resources default:
console.log("Unhandled OS Platform: ", os.platform());
__dirname --> break;
/tmp/.mount_FreeDAUQYfKb/resources/app.asar
*/
if(os.platform()=='linux'){
/*
var folder = path.join(process.resourcesPath, 'tnc');
//var folder = path.join(__dirname, 'extraResources', 'tnc');
console.log(folder);
fs.readdir(folder, (err, files) => {
console.log(files);
});
*/
daemonProcess = spawn(path.join(process.resourcesPath, 'tnc', 'freedata-daemon'), [],
{
cwd: path.join(process.resourcesPath, 'tnc'),
});
} }
//Start daemon binary if it exists
if(os.platform()=='win32' || os.platform()=='win64'){ if (fs.existsSync(daemonPath)){
// for windows the relative path via path.join(__dirname) is not needed for some reason mainLog.info('Starting freedata-daemon binary');
//daemonProcess = exec('\\tnc\\daemon.exe', []) daemonProcess = spawn(daemonPath,[],
{
daemonProcess = spawn(path.join(process.resourcesPath, 'tnc', 'freedata-daemon.exe'), [], cwd: path.join(daemonPath,".."),
{
cwd: path.join(process.resourcesPath, 'tnc'),
}); });
// return process messages
} daemonProcess.on('error', (err) => {
daemonProcessLog.error(`error when starting daemon: ${err}`);
// return process messages });
daemonProcess.on('message', (data) => {
daemonProcess.on('error', (err) => { daemonProcessLog.info(`${data}`);
daemonProcessLog.error(`error when starting daemon: ${err}`); });
}); daemonProcess.stdout.on('data', (data) => {
daemonProcessLog.info(`${data}`);
daemonProcess.on('message', (data) => { });
daemonProcessLog.info(`${data}`); daemonProcess.stderr.on('data', (data) => {
}); daemonProcessLog.info(`${data}`);
daemonProcess.stdout.on('data', (data) => {
daemonProcessLog.info(`${data}`);
});
daemonProcess.stderr.on('data', (data) => {
daemonProcessLog.info(`${data}`);
let arg = { let arg = {
entry: `${data}` entry: `${data}`
}; };
// send info to log only if log screen available // send info to log only if log screen available
// it seems an error occurs when updating // it seems an error occurs when updating
if (logViewer !== null && logViewer !== ''){ if (logViewer !== null && logViewer !== ''){
try{ try{
logViewer.webContents.send('action-update-log', arg); logViewer.webContents.send('action-update-log', arg);
} catch (e) { } catch (e) {
// empty for keeping error stuff silent // empty for keeping error stuff silent
// this is important to avoid error messages if we are going to close the app while // 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 // 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());
});
daemonProcess.on('close', (code) => { app.on('activate', () => {
daemonProcessLog.warn(`daemonProcess exited with code ${code}`); if (BrowserWindow.getAllWindows().length === 0) {
}); createWindow();
}
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
})
}) })
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
close_all(); close_all();
}) })
// IPC HANDLER // IPC HANDLER
//Show/update task bar/button progressbar
ipcMain.on('request-show-electron-progressbar',(event,data)=>{
win.setProgressBar(data/100);
});
ipcMain.on('request-show-chat-window', () => { ipcMain.on('request-show-chat-window', () => {
chat.show(); chat.show();
@ -488,6 +464,7 @@ ipcMain.on('request-new-msg-received', (event, arg) => {
}); });
ipcMain.on('request-update-transmission-status', (event, arg) => { ipcMain.on('request-update-transmission-status', (event, arg) => {
chat.webContents.send('action-update-transmission-status', arg); chat.webContents.send('action-update-transmission-status', arg);
win.webContents.send('action-update-transmission-status',arg);
}); });
ipcMain.on('request-open-tnc-log', () => { ipcMain.on('request-open-tnc-log', () => {
@ -655,6 +632,11 @@ ipcMain.on('request-show-arq-toast-transmission-failed',(event,data)=>{
win.webContents.send('action-show-arq-toast-transmission-failed', 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 // ARQ TRANSMISSION RECEIVING
ipcMain.on('request-show-arq-toast-transmission-receiving',(event,data)=>{ ipcMain.on('request-show-arq-toast-transmission-receiving',(event,data)=>{
win.webContents.send('action-show-arq-toast-transmission-receiving', data); win.webContents.send('action-show-arq-toast-transmission-receiving', data);
@ -782,7 +764,9 @@ function close_sub_processes(){
// closing the tnc binary if not closed when closing application and also our daemon which has been started by the gui // closing the tnc binary if not closed when closing application and also our daemon which has been started by the gui
try { try {
daemonProcess.kill(); if (daemonProcess != null) {
daemonProcess.kill();
}
} catch (e) { } catch (e) {
mainLog.error(e) mainLog.error(e)
} }
@ -894,6 +878,8 @@ ipcMain.on('request-stop-rigctld',(event,data)=>{
// create new socket so we are not reopening every time a new one // create new socket so we are not reopening every time a new one
var rigctld_connection = new net.Socket(); var rigctld_connection = new net.Socket();
var rigctld_connection_state = false; var rigctld_connection_state = false;
var rigctld_events_wired = false;
ipcMain.on('request-check-rigctld',(event, data)=>{ ipcMain.on('request-check-rigctld',(event, data)=>{
try{ try{
@ -904,41 +890,44 @@ ipcMain.on('request-check-rigctld',(event, data)=>{
if(!rigctld_connection_state){ if(!rigctld_connection_state){
rigctld_connection = new net.Socket(); rigctld_connection = new net.Socket();
rigctld_events_wired = false;
rigctld_connection.connect(data.port, data.ip) rigctld_connection.connect(data.port, data.ip)
} }
// check if we have created a new socket object // Check if we have created a new socket object and attach listeners if not already created
if (typeof(rigctld_connection) != 'undefined') { if (typeof(rigctld_connection) != 'undefined' && !rigctld_events_wired) {
rigctld_connection.on('connect', function() { rigctld_connection.on('connect', function() {
rigctld_connection_state = true; rigctld_events_wired=true;
Data["state"] = "connection possible - (" + data.ip + ":" + data.port + ")"; mainLog.info("Starting rigctld event listeners");
if (win !== null && win !== '' && typeof(win) != 'undefined'){ rigctld_connection_state = true;
// try catch for being sure we have a clean app close Data["state"] = "connection possible - (" + data.ip + ":" + data.port + ")";
try{ if (win !== null && win !== '' && typeof(win) != 'undefined'){
win.webContents.send('action-check-rigctld', Data); // try catch for being sure we have a clean app close
} catch(e){ try{
console.log(e) win.webContents.send('action-check-rigctld', Data);
} catch(e){
console.log(e)
}
} }
} })
})
rigctld_connection.on('error', function() {
rigctld_connection.on('error', function() { rigctld_connection_state = false;
rigctld_connection_state = false; Data["state"] = "unknown/stopped - (" + data.ip + ":" + data.port + ")";
Data["state"] = "unknown/stopped - (" + data.ip + ":" + data.port + ")"; if (win !== null && win !== '' && typeof(win) != 'undefined'){
if (win !== null && win !== '' && typeof(win) != 'undefined'){ // try catch for being sure we have a clean app close
// try catch for being sure we have a clean app close try{
try{ win.webContents.send('action-check-rigctld', Data);
win.webContents.send('action-check-rigctld', Data); } catch(e){
} catch(e){ console.log(e)
console.log(e) }
} }
} })
})
rigctld_connection.on('end', function() {
rigctld_connection.on('end', function() { rigctld_connection_state = false;
rigctld_connection_state = false; })
})
} }
@ -946,4 +935,4 @@ ipcMain.on('request-check-rigctld',(event, data)=>{
console.log(e) console.log(e)
} }
}); });

View file

@ -8,8 +8,8 @@
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"engines": { "engines": {
"node": ">=14.0.0", "node": ">=16.0.0",
"npm": ">=6.0.0" "npm": ">=9.0.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -32,30 +32,30 @@
"@electron/osx-sign": "^1.0.4", "@electron/osx-sign": "^1.0.4",
"@popperjs/core": "^2.11.6", "@popperjs/core": "^2.11.6",
"blob-util": "^2.0.2", "blob-util": "^2.0.2",
"bootstrap": "^5.2.1", "bootstrap": "^5.2.3",
"bootstrap-icons": "^1.9.1", "bootstrap-icons": "^1.10.3",
"bootswatch": "^5.2.0", "bootswatch": "^5.2.3",
"chart.js": "^4.0.0", "chart.js": "^4.2.0",
"chartjs-plugin-annotation": "^2.1.2", "chartjs-plugin-annotation": "^2.1.2",
"electron-log": "^4.4.8", "electron-log": "^4.4.8",
"electron-updater": "^5.2.1", "electron-updater": "^5.3.0",
"emoji-picker-element": "^1.12.1", "emoji-picker-element": "^1.15.0",
"emoji-picker-element-data": "^1.3.0", "emoji-picker-element-data": "^1.3.0",
"express-pouchdb": "^4.2.0", "express-pouchdb": "^4.2.0",
"mime": "^3.0.0", "mime": "^3.0.0",
"pouchdb": "^7.3.0", "pouchdb": "^8.0.0",
"pouchdb-browser": "^7.3.0", "pouchdb-browser": "^8.0.0",
"pouchdb-express-router": "^0.0.11", "pouchdb-express-router": "^0.0.11",
"pouchdb-find": "^7.3.0", "pouchdb-find": "^8.0.0",
"pouchdb-replication": "^8.0.0", "pouchdb-replication": "^8.0.0",
"qth-locator": "^2.1.0", "qth-locator": "^2.1.0",
"utf8": "^3.0.0", "utf8": "^3.0.0",
"uuid": "^9.0.0" "uuid": "^9.0.0"
}, },
"devDependencies": { "devDependencies": {
"electron": "^22.0.2",
"electron-builder": "^23.6.0",
"@electron/notarize": "^1.2.3", "@electron/notarize": "^1.2.3",
"electron": "^20.1.3",
"electron-builder": "^23.3.3",
"electron-builder-notarize": "^1.5.0" "electron-builder-notarize": "^1.5.0"
}, },
"build": { "build": {

View file

@ -28,7 +28,8 @@ const config = require(configPath);
// we are going to check if we have unequal values before we start calculating again // we are going to check if we have unequal values before we start calculating again
var dbfs_level_raw = 0 var dbfs_level_raw = 0
//Global version variable
var appVer = null;
// START INTERVALL COMMAND EXECUTION FOR STATES // START INTERVALL COMMAND EXECUTION FOR STATES
//setInterval(sock.getRxBuffer, 1000); //setInterval(sock.getRxBuffer, 1000);
@ -169,7 +170,8 @@ document.getElementById('openReceivedFilesFolder').addEventListener('click', ()
ssid = callsign_and_ssid[1]; ssid = callsign_and_ssid[1];
document.getElementById("myCall").value = callsign; document.getElementById("myCall").value = callsign;
document.title = document.title + ' - Call: ' + config.mycall; //document.title = document.title + ' - Call: ' + config.mycall;
updateTitle();
document.getElementById("myCallSSID").value = ssid; document.getElementById("myCallSSID").value = ssid;
document.getElementById("myGrid").value = config.mygrid; document.getElementById("myGrid").value = config.mygrid;
@ -238,7 +240,13 @@ document.getElementById('openReceivedFilesFolder').addEventListener('click', ()
} else { } else {
document.getElementById("500HzModeSwitch").checked = false; document.getElementById("500HzModeSwitch").checked = false;
} }
if(config.high_graphics == 'True'){
document.getElementById("GraphicsSwitch").checked = true;
} else {
document.getElementById("GraphicsSwitch").checked = false;
}
if(config.enable_fsk == 'True'){ if(config.enable_fsk == 'True'){
document.getElementById("fskModeSwitch").checked = true; document.getElementById("fskModeSwitch").checked = true;
} else { } else {
@ -963,9 +971,9 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
callsign_ssid = callsign.toUpperCase() + '-' + ssid; callsign_ssid = callsign.toUpperCase() + '-' + ssid;
config.mycall = callsign_ssid; config.mycall = callsign_ssid;
// split document title by looking for Call then split and update it // split document title by looking for Call then split and update it
var documentTitle = document.title.split('Call:') //var documentTitle = document.title.split('Call:')
document.title = documentTitle[0] + 'Call: ' + callsign_ssid; //document.title = documentTitle[0] + 'Call: ' + callsign_ssid;
updateTitle(callsign_ssid);
fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
daemon.saveMyCall(callsign_ssid); daemon.saveMyCall(callsign_ssid);
}); });
@ -982,8 +990,10 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
// startPing button clicked // startPing button clicked
document.getElementById("sendPing").addEventListener("click", () => { document.getElementById("sendPing").addEventListener("click", () => {
var dxcallsign = document.getElementById("dxCall").value; var dxcallsign = document.getElementById("dxCall").value.toUpperCase();
dxcallsign = dxcallsign.toUpperCase(); if (dxcallsign == "" || dxcallsign == null || dxcallsign == undefined)
return;
pauseButton(document.getElementById("sendPing"),2000);
sock.sendPing(dxcallsign); sock.sendPing(dxcallsign);
}); });
@ -1018,6 +1028,7 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
// sendCQ button clicked // sendCQ button clicked
document.getElementById("sendCQ").addEventListener("click", () => { document.getElementById("sendCQ").addEventListener("click", () => {
pauseButton(document.getElementById("sendCQ"),2000);
sock.sendCQ(); sock.sendCQ();
}); });
@ -1080,6 +1091,15 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
} }
fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
}); });
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));
set_CPU_mode();
});
// enable fsk Switch clicked // enable fsk Switch clicked
document.getElementById("fskModeSwitch").addEventListener("click", () => { document.getElementById("fskModeSwitch").addEventListener("click", () => {
@ -1133,11 +1153,11 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
}); });
// Update channel selector clicked // Update channel selector changed
document.getElementById("update_channel_selector").addEventListener("click", () => { document.getElementById("update_channel_selector").addEventListener("change", () => {
config.update_channel = document.getElementById("update_channel_selector").value; config.update_channel = document.getElementById("update_channel_selector").value;
fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
console.log("Autoupdate channel changed to ", config.update_channel);
}); });
// rx buffer size selector clicked // rx buffer size selector clicked
@ -1312,7 +1332,7 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
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); 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);
}) })
@ -1474,21 +1494,65 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
}) })
//Listen for events caused by tnc 'tnc-message's
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 = 0;
} 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;
}
var time_left = "time left: ~ "+ minutes + "min" + " " + seconds + "s";
}
document.getElementById("transmission_timeleft").textContent = time_left;
// SET BYTES PER MINUTE
if (typeof(data.bytesperminute) == 'undefined') {
var arq_bytes_per_minute = 0;
} else {
var arq_bytes_per_minute = data.bytesperminute;
}
document.getElementById("bytes_per_min").textContent = arq_bytes_per_minute;
// 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);
document.getElementById("bytes_per_min_compressed").textContent = arq_bytes_per_minute_compressed;
});
var slowRollTable=4;
ipcRenderer.on('action-update-tnc-state', (event, arg) => { ipcRenderer.on('action-update-tnc-state', (event, arg) => {
// update FFT // update FFT
if (typeof(arg.fft) !== 'undefined') { if (typeof(arg.fft) !== 'undefined') {
var array = JSON.parse("[" + arg.fft + "]"); var array = JSON.parse("[" + arg.fft + "]");
spectrum.addData(array[0]); spectrum.addData(array[0]);
} }
if (typeof(arg.mycallsign) !== 'undefined') { if (typeof(arg.mycallsign) !== 'undefined') {
// split document title by looking for Call then split and update it updateTitle(arg.mycallsign);
var documentTitle = document.title.split('Call:')
document.title = documentTitle[0] + 'Call: ' + arg.mycallsign;
} }
// update mygrid information with data from tnc // update mygrid information with data from tnc
@ -1572,7 +1636,7 @@ ipcRenderer.on('action-update-tnc-state', (event, arg) => {
var scatterSize = arg.scatter.length; var scatterSize = arg.scatter.length;
} }
if (global.scatterData != newScatterData && scatterSize > 0) { if (scatterSize > 0 && global.scatterData != newScatterData) {
global.scatterData = newScatterData; global.scatterData = newScatterData;
if (typeof(global.scatterChart) == 'undefined') { if (typeof(global.scatterChart) == 'undefined') {
@ -1688,6 +1752,7 @@ var speedChartOptions = {
// END OF SPEED CHART // END OF SPEED CHART
// PTT STATE // PTT STATE
/*
if (arg.ptt_state == 'True') { if (arg.ptt_state == 'True') {
document.getElementById("ptt_state").className = "btn btn-sm btn-danger"; document.getElementById("ptt_state").className = "btn btn-sm btn-danger";
} else if (arg.ptt_state == 'False') { } else if (arg.ptt_state == 'False') {
@ -1695,24 +1760,33 @@ var speedChartOptions = {
} else { } else {
document.getElementById("ptt_state").className = "btn btn-sm btn-secondary"; document.getElementById("ptt_state").className = "btn btn-sm btn-secondary";
} }
*/
switch (arg.ptt_state){
case 'True':
document.getElementById("ptt_state").className = "btn btn-sm btn-danger";
break;
case 'False':
document.getElementById("ptt_state").className = "btn btn-sm btn-success";
break;
default:
document.getElementById("ptt_state").className = "btn btn-sm btn-secondary";
break;
}
// AUDIO RECORDING // AUDIO RECORDING
if (arg.audio_recording == 'True') { if (arg.audio_recording == 'True') {
document.getElementById("startStopRecording").className = "btn btn-sm btn-danger"; document.getElementById("startStopRecording").className = "btn btn-sm btn-danger";
document.getElementById("startStopRecording").innerHTML = "Stop Rec" document.getElementById("startStopRecording").textContent = "Stop Rec"
} else if (arg.ptt_state == 'False') { } else if (arg.ptt_state == 'False') {
document.getElementById("startStopRecording").className = "btn btn-sm btn-danger"; document.getElementById("startStopRecording").className = "btn btn-sm btn-danger";
document.getElementById("startStopRecording").innerHTML = "Start Rec" document.getElementById("startStopRecording").textContent = "Start Rec"
} else { } else {
document.getElementById("startStopRecording").className = "btn btn-sm btn-danger"; document.getElementById("startStopRecording").className = "btn btn-sm btn-danger";
document.getElementById("startStopRecording").innerHTML = "Start Rec" document.getElementById("startStopRecording").textContent = "Start Rec"
} }
// CHANNEL BUSY STATE // CHANNEL BUSY STATE
/*
if (arg.channel_busy == 'True') { if (arg.channel_busy == 'True') {
document.getElementById("channel_busy").className = "btn btn-sm btn-danger"; document.getElementById("channel_busy").className = "btn btn-sm btn-danger";
@ -1723,24 +1797,49 @@ var speedChartOptions = {
document.getElementById("channel_busy").className = "btn btn-sm btn-secondary"; document.getElementById("channel_busy").className = "btn btn-sm btn-secondary";
} }
*/
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 // BUSY STATE
/*
if (arg.busy_state == 'BUSY') { if (arg.busy_state == 'BUSY') {
document.getElementById("busy_state").className = "btn btn-sm btn-danger"; document.getElementById("busy_state").className = "btn btn-sm btn-danger";
document.getElementById("startTransmission").disabled = true; document.getElementById("startTransmission").disabled = true;
//document.getElementById("stopTransmission").disabled = false; //document.getElementById("stopTransmission").disabled = false;
} else if (arg.busy_state == 'IDLE') { } else if (arg.busy_state == 'IDLE') {
document.getElementById("busy_state").className = "btn btn-sm btn-success"; document.getElementById("busy_state").className = "btn btn-sm btn-success";
} else { } else {
document.getElementById("busy_state").className = "btn btn-sm btn-secondary"; document.getElementById("busy_state").className = "btn btn-sm btn-secondary";
document.getElementById("startTransmission").disabled = true; document.getElementById("startTransmission").disabled = true;
//document.getElementById("stopTransmission").disabled = false; //document.getElementById("stopTransmission").disabled = false;
} }
*/
switch(arg.busy_state){
case 'BUSY':
document.getElementById("busy_state").className = "btn btn-sm btn-danger";
document.getElementById("startTransmission").disabled = true;
break;
case 'IDLE':
document.getElementById("busy_state").className = "btn btn-sm btn-success";
break;
default:
document.getElementById("busy_state").className = "btn btn-sm btn-secondary";
document.getElementById("startTransmission").disabled = true;
break;
}
// ARQ STATE // ARQ STATE
/*
if (arg.arq_state == 'True') { if (arg.arq_state == 'True') {
document.getElementById("arq_state").className = "btn btn-sm btn-warning"; document.getElementById("arq_state").className = "btn btn-sm btn-warning";
//document.getElementById("startTransmission").disabled = true; //document.getElementById("startTransmission").disabled = true;
@ -1756,8 +1855,23 @@ var speedChartOptions = {
document.getElementById("startTransmission").disabled = false; document.getElementById("startTransmission").disabled = false;
//document.getElementById("stopTransmission").disabled = false; //document.getElementById("stopTransmission").disabled = false;
} }
*/
switch (arg.arq_state){
case 'True':
document.getElementById("arq_state").className = "btn btn-sm btn-warning";
document.getElementById("startTransmission").disabled = false;
break;
case 'False':
document.getElementById("arq_state").className = "btn btn-sm btn-secondary";
document.getElementById("startTransmission").disabled = false;
break;
default:
document.getElementById("arq_state").className = "btn btn-sm btn-secondary";
document.getElementById("startTransmission").disabled = false;
break;
}
// ARQ SESSION // ARQ SESSION
/*
if (arg.arq_session == 'True') { if (arg.arq_session == 'True') {
document.getElementById("arq_session").className = "btn btn-sm btn-warning"; document.getElementById("arq_session").className = "btn btn-sm btn-warning";
@ -1768,11 +1882,22 @@ var speedChartOptions = {
document.getElementById("arq_session").className = "btn btn-sm btn-secondary"; document.getElementById("arq_session").className = "btn btn-sm btn-secondary";
} }
*/
switch (arg.arq_session){
case 'True':
document.getElementById("arq_session").className = "btn btn-sm btn-warning";
break;
case 'False':
document.getElementById("arq_session").className = "btn btn-sm btn-secondary";
break;
default:
document.getElementById("arq_session").className = "btn btn-sm btn-secondary";
break;
}
// HAMLIB STATUS // HAMLIB STATUS
if (arg.hamlib_status == 'connected') { if (arg.hamlib_status == 'connected') {
document.getElementById("rigctld_state").className = "btn btn-success btn-sm"; document.getElementById("rigctld_state").className = "btn btn-success btn-sm";
} else { } else {
document.getElementById("rigctld_state").className = "btn btn-secondary btn-sm"; document.getElementById("rigctld_state").className = "btn btn-secondary btn-sm";
} }
@ -1780,6 +1905,7 @@ var speedChartOptions = {
// BEACON STATE // BEACON STATE
/*
if (arg.beacon_state == 'True') { if (arg.beacon_state == 'True') {
document.getElementById("startBeacon").className = "btn btn-sm btn-success spinner-grow"; document.getElementById("startBeacon").className = "btn btn-sm btn-success spinner-grow";
document.getElementById("startBeacon").disabled = true; document.getElementById("startBeacon").disabled = true;
@ -1796,71 +1922,53 @@ var speedChartOptions = {
document.getElementById("stopBeacon").disabled = true; document.getElementById("stopBeacon").disabled = true;
document.getElementById("beaconInterval").disabled = false; document.getElementById("beaconInterval").disabled = false;
} }
*/
switch (arg.beacon_state){
case 'True':
document.getElementById("startBeacon").className = "btn btn-sm btn-success spinner-grow";
document.getElementById("startBeacon").disabled = true;
document.getElementById("beaconInterval").disabled = true;
document.getElementById("stopBeacon").disabled = false;
break;
case 'False':
document.getElementById("startBeacon").className = "btn btn-sm btn-success";
document.getElementById("startBeacon").disabled = false;
document.getElementById("beaconInterval").disabled = false;
document.getElementById("stopBeacon").disabled = true;
break;
default:
document.getElementById("startBeacon").className = "btn btn-sm btn-success";
document.getElementById("startBeacon").disabled = false;
document.getElementById("stopBeacon").disabled = true;
document.getElementById("beaconInterval").disabled = false;
break;
}
// dbfs // dbfs
// https://www.moellerstudios.org/converting-amplitude-representations/ // https://www.moellerstudios.org/converting-amplitude-representations/
if (dbfs_level_raw != arg.dbfs_level){ if (dbfs_level_raw != 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 dbfs_level = Math.pow(10, arg.dbfs_level / 20) * 100
document.getElementById("dbfs_level_value").innerHTML = Math.round(arg.dbfs_level) + ' dBFS' document.getElementById("dbfs_level_value").textContent = Math.round(arg.dbfs_level) + ' dBFS'
document.getElementById("dbfs_level").setAttribute("aria-valuenow", dbfs_level); var dbfscntrl = document.getElementById("dbfs_level");
document.getElementById("dbfs_level").setAttribute("style", "width:" + dbfs_level + "%;"); dbfscntrl.setAttribute("aria-valuenow", dbfs_level);
dbfscntrl.setAttribute("style", "width:" + dbfs_level + "%;");
} }
// SET FREQUENCY // SET FREQUENCY
// https://stackoverflow.com/a/2901298 // https://stackoverflow.com/a/2901298
var freq = arg.frequency.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "."); var freq = arg.frequency.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
document.getElementById("frequency").innerHTML = freq; document.getElementById("frequency").textContent = freq;
//document.getElementById("newFrequency").value = arg.frequency; //document.getElementById("newFrequency").value = arg.frequency;
// SET MODE // SET MODE
document.getElementById("mode").innerHTML = arg.mode; document.getElementById("mode").textContent = arg.mode;
// SET bandwidth // SET bandwidth
document.getElementById("bandwidth").innerHTML = arg.bandwidth; document.getElementById("bandwidth").textContent = arg.bandwidth;
// SET BYTES PER MINUTE
if (typeof(arg.arq_bytes_per_minute) == 'undefined') {
var arq_bytes_per_minute = 0;
} else {
var arq_bytes_per_minute = arg.arq_bytes_per_minute;
}
document.getElementById("bytes_per_min").innerHTML = arq_bytes_per_minute;
// SET BYTES PER MINUTE COMPRESSED
if (typeof(arg.arq_bytes_per_minute) == 'undefined') {
var arq_bytes_per_minute_compressed = 0;
} else {
var arq_bytes_per_minute_compressed = Math.round(arg.arq_bytes_per_minute * arg.arq_compression_factor);
}
document.getElementById("bytes_per_min_compressed").innerHTML = arq_bytes_per_minute_compressed;
// SET TIME LEFT UNTIL FINIHED
if (typeof(arg.arq_seconds_until_finish) == 'undefined') {
var time_left = 0;
} else {
var arq_seconds_until_finish = arg.arq_seconds_until_finish
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;
}
var time_left = "time left: ~ "+ minutes + "min" + " " + seconds + "s";
}
document.getElementById("transmission_timeleft").innerHTML = time_left;
// SET SPEED LEVEL // SET SPEED LEVEL
/*
if(arg.speed_level >= 0) { if(arg.speed_level >= 0) {
document.getElementById("speed_level").className = "bi bi-reception-1"; document.getElementById("speed_level").className = "bi bi-reception-1";
} }
@ -1876,7 +1984,21 @@ var speedChartOptions = {
if(arg.speed_level >= 4) { if(arg.speed_level >= 4) {
document.getElementById("speed_level").className = "bi bi-reception-4"; document.getElementById("speed_level").className = "bi bi-reception-4";
} }
*/
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;
}
@ -1886,10 +2008,20 @@ var speedChartOptions = {
} else { } else {
var total_bytes = arg.total_bytes; var total_bytes = arg.total_bytes;
} }
document.getElementById("total_bytes").innerHTML = total_bytes; document.getElementById("total_bytes").textContent = total_bytes;
document.getElementById("transmission_progress").setAttribute("aria-valuenow", arg.arq_transmission_percent);
document.getElementById("transmission_progress").setAttribute("style", "width:" + arg.arq_transmission_percent + "%;");
//Ensure heard station table is last so we can return if we don't want to update it
//Only update heard stations every 5 iterations
//Allows for single click event to work more reliabily to populate dxcall textbox
//Should also save some CPU
slowRollTable++;
if (slowRollTable!=5) {
return;
}
slowRollTable=0;
// UPDATE HEARD STATIONS // UPDATE HEARD STATIONS
var tbl = document.getElementById("heardstations"); var tbl = document.getElementById("heardstations");
document.getElementById("heardstations").innerHTML = ''; document.getElementById("heardstations").innerHTML = '';
@ -1903,19 +2035,19 @@ var speedChartOptions = {
for (i = 0; i < heardStationsLength; i++) { for (i = 0; i < heardStationsLength; i++) {
// first we update the PING window // first we update the PING window
if (arg.stations[i]['dxcallsign'] == document.getElementById("dxCall").value) { if (arg.stations[i]['dxcallsign'] == document.getElementById("dxCall").value.toUpperCase()) {
var dxGrid = arg.stations[i]['dxgrid']; var dxGrid = arg.stations[i]['dxgrid'];
var myGrid = document.getElementById("myGrid").value; var myGrid = document.getElementById("myGrid").value;
try { try {
var dist = parseInt(distance(myGrid, dxGrid)) + ' km'; var dist = parseInt(distance(myGrid, dxGrid)) + ' km';
document.getElementById("pingDistance").innerHTML = dist; //document.getElementById("pingDistance").innerHTML = dist;
document.getElementById("dataModalPingDistance").innerHTML = dist; document.getElementById("dataModalPingDistance").textContent = dist;
} catch { } catch {
document.getElementById("pingDistance").innerHTML = '---'; //document.getElementById("pingDistance").innerHTML = '---';
document.getElementById("dataModalPingDistance").innerHTML = '---'; document.getElementById("dataModalPingDistance").textContent = '---';
} }
document.getElementById("pingDB").innerHTML = arg.stations[i]['snr']; //document.getElementById("pingDB").innerHTML = arg.stations[i]['snr'];
document.getElementById("dataModalPingDB").innerHTML = arg.stations[i]['snr']; document.getElementById("dataModalPingDB").textContent = arg.stations[i]['snr'];
} }
// now we update the heard stations list // now we update the heard stations list
@ -1940,10 +2072,13 @@ var speedChartOptions = {
frequencyText.innerText = arg.stations[i]['frequency']; frequencyText.innerText = arg.stations[i]['frequency'];
frequency.appendChild(frequencyText); frequency.appendChild(frequencyText);
var dxCall = document.createElement("td"); var dxCall = document.createElement("td");
var dxCallText = document.createElement('span'); var dxCallText = document.createElement('span');
dxCallText.innerText = arg.stations[i]['dxcallsign']; dxCallText.innerText = arg.stations[i]['dxcallsign'];
let dxCallTextCall = dxCallText.innerText;
row.addEventListener("click", function() {
document.getElementById("dxCall").value = dxCallTextCall;
});
dxCall.appendChild(dxCallText); dxCall.appendChild(dxCallText);
var dxGrid = document.createElement("td"); var dxGrid = document.createElement("td");
@ -1965,7 +2100,7 @@ var speedChartOptions = {
var dataTypeText = document.createElement('span'); var dataTypeText = document.createElement('span');
dataTypeText.innerText = arg.stations[i]['datatype']; dataTypeText.innerText = arg.stations[i]['datatype'];
dataType.appendChild(dataTypeText); dataType.appendChild(dataTypeText);
/*
if(arg.stations[i]['datatype'] == 'DATA-CHANNEL'){ if(arg.stations[i]['datatype'] == 'DATA-CHANNEL'){
dataTypeText.innerText = 'DATA-C'; dataTypeText.innerText = 'DATA-C';
dataType.appendChild(dataTypeText); dataType.appendChild(dataTypeText);
@ -1975,11 +2110,20 @@ var speedChartOptions = {
dataTypeText.innerHTML = '<i class="bi bi-heart-pulse-fill"></i>'; dataTypeText.innerHTML = '<i class="bi bi-heart-pulse-fill"></i>';
dataType.appendChild(dataTypeText); dataType.appendChild(dataTypeText);
} }
*/
switch (arg.stations[i]['datatype']){
case 'DATA-CHANNEL':
dataTypeText.innerText = 'DATA-C';
dataType.appendChild(dataTypeText);
break;
case 'SESSION-HB':
dataTypeText.innerHTML = '<i class="bi bi-heart-pulse-fill"></i>';
dataType.appendChild(dataTypeText);
break;
}
/*
if (dataTypeText.innerText == 'CQ CQ CQ') { if (dataTypeText.innerText == 'CQ CQ CQ') {
row.classList.add("table-success"); row.classList.add("table-success");
} }
if (dataTypeText.innerText == 'DATA-C') { if (dataTypeText.innerText == 'DATA-C') {
@ -1998,7 +2142,25 @@ var speedChartOptions = {
if (dataTypeText.innerText == 'PING-ACK') { if (dataTypeText.innerText == 'PING-ACK') {
row.classList.add("table-primary"); row.classList.add("table-primary");
} }
*/
switch (dataTypeText.innerText){
case 'CQ CQ CQ':
row.classList.add("table-success");
break;
case 'DATA-C':
dataTypeText.innerHTML = '<i class="bi bi-file-earmark-binary-fill"></i>';
row.classList.add("table-warning");
break;
case 'BEACON':
row.classList.add("table-light");
break;
case 'PING':
row.classList.add("table-info");
break;
case 'PING-ACK':
row.classList.add("table-primary");
break;
}
var snr = document.createElement("td"); var snr = document.createElement("td");
var snrText = document.createElement('span'); var snrText = document.createElement('span');
snrText.innerText = arg.stations[i]['snr']; snrText.innerText = arg.stations[i]['snr'];
@ -2204,7 +2366,11 @@ ipcRenderer.on('action-update-tnc-connection', (event, arg) => {
var collapseThirdRow = new bootstrap.Collapse(document.getElementById('collapseThirdRow'), {toggle: false}) var collapseThirdRow = new bootstrap.Collapse(document.getElementById('collapseThirdRow'), {toggle: false})
collapseThirdRow.show(); collapseThirdRow.show();
var collapseFourthRow = new bootstrap.Collapse(document.getElementById('collapseFourthRow'), {toggle: false}) var collapseFourthRow = new bootstrap.Collapse(document.getElementById('collapseFourthRow'), {toggle: false})
collapseFourthRow.show(); collapseFourthRow.show();
//Set tuning for fancy graphics mode (high/low CPU)
set_CPU_mode();
} else { } else {
/* /*
document.getElementById('hamlib_deviceid').disabled = false; document.getElementById('hamlib_deviceid').disabled = false;
@ -2249,15 +2415,15 @@ ipcRenderer.on('action-update-rx-buffer', (event, arg) => {
for (i = 0; i < arg.data.length; i++) { for (i = 0; i < arg.data.length; i++) {
// first we update the PING window // first we update the PING window
if (arg.data[i]['dxcallsign'] == document.getElementById("dxCall").value) { 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 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'] != ''){ if(arg.data[i]['DXGRID'] != ''){
document.getElementById("pingDistance").innerHTML = arg.stations[i]['DXGRID'] document.getElementById("pingDistance").innerHTML = arg.stations[i]['DXGRID']
} }
*/ */
document.getElementById("pingDB").innerHTML = arg.stations[i]['snr']; //document.getElementById("pingDB").innerHTML = arg.stations[i]['snr'];
document.getElementById("dataModalPingDB").innerHTML = arg.stations[i]['snr'];
} }
@ -2413,14 +2579,11 @@ ipcRenderer.on('action-updater', (event, arg) => {
} }
if (arg.status == "checking-for-update"){ if (arg.status == "checking-for-update"){
document.title = document.title + ' - v' + arg.version; //document.title = document.title + ' - v' + arg.version;
updateTitle(config.myCall,config.tnc_host,config.tnc_port, " -v " + arg.version);
document.getElementById("updater_status").innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>' document.getElementById("updater_status").innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>'
document.getElementById("updater_status").className = "btn btn-secondary btn-sm"; document.getElementById("updater_status").className = "btn btn-secondary btn-sm";
document.getElementById("update_and_install").style.display = 'none'; document.getElementById("update_and_install").style.display = 'none';
} }
@ -2562,6 +2725,13 @@ ipcRenderer.on('action-show-arq-toast-transmission-failed', (event, data) => {
toast.show(); toast.show();
}); });
// ARQ TRANSMISSION FAILED (Version mismatch)
ipcRenderer.on('action-show-arq-toast-transmission-failed-ver', (event, data) => {
document.getElementById("transmission_progress").className = "progress-bar progress-bar-striped bg-danger";
var toast = bootstrap.Toast.getOrCreateInstance(toastARQtransmittingfailedver); // Returns a Bootstrap toast instance
toast.show();
});
// ARQ TRANSMISSION STOPPED // ARQ TRANSMISSION STOPPED
// TODO: RENAME ID -- WRONG // TODO: RENAME ID -- WRONG
ipcRenderer.on('action-show-arq-toast-transmission-stopped', (event, data) => { ipcRenderer.on('action-show-arq-toast-transmission-stopped', (event, data) => {
@ -2691,11 +2861,6 @@ ipcRenderer.on('action-show-arq-toast-session-failed', (event, data) => {
}); });
// enable or disable a setting by given switch and element // enable or disable a setting by given switch and element
function enable_setting(enable_switch, enable_object){ function enable_setting(enable_switch, enable_object){
if(document.getElementById(enable_switch).checked){ if(document.getElementById(enable_switch).checked){
@ -2724,9 +2889,77 @@ function checkRigctld(){
ip: rigctld_ip, ip: rigctld_ip,
port: rigctld_port port: rigctld_port
}; };
ipcRenderer.send('request-check-rigctld', Data);
//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) => { ipcRenderer.on('action-check-rigctld', (event, data) => {
document.getElementById("hamlib_rigctld_status").value = data["state"]; document.getElementById("hamlib_rigctld_status").value = data["state"];
}); });
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, other 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.getAttribute('class');
//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.setAttribute("class",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("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("waterfall","disable-effects",false);
toggleClass("transmission_progress","disable-effects",false);
toggleClass("transmission_progress","progress-bar-striped",true);
}
}
//Teomporarily disable a button with timeout
function pauseButton(btn, timems) {
btn.disabled = true;
var curText = btn.innerHTML;
btn.innerHTML = "<span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\">";
setTimeout(()=>{
btn.innerHTML=curText;
btn.disabled = false;}, timems)
}

View file

@ -156,8 +156,8 @@ client.on('data', function(socketdata) {
// split data into chunks if we received multiple commands // split data into chunks if we received multiple commands
socketchunk = socketchunk.split("\n"); socketchunk = socketchunk.split("\n");
data = JSON.parse(socketchunk[0]) //don't think this is needed anymore
//data = JSON.parse(socketchunk[0])
// search for empty entries in socketchunk and remove them // search for empty entries in socketchunk and remove them
for (i = 0; i < socketchunk.length; i++) { for (i = 0; i < socketchunk.length; i++) {
@ -349,7 +349,11 @@ client.on('data', function(socketdata) {
// ARQ TRANSMISSION FAILED // ARQ TRANSMISSION FAILED
} else if (data['status'] == 'failed') { } else if (data['status'] == 'failed') {
ipcRenderer.send('request-show-arq-toast-transmission-failed', {data: [data]}); 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]});
}
ipcRenderer.send('request-update-transmission-status', {data: [data]}); ipcRenderer.send('request-update-transmission-status', {data: [data]});

View file

@ -18,8 +18,8 @@
<!-- bootstrap --> <!-- bootstrap -->
<script src="../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- chart.js --> <!-- chart.js -->
<script src="../node_modules/chart.js/dist/chart.min.js"></script> <script src="../node_modules/chart.js/dist/chart.umd.js"></script>
<script src="../node_modules/chartjs-plugin-annotation/dist/chartjs-plugin-annotation.min.js"></script> <!--<script src="../node_modules/chartjs-plugin-annotation/dist/chartjs-plugin-annotation.min.js"></script>-->
<!--<script type="module" src="../node_modules/emoji-picker-element/index.js"></script>--> <!--<script type="module" src="../node_modules/emoji-picker-element/index.js"></script>-->
<script type="module" src="../node_modules/emoji-picker-element/picker.js"></script> <script type="module" src="../node_modules/emoji-picker-element/picker.js"></script>
<script type="module" src="../node_modules/emoji-picker-element/database.js"></script> <script type="module" src="../node_modules/emoji-picker-element/database.js"></script>

View file

@ -28,7 +28,7 @@
<label class="btn btn-sm btn-outline-secondary" for="local-remote-switch2"> <i class="bi bi-ethernet" style="font-size: 1rem; color: black;"></i> </label> <label class="btn btn-sm btn-outline-secondary" for="local-remote-switch2"> <i class="bi bi-ethernet" style="font-size: 1rem; color: black;"></i> </label>
</div> </div>
<div class="input-group input-group-sm me-2" id="remote-tnc-field"> <span class="input-group-text" id="basic-addon1">TNC IP</span> <div class="input-group input-group-sm me-2" id="remote-tnc-field"> <span class="input-group-text" id="basic-addon1">TNC IP</span>
<input type="text" class="form-control" placeholder="ip adress" id="tnc_adress" value="192.168.178.163" maxlength="17" style="width: 8rem" aria-label="Username" aria-describedby="basic-addon1"> <span class="input-group-text" id="basic-addon1">:</span> <input type="text" class="form-control" placeholder="ip address" id="tnc_adress" value="192.168.178.163" maxlength="17" style="width: 8rem" aria-label="Username" aria-describedby="basic-addon1"> <span class="input-group-text" id="basic-addon1">:</span>
<input type="text" class="form-control" placeholder="port" value="3000" id="tnc_port" maxlength="5" max="65534" min="1025" style="width: 4rem" aria-label="Username" aria-describedby="basic-addon1"> <input type="text" class="form-control" placeholder="port" value="3000" id="tnc_port" maxlength="5" max="65534" min="1025" style="width: 4rem" aria-label="Username" aria-describedby="basic-addon1">
<button class="btn btn-sm btn-danger" id="daemon_connection_state" type="button" disabled> <i class="bi bi-diagram-3" style="font-size: 1rem; color: white;"></i> </button> <button class="btn btn-sm btn-danger" id="daemon_connection_state" type="button" disabled> <i class="bi bi-diagram-3" style="font-size: 1rem; color: white;"></i> </button>
</div> </div>
@ -214,6 +214,13 @@
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button> <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div> </div>
</div> </div>
<!-- ARQ TRANSMITTING FAILED -->
<div class="toast align-items-center text-white bg-danger border-0" id="toastARQtransmittingfailedver" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">TRANSMITTING FAILED, VERSION MISMATCH!</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
<!-- ARQ TRANSMITTING SUCCESS--> <!-- ARQ TRANSMITTING SUCCESS-->
<div class="toast align-items-center text-white bg-success border-0" id="toastARQtransmittingsuccess" role="alert" aria-live="assertive" aria-atomic="true"> <div class="toast align-items-center text-white bg-success border-0" id="toastARQtransmittingsuccess" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex"> <div class="d-flex">
@ -774,7 +781,7 @@
</div> </div>
<div class="card-body p-2"> <div class="card-body p-2">
<div class="progress mb-0" style="height: 15px;"> <div class="progress mb-0" style="height: 15px;">
<div class="progress-bar progress-bar-striped bg-primary" id="dbfs_level" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div> <div class="progress-bar progress-bar-striped bg-primary force-gpu" id="dbfs_level" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<p class="justify-content-center d-flex position-absolute w-100" id="dbfs_level_value">dBFS</p> <p class="justify-content-center d-flex position-absolute w-100" id="dbfs_level_value">dBFS</p>
</div> </div>
<div class="progress mb-0" style="height: 5px;"> <div class="progress mb-0" style="height: 5px;">
@ -848,9 +855,9 @@
</div> </div>
<div class="card-body p-1" style="height: 200px"> <div class="card-body p-1" style="height: 200px">
<!--278px--> <!--278px-->
<canvas id="waterfall" style="position: relative; z-index: 2; transform: translateZ(0);"></canvas> <canvas id="waterfall" style="position: relative; z-index: 2;" class="force-gpu"></canvas>
<canvas id="scatter" style="position: relative; z-index: 1; transform: translateZ(0);"></canvas> <canvas id="scatter" style="position: relative; z-index: 1;" class="force-gpu"></canvas>
<canvas id="chart" style="position: relative; z-index: 1; transform: translateZ(0);"></canvas> <canvas id="chart" style="position: relative; z-index: 1;" class="force-gpu"></canvas>
</div> </div>
</div> </div>
</div> </div>
@ -1117,7 +1124,7 @@
</div> </div>
<div class="container-fluid p-0" style="width:15rem"> <div class="container-fluid p-0" style="width:15rem">
<div class="progress" style="height: 30px;"> <div class="progress" style="height: 30px;">
<div class="progress-bar progress-bar-striped bg-primary" id="transmission_progress" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div> <div class="progress-bar progress-bar-striped bg-primary force-gpu" id="transmission_progress" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<!--<p class="justify-content-center d-flex position-absolute w-100">PROGRESS</p>--> <!--<p class="justify-content-center d-flex position-absolute w-100">PROGRESS</p>-->
<p class="justify-content-center mt-2 d-flex position-absolute w-100" id="transmission_timeleft">---</p> <p class="justify-content-center mt-2 d-flex position-absolute w-100" id="transmission_timeleft">---</p>
</div> </div>
@ -1129,7 +1136,6 @@
<!-- chart.js --> <!-- chart.js -->
<script src="../node_modules/chart.js/dist/chart.umd.js"></script> <script src="../node_modules/chart.js/dist/chart.umd.js"></script>
<!--<script src="../node_modules/chartjs-plugin-annotation/dist/chartjs-plugin-annotation.min.js"></script>--> <!--<script src="../node_modules/chartjs-plugin-annotation/dist/chartjs-plugin-annotation.min.js"></script>-->
<!--<script src="../ui.js"></script>-->
<!-- WATERFALL --> <!-- WATERFALL -->
<script src="waterfall/colormap.js"></script> <script src="waterfall/colormap.js"></script>
<script src="waterfall/spectrum.js"></script> <script src="waterfall/spectrum.js"></script>
@ -1162,6 +1168,11 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="alert alert-warning" role="alert">
Most settings need a tnc restart to take effect!
</div>
<div class="input-group input-group-sm mb-1"> <span class="input-group-text w-50" id="basic-addon1">Theme</span> <div class="input-group input-group-sm mb-1"> <span class="input-group-text w-50" id="basic-addon1">Theme</span>
<select class="form-select form-select-sm w-50" id="theme_selector"> <select class="form-select form-select-sm w-50" id="theme_selector">
<option value="default">Default</option> <option value="default">Default</option>
@ -1304,6 +1315,15 @@
</select> </select>
</label> </label>
</div> </div>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Enable Fancy GUI</label>
<label class="input-group-text bg-white w-50">
<div class="form-check form-switch form-check-inline">
<input class="form-check-input" type="checkbox" id="GraphicsSwitch">
<label class="form-check-label" for="GraphicsSwitch">Higher CPU Usage</label>
</div>
</label>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy" content="script-src 'self';"> <meta http-equiv="Content-Security-Policy" content="script-src 'self';">
</head> </head>
<body> <body style="overflow:hidden;">
<img src="img/icon_cube_border.png" width="100%" height="100%"> <img src="img/icon_cube_border.png" width="100%" height="100%">
</body> </body>
</html> </html>

View file

@ -3,6 +3,7 @@ body {
padding-right: 0px !important; padding-right: 0px !important;
overflow-y: hidden !important; overflow-y: hidden !important;
overflow-x: hidden !important; overflow-x: hidden !important;
} }
/*Progress bars with centered text*/ /*Progress bars with centered text*/
@ -65,4 +66,26 @@ th {
.picker { .picker {
border-radius: 10px: 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;
}

View file

@ -1060,6 +1060,12 @@ class DATA:
static.TOTAL_BYTES = len(data_out) static.TOTAL_BYTES = len(data_out)
frame_total_size = len(data_out).to_bytes(4, byteorder="big") frame_total_size = len(data_out).to_bytes(4, byteorder="big")
# Compress data frame
data_frame_compressed = lzma.compress(data_out)
compression_factor = len(data_out) / len(data_frame_compressed)
static.ARQ_COMPRESSION_FACTOR = np.clip(compression_factor, 0, 255)
compression_factor = bytes([int(static.ARQ_COMPRESSION_FACTOR * 10)])
self.send_data_to_socket_queue( self.send_data_to_socket_queue(
freedata="tnc-message", freedata="tnc-message",
arq="transmission", arq="transmission",
@ -1078,12 +1084,6 @@ class DATA:
Bytes=static.TOTAL_BYTES, Bytes=static.TOTAL_BYTES,
) )
# Compress data frame
data_frame_compressed = lzma.compress(data_out)
compression_factor = len(data_out) / len(data_frame_compressed)
static.ARQ_COMPRESSION_FACTOR = np.clip(compression_factor, 0, 255)
compression_factor = bytes([int(static.ARQ_COMPRESSION_FACTOR * 10)])
data_out = data_frame_compressed data_out = data_frame_compressed
# Reset data transfer statistics # Reset data transfer statistics