From ba6227695107de2386313156285a3897223d169a Mon Sep 17 00:00:00 2001
From: cv <34649812+cpvalente@users.noreply.github.com>
Date: Thu, 6 Apr 2023 14:42:34 +0200
Subject: [PATCH] refactor: improve performance on EventBlock
---
.../components/buttons/TooltipActionBtn.tsx | 8 +-
.../rundown/event-block/EventBlockInner.tsx | 47 +----------
.../composite/EventBlockPlayback.tsx | 79 +++++++++++++++++++
.../composite/EventBlockTimers.tsx | 53 +++++++++----
.../rundown/quick-add-block/QuickAddBlock.tsx | 8 +-
5 files changed, 126 insertions(+), 69 deletions(-)
create mode 100644 apps/client/src/features/rundown/event-block/composite/EventBlockPlayback.tsx
diff --git a/apps/client/src/common/components/buttons/TooltipActionBtn.tsx b/apps/client/src/common/components/buttons/TooltipActionBtn.tsx
index 3fff1c293..4d0c666b6 100644
--- a/apps/client/src/common/components/buttons/TooltipActionBtn.tsx
+++ b/apps/client/src/common/components/buttons/TooltipActionBtn.tsx
@@ -10,13 +10,7 @@ export default function TooltipActionBtn(props: TooltipActionBtnProps) {
const { clickHandler, icon, size = 'xs', tooltip, openDelay = 0, className, ...rest } = props;
return (
-
+
);
}
diff --git a/apps/client/src/features/rundown/event-block/EventBlockInner.tsx b/apps/client/src/features/rundown/event-block/EventBlockInner.tsx
index a88d40e3d..d3455acaa 100644
--- a/apps/client/src/features/rundown/event-block/EventBlockInner.tsx
+++ b/apps/client/src/features/rundown/event-block/EventBlockInner.tsx
@@ -4,26 +4,21 @@ import { IoCaretDownCircle } from '@react-icons/all-files/io5/IoCaretDownCircle'
import { IoCaretUpCircle } from '@react-icons/all-files/io5/IoCaretUpCircle';
import { IoOptions } from '@react-icons/all-files/io5/IoOptions';
import { IoPeople } from '@react-icons/all-files/io5/IoPeople';
-import { IoPlay } from '@react-icons/all-files/io5/IoPlay';
import { IoPlayCircle } from '@react-icons/all-files/io5/IoPlayCircle';
import { IoPlayForwardCircle } from '@react-icons/all-files/io5/IoPlayForwardCircle';
-import { IoPlayOutline } from '@react-icons/all-files/io5/IoPlayOutline';
import { IoPlaySkipForwardCircle } from '@react-icons/all-files/io5/IoPlaySkipForwardCircle';
-import { IoReload } from '@react-icons/all-files/io5/IoReload';
-import { IoRemoveCircle } from '@react-icons/all-files/io5/IoRemoveCircle';
-import { IoRemoveCircleOutline } from '@react-icons/all-files/io5/IoRemoveCircleOutline';
import { IoStopCircle } from '@react-icons/all-files/io5/IoStopCircle';
import { IoTime } from '@react-icons/all-files/io5/IoTime';
import { EndAction, Playback, TimerType } from 'ontime-types';
import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn';
-import { setEventPlayback } from '../../../common/hooks/useSocket';
import { useEventEditorStore } from '../../../common/stores/eventEditor';
import { tooltipDelayMid } from '../../../ontimeConfig';
import EditableBlockTitle from '../common/EditableBlockTitle';
import { EventItemActions } from '../RundownEntry';
import BlockActionMenu from './composite/BlockActionMenu';
+import EventBlockPlayback from './composite/EventBlockPlayback';
import EventBlockProgressBar from './composite/EventBlockProgressBar';
import EventBlockTimers from './composite/EventBlockTimers';
@@ -104,49 +99,13 @@ const EventBlockInner = (props: EventBlockInnerProps) => {
return !renderInner ? null : (
<>
-
- : }
- {...tooltipProps}
- {...blockBtnStyle}
- clickHandler={() => actionHandler('update', { field: 'skip', value: !skip })}
- tabIndex={-1}
- disabled={selected}
- />
- }
- disabled={skip}
- {...tooltipProps}
- {...blockBtnStyle}
- clickHandler={() => setEventPlayback.loadEvent(eventId)}
- tabIndex={-1}
- />
- : }
- disabled={skip}
- {...tooltipProps}
- {...blockBtnStyle}
- clickHandler={() => setEventPlayback.startEvent(eventId)}
- backgroundColor={eventIsPlaying ? '#58A151' : undefined}
- _hover={{ backgroundColor: eventIsPlaying ? '#58A151' : undefined }}
- tabIndex={-1}
- />
-
+
diff --git a/apps/client/src/features/rundown/event-block/composite/EventBlockPlayback.tsx b/apps/client/src/features/rundown/event-block/composite/EventBlockPlayback.tsx
new file mode 100644
index 000000000..8d180e75f
--- /dev/null
+++ b/apps/client/src/features/rundown/event-block/composite/EventBlockPlayback.tsx
@@ -0,0 +1,79 @@
+import { memo } from 'react';
+import { IoPlay } from '@react-icons/all-files/io5/IoPlay';
+import { IoPlayOutline } from '@react-icons/all-files/io5/IoPlayOutline';
+import { IoReload } from '@react-icons/all-files/io5/IoReload';
+import { IoRemoveCircle } from '@react-icons/all-files/io5/IoRemoveCircle';
+import { IoRemoveCircleOutline } from '@react-icons/all-files/io5/IoRemoveCircleOutline';
+
+import TooltipActionBtn from '../../../../common/components/buttons/TooltipActionBtn';
+import { useEventAction } from '../../../../common/hooks/useEventAction';
+import { setEventPlayback } from '../../../../common/hooks/useSocket';
+import { tooltipDelayMid } from '../../../../ontimeConfig';
+
+import style from '../EventBlock.module.scss';
+
+const blockBtnStyle = {
+ size: 'sm',
+};
+
+const tooltipProps = {
+ openDelay: tooltipDelayMid,
+};
+
+interface EventBlockPlaybackProps {
+ eventId: string;
+ skip: boolean;
+ isPlaying: boolean;
+ selected: boolean;
+}
+
+const EventBlockPlayback = (props: EventBlockPlaybackProps) => {
+ const { eventId, skip, isPlaying, selected } = props;
+ const { updateEvent } = useEventAction();
+
+ const toggleSkip = () => {
+ updateEvent({ id: eventId, skip: !skip });
+ };
+
+ return (
+
+ : }
+ {...tooltipProps}
+ {...blockBtnStyle}
+ clickHandler={toggleSkip}
+ tabIndex={-1}
+ isDisabled={selected}
+ />
+ }
+ isDisabled={skip}
+ {...tooltipProps}
+ {...blockBtnStyle}
+ clickHandler={() => setEventPlayback.loadEvent(eventId)}
+ tabIndex={-1}
+ />
+ : }
+ isDisabled={skip}
+ {...tooltipProps}
+ {...blockBtnStyle}
+ clickHandler={() => setEventPlayback.startEvent(eventId)}
+ backgroundColor={isPlaying ? '#58A151' : undefined}
+ _hover={{ backgroundColor: isPlaying ? '#58A151' : undefined }}
+ tabIndex={-1}
+ />
+
+ );
+};
+
+export default memo(EventBlockPlayback);
diff --git a/apps/client/src/features/rundown/event-block/composite/EventBlockTimers.tsx b/apps/client/src/features/rundown/event-block/composite/EventBlockTimers.tsx
index ff90585d6..1d935e952 100644
--- a/apps/client/src/features/rundown/event-block/composite/EventBlockTimers.tsx
+++ b/apps/client/src/features/rundown/event-block/composite/EventBlockTimers.tsx
@@ -1,28 +1,53 @@
-import { useCallback, useState } from 'react';
+import { memo, useCallback, useState } from 'react';
+import { OntimeEvent } from 'ontime-types';
import { millisToString } from 'ontime-utils';
import TimeInput from '../../../../common/components/input/time-input/TimeInput';
+import { useEventAction } from '../../../../common/hooks/useEventAction';
import { millisToMinutes } from '../../../../common/utils/dateConfig';
-import { TimeEntryField, validateEntry } from '../../../../common/utils/timesManager';
-import { EventItemActions } from '../../RundownEntry';
+import { calculateDuration, TimeEntryField, validateEntry } from '../../../../common/utils/timesManager';
import style from '../EventBlock.module.scss';
interface EventBlockTimerProps {
+ eventId: string;
timeStart: number;
timeEnd: number;
duration: number;
delay: number;
- actionHandler: (action: EventItemActions, payload?: any) => void;
previousEnd: number;
}
-export default function EventBlockTimers(props: EventBlockTimerProps) {
- const { timeStart, timeEnd, duration, delay, actionHandler, previousEnd } = props;
+type TimeActions = 'timeStart' | 'timeEnd' | 'durationOverride';
+
+const EventBlockTimers = (props: EventBlockTimerProps) => {
+ const { eventId, timeStart, timeEnd, duration, delay, previousEnd } = props;
+ const { updateEvent } = useEventAction();
+
const [warning, setWarnings] = useState({ start: '', end: '', duration: '' });
- const delayTime = `${delay >= 0 ? '+' : '-'} ${millisToMinutes(Math.abs(delay))}`;
- const newTime = millisToString(timeStart + delay);
+ const handleSubmit = (field: TimeActions, value: number) => {
+ const newEventData: Partial = { id: eventId };
+ switch (field) {
+ case 'durationOverride': {
+ // duration defines timeEnd
+ newEventData.duration = value;
+ newEventData.timeEnd = timeStart + value;
+ break;
+ }
+ case 'timeStart': {
+ newEventData.duration = calculateDuration(value, timeEnd);
+ newEventData.timeStart = value;
+ break;
+ }
+ case 'timeEnd': {
+ newEventData.duration = calculateDuration(timeStart, value);
+ newEventData.timeEnd = value;
+ break;
+ }
+ }
+ updateEvent(newEventData);
+ };
/**
* @description Validates a time input against its pair
@@ -39,12 +64,8 @@ export default function EventBlockTimers(props: EventBlockTimerProps) {
[timeEnd, timeStart],
);
- const handleSubmit = useCallback(
- (field: TimeEntryField, value: number) => {
- actionHandler('update', { field, value });
- },
- [actionHandler],
- );
+ const delayTime = `${delay >= 0 ? '+' : '-'} ${millisToMinutes(Math.abs(delay))}`;
+ const newTime = millisToString(timeStart + delay);
return (
@@ -86,4 +107,6 @@ export default function EventBlockTimers(props: EventBlockTimerProps) {
)}
);
-}
+};
+
+export default memo(EventBlockTimers);
diff --git a/apps/client/src/features/rundown/quick-add-block/QuickAddBlock.tsx b/apps/client/src/features/rundown/quick-add-block/QuickAddBlock.tsx
index 7eb3eb95e..8fd208644 100644
--- a/apps/client/src/features/rundown/quick-add-block/QuickAddBlock.tsx
+++ b/apps/client/src/features/rundown/quick-add-block/QuickAddBlock.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useRef } from 'react';
+import { memo, useCallback, useRef } from 'react';
import { Button, Checkbox, Tooltip } from '@chakra-ui/react';
import { SupportedEvent } from 'ontime-types';
@@ -17,7 +17,7 @@ interface QuickAddBlockProps {
disableAddBlock: boolean;
}
-export default function QuickAddBlock(props: QuickAddBlockProps) {
+const QuickAddBlock = (props: QuickAddBlockProps) => {
const { showKbd, eventId, previousEventId, disableAddDelay = true, disableAddBlock } = props;
const { addEvent } = useEventAction();
const { emitError } = useEmitLog();
@@ -117,4 +117,6 @@ export default function QuickAddBlock(props: QuickAddBlockProps) {
);
-}
+};
+
+export default memo(QuickAddBlock);