diff --git a/ElectronClient/app/app.js b/ElectronClient/app/app.js index 16bd63bd884..0deb020744c 100644 --- a/ElectronClient/app/app.js +++ b/ElectronClient/app/app.js @@ -308,6 +308,8 @@ class Application extends BaseApplication { const importItems = []; const exportItems = []; + const preferencesItems = []; + const toolsItemsFirst = []; const ioService = new InteropService(); const ioModules = ioService.modules(); for (let i = 0; i < ioModules.length; i++) { @@ -385,49 +387,161 @@ class Application extends BaseApplication { } }); + /* We need a dummy entry, otherwise the ternary operator to show a + * menu item only on a specific OS does not work. */ + const noItem = { + type: 'separator', + visible: false + } + + const syncStatusItem = { + label: _('Synchronisation status'), + click: () => { + this.dispatch({ + type: 'NAV_GO', + routeName: 'Status', + }); + } + } + + const newNoteItem = { + label: _('New note'), + accelerator: 'CommandOrControl+N', + screens: ['Main'], + click: () => { + this.dispatch({ + type: 'WINDOW_COMMAND', + name: 'newNote', + }); + } + } + + const newTodoItem = { + label: _('New to-do'), + accelerator: 'CommandOrControl+T', + screens: ['Main'], + click: () => { + this.dispatch({ + type: 'WINDOW_COMMAND', + name: 'newTodo', + }); + } + } + + const newNotebookItem = { + label: _('New notebook'), + screens: ['Main'], + click: () => { + this.dispatch({ + type: 'WINDOW_COMMAND', + name: 'newNotebook', + }); + } + } + + const printItem = { + label: _('Print'), + accelerator: 'CommandOrControl+P', + screens: ['Main'], + click: () => { + this.dispatch({ + type: 'WINDOW_COMMAND', + name: 'print', + }); + } + } + + preferencesItems.push({ + label: _('General Options'), + accelerator: 'CommandOrControl+,', + click: () => { + this.dispatch({ + type: 'NAV_GO', + routeName: 'Config', + }); + } + }, { + label: _('Encryption options'), + click: () => { + this.dispatch({ + type: 'NAV_GO', + routeName: 'EncryptionConfig', + }); + } + }, { + label: _('Web clipper options'), + click: () => { + this.dispatch({ + type: 'NAV_GO', + routeName: 'ClipperConfig', + }); + } + }); + + toolsItemsFirst.push(syncStatusItem, { + type: 'separator', + screens: ['Main'], + }); + + const toolsItems = toolsItemsFirst.concat(preferencesItems); + + function _checkForUpdates(ctx) { + bridge().checkForUpdates(false, bridge().window(), ctx.checkForUpdateLoggerPath(), { includePreReleases: Setting.value('autoUpdate.includePreReleases') }); + } + + function _showAbout() { + const p = packageInfo; + let message = [ + p.description, + '', + 'Copyright © 2016-2019 Laurent Cozic', + _('%s %s (%s, %s)', p.name, p.version, Setting.value('env'), process.platform), + ]; + bridge().showInfoMessageBox(message.join('\n'), { + icon: bridge().electronApp().buildDir() + '/icons/32x32.png', + }); + } + const template = [ { - label: _('&File'), + /* Using a dummy entry for macOS here, because first menu + * becomes 'Joplin' and we need a nenu called 'File' later. */ + label: shim.isMac() ? '&JoplinMainMenu' : _('&File'), /* `&` before one of the char in the label name mean, that * will open this menu. It's needed becase electron * opens the first menu on Alt press if no hotkey assigned. * Issue: https://github.com/laurent22/joplin/issues/934 */ submenu: [{ - label: _('New note'), - accelerator: 'CommandOrControl+N', - screens: ['Main'], - click: () => { - this.dispatch({ - type: 'WINDOW_COMMAND', - name: 'newNote', - }); - } + label: _('About Joplin'), + visible: shim.isMac() ? true : false, + click: () => _showAbout() }, { - label: _('New to-do'), - accelerator: 'CommandOrControl+T', - screens: ['Main'], - click: () => { - this.dispatch({ - type: 'WINDOW_COMMAND', - name: 'newTodo', - }); - } + type: 'separator', + visible: shim.isMac() ? true : false }, { - label: _('New notebook'), - screens: ['Main'], - click: () => { - this.dispatch({ - type: 'WINDOW_COMMAND', - name: 'newNotebook', - }); - } + label: _('Preferences...'), + visible: shim.isMac() ? true : false, + submenu: preferencesItems + }, { + label: _('Check for updates...'), + visible: shim.isMac() ? true : false, + click: () => _checkForUpdates(this) }, { type: 'separator', + visible: shim.isMac() ? true : false + }, + shim.isMac() ? noItem : newNoteItem, + shim.isMac() ? noItem : newTodoItem, + shim.isMac() ? noItem : newNotebookItem, { + type: 'separator', + visible: shim.isMac() ? false : true }, { label: _('Import'), + visible: shim.isMac() ? false : true, submenu: importItems, }, { label: _('Export'), + visible: shim.isMac() ? false : true, submenu: exportItems, }, { type: 'separator', @@ -441,19 +555,9 @@ class Application extends BaseApplication { name: 'synchronize', }); } - }, { + }, shim.isMac() ? syncStatusItem : noItem, { type: 'separator', - }, { - label: _('Print'), - accelerator: 'CommandOrControl+P', - screens: ['Main'], - click: () => { - this.dispatch({ - type: 'WINDOW_COMMAND', - name: 'print', - }); - } - }, { + }, shim.isMac() ? noItem : printItem, { type: 'separator', platforms: ['darwin'], }, { @@ -468,6 +572,25 @@ class Application extends BaseApplication { accelerator: 'CommandOrControl+Q', click: () => { bridge().electronApp().quit() } }] + }, { + label: _('&File'), + visible: shim.isMac() ? true : false, + submenu: [ + newNoteItem, + newTodoItem, + newNotebookItem, { + type: 'separator', + }, { + label: _('Import'), + submenu: importItems, + }, { + label: _('Export'), + submenu: exportItems, + }, { + type: 'separator', + }, + printItem + ] }, { label: _('&Edit'), submenu: [{ @@ -628,43 +751,8 @@ class Application extends BaseApplication { }], }, { label: _('&Tools'), - submenu: [{ - label: _('Synchronisation status'), - click: () => { - this.dispatch({ - type: 'NAV_GO', - routeName: 'Status', - }); - } - }, { - type: 'separator', - screens: ['Main'], - },{ - label: _('Web clipper options'), - click: () => { - this.dispatch({ - type: 'NAV_GO', - routeName: 'ClipperConfig', - }); - } - },{ - label: _('Encryption options'), - click: () => { - this.dispatch({ - type: 'NAV_GO', - routeName: 'EncryptionConfig', - }); - } - },{ - label: _('General Options'), - accelerator: 'CommandOrControl+,', - click: () => { - this.dispatch({ - type: 'NAV_GO', - routeName: 'Config', - }); - } - }], + visible: shim.isMac() ? false : true, + submenu: toolsItems }, { label: _('&Help'), submenu: [{ @@ -676,26 +764,16 @@ class Application extends BaseApplication { click () { bridge().openExternal('https://joplin.cozic.net/donate') } }, { label: _('Check for updates...'), - click: () => { - bridge().checkForUpdates(false, bridge().window(), this.checkForUpdateLoggerPath(), { includePreReleases: Setting.value('autoUpdate.includePreReleases') }); - } + visible: shim.isMac() ? false : true, + click: () => _checkForUpdates(this) }, { type: 'separator', + visible: shim.isMac() ? false : true, screens: ['Main'], }, { label: _('About Joplin'), - click: () => { - const p = packageInfo; - let message = [ - p.description, - '', - 'Copyright © 2016-2019 Laurent Cozic', - _('%s %s (%s, %s)', p.name, p.version, Setting.value('env'), process.platform), - ]; - bridge().showInfoMessageBox(message.join('\n'), { - icon: bridge().electronApp().buildDir() + '/icons/32x32.png', - }); - } + visible: shim.isMac() ? false : true, + click: () => _showAbout() }] }, ];