FreeDATA/gui/main.js

518 lines
14 KiB
JavaScript
Raw Normal View History

2021-09-04 18:23:58 +00:00
const {
app,
BrowserWindow,
ipcMain
} = require('electron');
const { autoUpdater } = require('electron-updater');
const path = require('path');
const fs = require('fs');
2022-01-11 21:16:14 +00:00
const os = require('os');
const exec = require('child_process').spawn;
const log = require('electron-log');
const mainLog = log.scope('main');
const daemonProcessLog = log.scope('freedata-daemon');
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());
2021-09-13 16:27:50 +00:00
app.setName("FreeDATA");
2021-09-04 15:11:20 +00:00
var appDataFolder = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Application Support' : process.env.HOME + "/.config");
2021-09-13 16:27:50 +00:00
var configFolder = path.join(appDataFolder, "FreeDATA");
var configPath = path.join(configFolder, 'config.json');
2021-09-04 14:33:17 +00:00
2021-11-19 16:30:17 +00:00
// create config folder if not exists
2021-09-04 18:23:58 +00:00
if (!fs.existsSync(configFolder)) {
fs.mkdirSync(configFolder);
}
2021-09-04 14:33:17 +00:00
// 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",\
"deviceid": "RIG_MODEL_DUMMY_NOVFO",\
"deviceport": "/dev/ttyACM1",\
"serialspeed_direct": "9600",\
"spectrum": "waterfall",\
"tnclocation": "localhost",\
"stop_bits_direct" : "1",\
"data_bits_direct" : "8",\
"handshake_direct" : "None",\
"radiocontrol" : "disabled",\
"deviceport_rigctl" : "3",\
"deviceid_rigctl" : "3",\
"serialspeed_rigctl" : "9600",\
"pttprotocol_direct" : "USB",\
"pttprotocol_rigctl" : "USB",\
"rigctld_port" : "4532",\
"rigctld_ip" : "127.0.0.1",\
"enable_scatter" : "False",\
"enable_fft" : "False",\
"low_bandwith_mode" : "False",\
"theme" : "default",\
"screen_height" : 430,\
"screen_width" : 1050,\
"update_channel" : "latest",\
"beacon_interval" : 5\
}';
2021-09-04 18:23:58 +00:00
if (!fs.existsSync(configPath)) {
fs.writeFileSync(configPath, configDefaultSettings)
2021-09-04 18:23:58 +00:00
}
// 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("------------------------------------------ ");
2021-09-10 15:59:33 +00:00
2021-11-19 16:30:17 +00:00
var chatDB = path.join(configFolder, 'chatDB.json')
// create chat database file if not exists
const configContentChatDB = `
2021-11-19 16:30:17 +00:00
{ "chatDB" : [{
"id" : "00000000",
"timestamp" : 1234566,
"mycall" : "AA0AA",
"dxcall" : "AB0AB",
"dxgrid" : "JN1200",
"message" : "hallowelt"
}]
}
`;
if (!fs.existsSync(chatDB)) {
fs.writeFileSync(chatDB, configContentChatDB);
2021-11-19 16:30:17 +00:00
}
2021-09-10 15:59:33 +00:00
/*
// Creates receivedFiles folder if not exists
// https://stackoverflow.com/a/26227660
var appDataFolder = process.env.HOME
2021-09-13 16:27:50 +00:00
var applicationFolder = path.join(appDataFolder, "FreeDATA");
2021-09-10 15:59:33 +00:00
var receivedFilesFolder = path.join(applicationFolder, "receivedFiles");
// https://stackoverflow.com/a/13544465
fs.mkdir(receivedFilesFolder, {
recursive: true
}, function(err) {
console.log(err);
});
*/
2021-07-23 15:40:44 +00:00
2021-07-17 07:02:56 +00:00
let win = null;
let data = null;
let logViewer = null;
2021-09-04 14:33:17 +00:00
var daemonProcess = null;
2021-07-24 07:06:22 +00:00
function createWindow() {
win = new BrowserWindow({
2022-02-10 14:05:04 +00:00
width: config.screen_width,
height: config.screen_height,
2021-08-28 13:50:59 +00:00
autoHideMenuBar: true,
icon: 'src/img/icon.png',
2021-07-24 07:06:22 +00:00
webPreferences: {
//preload: path.join(__dirname, 'preload-main.js'),
preload: require.resolve('./preload-main.js'),
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: false,
//https://stackoverflow.com/questions/53390798/opening-new-window-electron/53393655
//https://github.com/electron/remote
2021-07-24 07:06:22 +00:00
}
})
2021-08-28 13:50:59 +00:00
// hide menu bar
win.setMenuBarVisibility(false)
2021-09-04 18:23:58 +00:00
2021-07-24 07:06:22 +00:00
//open dev tools
2021-09-08 16:22:41 +00:00
/*win.webContents.openDevTools({
2021-07-24 07:06:22 +00:00
mode: 'undocked',
activate: true,
})
2021-09-05 15:30:46 +00:00
*/
2021-07-24 07:06:22 +00:00
win.loadFile('src/index.html')
2021-11-19 16:30:17 +00:00
chat = new BrowserWindow({
2021-07-24 07:06:22 +00:00
height: 900,
width: 600,
2021-11-19 16:30:17 +00:00
show: false,
2021-07-24 07:06:22 +00:00
parent: win,
webPreferences: {
2021-11-19 16:30:17 +00:00
preload: require.resolve('./preload-chat.js'),
2021-07-24 07:06:22 +00:00
nodeIntegration: true,
}
})
2021-11-19 16:30:17 +00:00
chat.loadFile('src/chat-module.html');
chat.setMenuBarVisibility(false);
2021-11-19 16:30:17 +00:00
logViewer = new BrowserWindow({
height: 900,
width: 600,
show: false,
parent: win,
webPreferences: {
preload: require.resolve('./preload-log.js'),
nodeIntegration: true,
}
})
logViewer.loadFile('src/log-module.html');
logViewer.setMenuBarVisibility(false);
// Emitted when the window is closed.
logViewer.on('close', function(evt) {
evt.preventDefault();
logViewer.hide();
})
2021-07-17 07:02:56 +00:00
// Emitted when the window is closed.
2021-07-24 07:06:22 +00:00
win.on('closed', function() {
2021-07-17 07:02:56 +00:00
win = null;
2021-11-19 16:30:17 +00:00
chat = null;
logViewer = null;
2021-07-17 07:02:56 +00:00
})
win.once('ready-to-show', () => {
2022-02-22 14:40:33 +00:00
log.transports.file.level = "debug"
autoUpdater.logger = log.scope('updater');
autoUpdater.channel = config.update_channel
autoUpdater.autoInstallOnAppQuit = false;
2022-02-22 14:40:33 +00:00
autoUpdater.autoDownload = true;
autoUpdater.checkForUpdatesAndNotify();
//autoUpdater.quitAndInstall();
});
2021-07-17 07:02:56 +00:00
2021-11-19 16:30:17 +00:00
chat.on('closed', function () {
2021-07-24 07:06:22 +00:00
})
2021-11-19 16:30:17 +00:00
2021-07-17 07:02:56 +00:00
2021-07-24 07:06:22 +00:00
// https://stackoverflow.com/questions/44258831/only-hide-the-window-when-closing-it-electron
2021-11-19 16:30:17 +00:00
chat.on('close', function(evt) {
2021-07-24 07:06:22 +00:00
evt.preventDefault();
chat.hide();
2021-07-24 07:06:22 +00:00
});
2021-11-19 16:30:17 +00:00
2021-07-17 07:02:56 +00:00
}
app.whenReady().then(() => {
createWindow();
2021-09-04 18:23:58 +00:00
2022-01-11 21:16:14 +00:00
// start daemon by checking os
mainLog.info('Starting freedata-daemon binary');
2022-02-19 20:30:52 +00:00
if(os.platform()=='darwin'){
daemonProcess = exec(path.join(process.resourcesPath, 'tnc', 'freedata-daemon'), [],
{
cwd: path.join(process.resourcesPath, 'tnc'),
});
2022-02-19 20:30:52 +00:00
}
/*
process.resourcesPath -->
/tmp/.mount_FreeDAUQYfKb/resources
__dirname -->
/tmp/.mount_FreeDAUQYfKb/resources/app.asar
*/
2022-02-19 19:45:57 +00:00
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 = exec(path.join(process.resourcesPath, 'tnc', 'freedata-daemon'), [],
{
cwd: path.join(process.resourcesPath, 'tnc'),
});
2022-01-11 21:16:14 +00:00
}
2022-01-11 21:16:14 +00:00
if(os.platform()=='win32' || os.platform()=='win64'){
// for windows the relative path via path.join(__dirname) is not needed for some reason
2022-02-21 17:59:03 +00:00
//daemonProcess = exec('\\tnc\\daemon.exe', [])
daemonProcess = exec(path.join(process.resourcesPath, 'tnc', 'freedata-daemon.exe'), [],
{
cwd: path.join(process.resourcesPath, 'tnc'),
});
2022-02-21 17:59:03 +00:00
}
// 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}`);
win.webContents.send('action-updater', data);
});
daemonProcess.stderr.on('data', (data) => {
daemonProcessLog.info(`${data}`);
let arg = {
entry: `${data}`
};
logViewer.webContents.send('action-update-log', arg);
});
daemonProcess.on('close', (code) => {
daemonProcessLog.warn(`daemonProcess exited with code ${code}`);
});
2021-07-24 07:06:22 +00:00
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
2021-07-24 07:06:22 +00:00
}
})
2021-07-17 07:02:56 +00:00
})
app.on('window-all-closed', () => {
2022-02-19 20:30:52 +00:00
// closing the tnc binary if not closed when closing application and also our daemon which has been started by the gui
try {
daemonProcess.kill();
} catch (e) {
mainLog.error(e)
}
2022-02-19 20:30:52 +00:00
mainLog.warn('closing tnc');
if(os.platform()=='win32' || os.platform()=='win64'){
exec('Taskkill', ['/IM', 'freedata-tnc.exe', '/F'])
}
if(os.platform()=='linux'){
exec('pkill', ['-9', 'freedata-tnc'])
2022-02-19 20:30:52 +00:00
2022-02-22 16:06:39 +00:00
// on macOS we need to kill the daemon as well. If we are not doing this,
// the daemon wont startup again because the socket is already in use
//for some reason killing the daemon is killing our screen on Ubuntu..it seems theres another "daemon" out there...
exec('pkill', ['-9', 'freedata-daemon'])
}
if(os.platform()=='darwin'){
exec('pkill', ['-9', 'freedata-tnc'])
// on macOS we need to kill the daemon as well. If we are not doing this,
// the daemon wont startup again because the socket is already in use
//for some reason killing the daemon is killing our screen on Ubuntu..it seems theres another "daemon" out there...
exec('pkill', ['-9', 'freedata-daemon'])
2022-02-22 16:06:39 +00:00
}
/*
2021-07-24 07:06:22 +00:00
if (process.platform !== 'darwin') {
app.quit();
2021-07-24 07:06:22 +00:00
}
*/
mainLog.warn('quitting app');
app.quit();
2021-07-17 07:02:56 +00:00
})
// IPC HANDLER
2021-11-19 16:30:17 +00:00
ipcMain.on('request-show-chat-window', (event, arg) => {
chat.show();
});
2021-11-19 16:30:17 +00:00
2021-07-17 07:02:56 +00:00
ipcMain.on('request-update-tnc-state', (event, arg) => {
win.webContents.send('action-update-tnc-state', arg);
//data.webContents.send('action-update-tnc-state', arg);
2021-07-17 07:02:56 +00:00
});
2021-08-07 18:57:36 +00:00
/*
2021-07-23 15:40:44 +00:00
ipcMain.on('request-update-data-state', (event, arg) => {
//win.webContents.send('action-update-data-state', arg);
//data.webContents.send('action-update-data-state', arg);
2021-07-23 15:40:44 +00:00
});
ipcMain.on('request-update-heard-stations', (event, arg) => {
2021-07-25 14:35:50 +00:00
win.webContents.send('action-update-heard-stations', arg);
2021-07-23 15:40:44 +00:00
});
2021-08-07 18:57:36 +00:00
*/
2021-07-17 07:02:56 +00:00
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);
});
2022-02-12 15:34:47 +00:00
ipcMain.on('request-update-tnc-connection', (event, arg) => {
win.webContents.send('action-update-tnc-connection', arg);
});
2021-07-17 07:02:56 +00:00
ipcMain.on('request-update-daemon-connection', (event, arg) => {
win.webContents.send('action-update-daemon-connection', arg);
});
ipcMain.on('run-tnc-command', (event, arg) => {
2021-09-04 18:23:58 +00:00
win.webContents.send('run-tnc-command', arg);
});
2021-08-16 18:04:03 +00:00
ipcMain.on('request-update-rx-buffer', (event, arg) => {
2021-09-04 18:23:58 +00:00
win.webContents.send('action-update-rx-buffer', arg);
2021-09-08 16:22:41 +00:00
});
2021-10-17 15:22:07 +00:00
ipcMain.on('request-update-rx-msg-buffer', (event, arg) => {
2021-11-19 16:30:17 +00:00
chat.webContents.send('action-update-rx-msg-buffer', arg);
});
ipcMain.on('request-open-tnc-log', (event) => {
logViewer.show();
});
2022-02-22 14:53:55 +00:00
// LISTENER FOR UPDATER EVENTS
autoUpdater.on('update-available', (info) => {
mainLog.info('update available');
2022-02-22 14:40:33 +00:00
let arg = {
status: "update-available",
info: info
2022-02-22 14:40:33 +00:00
};
win.webContents.send('action-updater', arg);
});
autoUpdater.on('update-not-available', (info) => {
mainLog.info('update not available');
2022-02-22 14:40:33 +00:00
let arg = {
status: "update-not-available",
info: info
2022-02-22 14:40:33 +00:00
};
win.webContents.send('action-updater', arg);
});
2022-02-22 14:40:33 +00:00
autoUpdater.on('update-downloaded', (info) => {
mainLog.info('update downloaded');
2022-02-22 14:40:33 +00:00
let arg = {
status: "update-downloaded",
info: info
2022-02-22 14:40:33 +00:00
};
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();
2022-02-22 14:40:33 +00:00
});
autoUpdater.on('checking-for-update', () => {
mainLog.info('checking for update');
2022-02-22 14:40:33 +00:00
let arg = {
status: "checking-for-update",
version: app.getVersion()
2022-02-22 14:40:33 +00:00
};
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');
2022-02-22 14:40:33 +00:00
let arg = {
status: "error",
progress: error
2022-02-22 14:40:33 +00:00
};
win.webContents.send('action-updater', arg);
});