mirror of
				https://github.com/notion-enhancer/notion-enhancer.git
				synced 2025-10-28 04:38:08 +11:00 
			
		
		
		
	feat: toggle window hotkey, reorderable tabs, dev mode
(merged tray & tabs extensions into the core now that the official notion app includes tray & tabs implementations
This commit is contained in:
		
							parent
							
								
									23f8e3b560
								
							
						
					
					
						commit
						bbb60ae76f
					
				| @ -22,41 +22,49 @@ const mainScript = ".webpack/main/index", | ||||
|   patches = { | ||||
|     [mainScript]: (scriptContent) => { | ||||
|       scriptContent = injectTriggerOnce(mainScript, scriptContent); | ||||
|       const replace = (...args) => | ||||
|         (scriptContent = replaceIfNotFound(scriptContent, ...args)); | ||||
| 
 | ||||
|       // https://github.com/notion-enhancer/notion-enhancer/issues/160:
 | ||||
|       // enable the notion:// protocol, windows-style tab layouts, and
 | ||||
|       // quitting the app when the last window is closed on linux
 | ||||
|       scriptContent = scriptContent.replace( | ||||
|         /(?:"win32"===process\.platform(?:(?=,isFullscreen)|(?=&&\w\.BrowserWindow)|(?=&&\(\w\.app\.requestSingleInstanceLock)))/g, | ||||
|         '["win32","linux"].includes(process.platform)' | ||||
|       ); | ||||
|       const isWindows = | ||||
|           /(?:"win32"===process\.platform(?:(?=,isFullscreen)|(?=&&\w\.BrowserWindow)|(?=&&\(\w\.app\.requestSingleInstanceLock)))/g, | ||||
|         isWindowsOrLinux = '["win32","linux"].includes(process.platform)'; | ||||
|       replace(isWindows, isWindowsOrLinux); | ||||
| 
 | ||||
|       // restore node integration in the renderer process
 | ||||
|       // so the notion-enhancer can be require()-d into it
 | ||||
|       scriptContent = replaceIfNotFound( | ||||
|         scriptContent, | ||||
|         /spellcheck:!0,sandbox:!0/g, | ||||
|         "spellcheck:!0,nodeIntegration:true" | ||||
|       ); | ||||
|       replace("spellcheck:!0,sandbox:!0", "spellcheck:!0,nodeIntegration:true"); | ||||
| 
 | ||||
|       // bypass webRequest filter to load enhancer menu
 | ||||
|       replace("r.top!==r?t({cancel:!0})", "r.top!==r?t({})"); | ||||
| 
 | ||||
|       // https://github.com/notion-enhancer/desktop/issues/291
 | ||||
|       // bypass csp issues by intercepting the notion:// protocol
 | ||||
|       const protocolHandler = | ||||
|         "try{const t=await p.assetCache.handleRequest(e);"; | ||||
|       scriptContent = replaceIfNotFound( | ||||
|         scriptContent, | ||||
|         protocolHandler, | ||||
|         `{const n="notion://www.notion.so/__notion-enhancer/";if(e.url.startsWith(n))return require("electron").net.fetch(\`file://\${require("path").join(__dirname,"..","..","node_modules","notion-enhancer",e.url.slice(n.length))}\`)}${protocolHandler}` | ||||
|       ); | ||||
|       const protocolHandler = `try{const t=await p.assetCache.handleRequest(e);`, | ||||
|         protocolInterceptor = `{const n="notion://www.notion.so/__notion-enhancer/";if(e.url.startsWith(n))return require("electron").net.fetch(\`file://\${require("path").join(__dirname,"..","..","node_modules","notion-enhancer",e.url.slice(n.length))}\`)}`; | ||||
|       replace(protocolHandler, protocolInterceptor + protocolHandler); | ||||
| 
 | ||||
|       // bypass webRequest filter to load enhancer menu
 | ||||
|       return replaceIfNotFound( | ||||
|         scriptContent, | ||||
|         /r\.top!==r\?t\({cancel:!0}\)/g, | ||||
|         "r.top!==r?t({})" | ||||
|       ); | ||||
|       // expose the app config to the global namespace for manipulation
 | ||||
|       // e.g. to enable development mode
 | ||||
|       const configDeclaration = `e.exports=JSON.parse('{"env":"production"`, | ||||
|         configInterceptor = `globalThis.__notionConfig=${configDeclaration}`; | ||||
|       replace(configDeclaration, configInterceptor); | ||||
| 
 | ||||
|       // expose the app store to the global namespace for reading
 | ||||
|       // e.g. to check if keep in background is enabled
 | ||||
|       const storeDeclaration = "t.Store=(0,p.configureStore)", | ||||
|         updateDeclaration = "t.updatePreferences=n.updatePreferences", | ||||
|         storeInterceptor = `globalThis.__notionStore=${storeDeclaration}`, | ||||
|         updateInterceptor = `globalThis.__updatePreferences=${updateDeclaration}`; | ||||
|       replace(storeDeclaration, storeInterceptor); | ||||
|       replace(updateDeclaration, updateInterceptor); | ||||
| 
 | ||||
|       return scriptContent; | ||||
|     }, | ||||
|     [rendererScript]: (scriptContent) => injectTriggerOnce(rendererScript, scriptContent) | ||||
|     [rendererScript]: (scriptContent) => | ||||
|       injectTriggerOnce(rendererScript, scriptContent), | ||||
|   }; | ||||
| 
 | ||||
| export default (scriptId, scriptContent) => { | ||||
|  | ||||
| @ -112,7 +112,6 @@ const modifierAliases = [ | ||||
|     keyListeners = keyListeners.filter(([, c]) => c !== callback); | ||||
|   }, | ||||
|   handleKeypress = (event, keyListeners) => { | ||||
|     console.log(event); | ||||
|     for (const [accelerator, callback] of keyListeners) { | ||||
|       const acceleratorModifiers = [], | ||||
|         combinationTriggered = | ||||
|  | ||||
							
								
								
									
										52
									
								
								src/core/electron.cjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/core/electron.cjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| /** | ||||
|  * notion-enhancer | ||||
|  * (c) 2024 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
 | ||||
|  * (https://notion-enhancer.github.io/) under the MIT license
 | ||||
|  */ | ||||
| 
 | ||||
| const getPreference = (key) => { | ||||
|     const { preferences = {} } = globalThis.__notionStore?.getState()?.app; | ||||
|     return preferences[key]; | ||||
|   }, | ||||
|   setPreference = (key, value) => { | ||||
|     const action = globalThis.__updatePreferences?.({ [key]: value }); | ||||
|     globalThis.__notionStore?.dispatch?.(action); | ||||
|   }; | ||||
| 
 | ||||
| module.exports = async ({}, db) => { | ||||
|   const toggleWindowHotkey = await db.get("toggleWindowHotkey"), | ||||
|     developerMode = await db.get("developerMode"), | ||||
|     draggableTabs = await db.get("draggableTabs"); | ||||
| 
 | ||||
|   // experimental: enable tab reordering from notion's hidden preferences
 | ||||
|   setPreference("isDraggableTabsEnabled", draggableTabs); | ||||
| 
 | ||||
|   // enable developer mode, access extra debug tools
 | ||||
|   globalThis.__notionConfig ??= {}; | ||||
|   Object.assign(globalThis.__notionConfig, { | ||||
|     env: developerMode ? "development" : "production", | ||||
|   }); | ||||
| 
 | ||||
|   // listen for the global window toggle hotkey
 | ||||
|   const { app, globalShortcut, BrowserWindow } = require("electron"); | ||||
|   app.whenReady().then(() => { | ||||
|     globalShortcut.register(toggleWindowHotkey, () => { | ||||
|       const windows = BrowserWindow.getAllWindows() | ||||
|           // filter out quick search window
 | ||||
|           .filter((win) => win.fullScreenable), | ||||
|         focused = windows.some((win) => win.isFocused() && win.isVisible()); | ||||
|       windows.forEach((win) => | ||||
|         // check if notion is set to run in the background
 | ||||
|         getPreference("isHideLastWindowOnCloseEnabled") | ||||
|           ? focused | ||||
|             ? win.hide() | ||||
|             : win.show() | ||||
|           : focused | ||||
|           ? win.minimize() | ||||
|           : win.isMinimized() | ||||
|           ? win.restore() | ||||
|           : win.focus() | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| }; | ||||
| @ -56,6 +56,17 @@ | ||||
|       "description": "Sets whether the notion-enhancer icon added to Notion's sidebar should be coloured or monochrome. The latter style will match the theme's icon colour for users who would like the icon to be less noticeable.", | ||||
|       "values": ["Colour", "Monochrome"] | ||||
|     }, | ||||
|     { | ||||
|       "type": "heading", | ||||
|       "label": "Experimental" | ||||
|     }, | ||||
|     { | ||||
|       "type": "toggle", | ||||
|       "key": "draggableTabs", | ||||
|       "description": "Enables reordering tabs within the Notion app via drag and drop.", | ||||
|       "platforms": ["linux", "win32", "darwin"], | ||||
|       "value": false | ||||
|     }, | ||||
|     { | ||||
|       "type": "heading", | ||||
|       "label": "Advanced", | ||||
| @ -70,5 +81,6 @@ | ||||
|     } | ||||
|   ], | ||||
|   "clientStyles": ["variables.css"], | ||||
|   "clientScripts": ["client.mjs"] | ||||
|   "clientScripts": ["client.mjs"], | ||||
|   "electronScripts": [[".webpack/main/index", "electron.cjs"]] | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /** | ||||
|  * notion-enhancer | ||||
|  * (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
 | ||||
|  * (c) 2024 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
 | ||||
|  * (https://notion-enhancer.github.io/) under the MIT license
 | ||||
|  */ | ||||
| 
 | ||||
| @ -44,8 +44,9 @@ if (isElectron()) { | ||||
|     for (const mod of await getMods()) { | ||||
|       if (!mod.electronScripts || !(await isEnabled(mod.id))) continue; | ||||
|       const db = await modDatabase(mod.id); | ||||
|       for (let script of mod.clientScripts ?? []) { | ||||
|         script = require(`notion-enhancer/${mod._src}/${source}`); | ||||
|       for (let [scriptTarget, script] of mod.electronScripts ?? []) { | ||||
|         if (target !== scriptTarget) continue; | ||||
|         script = require(`./${mod._src}/${script}`); | ||||
|         script(globalThis.__enhancerApi, db, __exports, __eval); | ||||
|       } | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user