From a2bed50ff9aca084d23283f8790aa0d895669aa0 Mon Sep 17 00:00:00 2001 From: Dennis Benz Date: Mon, 3 Jul 2023 15:15:35 +0200 Subject: [PATCH 1/7] Add button to delete all segments Ref #1083 --- src/i18n/locales/en-US.json | 3 +++ src/main/CuttingActions.tsx | 7 ++++++- src/redux/videoSlice.ts | 8 +++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index fd8754ccb..3efc78cbd 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -17,6 +17,9 @@ "delete-button": "Delete", "delete-restore-tooltip": "Mark or unmark the segment at the current position as to be deleted. Hotkey: {{hotkeyName}}", "delete-restore-tooltip-aria": "Delete and Restore. Mark or unmark the segment at the current position as to be deleted. Hotkey: {{hotKeyName}}.", + "delete-all-button": "Delete All", + "delete-all-tooltip": "Mark all segments as to be deleted.", + "delete-all-tooltip-aria": "Delete All. Mark all segments as to be deleted.", "restore-button": "Restore", "mergeLeft-button": "Merge Left", "mergeLeft-tooltip": "Combine the currently active segment with the segment to its left. Hotkey: {{hotkeyName}}", diff --git a/src/main/CuttingActions.tsx b/src/main/CuttingActions.tsx index 0f3629ff5..03a3b78fc 100644 --- a/src/main/CuttingActions.tsx +++ b/src/main/CuttingActions.tsx @@ -16,7 +16,7 @@ import { css } from '@emotion/react' import { useDispatch, useSelector } from 'react-redux'; import { - cut, markAsDeletedOrAlive, selectIsCurrentSegmentAlive, mergeLeft, mergeRight + cut, markAsDeletedOrAlive, selectIsCurrentSegmentAlive, mergeLeft, mergeRight, markAllAsDeleted } from '../redux/videoSlice' import { GlobalHotKeys, KeySequence, KeyMapOptions } from "react-hotkeys"; import { cuttingKeyMap } from "../globalKeys"; @@ -86,6 +86,11 @@ const CuttingActions: React.FC = () => { + { + state.segments.forEach((segment: Segment) => { + segment.deleted = true; + }); + state.hasChanges = true + }, setSelectedWorkflowIndex: (state, action: PayloadAction) => { state.selectedWorkflowId = action.payload }, @@ -336,7 +342,7 @@ const setThumbnailHelper = (state: video, id: Track["id"], uri: Track["thumbnail export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setCurrentlyAt, setCurrentlyAtInSeconds, addSegment, setAspectRatio, setHasChanges, setWaveformImages, setThumbnails, setThumbnail, removeThumbnail, - cut, markAsDeletedOrAlive, setSelectedWorkflowIndex, mergeLeft, mergeRight, setPreviewTriggered, + cut, markAsDeletedOrAlive, markAllAsDeleted, setSelectedWorkflowIndex, mergeLeft, mergeRight, setPreviewTriggered, setClickTriggered } = videoSlice.actions // Export selectors From 03549148f801af2794b3808e7e19854781ed3f62 Mon Sep 17 00:00:00 2001 From: Dennis Benz Date: Tue, 4 Jul 2023 09:16:09 +0200 Subject: [PATCH 2/7] Add delete restore button to each segment of timeline Ref #1083 --- src/i18n/locales/en-US.json | 6 ++++- src/main/Timeline.tsx | 44 ++++++++++++++++++++++++++++++++----- src/redux/videoSlice.ts | 8 +++++-- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 3efc78cbd..a368730bf 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -93,7 +93,11 @@ "generateWaveform-text": "Generating Waveform", "segment-tooltip": "Segment {{segment}}", "scrubber-text-aria": "Timeline marker. {{currentTime}}. Active segment: {{segment}}. {{segmentStatus}}. Controls: {{moveLeft}} and {{moveRight}} to move the timeline marker. {{increase}} and {{decrease}} to increase/decrease the move delta.\n", - "segments-text-aria": "Segment {{index}}. {{segmentStatus}}. Start: {{start}}. End: {{end}}.\n" + "segments-text-aria": "Segment {{index}}. {{segmentStatus}}. Start: {{start}}. End: {{end}}.\n", + "segment-delete-tooltip": "Mark this segment as to be deleted", + "segment-delete-tooltip-aria": "Delete. Mark this segment as to be deleted", + "segment-restore-tooltip": "Unmark this segment as to be deleted", + "segment-restore-tooltip-aria": "Restore. Unmark this segment as to be deleted" }, "workflowConfig": { diff --git a/src/main/Timeline.tsx b/src/main/Timeline.tsx index 6ed81d1c3..408e7ffaf 100644 --- a/src/main/Timeline.tsx +++ b/src/main/Timeline.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from 'react' +import React, { useState, useRef, useEffect, SyntheticEvent } from 'react' import Draggable from 'react-draggable'; @@ -7,11 +7,11 @@ import { css } from '@emotion/react' import { useSelector, useDispatch } from 'react-redux'; import { Segment, httpRequestState } from '../types' import { - selectSegments, selectActiveSegmentIndex, selectDuration, selectVideoURL, selectWaveformImages, setWaveformImages + selectSegments, selectActiveSegmentIndex, selectDuration, selectVideoURL, selectWaveformImages, setWaveformImages, markAsDeletedOrAliveByIndex } from '../redux/videoSlice' import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faBars, faSpinner } from "@fortawesome/free-solid-svg-icons"; +import { faBars, faSpinner, faTrash, faTrashRestore } from "@fortawesome/free-solid-svg-icons"; import useResizeObserver from "use-resize-observer"; @@ -23,8 +23,9 @@ import { scrubberKeyMap } from '../globalKeys'; import { useTranslation } from 'react-i18next'; import { ActionCreatorWithPayload } from '@reduxjs/toolkit'; import { RootState } from '../redux/store'; -import { selectTheme } from '../redux/themeSlice'; +import { selectTheme, Theme } from '../redux/themeSlice'; import { ThemedTooltip } from './Tooltip'; +import { basicButtonStyle } from "../cssStyles"; /** * A container for visualizing the cutting of the video, as well as for controlling @@ -195,7 +196,7 @@ export const Scrubber: React.FC<{ height: timelineHeight - 10 + 'px', // TODO: CHECK IF height: '100%', width: '1px', position: 'absolute', - zIndex: 2, + zIndex: 1, boxShadow: `${theme.boxShadow}`, display: 'flex', flexDirection: 'column', @@ -293,12 +294,21 @@ export const SegmentsList: React.FC<{ }) => { const { t } = useTranslation(); + const theme = useSelector(selectTheme); // Init redux variables + const dispatch = useDispatch() const segments = useSelector(selectSegments) const duration = useSelector(selectDuration) const activeSegmentIndex = useSelector(selectActiveSegmentIndex) + const markAsDeletedOrAlive = (event: KeyboardEvent | SyntheticEvent, index: number) => { + event.preventDefault() // Prevent page scrolling due to Space bar press + event.stopPropagation() // Prevent video playback due to Space bar press + + dispatch(markAsDeletedOrAliveByIndex(index)); + } + /** * Returns a background color based on whether the segment is to be deleted * and whether the segment is currently active @@ -325,6 +335,15 @@ export const SegmentsList: React.FC<{ } } + const markAsDeletedButtonStyle = (theme: Theme) => css({ + position: 'absolute', + right: '8px', + top: '8px', + padding: '5px', + background: `${theme.element_bg}`, + zIndex: 2, + }); + // Render the individual segments const renderedSegments = () => { return ( @@ -338,6 +357,7 @@ export const SegmentsList: React.FC<{ end: convertMsToReadableString(segment.end) })} tabIndex={tabable ? 0 : -1} css={{ + position: 'relative', background: bgColor(segment.deleted, styleByActiveSegment ? activeSegmentIndex === index : false), borderRadius: '5px', borderStyle: styleByActiveSegment ? (activeSegmentIndex === index ? 'dashed' : 'solid') : 'solid', @@ -346,8 +366,20 @@ export const SegmentsList: React.FC<{ boxSizing: 'border-box', width: ((segment.end - segment.start) / duration) * 100 + '%', height: timelineHeight - 20 + 'px', // CHECK IF 100% - zIndex: 1, }}> + +
markAsDeletedOrAlive(event, index)} + onKeyDown={(event: React.KeyboardEvent) => { if (event.key === " " || event.key === "Enter") { + markAsDeletedOrAlive(event, index) + }}} + onMouseDown={(event) => event.stopPropagation() } // Prevent timeline jump + > + +
+
)) diff --git a/src/redux/videoSlice.ts b/src/redux/videoSlice.ts index 797e35842..84f95cc3b 100644 --- a/src/redux/videoSlice.ts +++ b/src/redux/videoSlice.ts @@ -167,6 +167,10 @@ const videoSlice = createSlice({ state.segments[state.activeSegmentIndex].deleted = !state.segments[state.activeSegmentIndex].deleted state.hasChanges = true }, + markAsDeletedOrAliveByIndex: (state, action: PayloadAction) => { + state.segments[action.payload].deleted = !state.segments[action.payload].deleted + state.hasChanges = true + }, markAllAsDeleted: state => { state.segments.forEach((segment: Segment) => { segment.deleted = true; @@ -342,8 +346,8 @@ const setThumbnailHelper = (state: video, id: Track["id"], uri: Track["thumbnail export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setCurrentlyAt, setCurrentlyAtInSeconds, addSegment, setAspectRatio, setHasChanges, setWaveformImages, setThumbnails, setThumbnail, removeThumbnail, - cut, markAsDeletedOrAlive, markAllAsDeleted, setSelectedWorkflowIndex, mergeLeft, mergeRight, setPreviewTriggered, - setClickTriggered } = videoSlice.actions + cut, markAsDeletedOrAlive, markAsDeletedOrAliveByIndex, markAllAsDeleted, setSelectedWorkflowIndex, mergeLeft, + mergeRight, setPreviewTriggered, setClickTriggered } = videoSlice.actions // Export selectors // Selectors mainly pertaining to the video state From 4235cbbf977d37158c25a756e27e5574f84de910 Mon Sep 17 00:00:00 2001 From: Dennis Benz Date: Mon, 3 Jul 2023 15:15:35 +0200 Subject: [PATCH 3/7] Fix code formatting --- src/main/Timeline.tsx | 6 +++--- src/redux/videoSlice.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/Timeline.tsx b/src/main/Timeline.tsx index 408e7ffaf..a1179e901 100644 --- a/src/main/Timeline.tsx +++ b/src/main/Timeline.tsx @@ -369,13 +369,13 @@ export const SegmentsList: React.FC<{ }}>
markAsDeletedOrAlive(event, index)} onKeyDown={(event: React.KeyboardEvent) => { if (event.key === " " || event.key === "Enter") { markAsDeletedOrAlive(event, index) - }}} - onMouseDown={(event) => event.stopPropagation() } // Prevent timeline jump + } }} + onMouseDown={event => event.stopPropagation()} // Prevent timeline jump >
diff --git a/src/redux/videoSlice.ts b/src/redux/videoSlice.ts index 84f95cc3b..93119ffb4 100644 --- a/src/redux/videoSlice.ts +++ b/src/redux/videoSlice.ts @@ -346,7 +346,7 @@ const setThumbnailHelper = (state: video, id: Track["id"], uri: Track["thumbnail export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setCurrentlyAt, setCurrentlyAtInSeconds, addSegment, setAspectRatio, setHasChanges, setWaveformImages, setThumbnails, setThumbnail, removeThumbnail, - cut, markAsDeletedOrAlive, markAsDeletedOrAliveByIndex, markAllAsDeleted, setSelectedWorkflowIndex, mergeLeft, + cut, markAsDeletedOrAlive, markAsDeletedOrAliveByIndex, markAllAsDeleted, setSelectedWorkflowIndex, mergeLeft, mergeRight, setPreviewTriggered, setClickTriggered } = videoSlice.actions // Export selectors From 778b8f05cac4a08d91add6d89a82bf425ad7170e Mon Sep 17 00:00:00 2001 From: Dennis Benz Date: Mon, 4 Sep 2023 09:45:33 +0200 Subject: [PATCH 4/7] Revert "Add delete restore button to each segment of timeline" This reverts commit 03549148 --- src/i18n/locales/en-US.json | 6 +---- src/main/Timeline.tsx | 44 +++++-------------------------------- src/redux/videoSlice.ts | 8 ++----- 3 files changed, 9 insertions(+), 49 deletions(-) diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index a368730bf..3efc78cbd 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -93,11 +93,7 @@ "generateWaveform-text": "Generating Waveform", "segment-tooltip": "Segment {{segment}}", "scrubber-text-aria": "Timeline marker. {{currentTime}}. Active segment: {{segment}}. {{segmentStatus}}. Controls: {{moveLeft}} and {{moveRight}} to move the timeline marker. {{increase}} and {{decrease}} to increase/decrease the move delta.\n", - "segments-text-aria": "Segment {{index}}. {{segmentStatus}}. Start: {{start}}. End: {{end}}.\n", - "segment-delete-tooltip": "Mark this segment as to be deleted", - "segment-delete-tooltip-aria": "Delete. Mark this segment as to be deleted", - "segment-restore-tooltip": "Unmark this segment as to be deleted", - "segment-restore-tooltip-aria": "Restore. Unmark this segment as to be deleted" + "segments-text-aria": "Segment {{index}}. {{segmentStatus}}. Start: {{start}}. End: {{end}}.\n" }, "workflowConfig": { diff --git a/src/main/Timeline.tsx b/src/main/Timeline.tsx index a1179e901..6ed81d1c3 100644 --- a/src/main/Timeline.tsx +++ b/src/main/Timeline.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect, SyntheticEvent } from 'react' +import React, { useState, useRef, useEffect } from 'react' import Draggable from 'react-draggable'; @@ -7,11 +7,11 @@ import { css } from '@emotion/react' import { useSelector, useDispatch } from 'react-redux'; import { Segment, httpRequestState } from '../types' import { - selectSegments, selectActiveSegmentIndex, selectDuration, selectVideoURL, selectWaveformImages, setWaveformImages, markAsDeletedOrAliveByIndex + selectSegments, selectActiveSegmentIndex, selectDuration, selectVideoURL, selectWaveformImages, setWaveformImages } from '../redux/videoSlice' import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faBars, faSpinner, faTrash, faTrashRestore } from "@fortawesome/free-solid-svg-icons"; +import { faBars, faSpinner } from "@fortawesome/free-solid-svg-icons"; import useResizeObserver from "use-resize-observer"; @@ -23,9 +23,8 @@ import { scrubberKeyMap } from '../globalKeys'; import { useTranslation } from 'react-i18next'; import { ActionCreatorWithPayload } from '@reduxjs/toolkit'; import { RootState } from '../redux/store'; -import { selectTheme, Theme } from '../redux/themeSlice'; +import { selectTheme } from '../redux/themeSlice'; import { ThemedTooltip } from './Tooltip'; -import { basicButtonStyle } from "../cssStyles"; /** * A container for visualizing the cutting of the video, as well as for controlling @@ -196,7 +195,7 @@ export const Scrubber: React.FC<{ height: timelineHeight - 10 + 'px', // TODO: CHECK IF height: '100%', width: '1px', position: 'absolute', - zIndex: 1, + zIndex: 2, boxShadow: `${theme.boxShadow}`, display: 'flex', flexDirection: 'column', @@ -294,21 +293,12 @@ export const SegmentsList: React.FC<{ }) => { const { t } = useTranslation(); - const theme = useSelector(selectTheme); // Init redux variables - const dispatch = useDispatch() const segments = useSelector(selectSegments) const duration = useSelector(selectDuration) const activeSegmentIndex = useSelector(selectActiveSegmentIndex) - const markAsDeletedOrAlive = (event: KeyboardEvent | SyntheticEvent, index: number) => { - event.preventDefault() // Prevent page scrolling due to Space bar press - event.stopPropagation() // Prevent video playback due to Space bar press - - dispatch(markAsDeletedOrAliveByIndex(index)); - } - /** * Returns a background color based on whether the segment is to be deleted * and whether the segment is currently active @@ -335,15 +325,6 @@ export const SegmentsList: React.FC<{ } } - const markAsDeletedButtonStyle = (theme: Theme) => css({ - position: 'absolute', - right: '8px', - top: '8px', - padding: '5px', - background: `${theme.element_bg}`, - zIndex: 2, - }); - // Render the individual segments const renderedSegments = () => { return ( @@ -357,7 +338,6 @@ export const SegmentsList: React.FC<{ end: convertMsToReadableString(segment.end) })} tabIndex={tabable ? 0 : -1} css={{ - position: 'relative', background: bgColor(segment.deleted, styleByActiveSegment ? activeSegmentIndex === index : false), borderRadius: '5px', borderStyle: styleByActiveSegment ? (activeSegmentIndex === index ? 'dashed' : 'solid') : 'solid', @@ -366,20 +346,8 @@ export const SegmentsList: React.FC<{ boxSizing: 'border-box', width: ((segment.end - segment.start) / duration) * 100 + '%', height: timelineHeight - 20 + 'px', // CHECK IF 100% + zIndex: 1, }}> - -
markAsDeletedOrAlive(event, index)} - onKeyDown={(event: React.KeyboardEvent) => { if (event.key === " " || event.key === "Enter") { - markAsDeletedOrAlive(event, index) - } }} - onMouseDown={event => event.stopPropagation()} // Prevent timeline jump - > - -
-
)) diff --git a/src/redux/videoSlice.ts b/src/redux/videoSlice.ts index 93119ffb4..797e35842 100644 --- a/src/redux/videoSlice.ts +++ b/src/redux/videoSlice.ts @@ -167,10 +167,6 @@ const videoSlice = createSlice({ state.segments[state.activeSegmentIndex].deleted = !state.segments[state.activeSegmentIndex].deleted state.hasChanges = true }, - markAsDeletedOrAliveByIndex: (state, action: PayloadAction) => { - state.segments[action.payload].deleted = !state.segments[action.payload].deleted - state.hasChanges = true - }, markAllAsDeleted: state => { state.segments.forEach((segment: Segment) => { segment.deleted = true; @@ -346,8 +342,8 @@ const setThumbnailHelper = (state: video, id: Track["id"], uri: Track["thumbnail export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setCurrentlyAt, setCurrentlyAtInSeconds, addSegment, setAspectRatio, setHasChanges, setWaveformImages, setThumbnails, setThumbnail, removeThumbnail, - cut, markAsDeletedOrAlive, markAsDeletedOrAliveByIndex, markAllAsDeleted, setSelectedWorkflowIndex, mergeLeft, - mergeRight, setPreviewTriggered, setClickTriggered } = videoSlice.actions + cut, markAsDeletedOrAlive, markAllAsDeleted, setSelectedWorkflowIndex, mergeLeft, mergeRight, setPreviewTriggered, + setClickTriggered } = videoSlice.actions // Export selectors // Selectors mainly pertaining to the video state From 212ab47197bd28905a5db6640272a6c8017c0897 Mon Sep 17 00:00:00 2001 From: Dennis Benz Date: Mon, 4 Sep 2023 12:45:01 +0200 Subject: [PATCH 5/7] Change delete all button to merge all segments button Ref #1083 --- src/i18n/locales/en-US.json | 6 +++--- src/main/CuttingActions.tsx | 13 +++++++------ src/redux/videoSlice.ts | 35 +++++++++++++++++++---------------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 3efc78cbd..dd1fe8330 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -17,9 +17,9 @@ "delete-button": "Delete", "delete-restore-tooltip": "Mark or unmark the segment at the current position as to be deleted. Hotkey: {{hotkeyName}}", "delete-restore-tooltip-aria": "Delete and Restore. Mark or unmark the segment at the current position as to be deleted. Hotkey: {{hotKeyName}}.", - "delete-all-button": "Delete All", - "delete-all-tooltip": "Mark all segments as to be deleted.", - "delete-all-tooltip-aria": "Delete All. Mark all segments as to be deleted.", + "merge-all-button": "Merge All", + "merge-all-tooltip": "Combine all segments into a single segment.", + "merge-all-tooltip-aria": "Merge All. Combine all segments into a single segment.", "restore-button": "Restore", "mergeLeft-button": "Merge Left", "mergeLeft-tooltip": "Combine the currently active segment with the segment to its left. Hotkey: {{hotkeyName}}", diff --git a/src/main/CuttingActions.tsx b/src/main/CuttingActions.tsx index 03a3b78fc..1d3c3bef3 100644 --- a/src/main/CuttingActions.tsx +++ b/src/main/CuttingActions.tsx @@ -5,6 +5,7 @@ import { basicButtonStyle, flexGapReplacementStyle } from '../cssStyles' import { IconProp } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { + faArrowsLeftRightToLine, faCut, faStepBackward, faStepForward, @@ -16,7 +17,7 @@ import { css } from '@emotion/react' import { useDispatch, useSelector } from 'react-redux'; import { - cut, markAsDeletedOrAlive, selectIsCurrentSegmentAlive, mergeLeft, mergeRight, markAllAsDeleted + cut, markAsDeletedOrAlive, selectIsCurrentSegmentAlive, mergeLeft, mergeRight, mergeAll } from '../redux/videoSlice' import { GlobalHotKeys, KeySequence, KeyMapOptions } from "react-hotkeys"; import { cuttingKeyMap } from "../globalKeys"; @@ -86,11 +87,6 @@ const CuttingActions: React.FC = () => { - { tooltip={t('cuttingActions.mergeRight-tooltip', { hotkeyName: (cuttingKeyMap[handlers.mergeRight.name] as KeyMapOptions).sequence })} ariaLabelText={t('cuttingActions.mergeRight-tooltip-aria', { hotkeyName: (cuttingKeyMap[handlers.mergeRight.name] as KeyMapOptions).sequence })} /> +
{/* { - state.segments.forEach((segment: Segment) => { - segment.deleted = true; - }); - state.hasChanges = true - }, setSelectedWorkflowIndex: (state, action: PayloadAction) => { state.selectedWorkflowId = action.payload }, @@ -184,6 +178,10 @@ const videoSlice = createSlice({ mergeSegments(state, state.activeSegmentIndex, state.activeSegmentIndex + 1) state.hasChanges = true }, + mergeAll: state => { + mergeSegments(state, 0, state.segments.length - 1) + state.hasChanges = true + }, }, // For Async Requests extraReducers: builder => { @@ -264,22 +262,27 @@ export const parseSegments = (segments: Segment[], duration: number) => { } /** - * Helper function for merging two segments + * Helper function for merging segments */ -const mergeSegments = (state: video, activeSegmentIndex: number, mergeSegmentIndex: number) => { +const mergeSegments = (state: video, startSegmentIndex: number, endSegmentIndex: number) => { // Check if mergeSegmentIndex is valid - if (mergeSegmentIndex < 0 || mergeSegmentIndex > state.segments.length - 1) { + if (endSegmentIndex < 0 || endSegmentIndex > state.segments.length - 1) { return } + const minSegmentIndex = Math.min(startSegmentIndex, endSegmentIndex) + // Increase activeSegment length - state.segments[activeSegmentIndex].start = Math.min( - state.segments[activeSegmentIndex].start, state.segments[mergeSegmentIndex].start) - state.segments[activeSegmentIndex].end = Math.max( - state.segments[activeSegmentIndex].end, state.segments[mergeSegmentIndex].end) + state.segments[minSegmentIndex].start = Math.min( + state.segments[startSegmentIndex].start, state.segments[endSegmentIndex].start) + state.segments[minSegmentIndex].end = Math.max( + state.segments[startSegmentIndex].end, state.segments[endSegmentIndex].end) - // Remove the other segment - state.segments.splice(mergeSegmentIndex, 1); + // Remove the last segment and segments between + state.segments.splice( + minSegmentIndex + 1, + Math.abs(endSegmentIndex - startSegmentIndex) + ); // Update active segment updateActiveSegment(state) @@ -342,7 +345,7 @@ const setThumbnailHelper = (state: video, id: Track["id"], uri: Track["thumbnail export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setCurrentlyAt, setCurrentlyAtInSeconds, addSegment, setAspectRatio, setHasChanges, setWaveformImages, setThumbnails, setThumbnail, removeThumbnail, - cut, markAsDeletedOrAlive, markAllAsDeleted, setSelectedWorkflowIndex, mergeLeft, mergeRight, setPreviewTriggered, + cut, markAsDeletedOrAlive, setSelectedWorkflowIndex, mergeLeft, mergeRight, mergeAll, setPreviewTriggered, setClickTriggered } = videoSlice.actions // Export selectors From f34f771271534fa141e52e6828374cef475de20d Mon Sep 17 00:00:00 2001 From: Dennis Benz Date: Mon, 4 Sep 2023 15:47:30 +0200 Subject: [PATCH 6/7] Fix incorrect state inheritance during merges --- src/redux/videoSlice.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/redux/videoSlice.ts b/src/redux/videoSlice.ts index 50594e375..36df9d0a5 100644 --- a/src/redux/videoSlice.ts +++ b/src/redux/videoSlice.ts @@ -270,17 +270,15 @@ const mergeSegments = (state: video, startSegmentIndex: number, endSegmentIndex: return } - const minSegmentIndex = Math.min(startSegmentIndex, endSegmentIndex) - // Increase activeSegment length - state.segments[minSegmentIndex].start = Math.min( + state.segments[startSegmentIndex].start = Math.min( state.segments[startSegmentIndex].start, state.segments[endSegmentIndex].start) - state.segments[minSegmentIndex].end = Math.max( + state.segments[startSegmentIndex].end = Math.max( state.segments[startSegmentIndex].end, state.segments[endSegmentIndex].end) - // Remove the last segment and segments between + // Remove the end segment and segments between state.segments.splice( - minSegmentIndex + 1, + startSegmentIndex < endSegmentIndex ? startSegmentIndex + 1 : endSegmentIndex, Math.abs(endSegmentIndex - startSegmentIndex) ); From e0eccd2609a5e0bfc3d9c8967c1b37707f42a020 Mon Sep 17 00:00:00 2001 From: Dennis Benz Date: Thu, 21 Sep 2023 11:50:04 +0200 Subject: [PATCH 7/7] Fix still incorrect state inheritance during merges --- src/redux/videoSlice.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/redux/videoSlice.ts b/src/redux/videoSlice.ts index f5a5aa5da..7512131d7 100644 --- a/src/redux/videoSlice.ts +++ b/src/redux/videoSlice.ts @@ -179,7 +179,8 @@ const videoSlice = createSlice({ state.hasChanges = true }, mergeAll: state => { - mergeSegments(state, 0, state.segments.length - 1) + mergeSegments(state, state.activeSegmentIndex, 0) + mergeSegments(state, state.activeSegmentIndex, state.segments.length - 1) state.hasChanges = true }, },