improve trash logic

pull/949/head
Mikael Finstad 5 years ago
parent 6cc18f1d8e
commit 5e2d8891c7
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -2,7 +2,6 @@ import React, { memo, useEffect, useState, useCallback, useRef, useMemo } from '
import { unstable_batchedUpdates as batchedUpdates } from 'react-dom';
import { FaAngleLeft, FaWindowClose, FaTimes, FaAngleRight, FaFile } from 'react-icons/fa';
import { AnimatePresence, motion } from 'framer-motion';
import Swal from 'sweetalert2';
import Lottie from 'react-lottie-player';
import { SideSheet, Button, Position, ForkIcon, DisableIcon, Select, ThemeProvider } from 'evergreen-ui';
import { useStateWithHistory } from 'react-use/lib/useStateWithHistory';
@ -59,6 +58,7 @@ import {
checkDirWriteAccess, dirExists, openDirToast, isMasBuild, isStoreBuild, dragPreventer, doesPlayerSupportFile,
isDurationValid, isWindows, filenamify, getOutFileExtension, generateSegFileName, defaultOutSegTemplate,
hasDuplicates, havePermissionToReadFile, isMac, resolvePathIfNeeded, pathExists, html5ifiedPrefix, html5dummySuffix, findExistingHtml5FriendlyFile,
deleteFiles, getHtml5ifiedPath,
} from './util';
import { formatDuration } from './util/duration';
import { adjustRate } from './util/rate-calculator';
@ -70,17 +70,9 @@ import { createSegment, createInitialCutSegments, getCleanCutSegments, getSegApp
import loadingLottie from './7077-magic-flow.json';
function getHtml5ifiedPath(cod, fp, type) {
// See also inside ffmpegHtml5ify
const ext = (isMac && ['slowest', 'slow', 'slow-audio'].includes(type)) ? 'mp4' : 'mkv';
return getOutPath(cod, fp, `${html5ifiedPrefix}${type}.${ext}`);
}
const isDev = window.require('electron-is-dev');
const electron = window.require('electron'); // eslint-disable-line
const trash = window.require('trash');
const { unlink, exists } = window.require('fs-extra');
const { exists } = window.require('fs-extra');
const { extname, parse: parsePath, sep: pathSep, join: pathJoin, normalize: pathNormalize, basename, dirname } = window.require('path');
const { dialog } = electron.remote;
@ -941,17 +933,13 @@ const App = memo(() => {
}, [playing, filePath]);
const closeFileWithConfirm = useCallback(() => {
if (!isFileOpened || workingRef.current) return;
// eslint-disable-next-line no-alert
if (askBeforeClose && !window.confirm(i18n.t('Are you sure you want to close the current file?'))) return false;
if (askBeforeClose && !window.confirm(i18n.t('Are you sure you want to close the current file?'))) return;
resetState();
return true;
}, [askBeforeClose, resetState]);
const closeFile = useCallback(() => {
if (!isFileOpened || workingRef.current) return false;
return closeFileWithConfirm();
}, [closeFileWithConfirm, isFileOpened]);
}, [askBeforeClose, resetState, isFileOpened]);
const closeBatch = useCallback(() => {
// eslint-disable-next-line no-alert
@ -962,10 +950,7 @@ const App = memo(() => {
const removeBatchFile = useCallback((path) => setBatchFiles((existingBatch) => existingBatch.filter((existingFile) => existingFile.path !== path)), []);
const cleanupFiles = useCallback(async () => {
// Because we will reset state before deleting files
const saved = { previewFilePath, filePath, edlFilePath };
if (!closeFile()) return;
if (!isFileOpened) return;
let trashResponse = cleanupChoices;
if (!cleanupChoices.dontShowAgain) {
@ -975,44 +960,28 @@ const App = memo(() => {
setCleanupChoices(trashResponse); // Store for next time
}
const { tmpFiles: deleteTmpFiles, projectFile: deleteProjectFile, sourceFile: deleteOriginal } = trashResponse;
if (!deleteTmpFiles && !deleteProjectFile && !deleteOriginal) return;
if (workingRef.current) return;
removeBatchFile(saved.filePath);
// Because we will reset state before deleting files
const savedPaths = { previewFilePath, filePath, edlFilePath };
try {
setWorking(i18n.t('Cleaning up'));
resetState();
if (deleteTmpFiles && saved.previewFilePath) await trash(saved.previewFilePath).catch(console.error);
if (deleteProjectFile && saved.edlFilePath) await trash(saved.edlFilePath).catch(console.error);
// throw new Error('test');
if (deleteOriginal) await trash(saved.filePath);
} catch (err) {
try {
console.warn('Failed to trash', err);
removeBatchFile(savedPaths.filePath);
const { value } = await Swal.fire({
icon: 'warning',
text: i18n.t('Unable to move file to trash. Do you want to permanently delete it?'),
confirmButtonText: i18n.t('Permanently delete'),
showCancelButton: true,
});
if (!trashResponse.tmpFiles && !trashResponse.projectFile && !trashResponse.sourceFile) return;
if (value) {
if (deleteTmpFiles && saved.previewFilePath) await unlink(saved.previewFilePath).catch(console.error);
if (deleteProjectFile && saved.edlFilePath) await unlink(saved.edlFilePath).catch(console.error);
if (deleteOriginal) await unlink(saved.filePath);
}
} catch (err2) {
errorToast(`Unable to delete file: ${err2.message}`);
console.error(err2);
}
try {
setWorking(i18n.t('Cleaning up'));
console.log('trashing', trashResponse);
await deleteFiles({ toDelete: trashResponse, paths: savedPaths });
} catch (err) {
errorToast(i18n.t('Unable to delete file: {{message}}', { message: err.message }));
console.error(err);
} finally {
setWorking();
}
}, [previewFilePath, filePath, edlFilePath, closeFile, cleanupChoices, removeBatchFile, setWorking]);
}, [previewFilePath, filePath, edlFilePath, cleanupChoices, isFileOpened, resetState, removeBatchFile, setWorking]);
const outSegments = useMemo(() => (invertCutSegments ? inverseCutSegments : apparentCutSegments),
[invertCutSegments, inverseCutSegments, apparentCutSegments]);
@ -1927,7 +1896,7 @@ const App = memo(() => {
const fileOpened = (event, filePaths) => { userOpenFiles(filePaths.map(resolvePathIfNeeded)); };
const showStreamsSelector = () => setStreamsSelectorShown(true);
const openSendReportDialog2 = () => { openSendReportDialogWithState(); };
const closeFile2 = () => { closeFile(); };
const closeFile2 = () => { closeFileWithConfirm(); };
const closeBatch2 = () => { closeBatch(); };
electron.ipcRenderer.on('file-opened', fileOpened);
@ -1981,7 +1950,7 @@ const App = memo(() => {
mergeFiles, outputDir, filePath, customOutDir, startTimeOffset, userHtml5ifyCurrentFile,
extractAllStreams, userOpenFiles, openSendReportDialogWithState, setWorking,
loadEdlFile, cutSegments, apparentCutSegments, edlFilePath, toggleHelp, toggleSettings, ensureOutDirAccessible, html5ifyAndLoad, html5ify,
loadCutSegments, duration, checkFileOpened, loadMedia, fileFormat, reorderSegsByStartTime, closeFile, closeBatch, clearSegments, fixInvalidDuration, invertAllCutSegments,
loadCutSegments, duration, checkFileOpened, loadMedia, fileFormat, reorderSegsByStartTime, closeFileWithConfirm, closeBatch, clearSegments, fixInvalidDuration, invertAllCutSegments,
]);
const showAddStreamSourceDialog = useCallback(async () => {

@ -1,13 +1,15 @@
import Swal from 'sweetalert2';
import i18n from 'i18next';
import lodashTemplate from 'lodash/template';
import pMap from 'p-map';
const { dirname, parse: parsePath, join, basename, extname, isAbsolute, resolve } = window.require('path');
const fs = window.require('fs-extra');
const open = window.require('open');
const os = window.require('os');
const trash = window.require('trash');
const { readdir } = fs;
const { readdir, unlink } = fs;
export function getOutDir(customOutDir, filePath) {
if (customOutDir) return customOutDir;
@ -223,3 +225,52 @@ export async function findExistingHtml5FriendlyFile(fp, cod) {
usingDummyVideo: ['fastest-audio', 'fastest-audio-remux', html5dummySuffix].includes(suffix),
};
}
export function getHtml5ifiedPath(cod, fp, type) {
// See also inside ffmpegHtml5ify
const ext = (isMac && ['slowest', 'slow', 'slow-audio'].includes(type)) ? 'mp4' : 'mkv';
return getOutPath(cod, fp, `${html5ifiedPrefix}${type}.${ext}`);
}
export async function deleteFiles({ toDelete, paths: { previewFilePath, filePath, edlFilePath } }) {
const failedToTrashFiles = [];
if (toDelete.tmpFiles && previewFilePath) {
try {
await trash(previewFilePath);
} catch (err) {
console.error(err);
failedToTrashFiles.push(previewFilePath);
}
}
if (toDelete.projectFile && edlFilePath) {
try {
// throw new Error('test');
await trash(edlFilePath);
} catch (err) {
console.error(err);
failedToTrashFiles.push(edlFilePath);
}
}
if (toDelete.sourceFile) {
try {
await trash(filePath);
} catch (err) {
console.error(err);
failedToTrashFiles.push(filePath);
}
}
if (failedToTrashFiles.length === 0) return; // All good!
const { value } = await Swal.fire({
icon: 'warning',
text: i18n.t('Unable to move file to trash. Do you want to permanently delete it?'),
confirmButtonText: i18n.t('Permanently delete'),
showCancelButton: true,
});
if (value) {
await pMap(failedToTrashFiles, async (path) => unlink(path), { concurrency: 1 });
}
}

Loading…
Cancel
Save