mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 06:59:09 +00:00
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user