| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  | const path = require('path'); | 
					
						
							|  |  |  | const url = require("url"); | 
					
						
							|  |  |  | const port = require('./port'); | 
					
						
							|  |  |  | const optionService = require('./options'); | 
					
						
							|  |  |  | const env = require('./env'); | 
					
						
							| 
									
										
										
										
											2019-12-27 20:28:27 +01:00
										 |  |  | const log = require('./log'); | 
					
						
							|  |  |  | const sqlInit = require('./sql_init'); | 
					
						
							|  |  |  | const cls = require('./cls'); | 
					
						
							|  |  |  | const keyboardActionsService = require('./keyboard_actions'); | 
					
						
							| 
									
										
										
										
											2020-04-23 23:08:15 +02:00
										 |  |  | const {ipcMain} = require('electron'); | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Prevent window being garbage collected
 | 
					
						
							|  |  |  | /** @type {Electron.BrowserWindow} */ | 
					
						
							|  |  |  | let mainWindow; | 
					
						
							|  |  |  | /** @type {Electron.BrowserWindow} */ | 
					
						
							|  |  |  | let setupWindow; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-03 23:47:24 +02:00
										 |  |  | async function createExtraWindow(notePath, hoistedNoteId = 'root', viewScope = {}) { | 
					
						
							| 
									
										
										
										
											2022-01-02 21:35:02 +01:00
										 |  |  |     const spellcheckEnabled = optionService.getOptionBool('spellCheckEnabled'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 23:08:15 +02:00
										 |  |  |     const {BrowserWindow} = require('electron'); | 
					
						
							| 
									
										
										
										
											2022-01-02 21:35:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 23:08:15 +02:00
										 |  |  |     const win = new BrowserWindow({ | 
					
						
							| 
									
										
										
										
											2020-04-27 22:29:39 +02:00
										 |  |  |         width: 1000, | 
					
						
							|  |  |  |         height: 800, | 
					
						
							| 
									
										
										
										
											2020-04-23 23:08:15 +02:00
										 |  |  |         title: 'Trilium Notes', | 
					
						
							|  |  |  |         webPreferences: { | 
					
						
							|  |  |  |             enableRemoteModule: true, | 
					
						
							|  |  |  |             nodeIntegration: true, | 
					
						
							| 
									
										
										
										
											2021-03-10 20:02:23 +01:00
										 |  |  |             contextIsolation: false, | 
					
						
							| 
									
										
										
										
											2022-01-02 21:35:02 +01:00
										 |  |  |             spellcheck: spellcheckEnabled | 
					
						
							| 
									
										
										
										
											2020-04-23 23:08:15 +02:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2020-06-20 12:31:38 +02:00
										 |  |  |         frame: optionService.getOptionBool('nativeTitleBarVisible'), | 
					
						
							| 
									
										
										
										
											2020-04-23 23:08:15 +02:00
										 |  |  |         icon: getIcon() | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     win.setMenuBarVisibility(false); | 
					
						
							| 
									
										
										
										
											2023-04-03 23:47:24 +02:00
										 |  |  |     win.loadURL(`http://127.0.0.1:${port}/?extraWindow=1&extraHoistedNoteId=${hoistedNoteId}&extraViewScope=${JSON.stringify(viewScope)}#${notePath}`); | 
					
						
							| 
									
										
										
										
											2022-01-02 21:35:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     configureWebContents(win.webContents, spellcheckEnabled); | 
					
						
							| 
									
										
										
										
											2020-04-23 23:08:15 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ipcMain.on('create-extra-window', (event, arg) => { | 
					
						
							| 
									
										
										
										
											2023-04-03 23:47:24 +02:00
										 |  |  |     createExtraWindow(arg.notePath, arg.hoistedNoteId, arg.viewScope); | 
					
						
							| 
									
										
										
										
											2020-04-23 23:08:15 +02:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 22:53:06 +02:00
										 |  |  | async function createMainWindow(app) { | 
					
						
							| 
									
										
										
										
											2019-12-25 19:38:28 +01:00
										 |  |  |     const windowStateKeeper = require('electron-window-state'); // should not be statically imported
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |     const mainWindowState = windowStateKeeper({ | 
					
						
							| 
									
										
										
										
											2023-01-15 21:04:17 +01:00
										 |  |  |         // default window width & height, so it's usable on 1600 * 900 display (including some extra panels etc.)
 | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |         defaultWidth: 1200, | 
					
						
							|  |  |  |         defaultHeight: 800 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 12:31:38 +02:00
										 |  |  |     const spellcheckEnabled = optionService.getOptionBool('spellCheckEnabled'); | 
					
						
							| 
									
										
										
										
											2020-02-28 22:07:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 19:38:28 +01:00
										 |  |  |     const {BrowserWindow} = require('electron'); // should not be statically imported
 | 
					
						
							| 
									
										
										
										
											2021-06-06 22:15:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |     mainWindow = new BrowserWindow({ | 
					
						
							|  |  |  |         x: mainWindowState.x, | 
					
						
							|  |  |  |         y: mainWindowState.y, | 
					
						
							|  |  |  |         width: mainWindowState.width, | 
					
						
							|  |  |  |         height: mainWindowState.height, | 
					
						
							|  |  |  |         title: 'Trilium Notes', | 
					
						
							|  |  |  |         webPreferences: { | 
					
						
							| 
									
										
										
										
											2021-12-24 22:18:05 +01:00
										 |  |  |             enableRemoteModule: true, | 
					
						
							| 
									
										
										
										
											2020-02-28 22:07:08 +01:00
										 |  |  |             nodeIntegration: true, | 
					
						
							| 
									
										
										
										
											2021-03-09 22:36:41 +01:00
										 |  |  |             contextIsolation: false, | 
					
						
							| 
									
										
										
										
											2022-05-29 17:42:09 +02:00
										 |  |  |             spellcheck: spellcheckEnabled, | 
					
						
							|  |  |  |             webviewTag: true | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2020-06-20 12:31:38 +02:00
										 |  |  |         frame: optionService.getOptionBool('nativeTitleBarVisible'), | 
					
						
							| 
									
										
										
										
											2021-09-08 21:54:26 +02:00
										 |  |  |         icon: getIcon() | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mainWindowState.manage(mainWindow); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mainWindow.setMenuBarVisibility(false); | 
					
						
							| 
									
										
										
										
											2022-12-21 15:19:05 +01:00
										 |  |  |     mainWindow.loadURL(`http://127.0.0.1:${port}`); | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |     mainWindow.on('closed', () => mainWindow = null); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 21:35:02 +01:00
										 |  |  |     configureWebContents(mainWindow.webContents, spellcheckEnabled); | 
					
						
							| 
									
										
										
										
											2022-08-02 22:53:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     app.on('second-instance', () => { | 
					
						
							|  |  |  |         // Someone tried to run a second instance, we should focus our window.
 | 
					
						
							|  |  |  |         // see www.js "requestSingleInstanceLock" for the rest of this logic with explanation
 | 
					
						
							|  |  |  |         if (mainWindow) { | 
					
						
							|  |  |  |             if (mainWindow.isMinimized()) { | 
					
						
							|  |  |  |                 mainWindow.restore(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             mainWindow.focus(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-01-02 21:35:02 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-28 22:07:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 21:35:02 +01:00
										 |  |  | function configureWebContents(webContents, spellcheckEnabled) { | 
					
						
							| 
									
										
										
										
											2021-11-16 22:43:08 +01:00
										 |  |  |     require("@electron/remote/main").enable(webContents); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 22:07:08 +01:00
										 |  |  |     webContents.on('new-window', (e, url) => { | 
					
						
							|  |  |  |         if (url !== webContents.getURL()) { | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |             e.preventDefault(); | 
					
						
							|  |  |  |             require('electron').shell.openExternal(url); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // prevent drag & drop to navigate away from trilium
 | 
					
						
							| 
									
										
										
										
											2020-02-28 22:07:08 +01:00
										 |  |  |     webContents.on('will-navigate', (ev, targetUrl) => { | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |         const parsedUrl = url.parse(targetUrl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // we still need to allow internal redirects from setup and migration pages
 | 
					
						
							| 
									
										
										
										
											2021-09-27 21:01:56 +02:00
										 |  |  |         if (!['localhost', '127.0.0.1'].includes(parsedUrl.hostname) || (parsedUrl.path && parsedUrl.path !== '/' && parsedUrl.path !== '/?')) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |             ev.preventDefault(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-02-28 22:07:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (spellcheckEnabled) { | 
					
						
							| 
									
										
										
										
											2020-06-20 12:31:38 +02:00
										 |  |  |         const languageCodes = (optionService.getOption('spellCheckLanguageCode')) | 
					
						
							| 
									
										
										
										
											2020-04-20 22:26:31 +02:00
										 |  |  |             .split(',') | 
					
						
							| 
									
										
										
										
											2020-02-28 22:07:08 +01:00
										 |  |  |             .map(code => code.trim()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         webContents.session.setSpellCheckerLanguages(languageCodes); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function getIcon() { | 
					
						
							| 
									
										
										
										
											2021-09-07 23:14:17 +02:00
										 |  |  |     return path.join(__dirname, '../../images/app-icons/png/256x256' + (env.isDev() ? '-dev' : '') + '.png'); | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function createSetupWindow() { | 
					
						
							| 
									
										
										
										
											2019-12-25 19:38:28 +01:00
										 |  |  |     const {BrowserWindow} = require('electron'); // should not be statically imported
 | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |     setupWindow = new BrowserWindow({ | 
					
						
							|  |  |  |         width: 800, | 
					
						
							|  |  |  |         height: 800, | 
					
						
							|  |  |  |         title: 'Trilium Notes Setup', | 
					
						
							| 
									
										
										
										
											2019-12-27 20:22:46 +01:00
										 |  |  |         icon: getIcon(), | 
					
						
							|  |  |  |         webPreferences: { | 
					
						
							|  |  |  |             // necessary for e.g. utils.isElectron()
 | 
					
						
							|  |  |  |             nodeIntegration: true | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setupWindow.setMenuBarVisibility(false); | 
					
						
							| 
									
										
										
										
											2022-12-21 15:19:05 +01:00
										 |  |  |     setupWindow.loadURL(`http://127.0.0.1:${port}`); | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  |     setupWindow.on('closed', () => setupWindow = null); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function closeSetupWindow() { | 
					
						
							|  |  |  |     if (setupWindow) { | 
					
						
							|  |  |  |         setupWindow.close(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 21:42:41 +02:00
										 |  |  | async function registerGlobalShortcuts() { | 
					
						
							| 
									
										
										
										
											2019-12-27 20:28:27 +01:00
										 |  |  |     const {globalShortcut} = require('electron'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 21:42:41 +02:00
										 |  |  |     await sqlInit.dbReady; | 
					
						
							| 
									
										
										
										
											2019-12-27 20:28:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 12:31:38 +02:00
										 |  |  |     const allActions = keyboardActionsService.getKeyboardActions(); | 
					
						
							| 
									
										
										
										
											2019-12-27 20:28:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (const action of allActions) { | 
					
						
							|  |  |  |         if (!action.effectiveShortcuts) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const shortcut of action.effectiveShortcuts) { | 
					
						
							|  |  |  |             if (shortcut.startsWith('global:')) { | 
					
						
							|  |  |  |                 const translatedShortcut = shortcut.substr(7); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 12:31:38 +02:00
										 |  |  |                 const result = globalShortcut.register(translatedShortcut, cls.wrap(() => { | 
					
						
							| 
									
										
										
										
											2019-12-27 20:28:27 +01:00
										 |  |  |                     // window may be hidden / not in focus
 | 
					
						
							|  |  |  |                     mainWindow.focus(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     mainWindow.webContents.send('globalShortcut', action.actionName); | 
					
						
							|  |  |  |                 })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (result) { | 
					
						
							|  |  |  |                     log.info(`Registered global shortcut ${translatedShortcut} for action ${action.actionName}`); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     log.info(`Could not register global shortcut ${translatedShortcut}`); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-14 12:36:39 +00:00
										 |  |  | function getMainWindow() { | 
					
						
							|  |  |  |     return mainWindow; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-24 14:42:03 +01:00
										 |  |  | module.exports = { | 
					
						
							|  |  |  |     createMainWindow, | 
					
						
							|  |  |  |     createSetupWindow, | 
					
						
							| 
									
										
										
										
											2019-12-27 20:28:27 +01:00
										 |  |  |     closeSetupWindow, | 
					
						
							| 
									
										
										
										
											2021-11-14 12:36:39 +00:00
										 |  |  |     registerGlobalShortcuts, | 
					
						
							|  |  |  |     getMainWindow | 
					
						
							| 
									
										
										
										
											2020-06-20 12:31:38 +02:00
										 |  |  | }; |