mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-22 02:12:30 +01:00
allow drag drop multiple files to merge
also fix breaking electron change to showOpenDialog and fix react warnings
This commit is contained in:
parent
c70beb38c9
commit
f4d2dd9cdf
@ -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);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -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: (<SortableFiles
|
||||
items={outPaths}
|
||||
onChange={(val) => { 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: (<SortableFiles
|
||||
items={outPaths}
|
||||
onChange={(val) => { outPaths = val; }}
|
||||
helperContainer={() => swalElem}
|
||||
/>),
|
||||
});
|
||||
|
||||
if (!dismiss) {
|
||||
onMergeClick(outPaths);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (canceled) return;
|
||||
showMergeDialog(filePaths, onMergeClick);
|
||||
}
|
||||
|
||||
module.exports = { showMergeDialog };
|
||||
module.exports = {
|
||||
showMergeDialog,
|
||||
showOpenAndMergeDialog,
|
||||
};
|
||||
|
@ -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 {
|
||||
</div>
|
||||
|
||||
<div className="left-menu">
|
||||
<select style={{ width: 60 }} value={fileFormat} title="Format of current file" onChange={withBlur(e => this.setState({ fileFormat: e.target.value }))}>
|
||||
<option disabled selected>Out fmt</option>
|
||||
{detectedFileFormat && <option value={detectedFileFormat}>{detectedFileFormat}</option>}
|
||||
{selectableFormats.map(f => <option value={f}>{f}</option>)}
|
||||
<select style={{ width: 60 }} defaultValue="" value={fileFormat} title="Format of current file" onChange={withBlur(e => this.setState({ fileFormat: e.target.value }))}>
|
||||
<option key="" value="" disabled>Out fmt</option>
|
||||
{detectedFileFormat && (
|
||||
<option key={detectedFileFormat} value={detectedFileFormat}>
|
||||
{detectedFileFormat}
|
||||
</option>
|
||||
)}
|
||||
{selectableFormats.map(f => <option key={f} value={f}>{f}</option>)}
|
||||
</select>
|
||||
|
||||
<span style={infoSpanStyle} title="Playback rate">
|
||||
|
Loading…
Reference in New Issue
Block a user