feat: customise timer elements (#607)

* feat: customise timer elements
This commit is contained in:
Carlos Valente
2023-11-22 21:38:35 +01:00
committed by GitHub
parent 797a0edf57
commit bdd216d881
2 changed files with 123 additions and 52 deletions
@@ -70,7 +70,39 @@ export const CLOCK_OPTIONS: ParamField[] = [
}, },
]; ];
export const TIMER_OPTIONS: ParamField[] = [TIME_FORMAT_OPTION]; export const TIMER_OPTIONS: ParamField[] = [
TIME_FORMAT_OPTION,
{
id: 'hideClock',
title: 'Hide Time Now',
description: 'Hides the Time Now field',
type: 'boolean',
},
{
id: 'hideCards',
title: 'Hide Cards',
description: 'Hides the Now and Next cards',
type: 'boolean',
},
{
id: 'hideProgress',
title: 'Hide progress bar',
description: 'Hides the progress bar',
type: 'boolean',
},
{
id: 'hideMessage',
title: 'Hide Presenter Message',
description: 'Prevents the screen from displaying messages from the presenter',
type: 'boolean',
},
{
id: 'hideExternal',
title: 'Hide External',
description: 'Prevents the screen from displaying the external field',
type: 'boolean',
},
];
export const MINIMAL_TIMER_OPTIONS: ParamField[] = [ export const MINIMAL_TIMER_OPTIONS: ParamField[] = [
{ {
@@ -1,4 +1,5 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { AnimatePresence, motion } from 'framer-motion'; import { AnimatePresence, motion } from 'framer-motion';
import { Message, OntimeEvent, Playback, TimerMessage, TimerType, ViewSettings } from 'ontime-types'; import { Message, OntimeEvent, Playback, TimerMessage, TimerType, ViewSettings } from 'ontime-types';
@@ -11,6 +12,7 @@ import ViewParamsEditor from '../../../common/components/view-params-editor/View
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet'; import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
import { TimeManagerType } from '../../../common/models/TimeManager.type'; import { TimeManagerType } from '../../../common/models/TimeManager.type';
import { formatTime } from '../../../common/utils/time'; import { formatTime } from '../../../common/utils/time';
import { isStringBoolean } from '../../../common/utils/viewUtils';
import { useTranslation } from '../../../translation/TranslationProvider'; import { useTranslation } from '../../../translation/TranslationProvider';
import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
import { formatTimerDisplay, getTimerByType } from '../common/viewerUtils'; import { formatTimerDisplay, getTimerByType } from '../common/viewerUtils';
@@ -52,6 +54,8 @@ export default function Timer(props: TimerProps) {
const { isMirrored, pres, eventNow, eventNext, time, viewSettings, external } = props; const { isMirrored, pres, eventNow, eventNext, time, viewSettings, external } = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL); const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const { getLocalizedString } = useTranslation(); const { getLocalizedString } = useTranslation();
const [searchParams] = useSearchParams();
useEffect(() => { useEffect(() => {
document.title = 'ontime - Timer'; document.title = 'ontime - Timer';
}, []); }, []);
@@ -61,6 +65,26 @@ export default function Timer(props: TimerProps) {
return null; return null;
} }
// USER OPTIONS
const userOptions = {
hideClock: false,
hideCards: false,
hideProgress: false,
hideMessage: false,
};
const hideClock = searchParams.get('hideClock');
userOptions.hideClock = isStringBoolean(hideClock);
const hideCards = searchParams.get('hideCards');
userOptions.hideCards = isStringBoolean(hideCards);
const hideProgress = searchParams.get('hideProgress');
userOptions.hideProgress = isStringBoolean(hideProgress);
const hideMessage = searchParams.get('hideMessage');
userOptions.hideMessage = isStringBoolean(hideMessage);
const clock = formatTime(time.clock, formatOptions); const clock = formatTime(time.clock, formatOptions);
const showOverlay = pres.text !== '' && pres.visible; const showOverlay = pres.text !== '' && pres.visible;
const isPlaying = time.playback !== Playback.Pause; const isPlaying = time.playback !== Playback.Pause;
@@ -108,14 +132,18 @@ export default function Timer(props: TimerProps) {
<div className={showFinished ? `${baseClasses} stage-timer--finished` : baseClasses} data-testid='timer-view'> <div className={showFinished ? `${baseClasses} stage-timer--finished` : baseClasses} data-testid='timer-view'>
<NavigationMenu /> <NavigationMenu />
<ViewParamsEditor paramFields={TIMER_OPTIONS} /> <ViewParamsEditor paramFields={TIMER_OPTIONS} />
<div className={showOverlay ? 'message-overlay message-overlay--active' : 'message-overlay'}> {!userOptions.hideMessage && (
<div className={`message ${showBlinking ? 'blink' : ''}`}>{pres.text}</div> <div className={showOverlay ? 'message-overlay message-overlay--active' : 'message-overlay'}>
</div> <div className={`message ${showBlinking ? 'blink' : ''}`}>{pres.text}</div>
</div>
)}
<div className={`clock-container ${showClock ? '' : 'clock-container--hidden'}`}> {!userOptions.hideClock && (
<div className='label'>{getLocalizedString('common.time_now')}</div> <div className={`clock-container ${showClock ? '' : 'clock-container--hidden'}`}>
<SuperscriptTime time={clock} className='clock' /> <div className='label'>{getLocalizedString('common.time_now')}</div>
</div> <SuperscriptTime time={clock} className='clock' />
</div>
)}
<div className={timerContainerClasses}> <div className={timerContainerClasses}>
{showEndMessage ? ( {showEndMessage ? (
@@ -139,52 +167,63 @@ export default function Timer(props: TimerProps) {
</div> </div>
</div> </div>
<MultiPartProgressBar {!userOptions.hideProgress && (
className={isPlaying ? 'progress-container' : 'progress-container progress-container--paused'} <MultiPartProgressBar
now={time.current || 0} className={isPlaying ? 'progress-container' : 'progress-container progress-container--paused'}
complete={totalTime} now={time.current ?? 0}
normalColor={viewSettings.normalColor} complete={totalTime}
warning={viewSettings.warningThreshold} normalColor={viewSettings.normalColor}
warningColor={viewSettings.warningColor} warning={viewSettings.warningThreshold}
danger={viewSettings.dangerThreshold} warningColor={viewSettings.warningColor}
dangerColor={viewSettings.dangerColor} danger={viewSettings.dangerThreshold}
hidden={!showProgress} dangerColor={viewSettings.dangerColor}
/> hidden={!showProgress}
/>
)}
<AnimatePresence> {!userOptions.hideCards && (
{eventNow && !finished && ( <>
<motion.div <AnimatePresence>
className='event now' {eventNow && !finished && (
key='now' <motion.div
variants={titleVariants} className='event now'
initial='hidden' key='now'
animate='visible' variants={titleVariants}
exit='exit' initial='hidden'
> animate='visible'
<TitleCard label='now' title={eventNow.title} subtitle={eventNow.subtitle} presenter={eventNow.presenter} /> exit='exit'
</motion.div> >
)} <TitleCard
</AnimatePresence> label='now'
title={eventNow.title}
subtitle={eventNow.subtitle}
presenter={eventNow.presenter}
/>
</motion.div>
)}
</AnimatePresence>
<AnimatePresence> <AnimatePresence>
{eventNext && ( {eventNext && (
<motion.div <motion.div
className='event next' className='event next'
key='next' key='next'
variants={titleVariants} variants={titleVariants}
initial='hidden' initial='hidden'
animate='visible' animate='visible'
exit='exit' exit='exit'
> >
<TitleCard <TitleCard
label='next' label='next'
title={eventNext.title} title={eventNext.title}
subtitle={eventNext.subtitle} subtitle={eventNext.subtitle}
presenter={eventNext.presenter} presenter={eventNext.presenter}
/> />
</motion.div> </motion.div>
)} )}
</AnimatePresence> </AnimatePresence>
</>
)}
</div> </div>
); );
} }