fix mas logic

and rename method
pull/2599/head
Mikael Finstad 8 months ago
parent 251102004c
commit 251104fc51
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -15,7 +15,7 @@ import { SweetAlertOptions } from 'sweetalert2';
import useTimelineScroll from './hooks/useTimelineScroll';
import useUserSettingsRoot from './hooks/useUserSettingsRoot';
import useFfmpegOperations, { maybeMkdirOutDir, OutputNotWritableError } from './hooks/useFfmpegOperations';
import useFfmpegOperations, { maybeMkDeepOutDir, OutputNotWritableError } from './hooks/useFfmpegOperations';
import useKeyframes from './hooks/useKeyframes';
import useWaveform from './hooks/useWaveform';
import useKeyboard from './hooks/useKeyboard';
@ -878,13 +878,23 @@ function App() {
generatedFileNames: GeneratedOutFileNames,
}) => {
if (workingRef.current) return;
const firstPath = paths[0];
if (!firstPath) return;
try {
// need to ensure the output dir is writable, because the user might not yet have opened a file, and so MAS might not yet have access to write the dir
const newCustomOutDir = await ensureWritableOutDir({ inputPath: firstPath, outDir: customOutDir });
if (newCustomOutDir !== customOutDir) {
// throw user back to the concat dialog because now things might have changed (which could affect overwriting files etc!)
// also if the user cancels the dialog, `DirectoryAccessDeclinedError` will be thrown and we will return (see catch below)
return;
}
// only after ensuring out dir access, we can close the concat dialog
setConcatSheetOpen(false);
setWorking({ text: i18n.t('Merging') });
const firstPath = paths[0];
if (!firstPath) return;
const warnings = new Set<string>();
const notices = new Set<string>();
@ -913,7 +923,7 @@ function App() {
const metadataFromPath = paths[0];
invariant(metadataFromPath != null);
await maybeMkdirOutDir({ outputDir: outDir, fileOutPath: outPath });
await maybeMkDeepOutDir({ outputDir: outDir, fileOutPath: outPath });
const { haveExcludedStreams } = await concatFiles({ paths, outPath, outDir, outFormat, metadataFromPath, includeAllStreams, streams, ffmpegExperimental, onProgress: setProgress, preserveMovData, movFastStart, preserveMetadataOnMerge, chapters: chaptersFromSegments });
@ -953,13 +963,13 @@ function App() {
return;
}
const reportState = { includeAllStreams, streams, outFormat, segmentsToChapters, clearBatchFilesAfterConcat };
const reportState = { includeAllStreams, streams, outFormat, clearBatchFilesAfterConcat };
handleConcatFailed(err, reportState);
} finally {
setWorking(undefined);
setProgress(undefined);
}
}, [workingRef, setWorking, customOutDir, segmentsToChapters, concatFiles, ffmpegExperimental, preserveMovData, movFastStart, preserveMetadataOnMerge, closeBatch, enableOverwriteOutput, hideAllNotifications, t, showOsNotification, openConcatFinishedDialog, handleConcatFailed]);
}, [workingRef, ensureWritableOutDir, customOutDir, setWorking, segmentsToChapters, concatFiles, ffmpegExperimental, preserveMovData, movFastStart, preserveMetadataOnMerge, closeBatch, enableOverwriteOutput, hideAllNotifications, t, showOsNotification, openConcatFinishedDialog, handleConcatFailed]);
const cleanupFiles = useCallback(async (cleanupChoices2: CleanupChoicesType) => {
// Store paths before we reset state
@ -2750,7 +2760,7 @@ function App() {
</Dialog.Portal>
</Dialog.Root>
<ConcatSheet isShown={batchFiles.length > 0 && concatSheetOpen} onHide={() => setConcatSheetOpen(false)} paths={batchFilePaths} mergedFileTemplate={mergedFileTemplateOrDefault} generateMergedFileNames={generateMergedFileNames} onConcat={userConcatFiles} setAlwaysConcatMultipleFiles={setAlwaysConcatMultipleFiles} alwaysConcatMultipleFiles={alwaysConcatMultipleFiles} ensureWritableOutDir={ensureWritableOutDir} fileFormat={fileFormat} setFileFormat={setFileFormat} detectedFileFormat={detectedFileFormat} setDetectedFileFormat={setDetectedFileFormat} onOutputFormatUserChange={onOutputFormatUserChange} />
<ConcatSheet isShown={batchFiles.length > 0 && concatSheetOpen} onHide={() => setConcatSheetOpen(false)} paths={batchFilePaths} mergedFileTemplate={mergedFileTemplateOrDefault} generateMergedFileNames={generateMergedFileNames} onConcat={userConcatFiles} setAlwaysConcatMultipleFiles={setAlwaysConcatMultipleFiles} alwaysConcatMultipleFiles={alwaysConcatMultipleFiles} fileFormat={fileFormat} setFileFormat={setFileFormat} detectedFileFormat={detectedFileFormat} setDetectedFileFormat={setDetectedFileFormat} onOutputFormatUserChange={onOutputFormatUserChange} />
<KeyboardShortcuts isShown={keyboardShortcutsVisible} onHide={() => setKeyboardShortcutsVisible(false)} keyBindings={keyBindings} setKeyBindings={setKeyBindings} currentCutSeg={currentCutSeg} resetKeyBindings={resetKeyBindings} />

@ -18,7 +18,6 @@ import { primaryColor } from '../colors';
import ExportSheet from './ExportSheet';
import * as Dialog from './Dialog';
import FileNameTemplateEditor from './FileNameTemplateEditor';
import { EnsureWritableOutDir } from '../hooks/useDirectoryAccess';
const { basename } = window.require('path');
@ -33,7 +32,7 @@ function Alert({ text }: { text: string }) {
);
}
function ConcatSheet({ isShown, onHide, paths, mergedFileTemplate, generateMergedFileNames, onConcat, alwaysConcatMultipleFiles, setAlwaysConcatMultipleFiles, ensureWritableOutDir, fileFormat, setFileFormat, detectedFileFormat, setDetectedFileFormat, onOutputFormatUserChange }: {
function ConcatSheet({ isShown, onHide, paths, mergedFileTemplate, generateMergedFileNames, onConcat, alwaysConcatMultipleFiles, setAlwaysConcatMultipleFiles, fileFormat, setFileFormat, detectedFileFormat, setDetectedFileFormat, onOutputFormatUserChange }: {
isShown: boolean,
onHide: () => void,
paths: string[],
@ -42,7 +41,6 @@ function ConcatSheet({ isShown, onHide, paths, mergedFileTemplate, generateMerge
onConcat: (a: { paths: string[], includeAllStreams: boolean, streams: FFprobeStream[], fileFormat: string, clearBatchFilesAfterConcat: boolean, generatedFileNames: GeneratedOutFileNames }) => Promise<void>,
alwaysConcatMultipleFiles: boolean,
setAlwaysConcatMultipleFiles: (a: boolean) => void,
ensureWritableOutDir: EnsureWritableOutDir,
fileFormat: string | undefined,
setFileFormat: Dispatch<SetStateAction<string | undefined>>,
detectedFileFormat: string | undefined,
@ -162,19 +160,11 @@ function ConcatSheet({ isShown, onHide, paths, mergedFileTemplate, generateMerge
invariant(fileFormat != null);
invariant(firstPath != null);
// need to ensure the output dir is writable, because the user might not yet have opened a file, and so MAS might not yet have access to write the dir
const newCustomOutDir = await ensureWritableOutDir({ inputPath: firstPath, outDir: customOutDir });
if (newCustomOutDir !== customOutDir) {
// throw user back to dialog because now things might have changed (which could affect overwriting files etc!)
return;
}
const outputDir = getOutDir(customOutDir, firstPath);
const generatedFileNames = await generateMergedFileNames({ template: mergedFileTemplate, filePaths: paths, fileFormat, outputDir, epochMs: uniqueSuffix });
await onConcat({ paths, includeAllStreams, streams: fileMeta!.streams, fileFormat, clearBatchFilesAfterConcat, generatedFileNames });
}, [clearBatchFilesAfterConcat, customOutDir, ensureWritableOutDir, fileFormat, fileMeta, firstPath, generateMergedFileNames, includeAllStreams, mergedFileTemplate, onConcat, paths, uniqueSuffix]);
}, [clearBatchFilesAfterConcat, customOutDir, fileFormat, fileMeta, firstPath, generateMergedFileNames, includeAllStreams, mergedFileTemplate, onConcat, paths, uniqueSuffix]);
return (
<ExportSheet

@ -31,16 +31,19 @@ export default function useDirectoryAccess({ setCustomOutDir }: { setCustomOutDi
// If we are MAS, we need to loop try to make the user confirm the dialog with the same path as the defaultPath.
for (;;) {
// eslint-disable-next-line no-await-in-loop
// First check if we already have access, if so, we are done
if (await checkDirWriteAccess(inputFileDir) && !simulateMasPermissionError) break;
// If we are not MAS, but we don't have access, then we can't do anything
if (!masMode) {
// don't know what to do; fail right away
// so just fail right away
errorToast(i18n.t('You have no write access to the directory of this file'));
throw new DirectoryAccessDeclinedError();
}
// We are now mas, so we need to try to encourage the user to allow access to the dir
// We are now MAS, so we need to try to encourage the user to allow access to the dir
// If the user keeps choosing the wrong dir, we will keep asking
// Normally Apple grants access to the dir of the file that was selected in a file open dialog or drag-droppen, but maybe the user opened a file from the batch list, for example.
// eslint-disable-next-line no-await-in-loop
const userSelectedDir = await askForInputDir(inputFileDir);

@ -77,7 +77,7 @@ async function pathExists(path: string) {
}
}
export async function maybeMkdirOutDir({ outputDir, fileOutPath }: { outputDir: string, fileOutPath: string }) {
export async function maybeMkDeepOutDir({ outputDir, fileOutPath }: { outputDir: string, fileOutPath: string }) {
// cutFileNames might contain slashes and therefore might have a subdir(tree) that we need to mkdir
// https://github.com/mifi/lossless-cut/issues/1532
const actualOutputDir = dirname(fileOutPath);
@ -541,7 +541,7 @@ function useFfmpegOperations({ filePath, treatInputFileModifiedTimeAsStart, trea
if (await shouldSkipExistingFile(finalOutPath)) return { path: finalOutPath, created: false };
await maybeMkdirOutDir({ outputDir, fileOutPath: finalOutPath });
await maybeMkDeepOutDir({ outputDir, fileOutPath: finalOutPath });
if (!isEncoding) {
// simple lossless cut

Loading…
Cancel
Save