mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 06:29:07 +00:00
refactor: improve performance on EventBlock
This commit is contained in:
@@ -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 : (
|
||||
<>
|
||||
<div className={style.playbackActions}>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Skip event'
|
||||
tooltip='Skip event'
|
||||
icon={skip ? <IoRemoveCircle /> : <IoRemoveCircleOutline />}
|
||||
{...tooltipProps}
|
||||
{...blockBtnStyle}
|
||||
clickHandler={() => actionHandler('update', { field: 'skip', value: !skip })}
|
||||
tabIndex={-1}
|
||||
disabled={selected}
|
||||
/>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Load event'
|
||||
tooltip='Load event'
|
||||
icon={<IoReload className={style.flip} />}
|
||||
disabled={skip}
|
||||
{...tooltipProps}
|
||||
{...blockBtnStyle}
|
||||
clickHandler={() => setEventPlayback.loadEvent(eventId)}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Start event'
|
||||
tooltip='Start event'
|
||||
icon={eventIsPlaying ? <IoPlay /> : <IoPlayOutline />}
|
||||
disabled={skip}
|
||||
{...tooltipProps}
|
||||
{...blockBtnStyle}
|
||||
clickHandler={() => setEventPlayback.startEvent(eventId)}
|
||||
backgroundColor={eventIsPlaying ? '#58A151' : undefined}
|
||||
_hover={{ backgroundColor: eventIsPlaying ? '#58A151' : undefined }}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</div>
|
||||
<EventBlockPlayback eventId={eventId} skip={skip} isPlaying={eventIsPlaying} selected={selected} />
|
||||
<EventBlockTimers
|
||||
eventId={eventId}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
duration={duration}
|
||||
delay={delay}
|
||||
actionHandler={actionHandler}
|
||||
previousEnd={previousEnd}
|
||||
/>
|
||||
<EditableBlockTitle title={title} eventId={eventId} placeholder='Event title' className={style.eventTitle} />
|
||||
|
||||
@@ -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 (
|
||||
<div className={style.playbackActions}>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Skip event'
|
||||
tooltip='Skip event'
|
||||
icon={skip ? <IoRemoveCircle /> : <IoRemoveCircleOutline />}
|
||||
{...tooltipProps}
|
||||
{...blockBtnStyle}
|
||||
clickHandler={toggleSkip}
|
||||
tabIndex={-1}
|
||||
isDisabled={selected}
|
||||
/>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Load event'
|
||||
tooltip='Load event'
|
||||
icon={<IoReload className={style.flip} />}
|
||||
isDisabled={skip}
|
||||
{...tooltipProps}
|
||||
{...blockBtnStyle}
|
||||
clickHandler={() => setEventPlayback.loadEvent(eventId)}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Start event'
|
||||
tooltip='Start event'
|
||||
icon={isPlaying ? <IoPlay /> : <IoPlayOutline />}
|
||||
isDisabled={skip}
|
||||
{...tooltipProps}
|
||||
{...blockBtnStyle}
|
||||
clickHandler={() => setEventPlayback.startEvent(eventId)}
|
||||
backgroundColor={isPlaying ? '#58A151' : undefined}
|
||||
_hover={{ backgroundColor: isPlaying ? '#58A151' : undefined }}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(EventBlockPlayback);
|
||||
@@ -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<OntimeEvent> = { 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 (
|
||||
<div className={style.eventTimers}>
|
||||
@@ -86,4 +107,6 @@ export default function EventBlockTimers(props: EventBlockTimerProps) {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default memo(EventBlockTimers);
|
||||
|
||||
@@ -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) {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default memo(QuickAddBlock);
|
||||
|
||||
Reference in New Issue
Block a user