Skip to content

Commit

Permalink
Implement batch file list #89
Browse files Browse the repository at this point in the history
  • Loading branch information
mifi committed Aug 28, 2021
1 parent b487db5 commit d3c8fce
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 126 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The main feature is lossless trimming and cutting of video and audio files, whic
- Lossless merge/concatenation of arbitrary files (with identical codecs parameters, e.g. from the same camera)
- Lossless stream editing: Combine arbitrary tracks from multiple files (ex. add music or subtitle track to a video file)
- Losslessly extract all tracks from a file (extract video, audio, subtitle, attachments and other tracks from one file into separate files)
- Batch view for fast multi-file workflow
- Remux into any compatible output format
- Take full-resolution snapshots from videos in JPEG/PNG format
- Manual input of cutpoint times
Expand Down
6 changes: 6 additions & 0 deletions public/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ module.exports = (app, mainWindow, newVersion) => {
mainWindow.webContents.send('close-file');
},
},
{
label: i18n.t('Close batch'),
async click() {
mainWindow.webContents.send('close-batch-files');
},
},
{ type: 'separator' },
{
label: i18n.t('Import project (LLC)...'),
Expand Down
311 changes: 196 additions & 115 deletions src/App.jsx

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/HelpSheet.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ const HelpSheet = memo(({ visible, onTogglePress, ffmpegCommandLog, currentCutSe
<div><kbd>C</kbd> {t('Capture snapshot')}</div>
<div><kbd>D</kbd> {t('Delete source file')}</div>

<h2>{t('Batch file list')}</h2>
<div><kbd>SHIFT</kbd> + <kbd></kbd> {t('Previous file')}</div>
<div><kbd>SHIFT</kbd> + <kbd></kbd> {t('Next file')}</div>

<p style={{ fontWeight: 'bold' }}>{t('Hover mouse over buttons in the main interface to see which function they have')}</p>

<h1 style={{ marginTop: 40 }}>{t('Last ffmpeg commands')}</h1>
Expand Down
4 changes: 2 additions & 2 deletions src/NoFileLoaded.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import SimpleModeButton from './components/SimpleModeButton';

const electron = window.require('electron');

const NoFileLoaded = memo(({ topBarHeight, bottomBarHeight, mifiLink, toggleHelp, currentCutSeg, simpleMode, toggleSimpleMode }) => {
const NoFileLoaded = memo(({ top, bottom, left, mifiLink, toggleHelp, currentCutSeg, simpleMode, toggleSimpleMode }) => {
const { t } = useTranslation();

return (
<div className="no-user-select" style={{ position: 'fixed', left: 0, right: 0, top: topBarHeight, bottom: bottomBarHeight, border: '2vmin dashed #252525', color: '#505050', margin: '5vmin', display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', whiteSpace: 'nowrap' }}>
<div className="no-user-select" style={{ position: 'fixed', left, right: 0, top, bottom, border: '2vmin dashed #252525', color: '#505050', margin: '5vmin', display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', whiteSpace: 'nowrap' }}>
<div style={{ fontSize: '6vmin', textTransform: 'uppercase' }}>{t('DROP FILE(S)')}</div>

<div style={{ fontSize: '4vmin', color: '#777', cursor: 'pointer' }} role="button" onClick={toggleHelp}>
Expand Down
4 changes: 2 additions & 2 deletions src/SegmentList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const Segment = memo(({ seg, index, currentSegIndex, formatTimecode, getFrameCou
onClick={() => !invertCutSegments && onClick(index)}
onDoubleClick={onDoubleClick}
positionTransition
style={{ cursor: 'grab', originY: 0, margin: '5px 0', border: `1px solid rgba(255,255,255,${isActive ? 1 : 0.3})`, padding: 5, borderRadius: 5, position: 'relative', opacity: !enabled && !invertCutSegments ? 0.5 : undefined }}
style={{ cursor: 'grab', originY: 0, margin: '5px 0', background: 'rgba(0,0,0,0.1)', border: `1px solid rgba(255,255,255,${isActive ? 1 : 0.3})`, padding: 5, borderRadius: 5, position: 'relative', opacity: !enabled && !invertCutSegments ? 0.5 : undefined }}
initial={{ scaleY: 0 }}
animate={{ scaleY: 1 }}
exit={{ scaleY: 0 }}
Expand Down Expand Up @@ -237,7 +237,7 @@ const SegmentList = memo(({
<FaAngleRight
title={t('Close sidebar')}
size={18}
style={{ verticalAlign: 'middle', color: 'white' }}
style={{ verticalAlign: 'middle', color: 'white', cursor: 'pointer' }}
role="button"
onClick={toggleSideBar}
/>
Expand Down
35 changes: 28 additions & 7 deletions src/dialogs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -352,12 +352,6 @@ export function openAbout() {
}

export async function showMergeDialog(paths, onMergeClick) {
if (!paths) return;
if (paths.length < 2) {
errorToast(i18n.t('More than one file must be selected'));
return;
}

let swalElem;
let outPaths = paths;
let allStreams = false;
Expand All @@ -382,6 +376,28 @@ export async function showMergeDialog(paths, onMergeClick) {
}
}

export async function showMultipleFilesDialog(paths, onMergeClick, onBatchLoadFilesClick) {
const { isConfirmed, isDenied } = await Swal.fire({
showCloseButton: true,
showDenyButton: true,
denyButtonAriaLabel: '',
denyButtonColor: '#7367f0',
denyButtonText: i18n.t('Batch files'),
confirmButtonText: i18n.t('Merge/concatenate files'),
title: i18n.t('Multiple files'),
text: i18n.t('Do you want to merge/concatenate the files or load them for batch processing?'),
});

if (isDenied) {
await onBatchLoadFilesClick(paths);
return;
}

if (isConfirmed) {
await showMergeDialog(paths, onMergeClick);
}
}

export async function showOpenAndMergeDialog({ defaultPath, onMergeClick }) {
const title = i18n.t('Please select files to be merged');
const message = i18n.t('Please select files to be merged. The files need to be of the exact same format and codecs');
Expand All @@ -391,7 +407,12 @@ export async function showOpenAndMergeDialog({ defaultPath, onMergeClick }) {
properties: ['openFile', 'multiSelections'],
message,
});
if (canceled) return;
if (canceled || !filePaths) return;

if (filePaths.length < 2) {
errorToast(i18n.t('More than one file must be selected'));
return;
}

showMergeDialog(filePaths, onMergeClick);
}
Expand Down

0 comments on commit d3c8fce

Please sign in to comment.