refactor: pass events instead of derived data to titles (#493)

* refactor: pass events instead of derived data to titles
This commit is contained in:
Carlos Valente
2023-09-14 22:30:23 +02:00
committed by GitHub
parent 13eca98133
commit 9708f0bfc6
17 changed files with 178 additions and 399 deletions
@@ -5,7 +5,6 @@ import { Message } from 'ontime-types';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import { LOWER_THIRDS_OPTIONS } from '../../../common/components/view-params-editor/constants';
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import { TitleManager } from '../ViewWrapper';
import { LowerOptions } from './LowerWrapper';
@@ -13,12 +12,14 @@ import './LowerLines.scss';
interface LowerLinesProps {
lower: Message;
title: TitleManager;
heading: string;
subheading: string;
options: LowerOptions;
doShow: boolean;
}
export default function LowerLines(props: LowerLinesProps) {
const { lower, title, options } = props;
const { lower, heading, subheading, options, doShow } = props;
const [showLower, setShowLower] = useState(true);
// Unmount if fadeOut
@@ -36,8 +37,8 @@ export default function LowerLines(props: LowerLinesProps) {
}, [options.fadeOut, options.transitionIn]);
useEffect(() => {
setShowLower(title.showNow);
}, [title.showNow]);
setShowLower(doShow);
}, [doShow]);
// Format messages
const showLowerMessage = lower.text !== '' && lower.visible;
@@ -146,14 +147,14 @@ export default function LowerLines(props: LowerLinesProps) {
>
<motion.div className='title-container' variants={titleContainerVariants}>
<motion.div className='title' variants={titleVariants}>
{title.titleNow}
{heading}
</motion.div>
<div className='title-decor' />
</motion.div>
<motion.div className='subtitle-container' variants={subtitleContainerVariants}>
<div className='sub-decor' />
<motion.div className='subtitle' variants={subtitleVariants}>
{title.presenterNow}
{subheading}
</motion.div>
</motion.div>
</motion.div>
@@ -1,11 +1,10 @@
import { memo, useEffect, useState } from 'react';
import isEqual from 'react-fast-compare';
import { useSearchParams } from 'react-router-dom';
import { Message, ViewSettings } from 'ontime-types';
import { Message, OntimeEvent, ViewSettings } from 'ontime-types';
import { overrideStylesURL } from '../../../common/api/apiConstants';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
import { TitleManager } from '../ViewWrapper';
import LowerLines from './LowerLines';
@@ -17,33 +16,26 @@ export type LowerOptions = {
keyColour?: string;
fadeOut: number;
};
interface LowerProps {
title: TitleManager;
eventNow: OntimeEvent | null;
lower: Message;
viewSettings: ViewSettings;
}
// prevent triggering animation without a content change
const areEqual = (prevProps: LowerProps, nextProps: LowerProps) => {
return isEqual(prevProps.title, nextProps.title) && isEqual(prevProps.lower, nextProps.lower);
return isEqual(prevProps.eventNow?.title, nextProps.eventNow?.title) && isEqual(prevProps.lower, nextProps.lower);
};
const Lower = (props: LowerProps) => {
const { title, lower, viewSettings } = props;
const { eventNow, lower, viewSettings } = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const [searchParams] = useSearchParams();
const [titles, setTitles] = useState<TitleManager>({
titleNow: '',
titleNext: '',
subtitleNow: '',
subtitleNext: '',
presenterNow: '',
presenterNext: '',
noteNow: '',
noteNext: '',
showNow: false,
showNext: false,
});
const [heading, setHeading] = useState('');
const [subheading, setSubheading] = useState('');
const [showLower, setShowLower] = useState(false);
// Set window title
useEffect(() => {
@@ -54,28 +46,32 @@ const Lower = (props: LowerProps) => {
useEffect(() => {
// clear titles if necessary
// will trigger an animation out in the component
let timeout: NodeJS.Timeout | null = null;
if (
title?.titleNow !== titles?.titleNow ||
title?.subtitleNow !== titles?.subtitleNow ||
title?.presenterNow !== titles?.presenterNow
) {
setTitles((t) => ({ ...t, showNow: false }));
let timeout: NodeJS.Timeout;
const transitionTime = 2000;
const haveTitlesChanged = eventNow?.title !== heading || eventNow?.presenter !== subheading;
const areTitlesEmpty = !eventNow?.title && !eventNow?.presenter;
// we have new titles
if (haveTitlesChanged && !areTitlesEmpty) {
// show lower
setHeading(eventNow?.title ?? '');
setSubheading(eventNow?.presenter ?? '');
setShowLower(true);
// schedule transition out
const transitionTime = 5000;
timeout = setTimeout(() => {
setTitles(title);
setShowLower(false);
}, transitionTime);
}
return () => {
if (timeout != null) {
if (timeout) {
clearTimeout(timeout);
}
};
// eslint-disable-next-line -- we do this to keep animations
}, [title.titleNow, title.subtitleNow, title.presenterNow]);
}, [eventNow?.title, eventNow?.presenter]);
// defer rendering until we load stylesheets
if (!shouldRender) {
@@ -135,7 +131,7 @@ const Lower = (props: LowerProps) => {
}
}
return <LowerLines lower={lower} title={titles} options={options} />;
return <LowerLines lower={lower} heading={heading} subheading={subheading} options={options} doShow={showLower} />;
};
export default memo(Lower, areEqual);