Skip to content

Commit

Permalink
Merge pull request #417 from BinaryStudioAcademy/task/OV-415-do-not-d…
Browse files Browse the repository at this point in the history
…elete-scene-on-resize

OV-415: Do not delete scene on resize
  • Loading branch information
nikita-remeslov authored Sep 25, 2024
2 parents 8e7aad5 + 2a0c8fa commit 64c3327
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 11 deletions.
44 changes: 43 additions & 1 deletion frontend/src/bundles/studio/components/timeline/timeline.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
import { type PlayerRef } from '@remotion/player';
import { secondsToMilliseconds } from 'date-fns';
import {
type DragEndEvent,
type DragMoveEvent,
type Range,
type ResizeEndEvent,
type ResizeMoveEvent,
TimelineContext,
} from 'dnd-timeline';
import { type RefObject } from 'react';
Expand All @@ -14,7 +16,10 @@ import {
useAppSelector,
useCallback,
} from '~/bundles/common/hooks/hooks.js';
import { DND_ACTIVATION_DISTANCE_PIXELS } from '~/bundles/studio/constants/constants.js';
import {
DND_ACTIVATION_DISTANCE_PIXELS,
MIN_SCENE_DURATION,
} from '~/bundles/studio/constants/constants.js';
import { RowNames } from '~/bundles/studio/enums/row-names.enum.js';
import { actions as studioActions } from '~/bundles/studio/store/studio.js';
import { type RowType } from '~/bundles/studio/types/types.js';
Expand Down Expand Up @@ -57,6 +62,42 @@ const Timeline: React.FC<Properties> = ({ playerRef }) => {
[dispatch],
);

const handleResizing = useCallback(
(event: ResizeMoveEvent): void => {
const activeItem = event.active.data.current;
const activeItemType = activeItem['type'] as RowType;

const updatedSpan = activeItem.getSpanFromResizeEvent?.(event);

if (
!updatedSpan ||
activeItemType === RowNames.SCRIPT ||
activeItemType === RowNames.BUTTON
) {
return;
}

if (
updatedSpan.end - updatedSpan.start <
secondsToMilliseconds(MIN_SCENE_DURATION)
) {
updatedSpan.end =
updatedSpan.start +
secondsToMilliseconds(MIN_SCENE_DURATION);

const activeItemId = event.active.id as string;

dispatch(
studioActions.resizeScene({
id: activeItemId,
span: updatedSpan,
}),
);
}
},
[dispatch],
);

const handleDragMove = useCallback(
(event: DragMoveEvent) => {
const activeItem = event.active.data.current;
Expand Down Expand Up @@ -149,6 +190,7 @@ const Timeline: React.FC<Properties> = ({ playerRef }) => {
<TimelineContext
range={range}
onDragEnd={handleDragEnd}
onResizeMove={handleResizing}
onResizeEnd={handleResizeEnd}
onRangeChanged={handleRangeChanged}
onDragMove={handleDragMove}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/bundles/studio/constants/constants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export { ADD_BUTTON_PADDING_MILLISECONDS } from './add-button-padding-milliseconds.js';
export { DEFAULT_SCENE_DURATION } from './default-scene-duration.constant.js';
export { DEFAULT_SCRIPT_DURATION } from './default-script-duration.constant.js';
export { DEFAULT_VIDEO_NAME } from './default-video-name.js';
export { DEFAULT_VOICE } from './default-voice-name.constant.js';
export { DND_ACTIVATION_DISTANCE_PIXELS } from './dnd-activation-distance-pixels.constant.js';
export { GROW_COEFFICIENT } from './grow-coefficient.js';
export { MAX_SCENES_BEFORE_RESIZE } from './max-scenes-before-resize.js';
export { MIN_SCENE_DURATION } from './min-scene-duration.constant.js';
export { MIN_SCRIPT_DURATION } from './min-script-duration.constant.js';
export { NEW_SCRIPT_TEXT } from './new-script-text.constant.js';
export { SCRIPT_AND_AVATAR_ARE_REQUIRED } from './script-and-avatar-are-required.constant.js';
export { SKIP_TO_PREV_SCENE_THRESHOLD } from './skip-to-previous-scene-threshold.constant.js';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const DEFAULT_SCENE_DURATION = 15;

export { DEFAULT_SCENE_DURATION };
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const DEFAULT_SCRIPT_DURATION = 10;

export { DEFAULT_SCRIPT_DURATION };
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const MIN_SCENE_DURATION = 15;
const MIN_SCENE_DURATION = 1;

export { MIN_SCENE_DURATION };

This file was deleted.

15 changes: 10 additions & 5 deletions frontend/src/bundles/studio/store/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import {
type VideoPreview as VideoPreviewT,
} from '~/bundles/common/types/types.js';
import {
DEFAULT_SCENE_DURATION,
DEFAULT_SCRIPT_DURATION,
DEFAULT_VOICE,
MIN_SCENE_DURATION,
MIN_SCRIPT_DURATION,
} from '~/bundles/studio/constants/constants.js';

import { type MenuItems, PlayIconNames, RowNames } from '../enums/enums.js';
Expand Down Expand Up @@ -102,7 +103,7 @@ const initialState: State = {
elapsedTime: 0,
},
range: { start: 0, end: minutesToMilliseconds(1) },
scenes: [{ id: uuidv4(), duration: MIN_SCENE_DURATION }],
scenes: [{ id: uuidv4(), duration: DEFAULT_SCENE_DURATION }],
scripts: [],
selectedScriptId: null,
videoSize: VideoPreview.LANDSCAPE,
Expand All @@ -129,7 +130,7 @@ const { reducer, actions, name } = createSlice({
addScript(state, action: PayloadAction<string>) {
const script = {
id: uuidv4(),
duration: MIN_SCRIPT_DURATION,
duration: DEFAULT_SCRIPT_DURATION,
text: action.payload,
voice: DEFAULT_VOICE,
iconName: PlayIconNames.READY,
Expand Down Expand Up @@ -194,7 +195,7 @@ const { reducer, actions, name } = createSlice({
addScene(state) {
const scene = {
id: uuidv4(),
duration: MIN_SCENE_DURATION,
duration: DEFAULT_SCENE_DURATION,
};
state.ui.selectedItem = { id: scene.id, type: RowNames.SCENE };
state.scenes.push(scene);
Expand All @@ -212,7 +213,11 @@ const { reducer, actions, name } = createSlice({
return item;
}

const duration = millisecondsToSeconds(span.end - span.start);
let duration = millisecondsToSeconds(span.end - span.start);

if (duration < MIN_SCENE_DURATION) {
duration = MIN_SCENE_DURATION;
}

return {
...item,
Expand Down

0 comments on commit 64c3327

Please sign in to comment.