import { useEffect } from '../../lib/teact/teact';
import { formatClockDuration, formatCountdownDateTime, secondsToDate } from '../../util/localization/dateFormat';
import { getServerTime } from '../../util/serverTime';
import useInterval from '../../hooks/schedulers/useInterval';
import useTimeout from '../../hooks/schedulers/useTimeout';
import useForceUpdate from '../../hooks/useForceUpdate';
import useLang from '../../hooks/useLang';
import AnimatedCounter from '../common/AnimatedCounter';
type OwnProps = {
className?: string;
endsAt: number;
mode?: 'clock' | 'countdown';
shouldShowZeroOnEnd?: boolean;
onEnd?: NoneToVoidFunction;
};
const DAY_IN_SECONDS = 24 * 60 * 60;
const UPDATE_FREQUENCY = 500; // Sometimes second gets skipped if using 1000
const TextTimer = ({
className,
endsAt,
mode = 'clock',
shouldShowZeroOnEnd,
onEnd,
}: OwnProps) => {
const forceUpdate = useForceUpdate();
const lang = useLang();
const serverTime = getServerTime();
const isActive = serverTime < endsAt;
const timeLeft = Math.max(0, endsAt - serverTime);
const shouldUseClock = mode === 'clock' || timeLeft < DAY_IN_SECONDS;
const switchToClockDelay = isActive && mode === 'countdown' && !shouldUseClock
? ((timeLeft - DAY_IN_SECONDS) * 1000) + UPDATE_FREQUENCY
: undefined;
useTimeout(forceUpdate, switchToClockDelay);
useInterval(forceUpdate, isActive && shouldUseClock ? UPDATE_FREQUENCY : undefined);
useEffect(() => {
if (!isActive) {
onEnd?.();
}
}, [isActive, onEnd]);
if (!isActive && !shouldShowZeroOnEnd) return undefined;
if (mode === 'countdown' && !shouldUseClock) {
return (
{formatCountdownDateTime(lang, secondsToDate(endsAt), {
anchorDate: secondsToDate(serverTime),
})}
);
}
const time = formatClockDuration(timeLeft);
const timeParts = time.split(':');
const clockNode = (
<>
{timeParts.map((part, index) => (
{index > 0 && ':'}
))}
>
);
return (
{mode === 'countdown'
? lang('TimeIn', { time: clockNode }, { withNodes: true })
: clockNode}
);
};
export default TextTimer;