import { MaybeString, OntimeView, TimerType } from 'ontime-types';
import { useMemo } from 'react';
import { FitText } from '../../common/components/fit-text/FitText';
import MultiPartProgressBar from '../../common/components/multi-part-progress-bar/MultiPartProgressBar';
import EmptyPage from '../../common/components/state/EmptyPage';
import TitleCard from '../../common/components/title-card/TitleCard';
import ViewLogo from '../../common/components/view-logo/ViewLogo';
import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor';
import { useAutoTickingClock } from '../../common/hooks/useAutoTickingClock';
import { useTimerSocket } from '../../common/hooks/useSocket';
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
import { cx } from '../../common/utils/styleUtils';
import { formatTime, getDefaultFormat } from '../../common/utils/time';
import { useTranslation } from '../../translation/TranslationProvider';
import Loader from '../common/loader/Loader';
import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
import { getFormattedTimer, getTimerByType } from '../common/viewUtils';
import { getTimerColour } from '../utils/presentation.utils';
import { getTimerOptions, useTimerOptions } from './timer.options';
import {
getCardData,
getEstimatedFontSize,
getIsPlaying,
getSecondaryDisplay,
getShowClock,
getShowMessage,
getShowModifiers,
getShowProgressBar,
getTotalTime,
} from './timer.utils';
import { TimerData, useTimerData } from './useTimerData';
import './Timer.scss';
export default function TimerLoader() {
const { data, status } = useTimerData();
useWindowTitle('Timer');
if (status === 'pending') {
return ;
}
if (status === 'error') {
return ;
}
return ;
}
function Timer({ customFields, projectData, isMirrored, settings, viewSettings, entries }: TimerData) {
const { eventNext, eventNow, message, time, clock, timerTypeNow, countToEndNow, auxTimer } = useTimerSocket();
const {
hideClock,
hideCards,
hideProgress,
hideMessage,
hideSecondary,
hideLogo,
hideTimerSeconds,
removeLeadingZeros,
mainSource,
secondarySource,
timerType,
freezeOvertime,
freezeMessage,
hidePhase,
font,
keyColour,
timerColour,
timeformat,
} = useTimerOptions();
const { getLocalizedString } = useTranslation();
const localisedMinutes = getLocalizedString('common.minutes');
// gather modifiers
const viewTimerType = timerType ?? timerTypeNow;
const showOverlay = getShowMessage(message.timer);
const { showEndMessage, showFinished, showWarning, showDanger } = getShowModifiers(
timerTypeNow,
countToEndNow,
time.phase,
freezeOvertime,
freezeMessage,
hidePhase,
);
const isPlaying = getIsPlaying(time.playback);
const showClock = !hideClock && getShowClock(viewTimerType);
const showProgressBar = !hideProgress && getShowProgressBar(viewTimerType);
// gather card data
const { showNow, nowMain, nowSecondary, showNext, nextMain, nextSecondary } = getCardData(
eventNow,
eventNext,
mainSource,
secondarySource,
time.playback,
time.phase,
entries,
);
// gather timer data
const totalTime = getTotalTime(time.duration, time.addedTime);
const stageTimer = getTimerByType(freezeOvertime, timerTypeNow, clock, time, timerType);
const display = getFormattedTimer(stageTimer, viewTimerType, localisedMinutes, {
removeSeconds: hideTimerSeconds,
removeLeadingZero: removeLeadingZeros,
clockFormat: timeformat,
});
const currentAux = (() => {
if (message.timer.secondarySource === 'aux1') {
return auxTimer.aux1;
}
if (message.timer.secondarySource === 'aux2') {
return auxTimer.aux2;
}
if (message.timer.secondarySource === 'aux3') {
return auxTimer.aux3;
}
return null;
})();
const secondaryContent = getSecondaryDisplay(
message,
currentAux,
localisedMinutes,
hideTimerSeconds,
removeLeadingZeros,
hideSecondary,
);
// gather presentation styles
const resolvedTimerColour = getTimerColour(viewSettings, timerColour, showWarning, showDanger);
const timerFontSize = getEstimatedFontSize(display, secondaryContent);
const subduePaused = !isPlaying && viewTimerType !== TimerType.Clock;
const userStyles = {
...(keyColour && { '--timer-bg': keyColour }),
...(resolvedTimerColour && { '--timer-colour': resolvedTimerColour }),
...(font && { '--timer-font': font }),
};
// gather option data
const defaultFormat = getDefaultFormat(settings?.timeFormat);
const timerOptions = useMemo(() => getTimerOptions(defaultFormat, customFields), [customFields, defaultFormat]);
return (
{!hideLogo && projectData?.logo &&
}
{!hideMessage && (
{message.timer.text}
)}
{showClock &&
}
{showEndMessage ? (
{freezeMessage}
) : (
{display}
)}
{secondaryContent}
{showProgressBar && (
)}
{!hideCards && (
<>
{showNow &&
}
{showNext &&
}
>
)}
);
}
function TimerAutoTickingClock({ clockFormat }: { clockFormat: MaybeString }) {
const autoTickingClock = useAutoTickingClock();
const formattedClock = formatTime(autoTickingClock, { override: clockFormat });
const { getLocalizedString } = useTranslation();
return (
{getLocalizedString('common.time_now')}
);
}