From a10d10330a54046e68a14841410bf69447f3a04d Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 16 May 2025 11:34:46 -0700 Subject: [PATCH] Upload files to "modules" --- modules/menu-service.js | 177 ++++++++++++++++++++++++++++++++++++ modules/settings-service.js | 30 ++++++ modules/tray-service.js | 52 +++++++++++ 3 files changed, 259 insertions(+) create mode 100644 modules/menu-service.js create mode 100644 modules/settings-service.js create mode 100644 modules/tray-service.js diff --git a/modules/menu-service.js b/modules/menu-service.js new file mode 100644 index 0000000..0bac65f --- /dev/null +++ b/modules/menu-service.js @@ -0,0 +1,177 @@ +/** + * Module for Menu functions. + */ +import { app, Menu, MenuItem, dialog } from 'electron'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import settingsService from './settings-service.js'; +import { mainWindow } from '../main.js'; // this is bad practice, however i dont have any other good way of doing it +let zoom = 1; + +const menuService = {}; + +menuService.createMenu = (window) => { + let converse; + const application = new Menu(); + + application.append(new MenuItem({ + label: 'RS Desktop', + submenu: (converse = Menu.buildFromTemplate([ + { + label: 'Reconnect', + accelerator: 'CmdOrCtrl+R', + click: () => { + window.show(); + window.loadFile('index.html').catch((reason) => { + console.log(reason); + app.isQuitting = true; + app.quit(); + }); + } + }, + { type: 'separator' }, + { + label: 'Minimize on close', + type: 'checkbox', + id: 'minimize-on-close', + checked: settingsService.get('minimizeOnClose'), + click: () => { + settingsService.set('minimizeOnClose', converse.getMenuItemById('minimize-on-close').checked); + } + }, + { + label: 'Hide Menubar', + type: 'checkbox', + id: 'hide-menubar', + checked: settingsService.get('hideMenubar'), + accelerator: 'alt', // just felt like this would be a good addition in case the user accidentally hides the alt bar + click: () => { + const menuItem = converse.getMenuItemById('hide-menubar'); + settingsService.set('hideMenubar', menuItem.checked); + window.setAutoHideMenuBar(menuItem.checked); + } + }, + { + label: 'Encrypt by default', + type: 'checkbox', + id: 'encrypt-by-default', + checked: settingsService.get('omemo_default'), + click: () => { + const menuItem = converse.getMenuItemById('encrypt-by-default'); + settingsService.set('omemo_default', menuItem.checked); + } + }, + { type: 'separator' }, + { + label: 'Help', // migrate this here + submenu: Menu.buildFromTemplate([ + { + label: 'Debug info', + accelerator: 'F12', + click: () => { + window.webContents.openDevTools(); + } + }, + ])}, + + { + label: 'Navigation', // migrate this here + submenu: Menu.buildFromTemplate([ + { + label: '<', + accelerator: 'Alt+Left', // for this it was alt left arrow key + click() { + if (mainWindow.webContents.canGoBack()) { + mainWindow.webContents.goBack(); + } + } + }, + { + label: '>', + accelerator: 'Alt+Right', // shortcut for this was alt and right arrow key i think + click() { + if (mainWindow.webContents.canGoForward()) { + mainWindow.webContents.goForward(); + } + } + }, + { + label: '🔄', + click() { + mainWindow.reload(); + } + }, + ])}, + { type: 'separator' }, + { + label: 'Reset Zoom', + accelerator: 'Ctrl+0', // shortcut like in chrome/firefox + click() { + zoom = 1 + mainWindow.webContents.setZoomFactor(zoom) + } + }, + { type: 'separator' }, + { + label: 'Quit', + accelerator: 'CmdOrCtrl+Q', + click: () => { + app.isQuitting = true; + app.quit(); + }, + }, + ])) + })); + + application.append(new MenuItem({ + label: 'Edit', // i dont know what the point of this is, we have keyboards and they use the same shortcuts, but i will leave this alone for now + submenu: Menu.buildFromTemplate([ + { label: 'Undo', accelerator: 'CmdOrCtrl+Z', role: 'undo' }, + { label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo' }, + { label: 'Cut', accelerator: 'CmdOrCtrl+X', role: 'cut' }, + { label: 'Copy', accelerator: 'CmdOrCtrl+C', role: 'copy' }, + { label: 'Paste', accelerator: 'CmdOrCtrl+V', role: 'paste' }, + { label: 'Select All', accelerator: 'CmdOrCtrl+A', role: 'selectAll' }, + ]) + })); + + application.append(new MenuItem({ + label: 'Themes', + submenu: Menu.buildFromTemplate([ + { + label: 'Coming soon', + click: () => { + window.webContents.openDevTools(); // TODO: theme switching + } + + // { + /// label: 'Night', + // click: () => { + // window.webContents.openDevTools(); // TODO: proper dark mode + // } + // }, + // { + // label: 'Orange', + // click: () => { + // window.webContents.openDevTools(); // Orange & white theme + // } + // }, + // { + //// label: 'Orange + Night', + // click: () => { + // window.webContents.openDevTools(); // Orange & dark theme + // } + // }, + // { + // label: 'Fruit Tiger Aero', + // // click: () => { + // window.webContents.openDevTools(); // Blue & green theme + + } + ]) + })); + + Menu.setApplicationMenu(application); +}; + +export default menuService; diff --git a/modules/settings-service.js b/modules/settings-service.js new file mode 100644 index 0000000..fd0529b --- /dev/null +++ b/modules/settings-service.js @@ -0,0 +1,30 @@ +/** + * Module for getting settings in Main process. + */ +import electronSettings from 'electron-settings'; + +const settingsService = { + get(itemKey) { + const settingValue = electronSettings.getSync(itemKey); + return (typeof settingValue === 'undefined' || settingValue === null) ? false : settingValue; + }, + + set(itemKey, settingValue) { + electronSettings.setSync(itemKey, settingValue); + if (settingsService.webContents) { + settingsService.webContents.send('settings', 'changed', itemKey, settingValue); + } + }, + + has(itemKey) { + return electronSettings.hasSync(itemKey); + }, + + unset(itemKey) { + electronSettings.unsetSync(itemKey); + }, + + webContents: null +}; + +export default settingsService; diff --git a/modules/tray-service.js b/modules/tray-service.js new file mode 100644 index 0000000..5093a69 --- /dev/null +++ b/modules/tray-service.js @@ -0,0 +1,52 @@ +/** + * Module for Tray functions. + */ +import { Tray } from 'electron'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { dirname, join } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +let tray = null; + +const trayService = {}; + +const getTrayServiceIcon = (withEnvelope = false) => { + let size; + if (process.platform === 'darwin' || process.platform === 'win32') { + size = '16x16'; + } else { + size = '48x48'; + } + + if (withEnvelope) { + return join(__dirname, '..', 'resources', 'images', 'tray', `envelope-${size}.png`); + } else { + return join(__dirname, '..', 'resources', 'images', `logo-${size}.png`); + } +}; + +trayService.initTray = (window) => { + const iconPath = getTrayServiceIcon(); + tray = new Tray(iconPath); + tray.setToolTip('Converse Desktop'); + tray.on('click', () => { + window.webContents.send('open-unread-chat'); + trayService.hideEnvelope(); + window.show(); + }); +}; + +trayService.showEnvelope = () => { + const iconPath = getTrayServiceIcon(true); + tray.setImage(iconPath); +}; + +trayService.hideEnvelope = () => { + const iconPath = getTrayServiceIcon(); + tray.setImage(iconPath); +}; + +export default trayService;