2024-06-04 14:58:52 +02:00
|
|
|
const { app, BrowserWindow, ipcMain } = require('electron/main');
|
|
|
|
|
const path = require('node:path');
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
const log = require('electron-log/main');
|
|
|
|
|
|
|
|
|
|
|
2024-06-03 12:16:11 +02:00
|
|
|
class Config {
|
2024-06-04 14:58:52 +02:00
|
|
|
url = "";
|
|
|
|
|
whitelist = [];
|
|
|
|
|
logPath = "tooloop-kiosk-browser.log";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// Private fields
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
const locations = [
|
|
|
|
|
'/assets/presentation',
|
|
|
|
|
path.join(app.getPath('appData'), app.name),
|
|
|
|
|
app.getAppPath()
|
|
|
|
|
];
|
|
|
|
|
let configPath;
|
|
|
|
|
let configWindow;
|
|
|
|
|
let saveCallback;
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// Public fields
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
exports.data = new Config();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// Public functions
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Loads a config file from disc.
|
|
|
|
|
* The file is expected to be named `config.json` and is searched for in these
|
|
|
|
|
* locations and in this order:
|
|
|
|
|
*
|
|
|
|
|
* 1. `/assets/presentation/config.json` (Tooloop OS)
|
|
|
|
|
* 2. appData directory
|
|
|
|
|
* 3. Path of the executable (Development)
|
|
|
|
|
*/
|
|
|
|
|
exports.load = () => {
|
|
|
|
|
// Check all locations
|
|
|
|
|
for (const location of locations) {
|
|
|
|
|
// Update the filepath
|
|
|
|
|
let configFile = path.join(location, 'config.json');
|
|
|
|
|
try {
|
|
|
|
|
// Try access
|
|
|
|
|
fs.accessSync(configFile);
|
|
|
|
|
|
|
|
|
|
// Parse the file if found
|
|
|
|
|
console.info('Found config file at ' + configFile);
|
|
|
|
|
const fileContent = fs.readFileSync(configFile, { encoding: 'utf8' });
|
|
|
|
|
this.data = JSON.parse(fileContent);
|
|
|
|
|
|
|
|
|
|
// store successful location
|
|
|
|
|
configPath = location;
|
|
|
|
|
|
|
|
|
|
// Break the loop
|
|
|
|
|
break;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
// console.info('No config file found at ' + location);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-03 12:16:11 +02:00
|
|
|
|
2024-06-04 14:58:52 +02:00
|
|
|
/**
|
|
|
|
|
* Saves the current configuration to disc.
|
|
|
|
|
* These locations are tried in this order:
|
|
|
|
|
*
|
|
|
|
|
* 1. `/assets/presentation/config.json` (Tooloop OS)
|
|
|
|
|
* 2. appData directory
|
|
|
|
|
*
|
|
|
|
|
* @param {Config} newConfig
|
|
|
|
|
*/
|
|
|
|
|
exports.save = (newConfig) => {
|
|
|
|
|
if (!configPath) {
|
|
|
|
|
try {
|
|
|
|
|
// /assets/presentation
|
|
|
|
|
fs.accessSync(locations[0]);
|
|
|
|
|
configPath = locations[0];
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// appData
|
|
|
|
|
configPath = locations[1];
|
|
|
|
|
}
|
2024-06-03 12:16:11 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-04 14:58:52 +02:00
|
|
|
// Store changes
|
|
|
|
|
if (this.data.url != newConfig.url) {
|
|
|
|
|
this.data.url = newConfig.url;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.data.whitelist = [];
|
|
|
|
|
let whitelist = newConfig.whitelist.split(";");
|
|
|
|
|
whitelist = whitelist.filter(function (entry) { return entry.trim() != ''; });
|
|
|
|
|
whitelist.forEach(
|
|
|
|
|
token => {
|
|
|
|
|
this.data.whitelist.push(token.replace(/\r?\n|\r/g, ""));
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this.data.logPath = newConfig.logPath;
|
|
|
|
|
|
|
|
|
|
// Write file
|
|
|
|
|
let configFile = path.join(configPath, 'config.json');
|
|
|
|
|
fs.writeFile(
|
|
|
|
|
configFile,
|
|
|
|
|
JSON.stringify(this.data, null, " "),
|
|
|
|
|
(error) => {
|
|
|
|
|
if (error) log.warn('Error writing to ' + configPath, error);
|
|
|
|
|
log.info("Saved config to " + configFile);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Update UI with new values
|
|
|
|
|
configWindow.webContents.send('update-config', this.data);
|
|
|
|
|
|
|
|
|
|
// Notify listeners
|
|
|
|
|
saveCallback(this.data);
|
|
|
|
|
|
2024-06-03 12:16:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-06-04 14:58:52 +02:00
|
|
|
/**
|
|
|
|
|
* Creates a modal config view and attaches as to the main window
|
|
|
|
|
*
|
|
|
|
|
* @param {BrowserWindow} parent Reference to the parent window
|
|
|
|
|
* @param {function(Config)} saveCallback
|
|
|
|
|
*/
|
|
|
|
|
exports.showWindow = (parent, callback) => {
|
2024-06-03 12:16:11 +02:00
|
|
|
|
2024-06-04 14:58:52 +02:00
|
|
|
// create lazily
|
|
|
|
|
if (configWindow == undefined) {
|
|
|
|
|
console.log("create windows");
|
|
|
|
|
saveCallback = callback;
|
|
|
|
|
|
|
|
|
|
configWindow = new BrowserWindow({
|
|
|
|
|
parent: parent,
|
|
|
|
|
width: 640,
|
|
|
|
|
height: 460,
|
|
|
|
|
minimizable: false,
|
|
|
|
|
maximizable: false,
|
|
|
|
|
fullscreenable: false,
|
|
|
|
|
backgroundColor: '#1f1f1f',
|
|
|
|
|
autoHideMenuBar: true,
|
|
|
|
|
excludedFromShownWindowsMenu: true,
|
|
|
|
|
webPreferences: {
|
|
|
|
|
preload: path.join(__dirname, 'configPreload.js')
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
configWindow.on('close', (event) => {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
configWindow.hide();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
ipcMain.on('save-config', (event, configData) => {
|
|
|
|
|
configWindow.hide();
|
|
|
|
|
this.save(configData);
|
|
|
|
|
});
|
|
|
|
|
ipcMain.on('cancel-config', (event) => {
|
|
|
|
|
configWindow.hide();
|
|
|
|
|
configWindow.webContents.send('update-config', this.data);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
configWindow.loadFile('./html/config.html');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// update text field values
|
|
|
|
|
configWindow.webContents.send('update-config', this.data);
|
|
|
|
|
|
|
|
|
|
// show window
|
|
|
|
|
configWindow.show();
|
|
|
|
|
}
|