const { app, BrowserWindow, ipcMain } = require('electron/main'); const path = require('node:path'); const fs = require('fs'); const log = require('electron-log/main'); class Config { 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); } } } /** * 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]; } } // 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); } /** * 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) => { // 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(); }