kopia lustrzana https://github.com/mifi/lossless-cut
improve merge menu
show the Open files-dialog if the Merge menu item is clicked without any files already open had to rearrange a lot of code due to deps fixes #1316pull/1286/merge
rodzic
cefc6e6ccc
commit
f801094d66
226
src/App.jsx
226
src/App.jsx
|
@ -712,15 +712,6 @@ const App = memo(() => {
|
|||
return { cancel: false, newCustomOutDir };
|
||||
}, [customOutDir, setCustomOutDir]);
|
||||
|
||||
const concatCurrentBatch = useCallback(() => {
|
||||
if (batchFiles.length < 2) {
|
||||
errorToast(i18n.t('Please open at least 2 files to merge, then try again'));
|
||||
return;
|
||||
}
|
||||
|
||||
setConcatDialogVisible(true);
|
||||
}, [batchFiles]);
|
||||
|
||||
const toggleCaptureFormat = useCallback(() => setCaptureFormat(f => (f === 'png' ? 'jpeg' : 'png')), [setCaptureFormat]);
|
||||
|
||||
const toggleKeyframeCut = useCallback((showMessage) => setKeyframeCut((val) => {
|
||||
|
@ -1895,6 +1886,119 @@ const App = memo(() => {
|
|||
}
|
||||
}, [addFileAsCoverArt, captureFormat, customOutDir, enableTransferTimestamps, filePath, getCurrentTime, hideAllNotifications]);
|
||||
|
||||
const batchLoadPaths = useCallback((newPaths, append) => {
|
||||
setBatchFiles((existingFiles) => {
|
||||
const mapPathsToFiles = (paths) => paths.map((path) => ({ path, name: basename(path) }));
|
||||
if (append) {
|
||||
const newUniquePaths = newPaths.filter((newPath) => !existingFiles.some(({ path: existingPath }) => newPath === existingPath));
|
||||
setSelectedBatchFiles([newUniquePaths[0]]);
|
||||
return [...existingFiles, ...mapPathsToFiles(newUniquePaths)];
|
||||
}
|
||||
setSelectedBatchFiles([newPaths[0]]);
|
||||
return mapPathsToFiles(newPaths);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const userOpenFiles = useCallback(async (filePaths) => {
|
||||
if (!filePaths || filePaths.length < 1) return;
|
||||
|
||||
console.log('userOpenFiles');
|
||||
console.log(filePaths.join('\n'));
|
||||
|
||||
[lastOpenedPath] = filePaths;
|
||||
|
||||
if (filePaths.length > 1) {
|
||||
if (alwaysConcatMultipleFiles) {
|
||||
batchLoadPaths(filePaths);
|
||||
setConcatDialogVisible(true);
|
||||
} else {
|
||||
batchLoadPaths(filePaths, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// filePaths.length is now 1
|
||||
const firstFilePath = filePaths[0];
|
||||
|
||||
const filePathLowerCase = firstFilePath.toLowerCase();
|
||||
|
||||
if (workingRef.current) return;
|
||||
try {
|
||||
setWorking(i18n.t('Loading file'));
|
||||
|
||||
// Import segments for for already opened file
|
||||
const edlFormats = { csv: 'csv', pbf: 'pbf', edl: 'mplayer', cue: 'cue', xml: 'xmeml', fcpxml: 'fcpxml' };
|
||||
const matchingExt = Object.keys(edlFormats).find((ext) => filePathLowerCase.endsWith(`.${ext}`));
|
||||
if (matchingExt) {
|
||||
if (!checkFileOpened()) return;
|
||||
await loadEdlFile({ path: firstFilePath, type: edlFormats[matchingExt], append: true });
|
||||
return;
|
||||
}
|
||||
|
||||
const isLlcProject = filePathLowerCase.endsWith('.llc');
|
||||
|
||||
// Need to ask the user what to do if more than one option
|
||||
const inputOptions = {
|
||||
open: isFileOpened ? i18n.t('Open the file instead of the current one') : i18n.t('Open the file'),
|
||||
};
|
||||
if (isFileOpened) {
|
||||
if (isLlcProject) inputOptions.project = i18n.t('Load segments from the new file, but keep the current media');
|
||||
else inputOptions.tracks = i18n.t('Include all tracks from the new file');
|
||||
}
|
||||
if (batchFiles.length > 0) inputOptions.addToBatch = i18n.t('Add the file to the batch list');
|
||||
|
||||
if (Object.keys(inputOptions).length > 1) {
|
||||
const openFileResponse = enableAskForFileOpenAction ? await askForFileOpenAction(inputOptions) : 'open';
|
||||
|
||||
if (openFileResponse === 'open') {
|
||||
await userOpenSingleFile({ path: firstFilePath, isLlcProject });
|
||||
return;
|
||||
}
|
||||
if (openFileResponse === 'project') {
|
||||
await loadEdlFile({ path: firstFilePath, type: 'llc' });
|
||||
return;
|
||||
}
|
||||
if (openFileResponse === 'tracks') {
|
||||
await addStreamSourceFile(firstFilePath);
|
||||
setStreamsSelectorShown(true);
|
||||
return;
|
||||
}
|
||||
if (openFileResponse === 'addToBatch') {
|
||||
batchLoadPaths([firstFilePath], true);
|
||||
return;
|
||||
}
|
||||
// Dialog canceled:
|
||||
return;
|
||||
}
|
||||
|
||||
await userOpenSingleFile({ path: firstFilePath, isLlcProject });
|
||||
} catch (err) {
|
||||
console.error('userOpenFiles', err);
|
||||
if (err.code === 'LLC_FFPROBE_UNSUPPORTED_FILE') {
|
||||
errorToast(i18n.t('Unsupported file'));
|
||||
} else {
|
||||
handleError(i18n.t('Failed to open file'), err);
|
||||
}
|
||||
} finally {
|
||||
setWorking();
|
||||
}
|
||||
}, [alwaysConcatMultipleFiles, batchLoadPaths, setWorking, batchFiles.length, isFileOpened, userOpenSingleFile, checkFileOpened, loadEdlFile, enableAskForFileOpenAction, addStreamSourceFile]);
|
||||
|
||||
const openFilesDialog = useCallback(async () => {
|
||||
const { canceled, filePaths } = await dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'], defaultPath: lastOpenedPath });
|
||||
if (canceled) return;
|
||||
userOpenFiles(filePaths);
|
||||
}, [userOpenFiles]);
|
||||
|
||||
const concatCurrentBatch = useCallback(() => {
|
||||
if (batchFiles.length < 2) {
|
||||
openFilesDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
setConcatDialogVisible(true);
|
||||
}, [batchFiles.length, openFilesDialog]);
|
||||
|
||||
const onKeyPress = useCallback(({ action, keyup }) => {
|
||||
function seekReset() {
|
||||
seekAccelerationRef.current = 1;
|
||||
|
@ -2067,104 +2171,6 @@ const App = memo(() => {
|
|||
|
||||
const batchFilePaths = useMemo(() => batchFiles.map((f) => f.path), [batchFiles]);
|
||||
|
||||
const batchLoadPaths = useCallback((newPaths, append) => {
|
||||
setBatchFiles((existingFiles) => {
|
||||
const mapPathsToFiles = (paths) => paths.map((path) => ({ path, name: basename(path) }));
|
||||
if (append) {
|
||||
const newUniquePaths = newPaths.filter((newPath) => !existingFiles.some(({ path: existingPath }) => newPath === existingPath));
|
||||
setSelectedBatchFiles([newUniquePaths[0]]);
|
||||
return [...existingFiles, ...mapPathsToFiles(newUniquePaths)];
|
||||
}
|
||||
setSelectedBatchFiles([newPaths[0]]);
|
||||
return mapPathsToFiles(newPaths);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const userOpenFiles = useCallback(async (filePaths) => {
|
||||
if (!filePaths || filePaths.length < 1) return;
|
||||
|
||||
console.log('userOpenFiles');
|
||||
console.log(filePaths.join('\n'));
|
||||
|
||||
[lastOpenedPath] = filePaths;
|
||||
|
||||
if (filePaths.length > 1) {
|
||||
if (alwaysConcatMultipleFiles) {
|
||||
batchLoadPaths(filePaths);
|
||||
setConcatDialogVisible(true);
|
||||
} else {
|
||||
batchLoadPaths(filePaths, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// filePaths.length is now 1
|
||||
const firstFilePath = filePaths[0];
|
||||
|
||||
const filePathLowerCase = firstFilePath.toLowerCase();
|
||||
|
||||
if (workingRef.current) return;
|
||||
try {
|
||||
setWorking(i18n.t('Loading file'));
|
||||
|
||||
// Import segments for for already opened file
|
||||
const edlFormats = { csv: 'csv', pbf: 'pbf', edl: 'mplayer', cue: 'cue', xml: 'xmeml', fcpxml: 'fcpxml' };
|
||||
const matchingExt = Object.keys(edlFormats).find((ext) => filePathLowerCase.endsWith(`.${ext}`));
|
||||
if (matchingExt) {
|
||||
if (!checkFileOpened()) return;
|
||||
await loadEdlFile({ path: firstFilePath, type: edlFormats[matchingExt], append: true });
|
||||
return;
|
||||
}
|
||||
|
||||
const isLlcProject = filePathLowerCase.endsWith('.llc');
|
||||
|
||||
// Need to ask the user what to do if more than one option
|
||||
const inputOptions = {
|
||||
open: isFileOpened ? i18n.t('Open the file instead of the current one') : i18n.t('Open the file'),
|
||||
};
|
||||
if (isFileOpened) {
|
||||
if (isLlcProject) inputOptions.project = i18n.t('Load segments from the new file, but keep the current media');
|
||||
else inputOptions.tracks = i18n.t('Include all tracks from the new file');
|
||||
}
|
||||
if (batchFiles.length > 0) inputOptions.addToBatch = i18n.t('Add the file to the batch list');
|
||||
|
||||
if (Object.keys(inputOptions).length > 1) {
|
||||
const openFileResponse = enableAskForFileOpenAction ? await askForFileOpenAction(inputOptions) : 'open';
|
||||
|
||||
if (openFileResponse === 'open') {
|
||||
await userOpenSingleFile({ path: firstFilePath, isLlcProject });
|
||||
return;
|
||||
}
|
||||
if (openFileResponse === 'project') {
|
||||
await loadEdlFile({ path: firstFilePath, type: 'llc' });
|
||||
return;
|
||||
}
|
||||
if (openFileResponse === 'tracks') {
|
||||
await addStreamSourceFile(firstFilePath);
|
||||
setStreamsSelectorShown(true);
|
||||
return;
|
||||
}
|
||||
if (openFileResponse === 'addToBatch') {
|
||||
batchLoadPaths([firstFilePath], true);
|
||||
return;
|
||||
}
|
||||
// Dialog canceled:
|
||||
return;
|
||||
}
|
||||
|
||||
await userOpenSingleFile({ path: firstFilePath, isLlcProject });
|
||||
} catch (err) {
|
||||
console.error('userOpenFiles', err);
|
||||
if (err.code === 'LLC_FFPROBE_UNSUPPORTED_FILE') {
|
||||
errorToast(i18n.t('Unsupported file'));
|
||||
} else {
|
||||
handleError(i18n.t('Failed to open file'), err);
|
||||
}
|
||||
} finally {
|
||||
setWorking();
|
||||
}
|
||||
}, [alwaysConcatMultipleFiles, batchLoadPaths, setWorking, batchFiles.length, isFileOpened, userOpenSingleFile, checkFileOpened, loadEdlFile, enableAskForFileOpenAction, addStreamSourceFile]);
|
||||
|
||||
const onVideoError = useCallback(async () => {
|
||||
const { error } = videoRef.current;
|
||||
if (!error) return;
|
||||
|
@ -2203,12 +2209,6 @@ const App = memo(() => {
|
|||
}
|
||||
}, [fileUri, usingPreviewFile, hasVideo, hasAudio, html5ifyAndLoadWithPreferences, customOutDir, filePath, setWorking]);
|
||||
|
||||
const openFilesDialog = useCallback(async () => {
|
||||
const { canceled, filePaths } = await dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'], defaultPath: lastOpenedPath });
|
||||
if (canceled) return;
|
||||
userOpenFiles(filePaths);
|
||||
}, [userOpenFiles]);
|
||||
|
||||
useEffect(() => {
|
||||
async function exportEdlFile2(e, type) {
|
||||
if (!checkFileOpened()) return;
|
||||
|
|
Ładowanie…
Reference in New Issue