kopia lustrzana https://github.com/mifi/lossless-cut
Make trash function more flexible #541
rodzic
f5afe25715
commit
69f3845689
44
src/App.jsx
44
src/App.jsx
|
@ -51,7 +51,7 @@ import {
|
||||||
checkDirWriteAccess, dirExists, openDirToast, isMasBuild, isStoreBuild, dragPreventer, doesPlayerSupportFile,
|
checkDirWriteAccess, dirExists, openDirToast, isMasBuild, isStoreBuild, dragPreventer, doesPlayerSupportFile,
|
||||||
isDurationValid, isWindows,
|
isDurationValid, isWindows,
|
||||||
} from './util';
|
} from './util';
|
||||||
import { askForOutDir, askForImportChapters, createNumSegments, createFixedDurationSegments, promptTimeOffset, askForHtml5ifySpeed, askForYouTubeInput, askForFileOpenAction, confirmExtractAllStreamsDialog, confirmTrashSourceDialog } from './dialogs';
|
import { askForOutDir, askForImportChapters, createNumSegments, createFixedDurationSegments, promptTimeOffset, askForHtml5ifySpeed, askForYouTubeInput, askForFileOpenAction, confirmExtractAllStreamsDialog, cleanupFilesDialog } from './dialogs';
|
||||||
import { openSendReportDialog } from './reporting';
|
import { openSendReportDialog } from './reporting';
|
||||||
import { fallbackLng } from './i18n';
|
import { fallbackLng } from './i18n';
|
||||||
import { createSegment, createInitialCutSegments, getCleanCutSegments, getSegApparentStart, findSegmentsAtCursor } from './segments';
|
import { createSegment, createInitialCutSegments, getCleanCutSegments, getSegApparentStart, findSegmentsAtCursor } from './segments';
|
||||||
|
@ -926,39 +926,47 @@ const App = memo(() => {
|
||||||
return true;
|
return true;
|
||||||
}, [askBeforeClose, isFileOpened, resetState, working]);
|
}, [askBeforeClose, isFileOpened, resetState, working]);
|
||||||
|
|
||||||
const deleteSource = useCallback(async () => {
|
const cleanupFiles = useCallback(async () => {
|
||||||
// Because we will reset state before deleting files
|
// Because we will reset state before deleting files
|
||||||
const saved = { html5FriendlyPath, dummyVideoPath, filePath };
|
const saved = { html5FriendlyPath, dummyVideoPath, filePath, edlFilePath };
|
||||||
|
|
||||||
if (!closeFile()) return;
|
if (!closeFile()) return;
|
||||||
|
|
||||||
if (!(await confirmTrashSourceDialog())) return;
|
const trashResponse = await cleanupFilesDialog();
|
||||||
|
console.log('trashResponse', trashResponse);
|
||||||
|
if (!trashResponse) return;
|
||||||
|
|
||||||
|
const deleteTmpFiles = ['all', 'projectAndTmpFiles', 'tmpFiles'].includes(trashResponse);
|
||||||
|
const deleteProjectFile = ['all', 'projectAndTmpFiles'].includes(trashResponse);
|
||||||
|
const deleteOriginal = ['all'].includes(trashResponse);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setWorking(i18n.t('Deleting source'));
|
setWorking(i18n.t('Cleaning up'));
|
||||||
|
|
||||||
if (saved.html5FriendlyPath) await trash(saved.html5FriendlyPath).catch(console.error);
|
if (deleteTmpFiles && saved.html5FriendlyPath) await trash(saved.html5FriendlyPath).catch(console.error);
|
||||||
if (saved.dummyVideoPath) await trash(saved.dummyVideoPath).catch(console.error);
|
if (deleteTmpFiles && saved.dummyVideoPath) await trash(saved.dummyVideoPath).catch(console.error);
|
||||||
|
if (deleteProjectFile && saved.edlFilePath) await trash(saved.edlFilePath).catch(console.error);
|
||||||
|
|
||||||
// throw new Error('test');
|
// throw new Error('test');
|
||||||
await trash(saved.filePath);
|
if (deleteOriginal) await trash(saved.filePath);
|
||||||
toast.fire({ icon: 'info', title: i18n.t('File has been moved to trash') });
|
toast.fire({ icon: 'info', title: i18n.t('Cleanup successful') });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
try {
|
try {
|
||||||
console.warn('Failed to trash', err);
|
console.warn('Failed to trash', err);
|
||||||
|
|
||||||
const { value } = await Swal.fire({
|
const { value } = await Swal.fire({
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
text: i18n.t('Unable to move source file to trash. Do you want to permanently delete it?'),
|
text: i18n.t('Unable to move file to trash. Do you want to permanently delete it?'),
|
||||||
confirmButtonText: i18n.t('Permanently delete'),
|
confirmButtonText: i18n.t('Permanently delete'),
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
if (saved.html5FriendlyPath) await unlink(saved.html5FriendlyPath).catch(console.error);
|
if (deleteTmpFiles && saved.html5FriendlyPath) await unlink(saved.html5FriendlyPath).catch(console.error);
|
||||||
if (saved.dummyVideoPath) await unlink(saved.dummyVideoPath).catch(console.error);
|
if (deleteTmpFiles && saved.dummyVideoPath) await unlink(saved.dummyVideoPath).catch(console.error);
|
||||||
await unlink(saved.filePath);
|
if (deleteProjectFile && saved.edlFilePath) await unlink(saved.edlFilePath).catch(console.error);
|
||||||
toast.fire({ icon: 'info', title: i18n.t('File has been permanently deleted') });
|
if (deleteOriginal) await unlink(saved.filePath);
|
||||||
|
toast.fire({ icon: 'info', title: i18n.t('Cleanup successful') });
|
||||||
}
|
}
|
||||||
} catch (err2) {
|
} catch (err2) {
|
||||||
errorToast(`Unable to delete file: ${err2.message}`);
|
errorToast(`Unable to delete file: ${err2.message}`);
|
||||||
|
@ -967,7 +975,7 @@ const App = memo(() => {
|
||||||
} finally {
|
} finally {
|
||||||
setWorking();
|
setWorking();
|
||||||
}
|
}
|
||||||
}, [filePath, html5FriendlyPath, dummyVideoPath, closeFile]);
|
}, [filePath, html5FriendlyPath, dummyVideoPath, closeFile, edlFilePath]);
|
||||||
|
|
||||||
const outSegments = useMemo(() => (invertCutSegments ? inverseCutSegments : apparentCutSegments),
|
const outSegments = useMemo(() => (invertCutSegments ? inverseCutSegments : apparentCutSegments),
|
||||||
[invertCutSegments, inverseCutSegments, apparentCutSegments]);
|
[invertCutSegments, inverseCutSegments, apparentCutSegments]);
|
||||||
|
@ -1387,7 +1395,7 @@ const App = memo(() => {
|
||||||
mousetrap.bind('i', () => setCutStart());
|
mousetrap.bind('i', () => setCutStart());
|
||||||
mousetrap.bind('o', () => setCutEnd());
|
mousetrap.bind('o', () => setCutEnd());
|
||||||
mousetrap.bind('backspace', () => removeCutSegment());
|
mousetrap.bind('backspace', () => removeCutSegment());
|
||||||
mousetrap.bind('d', () => deleteSource());
|
mousetrap.bind('d', () => cleanupFiles());
|
||||||
mousetrap.bind('b', () => splitCurrentSegment());
|
mousetrap.bind('b', () => splitCurrentSegment());
|
||||||
mousetrap.bind('r', () => increaseRotation());
|
mousetrap.bind('r', () => increaseRotation());
|
||||||
|
|
||||||
|
@ -1410,7 +1418,7 @@ const App = memo(() => {
|
||||||
return () => mousetrap.reset();
|
return () => mousetrap.reset();
|
||||||
}, [
|
}, [
|
||||||
addCutSegment, capture, changePlaybackRate, togglePlay, removeCutSegment,
|
addCutSegment, capture, changePlaybackRate, togglePlay, removeCutSegment,
|
||||||
setCutEnd, setCutStart, seekRel, seekRelPercent, shortStep, deleteSource, jumpSeg,
|
setCutEnd, setCutStart, seekRel, seekRelPercent, shortStep, cleanupFiles, jumpSeg,
|
||||||
seekClosestKeyframe, zoomRel, toggleComfortZoom, splitCurrentSegment, exportConfirmVisible,
|
seekClosestKeyframe, zoomRel, toggleComfortZoom, splitCurrentSegment, exportConfirmVisible,
|
||||||
increaseRotation, jumpCutStart, jumpCutEnd,
|
increaseRotation, jumpCutStart, jumpCutEnd,
|
||||||
]);
|
]);
|
||||||
|
@ -2213,7 +2221,7 @@ const App = memo(() => {
|
||||||
areWeCutting={areWeCutting}
|
areWeCutting={areWeCutting}
|
||||||
autoMerge={autoMerge}
|
autoMerge={autoMerge}
|
||||||
increaseRotation={increaseRotation}
|
increaseRotation={increaseRotation}
|
||||||
deleteSource={deleteSource}
|
cleanupFiles={cleanupFiles}
|
||||||
renderCaptureFormatButton={renderCaptureFormatButton}
|
renderCaptureFormatButton={renderCaptureFormatButton}
|
||||||
capture={capture}
|
capture={capture}
|
||||||
onExportPress={onExportPress}
|
onExportPress={onExportPress}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import ToggleExportConfirm from './components/ToggleExportConfirm';
|
||||||
|
|
||||||
|
|
||||||
const RightMenu = memo(({
|
const RightMenu = memo(({
|
||||||
isRotationSet, rotation, areWeCutting, increaseRotation, deleteSource, renderCaptureFormatButton,
|
isRotationSet, rotation, areWeCutting, increaseRotation, cleanupFiles, renderCaptureFormatButton,
|
||||||
capture, onExportPress, outSegments, hasVideo, autoMerge, exportConfirmEnabled, toggleExportConfirmEnabled,
|
capture, onExportPress, outSegments, hasVideo, autoMerge, exportConfirmEnabled, toggleExportConfirmEnabled,
|
||||||
simpleMode,
|
simpleMode,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -36,10 +36,10 @@ const RightMenu = memo(({
|
||||||
|
|
||||||
{!simpleMode && (
|
{!simpleMode && (
|
||||||
<FaTrashAlt
|
<FaTrashAlt
|
||||||
title={t('Delete source file')}
|
title={t('Close file and clean up')}
|
||||||
style={{ padding: '5px 10px' }}
|
style={{ padding: '5px 10px' }}
|
||||||
size={16}
|
size={16}
|
||||||
onClick={deleteSource}
|
onClick={cleanupFiles}
|
||||||
role="button"
|
role="button"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -198,16 +198,26 @@ export async function confirmExtractAllStreamsDialog() {
|
||||||
return !!value;
|
return !!value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function confirmTrashSourceDialog() {
|
export async function cleanupFilesDialog() {
|
||||||
const { value } = await Swal.fire({
|
const { value } = await Swal.fire({
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
text: i18n.t('Do you want to move the source file to trash?'),
|
title: i18n.t('Cleanup files?'),
|
||||||
confirmButtonText: i18n.t('Trash/delete original file'),
|
input: 'radio',
|
||||||
|
inputValue: 'all',
|
||||||
|
text: i18n.t('Do you want to move the original file and/or any generated files to trash?'),
|
||||||
|
confirmButtonText: i18n.t('Trash selected file(s)'),
|
||||||
confirmButtonColor: '#d33',
|
confirmButtonColor: '#d33',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
cancelButtonText: i18n.t('Do not delete'),
|
cancelButtonText: i18n.t('Do not delete'),
|
||||||
focusCancel: true,
|
focusCancel: true,
|
||||||
|
customClass: { input: 'swal2-losslesscut-radio' },
|
||||||
|
inputOptions: {
|
||||||
|
tmpFiles: i18n.t('Trash auto-generated files'),
|
||||||
|
projectAndTmpFiles: i18n.t('Trash project CSV and auto-generated files'),
|
||||||
|
all: i18n.t('Trash original source file, project CSV and auto-generated files'),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue