mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-22 02:12:30 +01:00
implement duplicate segment
This commit is contained in:
parent
b1405632f6
commit
743d190369
@ -345,7 +345,7 @@ const App = memo(() => {
|
||||
}, [isFileOpened]);
|
||||
|
||||
const {
|
||||
cutSegments, cutSegmentsHistory, createSegmentsFromKeyframes, shuffleSegments, detectBlackScenes, detectSilentScenes, detectSceneChanges, removeCutSegment, invertAllSegments, fillSegmentsGaps, combineOverlappingSegments, combineSelectedSegments, shiftAllSegmentTimes, alignSegmentTimesToKeyframes, onViewSegmentTags, updateSegOrder, updateSegOrders, reorderSegsByStartTime, addSegment, setCutStart, setCutEnd, onLabelSegment, splitCurrentSegment, createNumSegments, createFixedDurationSegments, createRandomSegments, apparentCutSegments, haveInvalidSegs, currentSegIndexSafe, currentCutSeg, currentApparentCutSeg, inverseCutSegments, clearSegments, loadCutSegments, isSegmentSelected, setCutTime, setCurrentSegIndex, onLabelSelectedSegments, deselectAllSegments, selectAllSegments, selectOnlyCurrentSegment, toggleCurrentSegmentSelected, invertSelectedSegments, removeSelectedSegments, setDeselectedSegmentIds, onSelectSegmentsByLabel, toggleSegmentSelected, selectOnlySegment, getApparentCutSegmentById, selectedSegments, selectedSegmentsOrInverse, nonFilteredSegmentsOrInverse, segmentsToExport,
|
||||
cutSegments, cutSegmentsHistory, createSegmentsFromKeyframes, shuffleSegments, detectBlackScenes, detectSilentScenes, detectSceneChanges, removeCutSegment, invertAllSegments, fillSegmentsGaps, combineOverlappingSegments, combineSelectedSegments, shiftAllSegmentTimes, alignSegmentTimesToKeyframes, onViewSegmentTags, updateSegOrder, updateSegOrders, reorderSegsByStartTime, addSegment, setCutStart, setCutEnd, onLabelSegment, splitCurrentSegment, createNumSegments, createFixedDurationSegments, createRandomSegments, apparentCutSegments, haveInvalidSegs, currentSegIndexSafe, currentCutSeg, currentApparentCutSeg, inverseCutSegments, clearSegments, loadCutSegments, isSegmentSelected, setCutTime, setCurrentSegIndex, onLabelSelectedSegments, deselectAllSegments, selectAllSegments, selectOnlyCurrentSegment, toggleCurrentSegmentSelected, invertSelectedSegments, removeSelectedSegments, setDeselectedSegmentIds, onSelectSegmentsByLabel, toggleSegmentSelected, selectOnlySegment, getApparentCutSegmentById, selectedSegments, selectedSegmentsOrInverse, nonFilteredSegmentsOrInverse, segmentsToExport, duplicateCurrentSegment, duplicateSegment,
|
||||
} = useSegments({ filePath, workingRef, setWorking, setCutProgress, mainVideoStream, duration, getRelevantTime, maxLabelLength, checkFileOpened, invertCutSegments, segmentsToChaptersOnly });
|
||||
|
||||
const jumpSegStart = useCallback((index) => userSeekAbs(apparentCutSegments[index].start), [apparentCutSegments, userSeekAbs]);
|
||||
@ -1869,6 +1869,7 @@ const App = memo(() => {
|
||||
redo: () => cutSegmentsHistory.forward(),
|
||||
labelCurrentSegment: () => { onLabelSegment(currentSegIndexSafe); return false; },
|
||||
addSegment,
|
||||
duplicateCurrentSegment,
|
||||
toggleLastCommands: () => { toggleLastCommands(); return false; },
|
||||
export: onExportPress,
|
||||
extractCurrentSegmentFramesAsImages,
|
||||
@ -1946,7 +1947,7 @@ const App = memo(() => {
|
||||
if (match) return bubble;
|
||||
|
||||
return true; // bubble the event
|
||||
}, [addSegment, alignSegmentTimesToKeyframes, askSetStartTimeOffset, batchFileJump, batchOpenSelectedFile, captureSnapshot, captureSnapshotAsCoverArt, changePlaybackRate, cleanupFilesDialog, clearSegments, closeBatch, closeExportConfirm, combineOverlappingSegments, combineSelectedSegments, concatCurrentBatch, concatDialogVisible, convertFormatBatch, copySegmentsToClipboard, createFixedDurationSegments, createNumSegments, createRandomSegments, currentSegIndexSafe, cutSegmentsHistory, deselectAllSegments, exportConfirmVisible, extractAllStreams, extractCurrentSegmentFramesAsImages, fillSegmentsGaps, goToTimecode, increaseRotation, invertAllSegments, invertSelectedSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, keyboardShortcutsVisible, onExportConfirm, onExportPress, onLabelSegment, pause, play, removeCutSegment, removeSelectedSegments, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, selectAllSegments, selectOnlyCurrentSegment, setCutEnd, setCutStart, setPlaybackVolume, shiftAllSegmentTimes, shortStep, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleCurrentSegmentSelected, toggleKeyboardShortcuts, toggleKeyframeCut, toggleLastCommands, toggleLoopSelectedSegments, togglePlay, toggleSegmentsList, toggleStreamsSelector, toggleStripAudio, tryFixInvalidDuration, userHtml5ifyCurrentFile, zoomRel]);
|
||||
}, [addSegment, alignSegmentTimesToKeyframes, askSetStartTimeOffset, batchFileJump, batchOpenSelectedFile, captureSnapshot, captureSnapshotAsCoverArt, changePlaybackRate, cleanupFilesDialog, clearSegments, closeBatch, closeExportConfirm, combineOverlappingSegments, combineSelectedSegments, concatCurrentBatch, concatDialogVisible, convertFormatBatch, copySegmentsToClipboard, createFixedDurationSegments, createNumSegments, createRandomSegments, currentSegIndexSafe, cutSegmentsHistory, deselectAllSegments, duplicateCurrentSegment, exportConfirmVisible, extractAllStreams, extractCurrentSegmentFramesAsImages, fillSegmentsGaps, goToTimecode, increaseRotation, invertAllSegments, invertSelectedSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, keyboardShortcutsVisible, onExportConfirm, onExportPress, onLabelSegment, pause, play, removeCutSegment, removeSelectedSegments, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, selectAllSegments, selectOnlyCurrentSegment, setCutEnd, setCutStart, setPlaybackVolume, shiftAllSegmentTimes, shortStep, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleCurrentSegmentSelected, toggleKeyboardShortcuts, toggleKeyframeCut, toggleLastCommands, toggleLoopSelectedSegments, togglePlay, toggleSegmentsList, toggleStreamsSelector, toggleStripAudio, tryFixInvalidDuration, userHtml5ifyCurrentFile, zoomRel]);
|
||||
|
||||
useKeyboard({ keyBindings, onKeyPress });
|
||||
|
||||
@ -2286,6 +2287,7 @@ const App = memo(() => {
|
||||
currentCutSeg={currentCutSeg}
|
||||
segmentAtCursor={segmentAtCursor}
|
||||
addSegment={addSegment}
|
||||
onDuplicateSegmentClick={duplicateSegment}
|
||||
removeCutSegment={removeCutSegment}
|
||||
onRemoveSelected={removeSelectedSegments}
|
||||
toggleSegmentsList={toggleSegmentsList}
|
||||
|
@ -22,7 +22,7 @@ const buttonBaseStyle = {
|
||||
const neutralButtonColor = 'var(--gray8)';
|
||||
|
||||
|
||||
const Segment = memo(({ darkMode, seg, index, currentSegIndex, formatTimecode, getFrameCount, updateOrder, invertCutSegments, onClick, onRemovePress, onRemoveSelected, onLabelSelectedSegments, onReorderPress, onLabelPress, selected, onSelectSingleSegment, onToggleSegmentSelected, onDeselectAllSegments, onSelectSegmentsByLabel, onSelectAllSegments, jumpSegStart, jumpSegEnd, addSegment, onViewSegmentTags, onExtractSegmentFramesAsImages, onInvertSelectedSegments }) => {
|
||||
const Segment = memo(({ darkMode, seg, index, currentSegIndex, formatTimecode, getFrameCount, updateOrder, invertCutSegments, onClick, onRemovePress, onRemoveSelected, onLabelSelectedSegments, onReorderPress, onLabelPress, selected, onSelectSingleSegment, onToggleSegmentSelected, onDeselectAllSegments, onSelectSegmentsByLabel, onSelectAllSegments, jumpSegStart, jumpSegEnd, addSegment, onViewSegmentTags, onExtractSegmentFramesAsImages, onInvertSelectedSegments, onDuplicateSegmentClick }) => {
|
||||
const { t } = useTranslation();
|
||||
const { getSegColor } = useSegColors();
|
||||
|
||||
@ -39,6 +39,7 @@ const Segment = memo(({ darkMode, seg, index, currentSegIndex, formatTimecode, g
|
||||
{ label: t('Add segment'), click: addSegment },
|
||||
{ label: t('Label segment'), click: onLabelPress },
|
||||
{ label: t('Remove segment'), click: onRemovePress },
|
||||
{ label: t('Duplicate segment'), click: () => onDuplicateSegmentClick(seg) },
|
||||
|
||||
{ type: 'separator' },
|
||||
|
||||
@ -64,7 +65,7 @@ const Segment = memo(({ darkMode, seg, index, currentSegIndex, formatTimecode, g
|
||||
{ label: t('Segment tags'), click: () => onViewSegmentTags(index) },
|
||||
{ label: t('Extract frames as image files'), click: () => onExtractSegmentFramesAsImages(index) },
|
||||
];
|
||||
}, [invertCutSegments, t, jumpSegStart, jumpSegEnd, addSegment, onLabelPress, onRemovePress, onLabelSelectedSegments, onRemoveSelected, onReorderPress, onSelectSingleSegment, seg, onSelectAllSegments, onDeselectAllSegments, onSelectSegmentsByLabel, onInvertSelectedSegments, updateOrder, onViewSegmentTags, index, onExtractSegmentFramesAsImages]);
|
||||
}, [invertCutSegments, t, jumpSegStart, jumpSegEnd, addSegment, onLabelPress, onRemovePress, onLabelSelectedSegments, onRemoveSelected, onReorderPress, onDuplicateSegmentClick, seg, onSelectSingleSegment, onSelectAllSegments, onDeselectAllSegments, onSelectSegmentsByLabel, onInvertSelectedSegments, updateOrder, onViewSegmentTags, index, onExtractSegmentFramesAsImages]);
|
||||
|
||||
useContextMenu(ref, contextMenuTemplate);
|
||||
|
||||
@ -147,7 +148,7 @@ const SegmentList = memo(({
|
||||
currentSegIndex,
|
||||
updateSegOrder, updateSegOrders, addSegment, removeCutSegment, onRemoveSelected,
|
||||
onLabelSegment, currentCutSeg, segmentAtCursor, toggleSegmentsList, splitCurrentSegment,
|
||||
selectedSegments, isSegmentSelected, onSelectSingleSegment, onToggleSegmentSelected, onDeselectAllSegments, onSelectAllSegments, onSelectSegmentsByLabel, onExtractSegmentFramesAsImages, onLabelSelectedSegments, onInvertSelectedSegments,
|
||||
selectedSegments, isSegmentSelected, onSelectSingleSegment, onToggleSegmentSelected, onDeselectAllSegments, onSelectAllSegments, onSelectSegmentsByLabel, onExtractSegmentFramesAsImages, onLabelSelectedSegments, onInvertSelectedSegments, onDuplicateSegmentClick,
|
||||
jumpSegStart, jumpSegEnd, onViewSegmentTags,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
@ -311,6 +312,7 @@ const SegmentList = memo(({
|
||||
onExtractSegmentFramesAsImages={onExtractSegmentFramesAsImages}
|
||||
onLabelSelectedSegments={onLabelSelectedSegments}
|
||||
onInvertSelectedSegments={onInvertSelectedSegments}
|
||||
onDuplicateSegmentClick={onDuplicateSegmentClick}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@ -291,6 +291,10 @@ const KeyboardShortcuts = memo(({
|
||||
name: t('Split segment at cursor'),
|
||||
category: segmentsAndCutpointsCategory,
|
||||
},
|
||||
duplicateCurrentSegment: {
|
||||
name: t('Duplicate current segment'),
|
||||
category: segmentsAndCutpointsCategory,
|
||||
},
|
||||
jumpPrevSegment: {
|
||||
name: t('Jump to previous segment'),
|
||||
category: segmentsAndCutpointsCategory,
|
||||
|
@ -330,6 +330,27 @@ export default ({
|
||||
}
|
||||
}, [currentCutSeg.start, currentCutSeg.end, getRelevantTime, duration, cutSegments, createIndexedSegment, setCutSegments, setCurrentSegIndex]);
|
||||
|
||||
const duplicateSegment = useCallback((segment) => {
|
||||
try {
|
||||
// Cannot duplicate if seg is not finished
|
||||
if (segment.start === undefined && segment.end === undefined) return;
|
||||
|
||||
const cutSegmentsNew = [
|
||||
...cutSegments,
|
||||
createIndexedSegment({ segment: { start: segment.start, end: segment.end, name: segment.name }, incrementCount: true }),
|
||||
];
|
||||
|
||||
setCutSegments(cutSegmentsNew);
|
||||
setCurrentSegIndex(cutSegmentsNew.length - 1);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}, [createIndexedSegment, cutSegments, setCutSegments]);
|
||||
|
||||
const duplicateCurrentSegment = useCallback(() => {
|
||||
duplicateSegment(currentCutSeg);
|
||||
}, [currentCutSeg, duplicateSegment]);
|
||||
|
||||
const setCutStart = useCallback(() => {
|
||||
if (!checkFileOpened()) return;
|
||||
|
||||
@ -484,6 +505,8 @@ export default ({
|
||||
updateSegOrders,
|
||||
reorderSegsByStartTime,
|
||||
addSegment,
|
||||
duplicateCurrentSegment,
|
||||
duplicateSegment,
|
||||
setCutStart,
|
||||
setCutEnd,
|
||||
onLabelSegment,
|
||||
|
Loading…
Reference in New Issue
Block a user