+ left/right tab switching, + remove cmd/ctrl+w from menu, - break tab opening/closing/titles

This commit is contained in:
dragonwocky 2020-10-15 22:01:28 +11:00
parent dcbe96f447
commit b23b928289
Signed by: dragonwocky
GPG Key ID: C7A48B7846AA706D
9 changed files with 658 additions and 122 deletions

View File

@ -35,6 +35,8 @@ a flexibility update.
- bugfix: remove focus mode footer from neutral theme. - bugfix: remove focus mode footer from neutral theme.
- bugfix: improvements to the colour theming, particularly to make real- and fake-light/dark - bugfix: improvements to the colour theming, particularly to make real- and fake-light/dark
modes (as applied by the night shift extension) look consistent. modes (as applied by the night shift extension) look consistent.
relevant variables (assuming all are prefixed by `--theme_[dark|light]--`):
`box-shadow`, `box-shadow_strong`, `select_input`, and `ui-border`
- bugfix: font sizing applied to overlays/previews. - bugfix: font sizing applied to overlays/previews.
- bugfix: removed typo in variable name for brown text. - bugfix: removed typo in variable name for brown text.
- tweak: sticky table/list rows. - tweak: sticky table/list rows.
@ -52,6 +54,7 @@ a fork of notion-deb-builder that does generate an app.asar has been created and
- bugfix: night shift working on macOS. - bugfix: night shift working on macOS.
- bugfix: windows are properly hidden/shown on macOS. - bugfix: windows are properly hidden/shown on macOS.
- extension: "tweaks" = common layout changes. - extension: "tweaks" = common layout changes.
- update themes to new variables.
### v0.9.1 (2020-09-26) ### v0.9.1 (2020-09-26)

View File

@ -123,7 +123,7 @@ but some basic improvements are built in by default:
- a tray/menubar icon: links relevant to the enhancer + buttons to manage notion windows. - a tray/menubar icon: links relevant to the enhancer + buttons to manage notion windows.
once applied, modules can be configured via the graphical menu, once applied, modules can be configured via the graphical menu,
which is opened from the tray/menubar ic,on or with `OPTION/ALT+E`. which is opened from the tray/menubar icon or with `OPTION/ALT+E`.
![](https://user-images.githubusercontent.com/16874139/93692603-954fd980-fb38-11ea-9d52-82ac53449d33.png) ![](https://user-images.githubusercontent.com/16874139/93692603-954fd980-fb38-11ea-9d52-82ac53449d33.png)

View File

@ -14,7 +14,9 @@ module.exports = (store, __exports) => {
/\\/g, /\\/g,
'/' '/'
)}/app/helpers/notionIpc.js`), )}/app/helpers/notionIpc.js`),
{ toKeyEvent } = require('keyboardevent-from-electron-accelerator'); { toKeyEvent } = require('keyboardevent-from-electron-accelerator'),
tabsEnabled = (store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {})
.enabled;
document.defaultView.addEventListener('keyup', (event) => { document.defaultView.addEventListener('keyup', (event) => {
// additional hotkeys // additional hotkeys
@ -25,7 +27,7 @@ module.exports = (store, __exports) => {
for (let prop in hotkey) for (let prop in hotkey)
if (hotkey[prop] !== event[prop]) triggered = false; if (hotkey[prop] !== event[prop]) triggered = false;
if (triggered) electron.ipcRenderer.send('enhancer:open-menu'); if (triggered) electron.ipcRenderer.send('enhancer:open-menu');
if ((store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {}).enabled) { if (tabsEnabled) {
// switch between tabs via key modifier // switch between tabs via key modifier
const select_tab_modifier = toKeyEvent( const select_tab_modifier = toKeyEvent(
store('e1692c29-475e-437b-b7ff-3eee872e1a42').select_modifier store('e1692c29-475e-437b-b7ff-3eee872e1a42').select_modifier
@ -33,7 +35,22 @@ module.exports = (store, __exports) => {
let triggered = true; let triggered = true;
for (let prop in select_tab_modifier) for (let prop in select_tab_modifier)
if (select_tab_modifier[prop] !== event[prop]) triggered = false; if (select_tab_modifier[prop] !== event[prop]) triggered = false;
if (triggered && [1, 2, 3, 4, 5, 6, 7, 8, 9].includes(+event.key)) if (
triggered &&
[
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'ArrowRight',
'ArrowLeft',
].includes(event.key)
)
electron.ipcRenderer.sendToHost('enhancer:select-tab', event.key); electron.ipcRenderer.sendToHost('enhancer:select-tab', event.key);
// create/close tab keybindings // create/close tab keybindings
const new_tab_keybinding = toKeyEvent( const new_tab_keybinding = toKeyEvent(
@ -69,11 +86,7 @@ module.exports = (store, __exports) => {
document.body.classList.add('snappy-transitions'); document.body.classList.add('snappy-transitions');
// frameless // frameless
if ( if (store().frameless && !store().tiling_mode && !tabsEnabled) {
store().frameless &&
!store().tiling_mode &&
!(store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {}).enabled
) {
document.body.classList.add('frameless'); document.body.classList.add('frameless');
// draggable area // draggable area
document document
@ -86,9 +99,7 @@ module.exports = (store, __exports) => {
} }
// window buttons // window buttons
if ( if (!tabsEnabled) {
!(store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {}).enabled
) {
const buttons = require('./buttons.js')(store); const buttons = require('./buttons.js')(store);
document document
.querySelector('.notion-topbar > div[style*="display: flex"]') .querySelector('.notion-topbar > div[style*="display: flex"]')
@ -185,9 +196,7 @@ module.exports = (store, __exports) => {
'--theme--code_inline-background', '--theme--code_inline-background',
].map((rule) => [rule, getStyle(rule)]) ].map((rule) => [rule, getStyle(rule)])
); );
if ( if (tabsEnabled) {
(store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {}).enabled
) {
electron.ipcRenderer.sendToHost( electron.ipcRenderer.sendToHost(
'enhancer:set-tab-theme', 'enhancer:set-tab-theme',
[ [
@ -213,7 +222,7 @@ module.exports = (store, __exports) => {
); );
electron.ipcRenderer.on('enhancer:get-menu-theme', setThemeVars); electron.ipcRenderer.on('enhancer:get-menu-theme', setThemeVars);
if ((store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {}).enabled) { if (tabsEnabled) {
let tab_title = ''; let tab_title = '';
__electronApi.setWindowTitle = (title) => { __electronApi.setWindowTitle = (title) => {
if (tab_title !== title) { if (tab_title !== title) {

View File

@ -83,7 +83,8 @@ module.exports = {
], ],
hacks: { hacks: {
'main/main.js': require('./tray.js'), 'main/main.js': require('./tray.js'),
'main/createWindow.js': require('./create.js'), 'main/systemMenu.js': require('./systemMenu.js'),
'main/createWindow.js': require('./createWindow.js'),
'renderer/index.js': require('./render.js'), 'renderer/index.js': require('./render.js'),
'renderer/preload.js': require('./client.js'), 'renderer/preload.js': require('./client.js'),
}, },

View File

@ -42,7 +42,7 @@ module.exports = (store, __exports) => {
searching: false, searching: false,
searchingPeekView: false, searchingPeekView: false,
zoomFactor: 1, zoomFactor: 1,
tabs: new Map([[0, true]]), tabs: new Map([[0, ['notion.so', true]]]),
}; };
this.$titlebar = null; this.$titlebar = null;
this.$dragging = null; this.$dragging = null;
@ -84,42 +84,42 @@ module.exports = (store, __exports) => {
) || [] ) || []
); );
}; };
document.addEventListener('dragstart', (event) => { // document.addEventListener('dragstart', (event) => {
if (!this.$titlebar) return; // if (!this.$titlebar) return;
this.$dragging = getTab(event.target)[0]; // this.$dragging = getTab(event.target)[0];
event.target.style.opacity = 0.5; // event.target.style.opacity = 0.5;
}); // });
document.addEventListener('dragend', (event) => { // document.addEventListener('dragend', (event) => {
if (!this.$titlebar) return; // if (!this.$titlebar) return;
event.target.style.opacity = ''; // event.target.style.opacity = '';
}); // });
document.addEventListener('dragover', (event) => { // document.addEventListener('dragover', (event) => {
if (!this.$titlebar) return; // if (!this.$titlebar) return;
event.preventDefault(); // event.preventDefault();
document // document
.querySelectorAll('.dragged-over') // .querySelectorAll('.dragged-over')
.forEach((el) => el.classList.remove('dragged-over')); // .forEach((el) => el.classList.remove('dragged-over'));
const tab = getTab(event.target); // const tab = getTab(event.target);
if (tab[1]) tab[1].classList.add('dragged-over'); // if (tab[1]) tab[1].classList.add('dragged-over');
}); // });
document.addEventListener('drop', (event) => { // document.addEventListener('drop', (event) => {
if (!this.$titlebar || this.$dragging === null) return; // if (!this.$titlebar || this.$dragging === null) return;
event.preventDefault(); // event.preventDefault();
document // document
.querySelectorAll('.dragged-over') // .querySelectorAll('.dragged-over')
.forEach((el) => el.classList.remove('dragged-over')); // .forEach((el) => el.classList.remove('dragged-over'));
document // document
.querySelectorAll('.slideIn') // .querySelectorAll('.slideIn')
.forEach((el) => el.classList.remove('slideIn')); // .forEach((el) => el.classList.remove('slideIn'));
const from = getTab(this.views.tabs[+this.$dragging]), // const from = getTab(this.views.tabs[+this.$dragging]),
to = getTab(event.target); // to = getTab(event.target);
if (!from[1].classList.contains('new') && from[0] !== to[0]) // if (!from[1].classList.contains('new') && from[0] !== to[0])
to[1].parentElement.insertBefore(from[1], to[1]); // to[1].parentElement.insertBefore(from[1], to[1]);
this.$dragging = null; // this.$dragging = null;
document // document
.querySelector('#tabs') // .querySelector('#tabs')
.appendChild(document.querySelector('.tab.new')); // .appendChild(document.querySelector('.tab.new'));
}); // });
document.addEventListener('keyup', (event) => { document.addEventListener('keyup', (event) => {
if (!electron.remote.getCurrentWindow().isFocused()) return; if (!electron.remote.getCurrentWindow().isFocused()) return;
// switch between tabs via key modifier // switch between tabs via key modifier
@ -129,7 +129,22 @@ module.exports = (store, __exports) => {
let triggered = true; let triggered = true;
for (let prop in select_tab_modifier) for (let prop in select_tab_modifier)
if (select_tab_modifier[prop] !== event[prop]) triggered = false; if (select_tab_modifier[prop] !== event[prop]) triggered = false;
if (triggered && [1, 2, 3, 4, 5, 6, 7, 8, 9].includes(+event.key)) if (
triggered &&
[
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'ArrowRight',
'ArrowLeft',
].includes(event.key)
)
this.selectTab(event.key); this.selectTab(event.key);
// create/close tab keybindings // create/close tab keybindings
const new_tab_keybinding = toKeyEvent( const new_tab_keybinding = toKeyEvent(
@ -192,58 +207,64 @@ module.exports = (store, __exports) => {
newTab() { newTab() {
let id = 0; let id = 0;
const list = new Map(this.state.tabs); const list = new Map(this.state.tabs);
while (this.state.tabs.get(id)) id++; while (this.state.tabs.get(id) && this.state.tabs.get(id)[1]) id++;
list.delete(id); list.delete(id);
this.openTab(id, list, true); this.openTab(id, list, true);
} }
openTab(id, state = new Map(this.state.tabs), load) { openTab(id, state = new Map(this.state.tabs), load) {
if (!id && id !== 0) return; if (!id && id !== 0) {
if (this.views.current.$el().style.display === 'flex') return;
id = [...state].find(([id, [title, open]]) => open)[0];
}
const current_src = this.views.current.$el().src;
this.views.current.id = id; this.views.current.id = id;
this.setState({ tabs: state.set(id, true) }, async () => { this.setState(
this.focusTab(); {
if (load) { tabs: state.set(id, [
await new Promise((res, rej) => { state.get(id) ? state.get(id)[0] : 'notion.so',
let attempt; true,
attempt = setInterval(() => { ]),
if (!document.body.contains(this.views.html[id])) return; },
clearInterval(attempt); async () => {
res(); this.focusTab();
}, 50); if (load) {
}); await new Promise((res, rej) => {
this.views.html[id].style.opacity = '0'; let attempt;
let unhide; attempt = setInterval(() => {
unhide = () => { if (!document.body.contains(this.views.html[id])) return;
this.views.html[id].style.opacity = ''; clearInterval(attempt);
this.views.html[id].removeEventListener( res();
'did-stop-loading', }, 50);
unhide });
this.views.html[id].style.opacity = '0';
let unhide;
unhide = () => {
this.views.html[id].style.opacity = '';
this.views.html[id].removeEventListener(
'did-stop-loading',
unhide
);
};
this.views.html[id].addEventListener('did-stop-loading', unhide);
this.views.html[id].loadURL(
store().default_page
? idToNotionURL(store().default_page)
: current_src
); );
}; // this.views.html[id].getWebContents().openDevTools();
this.views.html[id].addEventListener('did-stop-loading', unhide); }
this.views.html[id].loadURL(
store().default_page
? idToNotionURL(store().default_page)
: this.views.current.$el().src
);
// this.views.html[id].getWebContents().openDevTools();
} }
}); );
} }
closeTab(id) { closeTab(id) {
if ((!id && id !== 0) || !this.state.tabs.get(id)) return; if ((!id && id !== 0) || !this.state.tabs.get(id)) return;
console.log(id);
const list = new Map(this.state.tabs); const list = new Map(this.state.tabs);
list.delete(id); list.set(id, [list.get(id)[0], false]);
list.set(id, false); console.log(list);
if (![...list].filter(([id, open]) => open).length) if (![...list].filter(([id, [title, open]]) => open).length)
return electron.remote.getCurrentWindow().close(); return electron.remote.getCurrentWindow().close();
while ( this.openTab(null, list);
!list.get(this.views.current.id) ||
this.views.current.id === id
) {
this.views.current.id = this.views.current.id - 1;
if (this.views.current.id < 0) this.views.current.id = list.size - 1;
}
this.setState({ tabs: list }, this.focusTab.bind(this));
} }
focusTab() { focusTab() {
if (this.views.active === this.views.current.id) return; if (this.views.active === this.views.current.id) return;
@ -263,18 +284,28 @@ module.exports = (store, __exports) => {
} }
} }
selectTab(num) { selectTab(num) {
num = +num; if (num === 'ArrowLeft') {
if (num == 9) { const prev = document.querySelector('.tab.current')
document .previousElementSibling;
.querySelector('#tabs') if (prev) prev.click();
.children[ } else if (num === 'ArrowRight') {
document.querySelector('#tabs').children.length - 2 const next = document.querySelector('.tab.current')
].click(); .nextElementSibling;
} else if ( if (next && !next.classList.contains('new')) next.click();
document.querySelector('#tabs').children[num - 1] && } else {
document.querySelector('#tabs').children.length > num num = +num;
) { if (num == 9) {
document.querySelector('#tabs').children[num - 1].click(); document
.querySelector('#tabs')
.children[
document.querySelector('#tabs').children.length - 2
].click();
} else if (
document.querySelector('#tabs').children[num - 1] &&
document.querySelector('#tabs').children.length > num
) {
document.querySelector('#tabs').children[num - 1].click();
}
} }
} }
@ -285,9 +316,15 @@ module.exports = (store, __exports) => {
document.body.style.setProperty(style[0], style[1]); document.body.style.setProperty(style[0], style[1]);
break; break;
case 'enhancer:set-tab-title': case 'enhancer:set-tab-title':
if (this.views.tabs[event.target.id]) { if (this.state.tabs.get(event.target.id)) {
this.views.tabs[event.target.id].children[0].innerText = const list = new Map(this.state.tabs);
event.args[0]; list.set(event.target.id, [
event.args[0],
this.state.tabs.get(event.target.id)[1],
]);
this.setState({
tabs: list,
});
const electronWindow = electron.remote.getCurrentWindow(); const electronWindow = electron.remote.getCurrentWindow();
if ( if (
event.target.id == this.views.current.id && event.target.id == this.views.current.id &&
@ -550,6 +587,7 @@ module.exports = (store, __exports) => {
} }
renderTitlebar() { renderTitlebar() {
console.log('title');
return React.createElement( return React.createElement(
'header', 'header',
{ {
@ -568,25 +606,24 @@ module.exports = (store, __exports) => {
'div', 'div',
{ id: 'tabs' }, { id: 'tabs' },
...[...this.state.tabs] ...[...this.state.tabs]
.filter(([id, open]) => open) .filter(([id, [title, open]]) => open)
.map(([id, open]) => .map(([id, [title, open]]) =>
React.createElement( React.createElement(
'button', 'button',
{ {
draggable: true,
className: className:
'tab slideIn' + 'tab' + (id === this.views.current.id ? ' current' : ''),
(id === this.views.current.id ? ' current' : ''), draggable: true,
'data-linked': id,
onClick: (e) => { onClick: (e) => {
if (!e.target.classList.contains('close')) if (!e.target.classList.contains('close'))
this.openTab(id); this.openTab(id);
}, },
ref: ($tab) => { ref: ($tab) => {
this.views.tabs[id] = $tab; this.views.tabs[id] = $tab;
this.focusTab();
}, },
}, },
React.createElement('span', {}, 'notion.so'), React.createElement('span', {}, title),
React.createElement( React.createElement(
'span', 'span',
{ {
@ -614,7 +651,7 @@ module.exports = (store, __exports) => {
} }
renderNotionContainer() { renderNotionContainer() {
this.views.react = Object.fromEntries( this.views.react = Object.fromEntries(
[...this.state.tabs].map(([id, open]) => { [...this.state.tabs].map(([id, [title, open]]) => {
return [ return [
id, id,
this.views.react[id] || this.views.react[id] ||

View File

@ -0,0 +1,476 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = (store, __exports) => {
const electron = require('electron'),
fs = require('fs-extra'),
{ __notion } = require('../../pkg/helpers.js'),
createWindow = require(`${__notion}/app/main/createWindow.js`),
config = require(`${__notion}/app/config.js`),
notion_intl = require(`${__notion}/app/shared/notion-intl/index.js`),
localizationHelper = require(`${__notion}/app/helpers/localizationHelper.js`),
isMac = process.platform === 'darwin',
// why is it inversed? i have no idea, but for some reason this is what works
tabsEnabled = !(store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {})
.enabled,
menuMessages = notion_intl.defineMessages({
fileMenuTitle: {
id: 'desktopTopbar.fileMenu.title',
defaultMessage: 'File',
},
editMenuTitle: {
id: 'desktopTopbar.editMenu.title',
defaultMessage: 'Edit',
},
viewMenuTitle: {
id: 'desktopTopbar.viewMenu.title',
defaultMessage: 'View',
},
windowMenuTitle: {
id: 'desktopTopbar.windowMenu.title',
defaultMessage: 'Window',
},
helpTitle: {
id: 'desktopTopbar.helpMenu.title',
defaultMessage: 'Help',
},
newWindow: {
id: 'desktopTopbar.fileMenu.newWindow',
defaultMessage: 'New Window',
},
closeWindow: {
id: 'desktopTopbar.fileMenu.close',
defaultMessage: 'Close Window',
},
quit: {
id: 'desktopTopbar.fileMenu.quit',
defaultMessage: 'Exit',
},
undo: {
id: 'desktopTopbar.editMenu.undo',
defaultMessage: 'Undo',
},
redo: {
id: 'desktopTopbar.editMenu.redo',
defaultMessage: 'Redo',
},
cut: {
id: 'desktopTopbar.editMenu.cut',
defaultMessage: 'Cut',
},
copy: {
id: 'desktopTopbar.editMenu.copy',
defaultMessage: 'Copy',
},
paste: {
id: 'desktopTopbar.editMenu.paste',
defaultMessage: 'Paste',
},
selectAll: {
id: 'desktopTopbar.editMenu.selectAll',
defaultMessage: 'Select All',
},
startSpeaking: {
id: 'desktopTopbar.editMenu.speech.startSpeaking',
defaultMessage: 'Start Speaking',
},
stopSpeaking: {
id: 'desktopTopbar.editMenu.speech.stopSpeaking',
defaultMessage: 'Stop Speaking',
},
speech: {
id: 'desktopTopbar.editMenu.speech',
defaultMessage: 'Speech',
},
reload: {
id: 'desktopTopbar.viewMenu.reload',
defaultMessage: 'Reload',
},
togglefullscreen: {
id: 'desktopTopbar.viewMenu.togglefullscreen',
defaultMessage: 'Toggle Full Screen',
},
toggleDevTools: {
id: 'desktopTopbar.toggleDevTools',
defaultMessage: 'Toggle Developer Tools',
},
toggleWindowDevTools: {
id: 'desktopTopbar.toggleWindowDevTools',
defaultMessage: 'Toggle Window Developer Tools',
},
maximize: {
id: 'desktopTopbar.windowMenu.maximize',
defaultMessage: 'Maximize',
},
minimize: {
id: 'desktopTopbar.windowMenu.minimize',
defaultMessage: 'Minimize',
},
zoom: {
id: 'desktopTopbar.windowMenu.zoom',
defaultMessage: 'Zoom',
},
front: {
id: 'desktopTopbar.windowMenu.front',
defaultMessage: 'Front',
},
close: {
id: 'desktopTopbar.windowMenu.close',
defaultMessage: 'Close',
},
help: {
id: 'desktopTopbar.helpMenu.openHelpAndSupport',
defaultMessage: 'Open Help & Support',
},
reset: {
id: 'desktopTopbar.appMenu.resetAppAndClearData',
defaultMessage: 'Reset App & Clear Local Data',
},
about: {
id: 'desktopTopbar.appMenu.about',
defaultMessage: 'About Notion',
},
services: {
id: 'desktopTopbar.appMenu.services',
defaultMessage: 'Services',
},
hide: { id: 'desktopTopbar.appMenu.hide', defaultMessage: 'Hide Notion' },
hideOthers: {
id: 'desktopTopbar.appMenu.hideOthers',
defaultMessage: 'Hide Others',
},
unhide: {
id: 'desktopTopbar.appMenu.unhide',
defaultMessage: 'Show All',
},
quitMac: { id: 'desktopTopbar.appMenu.quit', defaultMessage: 'Quit' },
}),
escapeAmpersand = (message) => message.replace(/&/g, '&&');
__exports.setupSystemMenu = (locale) => {
const intl = localizationHelper.createIntlShape(locale),
fileMenu = {
role: 'fileMenu',
label: escapeAmpersand(intl.formatMessage(menuMessages.fileMenuTitle)),
submenu: isMac
? [
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.newWindow)
),
accelerator: 'CmdOrCtrl+Shift+N',
click: () => createWindow.createWindow(),
},
...(tabsEnabled
? [
{
role: 'close',
label: escapeAmpersand(
intl.formatMessage(menuMessages.closeWindow)
),
},
]
: []),
]
: [
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.newWindow)
),
accelerator: 'CmdOrCtrl+Shift+N',
click: () => createWindow.createWindow(),
},
...(tabsEnabled
? [
{
role: 'quit',
label: escapeAmpersand(
intl.formatMessage(menuMessages.quit)
),
},
]
: []),
],
},
editMenu = {
role: 'editMenu',
label: escapeAmpersand(intl.formatMessage(menuMessages.editMenuTitle)),
submenu: isMac
? [
{
role: 'undo',
label: escapeAmpersand(intl.formatMessage(menuMessages.undo)),
},
{
role: 'redo',
label: escapeAmpersand(intl.formatMessage(menuMessages.redo)),
},
{ type: 'separator' },
{
role: 'cut',
label: escapeAmpersand(intl.formatMessage(menuMessages.cut)),
},
{
role: 'copy',
label: escapeAmpersand(intl.formatMessage(menuMessages.copy)),
},
{
role: 'paste',
label: escapeAmpersand(intl.formatMessage(menuMessages.paste)),
},
{
role: 'selectAll',
label: escapeAmpersand(
intl.formatMessage(menuMessages.selectAll)
),
},
{ type: 'separator' },
{
label: escapeAmpersand(intl.formatMessage(menuMessages.speech)),
submenu: [
{
role: 'startSpeaking',
label: escapeAmpersand(
intl.formatMessage(menuMessages.startSpeaking)
),
},
{
role: 'stopSpeaking',
label: escapeAmpersand(
intl.formatMessage(menuMessages.stopSpeaking)
),
},
],
},
]
: [
{
role: 'undo',
label: escapeAmpersand(intl.formatMessage(menuMessages.undo)),
},
{
role: 'redo',
label: escapeAmpersand(intl.formatMessage(menuMessages.redo)),
},
{ type: 'separator' },
{
role: 'cut',
label: escapeAmpersand(intl.formatMessage(menuMessages.cut)),
},
{
role: 'copy',
label: escapeAmpersand(intl.formatMessage(menuMessages.copy)),
},
{
role: 'paste',
label: escapeAmpersand(intl.formatMessage(menuMessages.paste)),
},
{ type: 'separator' },
{
role: 'selectAll',
label: escapeAmpersand(
intl.formatMessage(menuMessages.selectAll)
),
},
],
},
viewMenu = {
role: 'viewMenu',
label: escapeAmpersand(intl.formatMessage(menuMessages.viewMenuTitle)),
submenu: [
{
label: escapeAmpersand(intl.formatMessage(menuMessages.reload)),
accelerator: 'CmdOrCtrl+R',
click() {
const focusedWebContents = electron.webContents.getFocusedWebContents();
if (focusedWebContents) {
if (focusedWebContents.hostWebContents) {
for (const webContentsInstance of electron.webContents.getAllWebContents()) {
if (
webContentsInstance.hostWebContents ===
focusedWebContents.hostWebContents
) {
webContentsInstance.reload();
}
}
} else {
focusedWebContents.reload();
}
}
},
},
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.toggleDevTools)
),
accelerator: isMac ? 'Alt+Command+I' : 'Ctrl+Shift+I',
click() {
let focusedWebContents = electron.webContents.getFocusedWebContents();
if (focusedWebContents) {
const focusedWebContentsUrl = focusedWebContents.getURL();
if (
focusedWebContentsUrl.startsWith('file://') &&
focusedWebContentsUrl.endsWith('/search.html')
) {
const notionWebviewWebContents = electron.webContents
.getAllWebContents()
.find(
(webContentsInstance) =>
webContentsInstance.hostWebContents ===
focusedWebContents.hostWebContents &&
webContentsInstance !== focusedWebContents
);
if (notionWebviewWebContents) {
focusedWebContents = notionWebviewWebContents;
}
}
focusedWebContents.toggleDevTools();
}
},
},
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.toggleWindowDevTools)
),
accelerator: isMac ? 'Shift+Alt+Command+I' : 'Alt+Ctrl+Shift+I',
visible: false,
click(menuItem, focusedWindow) {
if (focusedWindow) {
focusedWindow.webContents.toggleDevTools();
}
},
},
{ type: 'separator' },
{
role: 'togglefullscreen',
label: escapeAmpersand(
intl.formatMessage(menuMessages.togglefullscreen)
),
},
],
},
windowMenu = {
role: 'windowMenu',
label: escapeAmpersand(
intl.formatMessage(menuMessages.windowMenuTitle)
),
submenu: isMac
? [
{
role: 'minimize',
label: escapeAmpersand(
intl.formatMessage(menuMessages.minimize)
),
},
{
role: 'zoom',
label: escapeAmpersand(intl.formatMessage(menuMessages.zoom)),
},
{ type: 'separator' },
{
role: 'front',
label: escapeAmpersand(intl.formatMessage(menuMessages.front)),
},
]
: [
{
role: 'minimize',
label: escapeAmpersand(
intl.formatMessage(menuMessages.minimize)
),
},
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.maximize)
),
click(item, focusedWindow) {
if (focusedWindow) {
if (focusedWindow.isMaximized()) {
focusedWindow.unmaximize();
} else {
focusedWindow.maximize();
}
}
},
},
...(tabsEnabled
? [
{
role: 'close',
label: escapeAmpersand(
intl.formatMessage(menuMessages.close)
),
},
]
: []),
],
},
helpMenu = {
role: 'help',
label: escapeAmpersand(intl.formatMessage(menuMessages.helpTitle)),
submenu: [
{
label: escapeAmpersand(intl.formatMessage(menuMessages.help)),
click() {
electron.shell.openExternal(config.default.baseURL + '/help');
},
},
],
},
appMenu = {
role: 'appMenu',
submenu: [
{
role: 'about',
label: escapeAmpersand(intl.formatMessage(menuMessages.about)),
},
{ type: 'separator' },
{
label: escapeAmpersand(intl.formatMessage(menuMessages.reset)),
async click(item, focusedWindow) {
await fs.remove(electron.app.getPath('userData'));
electron.app.relaunch();
electron.app.exit();
},
},
{ type: 'separator' },
{
role: 'services',
label: escapeAmpersand(intl.formatMessage(menuMessages.services)),
},
{ type: 'separator' },
{
role: 'hide',
label: escapeAmpersand(intl.formatMessage(menuMessages.hide)),
},
{
role: 'hideOthers',
label: escapeAmpersand(intl.formatMessage(menuMessages.hideOthers)),
},
{
role: 'unhide',
label: escapeAmpersand(intl.formatMessage(menuMessages.unhide)),
},
...(tabsEnabled
? [
{ type: 'separator' },
{
role: 'quit',
label: escapeAmpersand(
intl.formatMessage(menuMessages.quitMac)
),
},
]
: []),
],
},
template = [fileMenu, editMenu, viewMenu, windowMenu, helpMenu];
if (isMac) template.unshift(appMenu);
const menu = electron.Menu.buildFromTemplate(template);
electron.Menu.setApplicationMenu(menu);
};
};

View File

@ -87,7 +87,7 @@ module.exports = (store, __exports) => {
/\\/g, /\\/g,
'/' '/'
)}/app/node_modules/electron-window-state/index.js`)({ )}/app/node_modules/electron-window-state/index.js`)({
file: 'enhancerMenu.windowState.json', file: 'menu.windowstate.json',
path: helpers.__data, path: helpers.__data,
defaultWidth: 275, defaultWidth: 275,
defaultHeight: 600, defaultHeight: 600,
@ -172,7 +172,7 @@ module.exports = (store, __exports) => {
type: 'normal', type: 'normal',
label: 'New Window', label: 'New Window',
click: () => { click: () => {
require('./create.js')( require('./createWindow.js')(
store, store,
require(path.resolve( require(path.resolve(
`${helpers.__notion}/app/main/createWindow.js` `${helpers.__notion}/app/main/createWindow.js`

View File

@ -19,9 +19,19 @@ module.exports = {
options: [ options: [
{ {
key: 'select_modifier', key: 'select_modifier',
label: 'tab select modifier (key+1, +2, +3, ... +9):', label:
'tab select modifier (key+1, +2, +3, ... +9 and key+left/right arrows):',
type: 'select', type: 'select',
value: ['Alt', 'Command', 'Control', 'Shift', 'Super'], value: [
'Alt',
'Command',
'Control',
'Super',
'Alt+Shift',
'Command+Shift',
'Control+Shift',
'Super+Shift',
],
}, },
{ {
key: 'new_tab', key: 'new_tab',