diff --git a/ElectronClient/app/ElectronAppWrapper.js b/ElectronClient/app/ElectronAppWrapper.js index 84cf1d3f1..855f69fa9 100644 --- a/ElectronClient/app/ElectronAppWrapper.js +++ b/ElectronClient/app/ElectronAppWrapper.js @@ -172,6 +172,8 @@ class ElectronAppWrapper { } ensureSingleInstance() { + if (this.env_ === 'dev') return false; + return new Promise((resolve, reject) => { const alreadyRunning = this.electronApp_.makeSingleInstance((commandLine, workingDirectory) => { const win = this.window(); diff --git a/ElectronClient/app/InteropServiceHelper.js b/ElectronClient/app/InteropServiceHelper.js new file mode 100644 index 000000000..341a19c16 --- /dev/null +++ b/ElectronClient/app/InteropServiceHelper.js @@ -0,0 +1,51 @@ +const { _ } = require('lib/locale'); +const { bridge } = require('electron').remote.require('./bridge'); +const InteropService = require('lib/services/InteropService'); + +class InteropServiceHelper { + + static async export(dispatch, module, options = null) { + if (!options) options = {}; + + let path = null; + + if (module.target === 'file') { + path = bridge().showSaveDialog({ + filters: [{ name: module.description, extensions: [module.fileExtension]}] + }); + } else { + path = bridge().showOpenDialog({ + properties: ['openDirectory', 'createDirectory'], + }); + } + + if (!path || (Array.isArray(path) && !path.length)) return; + + if (Array.isArray(path)) path = path[0]; + + dispatch({ + type: 'WINDOW_COMMAND', + name: 'showModalMessage', + message: _('Exporting to "%s" as "%s" format. Please wait...', path, module.format), + }); + + const exportOptions = {}; + exportOptions.path = path; + exportOptions.format = module.format; + if (options.sourceFolderIds) exportOptions.sourceFolderIds = options.sourceFolderIds; + if (options.sourceNoteIds) exportOptions.sourceNoteIds = options.sourceNoteIds; + + const service = new InteropService(); + const result = await service.export(exportOptions); + + console.info('Export result: ', result); + + dispatch({ + type: 'WINDOW_COMMAND', + name: 'hideModalMessage', + }); + } + +} + +module.exports = InteropServiceHelper; \ No newline at end of file diff --git a/ElectronClient/app/app.js b/ElectronClient/app/app.js index 76b860990..febdde1ed 100644 --- a/ElectronClient/app/app.js +++ b/ElectronClient/app/app.js @@ -21,6 +21,7 @@ const AlarmService = require('lib/services/AlarmService.js'); const AlarmServiceDriverNode = require('lib/services/AlarmServiceDriverNode'); const DecryptionWorker = require('lib/services/DecryptionWorker'); const InteropService = require('lib/services/InteropService'); +const InteropServiceHelper = require('./InteropServiceHelper.js'); const { bridge } = require('electron').remote.require('./bridge'); const Menu = bridge().Menu; @@ -203,41 +204,7 @@ class Application extends BaseApplication { label: module.format + ' - ' + module.description, screens: ['Main'], click: async () => { - let path = null; - - if (module.target === 'file') { - path = bridge().showSaveDialog({ - filters: [{ name: module.description, extensions: [module.fileExtension]}] - }); - } else { - path = bridge().showOpenDialog({ - properties: ['openDirectory', 'createDirectory'], - }); - } - - if (!path || (Array.isArray(path) && !path.length)) return; - - if (Array.isArray(path)) path = path[0]; - - this.dispatch({ - type: 'WINDOW_COMMAND', - name: 'showModalMessage', - message: _('Exporting to "%s" as "%s" format. Please wait...', path, module.format), - }); - - const exportOptions = {}; - exportOptions.path = path; - exportOptions.format = module.format; - - const service = new InteropService(); - const result = await service.export(exportOptions); - - console.info('Export result: ', result); - - this.dispatch({ - type: 'WINDOW_COMMAND', - name: 'hideModalMessage', - }); + await InteropServiceHelper.export(this.dispatch.bind(this), module); } }); } else { diff --git a/ElectronClient/app/gui/NoteList.jsx b/ElectronClient/app/gui/NoteList.jsx index fd40ddc8f..87e4617eb 100644 --- a/ElectronClient/app/gui/NoteList.jsx +++ b/ElectronClient/app/gui/NoteList.jsx @@ -9,6 +9,8 @@ const { bridge } = require('electron').remote.require('./bridge'); const Menu = bridge().Menu; const MenuItem = bridge().MenuItem; const eventManager = require('../eventManager'); +const InteropService = require('lib/services/InteropService'); +const InteropServiceHelper = require('../InteropServiceHelper.js'); class NoteListComponent extends React.Component { @@ -91,6 +93,12 @@ class NoteListComponent extends React.Component { eventManager.emit('noteTypeToggle', { noteId: note.id }); } }})); + + menu.append(new MenuItem({label: _('Export'), click: async () => { + const ioService = new InteropService(); + const module = ioService.moduleByFormat_('exporter', 'jex'); + await InteropServiceHelper.export(this.props.dispatch.bind(this), module, { sourceNoteIds: noteIds }); + }})); } menu.append(new MenuItem({label: _('Delete'), click: async () => { diff --git a/ElectronClient/app/gui/SideBar.jsx b/ElectronClient/app/gui/SideBar.jsx index 863c05113..bae235868 100644 --- a/ElectronClient/app/gui/SideBar.jsx +++ b/ElectronClient/app/gui/SideBar.jsx @@ -11,6 +11,7 @@ const { themeStyle } = require('../theme.js'); const { bridge } = require('electron').remote.require('./bridge'); const Menu = bridge().Menu; const MenuItem = bridge().MenuItem; +const InteropServiceHelper = require('../InteropServiceHelper.js'); class SideBarComponent extends React.Component { @@ -136,7 +137,17 @@ class SideBarComponent extends React.Component { name: 'renameFolder', id: itemId, }); - }})) + }})); + + menu.append(new MenuItem({ type: 'separator' })); + + const InteropService = require('lib/services/InteropService.js'); + + menu.append(new MenuItem({label: _('Export'), click: async () => { + const ioService = new InteropService(); + const module = ioService.moduleByFormat_('exporter', 'jex'); + await InteropServiceHelper.export(this.props.dispatch.bind(this), module, { sourceFolderIds: [itemId] }); + }})); } menu.popup(bridge().window());