allow removing multiple segments

pull/901/head
Mikael Finstad 2022-03-06 21:18:34 +08:00
rodzic 2ff8689d40
commit cf9347904b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 25AB36E3E81CBC26
2 zmienionych plików z 33 dodań i 26 usunięć

Wyświetl plik

@ -498,7 +498,7 @@ const App = memo(() => {
// const getSafeCutTime = useCallback((cutTime, next) => ffmpeg.getSafeCutTime(neighbouringFrames, cutTime, next), [neighbouringFrames]);
const addCutSegment = useCallback(() => {
const addSegment = useCallback(() => {
try {
// Cannot add if prev seg is not finished
if (currentCutSeg.start === undefined && currentCutSeg.end === undefined) return;
@ -521,7 +521,7 @@ const App = memo(() => {
} catch (err) {
console.error(err);
}
}, [currentCutSeg.start, currentCutSeg.end, getCurrentTime, cutSegments, createIndexedSegment, setCutSegments]);
}, [currentCutSeg.start, currentCutSeg.end, getCurrentTime, duration, cutSegments, createIndexedSegment, setCutSegments]);
const setCutStart = useCallback(() => {
if (!filePath) return;
@ -530,8 +530,8 @@ const App = memo(() => {
// https://github.com/mifi/lossless-cut/issues/168
// If current time is after the end of the current segment in the timeline,
// add a new segment that starts at playerTime
if (currentCutSeg.end != null && currentTime > currentCutSeg.end) {
addCutSegment();
if (currentCutSeg.end != null && currentTime >= currentCutSeg.end) {
addSegment();
} else {
try {
const startTime = currentTime;
@ -544,7 +544,7 @@ const App = memo(() => {
handleError(err);
}
}
}, [filePath, getCurrentTime, currentCutSeg.end, addCutSegment, setCutTime]);
}, [filePath, getCurrentTime, currentCutSeg.end, addSegment, setCutTime]);
const setCutEnd = useCallback(() => {
if (!filePath) return;
@ -850,20 +850,22 @@ const App = memo(() => {
});
}, [copyAnyAudioTrack, filePath, mainStreams, setCopyStreamIdsForPath]);
const removeCutSegment = useCallback((index) => {
if (cutSegments.length === 1 && cutSegments[0].start == null && cutSegments[0].end == null) return; // Initial segment
if (cutSegments.length <= 1) {
clearSegments();
return;
}
const cutSegmentsNew = [...cutSegments];
cutSegmentsNew.splice(index, 1);
setCutSegments(cutSegmentsNew);
const removeSegments = useCallback((removeSegmentIds) => {
if (cutSegments.length === 1 && cutSegments[0].start == null && cutSegments[0].end == null) return; // We are at initial segment, nothing more we can do (it cannot be removed)
setCutSegments((existing) => {
const newSegments = existing.filter((seg) => !removeSegmentIds.includes(seg.segId));
if (newSegments.length === 0) {
clearSegments(); // when removing the last segments, we start over
return existing;
}
return newSegments;
});
}, [clearSegments, cutSegments, setCutSegments]);
const removeCutSegment = useCallback((index) => {
removeSegments([cutSegments[index].segId]);
}, [cutSegments, removeSegments]);
const thumnailsRef = useRef([]);
const thumnailsRenderingPromiseRef = useRef();
@ -1165,6 +1167,8 @@ const App = memo(() => {
const deselectAllSegments = useCallback(() => setDeselectedSegmentIds(Object.fromEntries(cutSegments.map((s) => [s.segId, true]))), [cutSegments]);
const selectAllSegments = useCallback(() => setDeselectedSegmentIds({}), []);
const removeSelectedSegments = useCallback(() => removeSegments(selectedSegmentsRaw.map((seg) => seg.segId)), [removeSegments, selectedSegmentsRaw]);
const selectOnlyCurrentSegment = useCallback(() => selectOnlySegment(currentCutSeg), [currentCutSeg, selectOnlySegment]);
const toggleCurrentSegmentSelected = useCallback(() => toggleSegmentSelected(currentCutSeg), [currentCutSeg, toggleSegmentSelected]);
@ -1841,7 +1845,7 @@ const App = memo(() => {
undo: () => cutSegmentsHistory.back(),
redo: () => cutSegmentsHistory.forward(),
labelCurrentSegment: () => { onLabelSegmentPress(currentSegIndexSafe); return false; },
addSegment: () => addCutSegment(),
addSegment,
toggleHelp: () => { toggleHelp(); return false; },
export: onExportPress,
reorderSegsByStartTime,
@ -1909,7 +1913,7 @@ const App = memo(() => {
if (match) return bubble;
return true; // bubble the event
}, [addCutSegment, askSetStartTimeOffset, batchFileJump, batchOpenSelectedFile, captureSnapshot, changePlaybackRate, cleanupFilesDialog, clearSegments, closeBatch, closeExportConfirm, concatCurrentBatch, concatDialogVisible, convertFormatBatch, createFixedDurationSegments, createNumSegments, currentSegIndexSafe, cutSegmentsHistory, deselectAllSegments, exportConfirmVisible, extractAllStreams, fillSegmentsGaps, goToTimecode, increaseRotation, invertAllCutSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, keyboardShortcutsVisible, onExportConfirm, onExportPress, onLabelSegmentPress, pause, play, removeCutSegment, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, selectAllSegments, selectOnlyCurrentSegment, setCutEnd, setCutStart, setPlaybackVolume, shortStep, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleCurrentSegmentSelected, toggleHelp, toggleKeyboardShortcuts, toggleKeyframeCut, togglePlay, toggleSegmentsList, toggleStreamsSelector, toggleStripAudio, tryFixInvalidDuration, userHtml5ifyCurrentFile, zoomRel]);
}, [addSegment, askSetStartTimeOffset, batchFileJump, batchOpenSelectedFile, captureSnapshot, changePlaybackRate, cleanupFilesDialog, clearSegments, closeBatch, closeExportConfirm, concatCurrentBatch, concatDialogVisible, convertFormatBatch, createFixedDurationSegments, createNumSegments, currentSegIndexSafe, cutSegmentsHistory, deselectAllSegments, exportConfirmVisible, extractAllStreams, fillSegmentsGaps, goToTimecode, increaseRotation, invertAllCutSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, keyboardShortcutsVisible, onExportConfirm, onExportPress, onLabelSegmentPress, pause, play, removeCutSegment, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, selectAllSegments, selectOnlyCurrentSegment, setCutEnd, setCutStart, setPlaybackVolume, shortStep, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleCurrentSegmentSelected, toggleHelp, toggleKeyboardShortcuts, toggleKeyframeCut, togglePlay, toggleSegmentsList, toggleStreamsSelector, toggleStripAudio, tryFixInvalidDuration, userHtml5ifyCurrentFile, zoomRel]);
useKeyboard({ keyBindings, onKeyPress });
@ -2327,8 +2331,9 @@ const App = memo(() => {
onLabelSegmentPress={onLabelSegmentPress}
currentCutSeg={currentCutSeg}
segmentAtCursor={segmentAtCursor}
addCutSegment={addCutSegment}
addSegment={addSegment}
removeCutSegment={removeCutSegment}
onRemoveSelectedPress={removeSelectedSegments}
toggleSegmentsList={toggleSegmentsList}
splitCurrentSegment={splitCurrentSegment}
selectedSegmentsRaw={selectedSegmentsRaw}

Wyświetl plik

@ -21,7 +21,7 @@ const buttonBaseStyle = {
const neutralButtonColor = 'rgba(255, 255, 255, 0.2)';
const Segment = memo(({ seg, index, currentSegIndex, formatTimecode, getFrameCount, updateOrder, invertCutSegments, onClick, onRemovePress, onReorderPress, onLabelPress, enabled, onSelectSingleSegment, onToggleSegmentSelected, onDeselectAllSegments, onSelectSegmentsByLabel, onSelectAllSegments, jumpSegStart, jumpSegEnd, addCutSegment, onViewSegmentTagsPress }) => {
const Segment = memo(({ seg, index, currentSegIndex, formatTimecode, getFrameCount, updateOrder, invertCutSegments, onClick, onRemovePress, onRemoveSelectedPress, onReorderPress, onLabelPress, enabled, onSelectSingleSegment, onToggleSegmentSelected, onDeselectAllSegments, onSelectSegmentsByLabel, onSelectAllSegments, jumpSegStart, jumpSegEnd, addSegment, onViewSegmentTagsPress }) => {
const { t } = useTranslation();
const ref = useRef();
@ -34,9 +34,10 @@ const Segment = memo(({ seg, index, currentSegIndex, formatTimecode, getFrameCou
{ type: 'separator' },
{ label: t('Add segment'), click: addCutSegment },
{ label: t('Add segment'), click: addSegment },
{ label: t('Label segment'), click: onLabelPress },
{ label: t('Remove segment'), click: onRemovePress },
{ label: t('Remove selected segments'), click: onRemoveSelectedPress },
{ type: 'separator' },
@ -55,7 +56,7 @@ const Segment = memo(({ seg, index, currentSegIndex, formatTimecode, getFrameCou
{ label: t('Segment tags'), click: () => onViewSegmentTagsPress(index) },
];
}, [invertCutSegments, t, jumpSegStart, jumpSegEnd, addCutSegment, onLabelPress, onRemovePress, onReorderPress, updateOrder, onSelectSingleSegment, seg, onSelectAllSegments, onDeselectAllSegments, onSelectSegmentsByLabel, onViewSegmentTagsPress, index]);
}, [invertCutSegments, t, jumpSegStart, jumpSegEnd, addSegment, onLabelPress, onRemovePress, onRemoveSelectedPress, onReorderPress, updateOrder, onSelectSingleSegment, seg, onSelectAllSegments, onDeselectAllSegments, onSelectSegmentsByLabel, onViewSegmentTagsPress, index]);
useContextMenu(ref, contextMenuTemplate);
@ -131,7 +132,7 @@ const Segment = memo(({ seg, index, currentSegIndex, formatTimecode, getFrameCou
const SegmentList = memo(({
width, formatTimecode, apparentCutSegments, inverseCutSegments, getFrameCount, onSegClick,
currentSegIndex,
updateSegOrder, updateSegOrders, addCutSegment, removeCutSegment,
updateSegOrder, updateSegOrders, addSegment, removeCutSegment, onRemoveSelectedPress,
onLabelSegmentPress, currentCutSeg, segmentAtCursor, toggleSegmentsList, splitCurrentSegment,
selectedSegments, selectedSegmentsRaw, onSelectSingleSegment, onToggleSegmentSelected, onDeselectAllSegments, onSelectAllSegments, onSelectSegmentsByLabel,
jumpSegStart, jumpSegEnd, onViewSegmentTagsPress,
@ -189,7 +190,7 @@ const SegmentList = memo(({
style={{ ...buttonBaseStyle, background: neutralButtonColor }}
role="button"
title={t('Add segment')}
onClick={addCutSegment}
onClick={addSegment}
/>
<FaMinus
@ -268,7 +269,8 @@ const SegmentList = memo(({
index={index}
enabled={enabled}
onClick={onSegClick}
addCutSegment={addCutSegment}
addSegment={addSegment}
onRemoveSelectedPress={onRemoveSelectedPress}
onRemovePress={() => removeCutSegment(index)}
onReorderPress={() => onReorderSegsPress(index)}
onLabelPress={() => onLabelSegmentPress(index)}