diff --git a/src/menu.js b/src/menu.js index 72206e59..b0d3110c 100644 --- a/src/menu.js +++ b/src/menu.js @@ -16,10 +16,10 @@ module.exports = (app, mainWindow, newVersion) => { { label: 'Open', accelerator: 'CmdOrCtrl+O', - click() { - dialog.showOpenDialog({ properties: ['openFile'] }, (filePaths) => { - mainWindow.webContents.send('file-opened', filePaths); - }); + async click() { + const { canceled, filePaths } = await dialog.showOpenDialog({ properties: ['openFile'] }); + if (canceled) return; + mainWindow.webContents.send('file-opened', filePaths); }, }, { diff --git a/src/merge/merge.jsx b/src/merge/merge.jsx index 5620879e..e3a4f4dc 100644 --- a/src/merge/merge.jsx +++ b/src/merge/merge.jsx @@ -8,42 +8,46 @@ const { errorToast } = require('../util'); const MySwal = withReactContent(swal); +async function showMergeDialog(paths, onMergeClick) { + if (!paths) return; + if (paths.length < 2) { + errorToast('More than one file must be selected'); + return; + } -function showMergeDialog({ dialog, defaultPath, onMergeClick }) { + let swalElem; + let outPaths = paths; + const { dismiss } = await MySwal.fire({ + width: '90%', + showCancelButton: true, + confirmButtonText: 'Merge!', + onBeforeOpen: (el) => { swalElem = el; }, + html: ( { outPaths = val; }} + helperContainer={() => swalElem} + />), + }); + + if (!dismiss) { + onMergeClick(outPaths); + } +} + +async function showOpenAndMergeDialog({ dialog, defaultPath, onMergeClick }) { const title = 'Please select files to be merged'; const message = 'Please select files to be merged. The files need to be of the exact same format and codecs'; - dialog.showOpenDialog({ + const { canceled, filePaths } = await dialog.showOpenDialog({ title, defaultPath, properties: ['openFile', 'multiSelections'], message, - }, async (paths) => { - if (!paths) return; - if (paths.length < 2) { - errorToast('More than one file must be selected'); - return; - } - - { - let swalElem; - let outPaths = paths; - const { dismiss } = await MySwal.fire({ - width: '90%', - showCancelButton: true, - confirmButtonText: 'Merge!', - onBeforeOpen: (el) => { swalElem = el; }, - html: ( { outPaths = val; }} - helperContainer={() => swalElem} - />), - }); - - if (!dismiss) { - onMergeClick(outPaths); - } - } }); + if (canceled) return; + showMergeDialog(filePaths, onMergeClick); } -module.exports = { showMergeDialog }; +module.exports = { + showMergeDialog, + showOpenAndMergeDialog, +}; diff --git a/src/renderer.jsx b/src/renderer.jsx index ff9f097b..02abbca6 100644 --- a/src/renderer.jsx +++ b/src/renderer.jsx @@ -18,7 +18,7 @@ const { default: PQueue } = require('p-queue'); const HelpSheet = require('./HelpSheet'); const TimelineSeg = require('./TimelineSeg'); -const { showMergeDialog } = require('./merge/merge'); +const { showMergeDialog, showOpenAndMergeDialog } = require('./merge/merge'); const captureFrame = require('./capture-frame'); const ffmpeg = require('./ffmpeg'); @@ -195,24 +195,10 @@ class App extends React.Component { } }); - electron.ipcRenderer.on('show-merge-dialog', () => showMergeDialog({ + electron.ipcRenderer.on('show-merge-dialog', () => showOpenAndMergeDialog({ dialog, defaultPath: this.getOutputDir(), - onMergeClick: async (paths) => { - try { - this.setState({ working: true }); - - const { customOutDir } = this.state; - - // console.log('merge', paths); - await ffmpeg.mergeAnyFiles({ customOutDir, paths }); - } catch (err) { - errorToast('Failed to merge files. Make sure they are all of the exact same format and codecs'); - console.error('Failed to merge files', err); - } finally { - this.setState({ working: false }); - } - }, + onMergeClick: this.mergeFiles, })); electron.ipcRenderer.on('set-start-offset', async () => { @@ -246,11 +232,10 @@ class App extends React.Component { document.body.ondrop = (ev) => { ev.preventDefault(); - if (ev.dataTransfer.files.length !== 1) { - errorToast('Please drop only one file'); - return; - } - load(ev.dataTransfer.files[0].path); + const { files } = ev.dataTransfer; + if (files.length < 1) return; + if (files.length === 1) load(files[0].path); + else showMergeDialog(Array.from(files).map(f => f.path), this.mergeFiles); }; Mousetrap.bind('space', () => this.playCommand()); @@ -308,9 +293,10 @@ class App extends React.Component { this.setCutTime('end', currentTime); } - setOutputDir = () => { - dialog.showOpenDialog({ properties: ['openDirectory'] }, (paths) => { - this.setState({ customOutDir: (paths && paths.length === 1) ? paths[0] : undefined }); + setOutputDir = async () => { + const { filePaths } = await dialog.showOpenDialog({ properties: ['openDirectory'] }); + this.setState({ + customOutDir: (filePaths && filePaths.length === 1) ? filePaths[0] : undefined, }); } @@ -375,6 +361,22 @@ class App extends React.Component { return (this.state.currentTime || 0) + this.state.startTimeOffset; } + mergeFiles = async (paths, onMergeClick) => { + try { + this.setState({ working: true }); + + const { customOutDir } = this.state; + + // console.log('merge', paths); + await ffmpeg.mergeAnyFiles({ customOutDir, paths }); + } catch (err) { + errorToast('Failed to merge files. Make sure they are all of the exact same format and codecs'); + console.error('Failed to merge files', err); + } finally { + this.setState({ working: false }); + } + } + frameRenderEnabled = () => { const { rotationPreviewRequested, userHtml5ified, streams } = this.state; if (rotationPreviewRequested) return true; @@ -856,10 +858,14 @@ class App extends React.Component {
- this.setState({ fileFormat: e.target.value }))}> + + {detectedFileFormat && ( + + )} + {selectableFormats.map(f => )}