diff --git a/package-lock.json b/package-lock.json index ec9eab0..4abbf43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.11.1", "license": "MIT", "dependencies": { - "@electron/asar": "^3.2.7", + "@electron/asar": "^3.2.8", "arg": "^5.0.2", "chalk-template": "^1.1.0" }, @@ -24,9 +24,9 @@ } }, "node_modules/@electron/asar": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.7.tgz", - "integrity": "sha512-8FaSCAIiZGYFWyjeevPQt+0e9xCK9YmJ2Rjg5SXgdsXon6cRnU0Yxnbe6CvJbQn26baifur2Y2G5EBayRIsjyg==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.8.tgz", + "integrity": "sha512-cmskk5M06ewHMZAplSiF4AlME3IrnnZhKnWbtwKVLRkdJkKyUVjMLhDIiPIx/+6zQWVlKX/LtmK9xDme7540Sg==", "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", @@ -36,7 +36,7 @@ "asar": "bin/asar.js" }, "engines": { - "node": ">=10.12.0" + "node": ">=10.11.1" } }, "node_modules/arg": { diff --git a/package.json b/package.json index 3c5359f..5bb28da 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "notion-enhancer" ], "dependencies": { - "@electron/asar": "^3.2.7", + "@electron/asar": "^3.2.8", "arg": "^5.0.2", "chalk-template": "^1.1.0" } diff --git a/src/extensions/integrated-titlebar/mod.json b/src/extensions/integrated-titlebar/mod.json index c84d400..b0bd9dc 100644 --- a/src/extensions/integrated-titlebar/mod.json +++ b/src/extensions/integrated-titlebar/mod.json @@ -1,8 +1,8 @@ { - "name": "integrated titlebar", + "name": "Titlebar", "id": "a5658d03-21c6-4088-bade-fa4780459133", "environments": ["linux", "win32"], - "version": "0.11.0", + "version": "0.11.1", "description": "replaces the native window titlebar with buttons inset into the app.", "preview": "integrated-titlebar.jpg", "tags": ["extension", "layout"], @@ -23,7 +23,9 @@ "frame": ["frame.mjs"], "client": ["client.mjs"], "menu": ["menu.mjs"], - "electron": [{ "source": "createWindow.cjs", "target": "main/createWindow.js" }] + "electron": [ + { "source": "createWindow.cjs", "target": "main/createWindow.js" } + ] }, "options": [ { diff --git a/src/extensions/tabs/client.mjs b/src/extensions/tabs/client.mjs deleted file mode 100644 index 9373351..0000000 --- a/src/extensions/tabs/client.mjs +++ /dev/null @@ -1,82 +0,0 @@ -/** - * notion-enhancer: theming - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -export default async function ({ web, electron }, db) { - const newTabHotkey = await db.get(['new_tab']), - closeTabHotkey = await db.get(['close_tab']), - restoreTabHotkey = await db.get(['restore_tab']), - selectTabModifier = await db.get(['select_modifier']), - prevTabHotkey = await db.get(['prev_tab']), - nextTabHotkey = await db.get(['next_tab']); - web.addHotkeyListener(newTabHotkey, () => { - electron.sendMessageToHost('new-tab'); - }); - web.addHotkeyListener(restoreTabHotkey, () => { - electron.sendMessageToHost('restore-tab'); - }); - web.addHotkeyListener(closeTabHotkey, () => electron.sendMessageToHost('close-tab')); - for (let i = 1; i < 10; i++) { - web.addHotkeyListener([selectTabModifier, i.toString()], () => { - electron.sendMessageToHost('select-tab', i); - }); - } - web.addHotkeyListener(prevTabHotkey, () => { - electron.sendMessageToHost('select-prev-tab') - }); - web.addHotkeyListener(nextTabHotkey, () => { - electron.sendMessageToHost('select-next-tab') - }); - - const breadcrumbSelector = - '.notion-topbar > div > [class="notranslate"] > .notion-focusable:last-child', - imgIconSelector = `${breadcrumbSelector} .notion-record-icon img:not(.notion-emoji)`, - emojiIconSelector = `${breadcrumbSelector} .notion-record-icon img.notion-emoji`, - nativeIconSelector = `${breadcrumbSelector} .notion-record-icon [role="image"]`, - titleSelector = `${breadcrumbSelector} > :not(.notion-record-icon)`, - viewSelector = '.notion-collection-view-select'; - - let title = '', - icon = ''; - const notionSetWindowTitle = __electronApi.setWindowTitle, - getIcon = () => { - const $imgIcon = document.querySelector(imgIconSelector), - $emojiIcon = document.querySelector(emojiIconSelector), - $nativeIcon = document.querySelector(nativeIconSelector); - if ($imgIcon) { - return `url("${$imgIcon.src}") 0 / 100%`; - } - if ($emojiIcon) { - return $emojiIcon.style.background.replace( - /url\("\/images/, - 'url("notion://www.notion.so/images' - ); - } - if ($nativeIcon) return $nativeIcon.ariaLabel; - return ''; - }, - updateTitle = (newTitle = title) => { - if (!newTitle) return; - title = newTitle; - icon = getIcon(); - electron.sendMessageToHost('set-tab-title', title); - electron.sendMessageToHost('set-tab-icon', icon); - notionSetWindowTitle(title); - }; - __electronApi.setWindowTitle = (newTitle) => updateTitle(newTitle); - document.addEventListener('focus', updateTitle); - electron.onMessage('trigger-title-update', () => updateTitle()); - - await web.whenReady([titleSelector]); - const $title = document.querySelector(titleSelector), - $view = document.querySelector(viewSelector); - if (!title && $title) { - if ($view) { - updateTitle(`${$title.innerText} | ${$view.innerText}`); - } else updateTitle($title.innerText); - } -} diff --git a/src/extensions/tabs/createWindow.cjs b/src/extensions/tabs/createWindow.cjs deleted file mode 100644 index bda9a95..0000000 --- a/src/extensions/tabs/createWindow.cjs +++ /dev/null @@ -1,23 +0,0 @@ -/** - * notion-enhancer: tabs - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -module.exports = async function (api, db, __exports, __eval) { - const notionCreateWindow = __exports.createWindow; - __exports.createWindow = (relativeUrl = '', args) => { - const windows = api.electron.getNotionWindows(); - // '/' is used to create new windows intentionally - if (relativeUrl && relativeUrl !== '/' && windows.length) { - const window = api.electron.getFocusedNotionWindow() || windows[0]; - window.webContents.send('notion-enhancer:open-tab', { - notionUrl: `notion://www.notion.so${relativeUrl}`, - }); - return window; - } - return notionCreateWindow(relativeUrl, args); - }; -}; diff --git a/src/extensions/tabs/main.cjs b/src/extensions/tabs/main.cjs deleted file mode 100644 index 9900eee..0000000 --- a/src/extensions/tabs/main.cjs +++ /dev/null @@ -1,37 +0,0 @@ -/** - * notion-enhancer: tabs - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -module.exports = async function ({}, db, __exports, __eval) { - const electron = require('electron'); - electron.ipcMain.on('notion-enhancer:close-tab', (event, { window, id }) => { - electron.webContents.fromId(window).send('notion-enhancer:close-tab', id); - }); - - __eval(` - const notionHandleActivate = handleActivate; - handleActivate = (relativeUrl) => { - const api = require('notion-enhancer/api/index.cjs'), - { BrowserWindow } = require('electron'), - windows = api.electron.getNotionWindows(), - electronWindows = BrowserWindow.getAllWindows(); - if (relativeUrl && windows.length) { - const win = api.electron.getFocusedNotionWindow() || windows[0]; - win.webContents.send('notion-enhancer:open-tab', { - notionUrl: \`notion://www.notion.so\$\{relativeUrl\}\`, - }); - win.show(); - win.focus(); - } else if (relativeUrl && electronWindows.length && !windows.length) { - // enhancer menu is open: prevent override - const { createWindow } = api.electron.notionRequire('main/createWindow'), - win = createWindow(relativeUrl); - win.focus(); - } else notionHandleActivate(relativeUrl); - }; - `); -}; diff --git a/src/extensions/tabs/mod.json b/src/extensions/tabs/mod.json deleted file mode 100644 index 0d3004b..0000000 --- a/src/extensions/tabs/mod.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "tabs", - "id": "e1692c29-475e-437b-b7ff-3eee872e1a42", - "environments": ["linux", "win32", "darwin"], - "version": "0.3.0", - "description": "open multiple notion pages in a single window.", - "preview": "tabs.jpg", - "tags": ["extension", "app"], - "authors": [ - { - "name": "dragonwocky", - "email": "thedragonring.bod@gmail.com", - "homepage": "https://dragonwocky.me/", - "avatar": "https://dragonwocky.me/avatar.jpg" - } - ], - "css": { - "frame": ["tabs.css"] - }, - "js": { - "client": ["client.mjs"], - "electron": [ - { "source": "main.cjs", "target": "main/main.js" }, - { "source": "systemMenu.cjs", "target": "main/systemMenu.js" }, - { "source": "createWindow.cjs", "target": "main/createWindow.js" }, - { "source": "rendererIndex.cjs", "target": "renderer/index.js" } - ] - }, - "options": [ - { - "type": "toggle", - "key": "remember_last_open", - "label": "remember last open tabs", - "tooltip": "**a continue-where-you-left-off experience** (reopens recently active tabs after an app relaunch)", - "value": true - }, - { - "type": "select", - "key": "label_type", - "label": "tab labels", - "values": ["page icon & title", "page icon only", "page title only"] - }, - { - "type": "select", - "key": "layout_style", - "label": "tab layout", - "values": ["traditional tabbed", "rectangular", "bubble", "compact"] - }, - { - "type": "select", - "key": "select_modifier", - "label": "tab select modifier", - "tooltip": "**usage: Modifier+1 to Modifier+9, Modifier+ArrowLeft and Modifier+ArrowRight**", - "values": [ - "Alt", - "Command", - "Control", - "Super", - "Alt+Shift", - "Command+Shift", - "Control+Shift", - "Super+Shift" - ] - }, - { - "type": "hotkey", - "key": "prev_tab", - "label": "previous tab hotkey", - "value": "Control+Shift+Tab" - }, - { - "type": "hotkey", - "key": "next_tab", - "label": "next tab hotkey", - "value": "Control+Tab" - }, - { - "type": "hotkey", - "key": "new_tab", - "label": "new tab hotkey", - "value": "Control+T" - }, - { - "type": "hotkey", - "key": "close_tab", - "label": "close tab hotkey", - "value": "Control+W" - }, - { - "type": "hotkey", - "key": "restore_tab", - "label": "restore previously opened tab hotkey", - "value": "Control+Shift+T" - } - ] -} diff --git a/src/extensions/tabs/rendererIndex.cjs b/src/extensions/tabs/rendererIndex.cjs deleted file mode 100644 index 8a5a5b1..0000000 --- a/src/extensions/tabs/rendererIndex.cjs +++ /dev/null @@ -1,142 +0,0 @@ -/** - * notion-enhancer: tabs - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -module.exports = async function (api, db, __exports, __eval) { - const url = require('url'), - electron = require('electron'), - electronWindow = electron.remote.getCurrentWindow(), - { components, web, env } = api; - - window['__start'] = async () => { - // display:none; to prevent content flash while css loads - document.body.style.display = 'none'; - - const tabCache = new Map(), - Tab = await require('./tab.cjs')(api, db, tabCache); - document.body.dataset.tabLabels = await db.get(['label_type']); - document.body.dataset.tabStyle = await db.get(['layout_style']); - - const $header = web.html`
`, - $tabs = web.html`
`, - $newTab = web.html`
${await components.feather('plus')}
`, - $root = document.querySelector('#root'), - $windowActions = web.html`
`; - document.body.prepend(web.render($header, $tabs, $newTab, $windowActions)); - - // make space for native window buttons on mac - if (env.name === 'darwin') $tabs.style.paddingLeft = '72px'; - - $newTab.addEventListener('click', () => new Tab($tabs, $root)); - electron.ipcRenderer.on('notion-enhancer:close-tab', (event, id) => { - const tab = tabCache.get(id); - if (tab) tab.close(); - }); - electron.ipcRenderer.on( - 'notion-enhancer:open-tab', - (event, opts) => new Tab($tabs, $root, opts) - ); - - const rememberLastOpen = await db.get(['remember_last_open']), - openTabs = await db.get(['last_open_tabs_cache']); - if (rememberLastOpen && openTabs && Array.isArray(openTabs)) { - for (const tab of openTabs) { - new Tab($tabs, $root, { ...tab, cancelAnimation: true }); - } - } else { - new Tab($tabs, $root, { - notionUrl: url.parse(window.location.href, true).query.path, - cancelAnimation: true, - }); - } - window.addEventListener('beforeunload', () => { - const openTabs = [...$tabs.children] - .filter(($tab) => tabCache.get($tab.id)) - .map(($tab) => { - const tab = tabCache.get($tab.id); - return { - notionUrl: tab.$notion.src, - icon: tab.icon, - title: tab.title, - }; - }); - db.set(['last_open_tabs_cache'], openTabs); - }); - - let $draggedTab; - const $dragIndicator = web.html``, - getDragTarget = ($el) => { - while (!$el.matches('.tab, header, body')) $el = $el.parentElement; - if ($el.matches('header')) $el = $el.firstElementChild; - return $el.matches('#tabs, .tab') ? $el : undefined; - }, - resetDraggedTabs = () => { - if ($draggedTab) { - $dragIndicator.remove(); - $draggedTab.style.opacity = ''; - $draggedTab = undefined; - } - }; - $header.addEventListener('dragstart', (event) => { - $draggedTab = getDragTarget(event.target); - $draggedTab.style.opacity = 0.5; - const tab = tabCache.get($draggedTab.id); - event.dataTransfer.setData( - 'text', - JSON.stringify({ - window: electronWindow.webContents.id, - tab: $draggedTab.id, - icon: tab.$tabIcon.innerText || tab.$tabIcon.style.background, - title: tab.$tabTitle.innerText, - url: tab.$notion.src, - }) - ); - }); - $header.addEventListener('dragover', (event) => { - const $target = getDragTarget(event.target); - if ($target) { - if ($target.matches('#tabs')) { - $target.after($dragIndicator); - } else if ($target.matches('#tabs > :first-child')) { - $tabs.before($dragIndicator); - } else $target.before($dragIndicator); - event.preventDefault(); - } - }); - document.addEventListener('drop', (event) => { - const eventData = JSON.parse(event.dataTransfer.getData('text')), - $target = getDragTarget(event.target) || $tabs, - sameWindow = eventData.window === electronWindow.webContents.id, - tabMovement = - !sameWindow || - ($target && - $target !== $draggedTab && - $target !== $draggedTab.nextElementSibling && - ($target.matches('#tabs') ? $target.lastElementChild !== $draggedTab : true)); - if (!sameWindow) { - electron.ipcRenderer.send('notion-enhancer:close-tab', { - window: eventData.window, - id: eventData.tab, - }); - const transferred = new Tab($tabs, $root, { - notionUrl: eventData.url, - cancelAnimation: true, - icon: eventData.icon, - title: eventData.title, - }); - $draggedTab = transferred.$tab; - } - if (tabMovement) { - if ($target.matches('#tabs')) { - $target.append($draggedTab); - } else $target.before($draggedTab); - } - resetDraggedTabs(); - }); - $header.addEventListener('dragend', (event) => resetDraggedTabs()); - }; -}; diff --git a/src/extensions/tabs/systemMenu.cjs b/src/extensions/tabs/systemMenu.cjs deleted file mode 100644 index 9460cff..0000000 --- a/src/extensions/tabs/systemMenu.cjs +++ /dev/null @@ -1,20 +0,0 @@ -/** - * notion-enhancer: tabs - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -module.exports = async function ({}, db, __exports, __eval) { - const notionSetupSystemMenu = __exports.setupSystemMenu; - __exports.setupSystemMenu = (locale) => { - const { Menu } = require('electron'), - template = notionSetupSystemMenu(locale); - for (const category of template) { - category.submenu = category.submenu.filter((item) => item.role !== 'close'); - } - Menu.setApplicationMenu(Menu.buildFromTemplate(template)); - return template; - }; -}; diff --git a/src/extensions/tabs/tab.cjs b/src/extensions/tabs/tab.cjs deleted file mode 100644 index 4e44cc0..0000000 --- a/src/extensions/tabs/tab.cjs +++ /dev/null @@ -1,296 +0,0 @@ -/** - * notion-enhancer: tabs - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -let focusedTab; - -module.exports = async function (api, db, tabCache = new Map()) { - const { components, web, fmt, fs } = api, - electron = require('electron'), - electronWindow = electron.remote.getCurrentWindow(), - notionIpc = api.electron.notionRequire('helpers/notionIpc'), - xIcon = await components.feather('x'); - - return class Tab { - id = fmt.uuidv4(); - - $notion = web.html` - - `; - $search = web.html` - - `; - - $tabIcon = web.html``; - $svgIconPlaceholder = web.html` - - - `; - $tabTitle = web.html``; - $closeTab = web.html`${xIcon}`; - $tab = web.render( - web.html`
`, - this.$tabIcon, - this.$svgIconPlaceholder, - this.$tabTitle, - this.$closeTab - ); - - constructor( - $tabList, - $tabContainer, - { - notionUrl = 'notion://www.notion.so/', - cancelAnimation = false, - icon = '', - title = 'notion.so', - cache = tabCache, - } = {} - ) { - this.tabCache = cache; - this.$tabList = $tabList; - this.$tabContainer = $tabContainer; - - this.$notion.src = notionUrl; - this.setTitle(title); - this.setIcon(icon); - this.tabCache.set(this.$tab.id, this); - - electronWindow.on('focus', () => { - if (focusedTab === this) this.$notion.focus(); - }); - this.$tab.addEventListener('click', (event) => { - if (event.target !== this.$closeTab && !this.$closeTab.contains(event.target)) { - this.focus(); - } - }); - this.$closeTab.addEventListener('click', () => this.close()); - - this.open(cancelAnimation); - this.addNotionListeners(); - return this; - } - - open(cancelAnimation = false) { - this.closed = false; - web.render(this.$tabList, this.$tab); - web.render(this.$tabContainer, this.$search); - web.render(this.$tabContainer, this.$notion); - if (!cancelAnimation) { - this.$tab.animate([{ width: '0px' }, { width: `${this.$tab.clientWidth}px` }], { - duration: 100, - easing: 'ease-in', - }).finished; - } - this.focus(); - } - async focus() { - document.querySelectorAll('.notion-webview, .search-webview').forEach(($webview) => { - if (![this.$notion, this.$search].includes($webview)) $webview.style.display = ''; - }); - document.querySelectorAll('.tab.current').forEach(($tab) => { - if ($tab !== this.$tab) $tab.classList.remove('current'); - }); - this.$tab.classList.add('current'); - this.$notion.style.display = 'flex'; - this.$search.style.display = 'flex'; - if (this.domReady) this.focusNotion(); - focusedTab = this; - } - async close() { - const $sibling = this.$tab.nextElementSibling || this.$tab.previousElementSibling; - if ($sibling) { - this.closed = Date.now(); - if (!focusedTab || focusedTab === this) $sibling.click(); - const width = `${this.$tab.clientWidth}px`; - this.$tab.style.width = 0; - this.$tab.style.pointerEvents = 'none'; - await this.$tab.animate([{ width }, { width: '0px' }], { - duration: 100, - easing: 'ease-out', - }).finished; - this.$tab.remove(); - this.$notion.remove(); - this.$search.remove(); - this.$tab.style.width = ''; - this.$tab.style.pointerEvents = ''; - this.domReady = false; - } else electronWindow.close(); - } - - title = ''; - setTitle(title) { - this.title = title; - this.$tabTitle.innerText = title; - } - icon = ''; - setIcon(icon) { - this.icon = icon; - if (icon.startsWith('url(')) { - // img - this.$tabIcon.style.background = icon; - this.$tabIcon.innerText = ''; - } else { - // unicode (native) - this.$tabIcon.innerText = icon; - this.$tabIcon.style.background = ''; - } - } - - webContents() { - return electron.remote.webContents.fromId(this.$notion.getWebContentsId()); - } - focusNotion() { - document.activeElement?.blur?.(); - this.$notion.blur(); - this.$notion.focus(); - requestAnimationFrame(() => { - notionIpc.sendIndexToNotion(this.$notion, 'notion-enhancer:trigger-title-update'); - }); - } - focusSearch() { - document.activeElement?.blur?.(); - this.$search.blur(); - this.$search.focus(); - } - - domReady = false; - addNotionListeners() { - const fromNotion = (channel, listener) => - notionIpc.receiveIndexFromNotion.addListener(this.$notion, channel, listener), - fromSearch = (channel, listener) => - notionIpc.receiveIndexFromSearch.addListener(this.$search, channel, listener), - toSearch = (channel, data) => notionIpc.sendIndexToSearch(this.$search, channel, data); - - this.$notion.addEventListener('dom-ready', () => { - if (focusedTab === this) this.focus(); - this.domReady = true; - - const navigateHistory = (event, cmd) => { - const swipe = event === 'swipe', - back = swipe ? cmd === 'left' : cmd === 'browser-backward', - fwd = swipe ? cmd === 'right' : cmd === 'browser-forward'; - if (back && this.$notion.canGoBack()) this.$notion.goBack(); - if (fwd && this.$notion.canGoForward()) this.$notion.goForward(); - }; - electronWindow.addListener('app-command', (e, cmd) => navigateHistory('app-cmd', cmd)); - electronWindow.addListener('swipe', (e, dir) => navigateHistory('swipe', dir)); - - this.webContents().addListener('found-in-page', (event, result) => { - const matches = result - ? { count: result.matches, index: result.activeMatchOrdinal } - : { count: 0, index: 0 }; - toSearch('search:result', matches); - }); - }); - - notionIpc.proxyAllMainToNotion(this.$notion); - - fromNotion('search:start', () => this.startSearch()); - fromNotion('search:stop', () => this.stopSearch()); - fromNotion('search:set-theme', (theme) => toSearch('search:set-theme', theme)); - fromSearch('search:clear', () => this.clearSearch()); - fromSearch('search:stop', () => this.stopSearch()); - fromSearch('search:next', (query) => this.searchNext(query)); - fromSearch('search:prev', (query) => this.searchPrev(query)); - - fromNotion('zoom', (zoomFactor) => { - this.webContents().setZoomFactor(zoomFactor); - }); - - fromNotion('notion-enhancer:set-tab-title', (title) => this.setTitle(title)); - fromNotion('notion-enhancer:set-tab-icon', (icon) => this.setIcon(icon)); - - fromNotion( - 'notion-enhancer:new-tab', - () => new this.constructor(this.$tabList, this.$tabContainer) - ); - fromNotion('notion-enhancer:close-tab', () => this.close()); - fromNotion('notion-enhancer:restore-tab', () => { - const tab = [...this.tabCache.values()] - .filter((tab) => tab.closed) - .sort((a, b) => b.closed - a.closed)[0]; - if (tab) tab.open(); - }); - fromNotion('notion-enhancer:select-tab', (i) => { - const $tab = i === 9 ? this.$tabList.lastElementChild : this.$tabList.children[i - 1]; - if ($tab) $tab.click(); - }); - fromNotion('notion-enhancer:select-prev-tab', () => { - if (this.$tabList.count == 1) { - return; - } - const $sibling = this.$tab.previousElementSibling; - if ($sibling) { - $sibling.click(); - } - else { - let $tab = this.$tabList.lastElementChild; - if ($tab) { - $tab.click(); - } - } - }); - fromNotion('notion-enhancer:select-next-tab', () => { - if (this.$tabList.count == 1) { - return; - } - const $sibling = this.$tab.nextElementSibling; - if ($sibling) { - $sibling.click(); - } - else { - let $tab = this.$tabList.children[0] - if ($tab) { - $tab.click(); - } - } - }); - } - - #firstQuery = true; - startSearch() { - this.$search.classList.add('search-active'); - this.focusSearch(); - notionIpc.sendIndexToSearch(this.$search, 'search:start'); - notionIpc.sendIndexToNotion(this.$search, 'search:started'); - } - clearSearch() { - this.#firstQuery = true; - this.webContents().stopFindInPage('clearSelection'); - } - stopSearch() { - this.$search.classList.remove('search-active'); - this.focusNotion(); - this.clearSearch(); - notionIpc.sendIndexToSearch(this.$search, 'search:reset'); - notionIpc.sendIndexToNotion(this.$notion, 'search:stopped'); - } - searchNext(query) { - this.webContents().findInPage(query, { - forward: true, - findNext: !this.#firstQuery, - }); - this.#firstQuery = false; - } - searchPrev(query) { - this.webContents().findInPage(query, { - forward: false, - findNext: !this.#firstQuery, - }); - this.#firstQuery = false; - } - }; -}; diff --git a/src/extensions/tabs/tabs.css b/src/extensions/tabs/tabs.css deleted file mode 100644 index 3b81480..0000000 --- a/src/extensions/tabs/tabs.css +++ /dev/null @@ -1,236 +0,0 @@ -/** - * notion-enhancer: tabs - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -* { - box-sizing: border-box; -} - -html, -body { - height: 100%; - width: 100%; - margin: 0; - padding: 0; - background: var(--theme--bg) !important; - overflow: hidden; -} - -body { - display: flex !important; - flex-direction: column; -} - -header { - display: flex; - background: var(--theme--bg_secondary); - border-bottom: 1px solid var(--theme--ui_divider); - width: 100%; - padding: 0.5em; - user-select: none; - -webkit-app-region: drag; - z-index: 3; - font-size: 16px; -} - -#tabs { - display: flex; - overflow: hidden; -} -.tab { - display: flex; - flex-grow: 1; - flex-shrink: 1; - width: 14em; - max-width: 14em; - overflow: hidden; - padding: 0.4em 0.6em; - - color: var(--theme--text_secondary); - background: var(--theme--bg); - font-family: var(--theme--font_sans); - font-weight: 500; - border: none; - -webkit-app-region: no-drag; -} -.tab:hover { - background: var(--theme--ui_interactive-hover); -} -.tab.current { - background: var(--theme--ui_interactive-active); -} - -.drag-indicator { - z-index: 1; - width: 0.125em; - margin: 0 -0.0625em; - background: var(--theme--accent_blue-selection); -} - -.tab-title { - white-space: nowrap; - overflow: hidden; - margin-right: 0.25em; -} -.tab-icon { - margin-right: 0.375em; - flex-shrink: 0; -} -.tab-icon[style*='background'] { - width: 0.875em; - height: 0.875em; - align-self: center; - margin-right: 0.5em; -} -.tab-icon:not([style*='background']):empty, -.tab-icon + svg { - display: none; -} -.tab-icon:not([style*='background']):empty + svg { - /* placeholder icon */ - flex-shrink: 0; - display: inline-block; - margin: 1px 0.5em 0 0; - width: 1.125em; - height: 1.125em; - display: block; - backface-visibility: hidden; - fill: var(--theme--icon_secondary); -} - -.new-tab, -.tab-close { - transition: background 20ms ease-in 0s; - cursor: pointer; - display: inline-flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - border-radius: 0.1875em; - height: 1.25em; - width: 1.25em; - padding: 0 0.25px 0 0; - - align-self: center; - border: none; - background: transparent; - -webkit-app-region: no-drag; -} -.new-tab svg, -.tab-close svg { - width: 0.875em; - height: 0.875em; - fill: var(--theme--icon_secondary); - color: var(--theme--icon_secondary); -} -.new-tab:focus, -.new-tab:hover, -.tab-close:focus, -.tab-close:hover { - background: var(--theme--ui_interactive-hover); -} -.new-tab:active, -.tab-close:active { - background: var(--theme--ui_interactive-active); -} - -.new-tab { - margin: 0 3em 0 0.375em; -} -.tab-close { - margin-left: auto; -} - -#window-actions { - display: flex; - align-items: center; - margin-left: auto; -} -#window-actions > * { - -webkit-app-region: no-drag; -} - -[data-tab-labels='page title only'] .tab-icon { - display: none; -} -[data-tab-labels='page icon only'] .tab { - width: 4em; - max-width: 4em; -} -[data-tab-labels='page icon only'] .tab-title { - display: none; -} - -[data-tab-style='rectangular'] .new-tab, -[data-tab-style='traditional tabbed'] .new-tab { - margin-bottom: -0.25em; -} -[data-tab-style='rectangular'] .tab-close, -[data-tab-style='traditional tabbed'] .tab-close { - align-self: auto; -} -[data-tab-style='rectangular'] .drag-indicator, -[data-tab-style='traditional tabbed'] .drag-indicator, -[data-tab-style='rectangular'] #tabs { - margin-bottom: -0.5em; -} -[data-tab-style='rectangular'] .tab { - padding: 0.6em 0.6em 0.8em 0.6em; -} -[data-tab-style='traditional tabbed'] header { - padding-top: 0.6875em; -} -[data-tab-style='traditional tabbed'] #tabs { - margin: -0.1875em 0 -0.5em 0; -} -[data-tab-style='traditional tabbed'] .tab { - border-top-left-radius: 0.875em; - border-top-right-radius: 0.875em; - padding: 0.6em; -} -[data-tab-style='bubble'] .tab { - border-radius: 0.375em; -} -[data-tab-style='bubble'] .tab:not(:first-child) { - margin-left: 0.5em; -} -[data-tab-style='bubble'] .drag-indicator { - margin: 0 -0.3125em 0 0.1875em; -} -[data-tab-style='bubble'] .drag-indicator:first-child { - margin: 0 0.187em 0 -0.312em; -} -[data-tab-style='compact'] header { - padding: 0; - font-size: 14px; -} -[data-tab-style='compact'] #window-actions { - transform: scale(0.8); - margin-right: -0.35em; -} - -#root { - flex-grow: 1; -} -.notion-webview { - width: 100%; - height: 100%; - display: none; -} -.search-webview { - width: 100%; - height: 60px; - display: none; - transition: transform 70ms ease-in; - transform: translateY(-100%); - pointer-events: none; - position: absolute; - z-index: 2; -} -.search-webview.search-active { - transition: transform 70ms ease-out; - transform: translateY(0%); - pointer-events: auto; -} diff --git a/src/extensions/tabs/tabs.jpg b/src/extensions/tabs/tabs.jpg deleted file mode 100644 index 2c9d0ab..0000000 Binary files a/src/extensions/tabs/tabs.jpg and /dev/null differ diff --git a/src/extensions/tray/client.mjs b/src/extensions/tray/client.mjs deleted file mode 100644 index 051c743..0000000 --- a/src/extensions/tray/client.mjs +++ /dev/null @@ -1,17 +0,0 @@ -/** - * notion-enhancer: tray - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -export default async function ({ electron, env, web }, db) { - const runInBackground = await db.get(['run_in_background']); - if (!runInBackground) return; - - // force new window creation on create new window hotkey - // hotkey is built into notion, so can't be changed, - // but is broken by this mod's window duplication prevention - web.addHotkeyListener([env.name === 'darwin' ? 'Meta' : 'Ctrl', 'Shift', 'N'], () => - electron.sendMessage('create-new-window') - ); -} diff --git a/src/extensions/tray/createWindow.cjs b/src/extensions/tray/createWindow.cjs deleted file mode 100644 index 4589738..0000000 --- a/src/extensions/tray/createWindow.cjs +++ /dev/null @@ -1,58 +0,0 @@ -/** - * notion-enhancer: tray - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -module.exports = async function (api, db, __exports, __eval) { - const electron = require('electron'), - urlHelpers = api.electron.notionRequire('helpers/urlHelpers'), - runInBackground = await db.get(['run_in_background']); - if (!runInBackground) return; - - let appQuit = false; - electron.app.once('before-quit', () => { - appQuit = true; - }); - - const notionCreateWindow = __exports.createWindow; - __exports.createWindow = (relativeUrl = '', args) => { - const windows = api.electron.getNotionWindows(); - if (windows.length) windows.forEach((win) => win.show()); - - if (relativeUrl || !windows.length) { - // hijack close event to hide instead - const window = notionCreateWindow(relativeUrl, args); - window.prependListener('close', (e) => { - const isLastWindow = electron.BrowserWindow.getAllWindows().length === 1; - if (!appQuit && isLastWindow) { - window.hide(); - e.preventDefault(); - throw new Error(': prevent window close'); - } - }); - - // no other windows yet + opened at startup = hide - const wasOpenedAtStartup = - process.argv.includes('--startup') || - app.getLoginItemSettings({ args: ['--startup'] }).wasOpenedAtLogin; - if (!windows.length && wasOpenedAtStartup) { - window.once('ready-to-show', () => window.hide()); - } - - return window; - } else { - const window = api.electron.getFocusedNotionWindow() || windows[0]; - // prevents duplicate windows on dock/taskbar click - window.focus(); - if (relativeUrl) { - // handle requests passed via the notion:// protocol - // or ctrl+click - window.loadURL(urlHelpers.getIndexUrl(relativeUrl)); - } - return window; - } - }; -}; diff --git a/src/extensions/tray/main.cjs b/src/extensions/tray/main.cjs deleted file mode 100644 index 057161c..0000000 --- a/src/extensions/tray/main.cjs +++ /dev/null @@ -1,108 +0,0 @@ -/** - * notion-enhancer: tray - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -let tray; - -module.exports = async function (api, db, __exports, __eval) { - const { env, registry } = api, - electron = require('electron'), - path = require('path'), - enhancerIcon = path.resolve(`${__dirname}/../../media/colour-x16.png`), - hotkey = await db.get(['hotkey']), - openAtStartup = await db.get(['startup']), - runInBackground = await db.get(['run_in_background']), - menuHotkey = await ( - await registry.db('a6621988-551d-495a-97d8-3c568bca2e9e') - ).get(['hotkey']); - - const toggleWindows = (checkFocus = true) => { - const windows = electron.BrowserWindow.getAllWindows(); - if (runInBackground) { - // hide - if (windows.some((win) => (checkFocus ? win.isFocused() : true) && win.isVisible())) { - windows.forEach((win) => [win.isFocused() && win.blur(), win.hide()]); - } else windows.forEach((win) => win.show()); - } else { - // minimize - if (windows.some((win) => (checkFocus ? win.isFocused() : true) && !win.isMinimized())) { - windows.forEach((win) => win.minimize()); - } else windows.forEach((win) => win.restore()); - } - }; - - await electron.app.whenReady(); - electron.app.setLoginItemSettings({ openAtLogin: openAtStartup, args: ['--startup'] }); - - tray = new electron.Tray(enhancerIcon); - tray.setToolTip('notion-enhancer'); - tray.on('click', () => toggleWindows(false)); - electron.globalShortcut.register(hotkey, toggleWindows); - - // connects to client hotkey listener - // manually forces new window creation - // since notion's default is broken by - // duplicate window prevention - const createWindow = () => { - const { createWindow } = api.electron.notionRequire('main/createWindow.js'); - createWindow('/'); - }; - electron.ipcMain.on('notion-enhancer:create-new-window', createWindow); - - const contextMenu = electron.Menu.buildFromTemplate([ - { - type: 'normal', - label: 'notion-enhancer', - icon: enhancerIcon, - enabled: false, - }, - { type: 'separator' }, - { - type: 'normal', - label: 'docs', - click: () => electron.shell.openExternal('https://notion-enhancer.github.io/'), - }, - { - type: 'normal', - label: 'source code', - click: () => electron.shell.openExternal('https://github.com/notion-enhancer/'), - }, - { - type: 'normal', - label: 'community', - click: () => electron.shell.openExternal('https://discord.gg/sFWPXtA'), - }, - { - type: 'normal', - label: 'enhancements menu', - accelerator: menuHotkey, - click: env.focusMenu, - }, - { type: 'separator' }, - { - type: 'normal', - label: 'toggle visibility', - accelerator: hotkey, - click: toggleWindows, - }, - { - type: 'normal', - label: 'new window', - click: createWindow, - accelerator: 'CmdOrCtrl+Shift+N', - }, - { - label: 'relaunch', - click: env.reload, - }, - { - label: 'quit', - role: 'quit', - }, - ]); - tray.setContextMenu(contextMenu); -}; diff --git a/src/extensions/tray/mod.json b/src/extensions/tray/mod.json deleted file mode 100644 index 7e3cc02..0000000 --- a/src/extensions/tray/mod.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "tray", - "id": "f96f4a73-21af-4e3f-a68f-ab4976b020da", - "environments": ["linux", "win32", "darwin"], - "version": "0.11.0", - "description": "adds an icon to the system tray/menubar for extra app/window management features (e.g. open on startup, a global hotkey).", - "preview": "tray.jpg", - "tags": ["extension", "app"], - "authors": [ - { - "name": "dragonwocky", - "email": "thedragonring.bod@gmail.com", - "homepage": "https://dragonwocky.me/", - "avatar": "https://dragonwocky.me/avatar.jpg" - } - ], - "css": {}, - "js": { - "client": ["client.mjs"], - "electron": [ - { "source": "main.cjs", "target": "main/main.js" }, - { "source": "createWindow.cjs", "target": "main/createWindow.js" } - ] - }, - "options": [ - { - "type": "toggle", - "key": "startup", - "label": "open notion on startup", - "tooltip": "**if the 'run notion in the background' option is also enabled, the app will open in the background on startup** (this option may require relaunching the app BEFORE restarting your system to properly take effect)", - "value": false - }, - { - "type": "toggle", - "key": "run_in_background", - "label": "run notion in the background", - "tooltip": "**pressing the close button or toggling window visibility will hide the app, running notion in the background** (instead of quitting or minimizing it)", - "value": true - }, - { - "type": "hotkey", - "key": "hotkey", - "label": "toggle window visibility hotkey", - "value": "Ctrl+Shift+A" - } - ] -} diff --git a/src/extensions/tray/tray.jpg b/src/extensions/tray/tray.jpg deleted file mode 100644 index af425b0..0000000 Binary files a/src/extensions/tray/tray.jpg and /dev/null differ diff --git a/src/extensions/tweaks/mod.json b/src/extensions/tweaks/mod.json index b57e912..2503688 100644 --- a/src/extensions/tweaks/mod.json +++ b/src/extensions/tweaks/mod.json @@ -20,11 +20,11 @@ }, "options": [ { - "type": "file", - "key": "insert.css", - "label": "css insert", - "tooltip": "**upload a css file that will be applied to the notion client**", - "extensions": [".css"] + "type": "toggle", + "key": "remember_last_open", + "label": "remember last open tabs", + "tooltip": "**a continue-where-you-left-off experience** (reopens recently active tabs after an app relaunch)", + "value": true }, { "type": "number",