mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-13 03:13:47 +00:00
End pause (#832)
* refactor: trigger ahead * refactor: refresh often * fix: handle empty rundown updates * fix: handle falsy values * style: avoid overlap of components * refactor: freeze end option
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { ViewSettings } from 'ontime-types';
|
||||
|
||||
export const viewsSettingsPlaceholder: ViewSettings = {
|
||||
overrideStyles: false,
|
||||
normalColor: '#ffffffcc',
|
||||
warningColor: '#FFAB33',
|
||||
dangerColor: '#ED3333',
|
||||
endMessage: '',
|
||||
freezeEnd: false,
|
||||
normalColor: '#ffffffcc',
|
||||
overrideStyles: false,
|
||||
warningColor: '#FFAB33',
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.corner {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
right: 2rem;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,17 @@ export default function ViewSettingsForm() {
|
||||
</Panel.ListGroup>
|
||||
<Panel.ListGroup>
|
||||
<Panel.ListItem>
|
||||
<Panel.Field title='End message' description='If no end message is provided, timer will continue' />
|
||||
<Panel.Field
|
||||
title='Freeze timer on end'
|
||||
description='Timer in views will stop from going negative after reaching'
|
||||
/>
|
||||
<Switch {...register('freezeEnd')} variant='ontime' size='lg' />
|
||||
</Panel.ListItem>
|
||||
<Panel.ListItem>
|
||||
<Panel.Field
|
||||
title='End message'
|
||||
description='Message to show on negative timers if not frozen. If not provided, timer will continue'
|
||||
/>
|
||||
<Input
|
||||
size='sm'
|
||||
autoComplete='off'
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { ViewExtendedTimer } from '../../../common/models/TimeManager.type'
|
||||
|
||||
type TimerTypeParams = Pick<ViewExtendedTimer, 'timerType' | 'current' | 'elapsed' | 'clock'>;
|
||||
|
||||
export function getTimerByType(timerObject?: TimerTypeParams): number | null {
|
||||
export function getTimerByType(freezeEnd: boolean, timerObject?: TimerTypeParams): number | null {
|
||||
if (!timerObject) {
|
||||
return null;
|
||||
}
|
||||
@@ -12,7 +12,10 @@ export function getTimerByType(timerObject?: TimerTypeParams): number | null {
|
||||
switch (timerObject.timerType) {
|
||||
case TimerType.CountDown:
|
||||
case TimerType.TimeToEnd:
|
||||
return timerObject.current;
|
||||
if (timerObject.current === null) {
|
||||
return null;
|
||||
}
|
||||
return freezeEnd ? Math.max(timerObject.current, 0) : timerObject.current;
|
||||
case TimerType.CountUp:
|
||||
return Math.abs(timerObject.elapsed ?? 0);
|
||||
case TimerType.Clock:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { Playback, TimerMessage, TimerType, ViewSettings } from 'ontime-types';
|
||||
import { millisToString, removeLeadingZero, removeSeconds } from 'ontime-utils';
|
||||
import { MILLIS_PER_SECOND, millisToString, removeLeadingZero, removeSeconds } from 'ontime-utils';
|
||||
|
||||
import { overrideStylesURL } from '../../../common/api/constants';
|
||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||
@@ -150,7 +150,7 @@ export default function MinimalTimer(props: MinimalTimerProps) {
|
||||
if (!timerIsTimeOfDay && showProgress && showWarning) timerColor = viewSettings.warningColor;
|
||||
if (!timerIsTimeOfDay && showProgress && showDanger) timerColor = viewSettings.dangerColor;
|
||||
|
||||
const stageTimer = getTimerByType(time);
|
||||
const stageTimer = getTimerByType(viewSettings.freezeEnd, time);
|
||||
let display = millisToString(stageTimer, { fallback: timerPlaceholder });
|
||||
if (stageTimer !== null) {
|
||||
if (hideTimerSeconds) {
|
||||
@@ -158,7 +158,8 @@ export default function MinimalTimer(props: MinimalTimerProps) {
|
||||
}
|
||||
display = removeLeadingZero(display);
|
||||
// last unit rounds up in negative timers
|
||||
const isNegative = (stageTimer ?? 0 < 0) && !timerIsTimeOfDay && time.timerType !== TimerType.CountUp;
|
||||
const isNegative =
|
||||
(stageTimer ?? 0 < MILLIS_PER_SECOND) && !timerIsTimeOfDay && time.timerType !== TimerType.CountUp;
|
||||
if (isNegative && display === '0') {
|
||||
display = '-1';
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
TimerType,
|
||||
ViewSettings,
|
||||
} from 'ontime-types';
|
||||
import { millisToString, removeLeadingZero, removeSeconds } from 'ontime-utils';
|
||||
import { MILLIS_PER_SECOND, millisToString, removeLeadingZero, removeSeconds } from 'ontime-utils';
|
||||
|
||||
import { overrideStylesURL } from '../../../common/api/constants';
|
||||
import MultiPartProgressBar from '../../../common/components/multi-part-progress-bar/MultiPartProgressBar';
|
||||
@@ -59,6 +59,7 @@ interface TimerProps {
|
||||
|
||||
export default function Timer(props: TimerProps) {
|
||||
const { customFields, isMirrored, pres, eventNow, eventNext, time, viewSettings, external, settings } = props;
|
||||
|
||||
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
|
||||
const { getLocalizedString } = useTranslation();
|
||||
const [searchParams] = useSearchParams();
|
||||
@@ -127,7 +128,7 @@ export default function Timer(props: TimerProps) {
|
||||
if (!timerIsTimeOfDay && showProgress && showWarning) timerColor = viewSettings.warningColor;
|
||||
if (!timerIsTimeOfDay && showProgress && showDanger) timerColor = viewSettings.dangerColor;
|
||||
|
||||
const stageTimer = getTimerByType(time);
|
||||
const stageTimer = getTimerByType(viewSettings.freezeEnd, time);
|
||||
let display = millisToString(stageTimer, { fallback: timerPlaceholder });
|
||||
if (stageTimer !== null) {
|
||||
if (hideTimerSeconds) {
|
||||
@@ -135,7 +136,8 @@ export default function Timer(props: TimerProps) {
|
||||
}
|
||||
display = removeLeadingZero(display);
|
||||
// last unit rounds up in negative timers
|
||||
const isNegative = (stageTimer ?? 0 < 0) && !timerIsTimeOfDay && time.timerType !== TimerType.CountUp;
|
||||
const isNegative =
|
||||
(stageTimer ?? 0 < -MILLIS_PER_SECOND) && !timerIsTimeOfDay && time.timerType !== TimerType.CountUp;
|
||||
if (isNegative && display === '0') {
|
||||
display = '-1';
|
||||
}
|
||||
@@ -215,7 +217,7 @@ export default function Timer(props: TimerProps) {
|
||||
{!userOptions.hideCards && (
|
||||
<>
|
||||
<AnimatePresence>
|
||||
{eventNow && (
|
||||
{eventNow?.title && (
|
||||
<motion.div
|
||||
className='event now'
|
||||
key='now'
|
||||
@@ -230,7 +232,7 @@ export default function Timer(props: TimerProps) {
|
||||
</AnimatePresence>
|
||||
|
||||
<AnimatePresence>
|
||||
{eventNext && (
|
||||
{eventNext?.title && (
|
||||
<motion.div
|
||||
className='event next'
|
||||
key='next'
|
||||
|
||||
Reference in New Issue
Block a user