diff --git a/apps/client/src/features/viewers/timeline/TimelinePage.tsx b/apps/client/src/features/viewers/timeline/TimelinePage.tsx index 28cf9d9ec..c1ff38b96 100644 --- a/apps/client/src/features/viewers/timeline/TimelinePage.tsx +++ b/apps/client/src/features/viewers/timeline/TimelinePage.tsx @@ -1,25 +1,26 @@ import { useMemo } from 'react'; -import { MaybeString, OntimeEvent, ProjectData, Settings, ViewSettings } from 'ontime-types'; +import { MaybeString, OntimeEvent, ProjectData, Runtime, Settings, ViewSettings } from 'ontime-types'; import { overrideStylesURL } from '../../../common/api/constants'; import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor'; import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet'; import { useWindowTitle } from '../../../common/hooks/useWindowTitle'; import { ViewExtendedTimer } from '../../../common/models/TimeManager.type'; -import { formatTime, getDefaultFormat } from '../../../common/utils/time'; +import { formatDuration, formatTime, getDefaultFormat } from '../../../common/utils/time'; import { useTranslation } from '../../../translation/TranslationProvider'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; import Section from './timeline-section/TimelineSection'; import Timeline from './Timeline'; import { getTimelineOptions } from './timeline.options'; -import { getFormattedTimeToStart, getUpcomingEvents, useScopedRundown } from './timeline.utils'; +import { getTimeToStart, getUpcomingEvents, useScopedRundown } from './timeline.utils'; import './TimelinePage.scss'; interface TimelinePageProps { backstageEvents: OntimeEvent[]; general: ProjectData; + runtime: Runtime; selectedId: MaybeString; settings: Settings | undefined; time: ViewExtendedTimer; @@ -32,7 +33,7 @@ interface TimelinePageProps { * There is little point splitting or memoising top level elements */ export default function TimelinePage(props: TimelinePageProps) { - const { backstageEvents, general, selectedId, settings, time, viewSettings } = props; + const { backstageEvents, general, runtime, selectedId, settings, time, viewSettings } = props; const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL); // holds copy of the rundown with only relevant events const { scopedRundown, firstStart, totalDuration } = useScopedRundown(backstageEvents, selectedId); @@ -57,9 +58,26 @@ export default function TimelinePage(props: TimelinePageProps) { const dueText = getLocalizedString('timeline.due').toUpperCase(); const nextText = next !== null ? next.title : '-'; const followedByText = followedBy !== null ? followedBy.title : '-'; + let nextStatus: string | undefined; + let followedByStatus: string | undefined; - const nextStatus = next !== null ? getFormattedTimeToStart(next, time.clock, dueText) : undefined; - const followedByStatus = followedBy !== null ? getFormattedTimeToStart(followedBy, time.clock, dueText) : undefined; + if (next !== null) { + const timeToStart = getTimeToStart(time.clock, next.timeStart, next?.delay ?? 0, runtime.offset); + if (timeToStart < 0) { + nextStatus = dueText; + } else { + nextStatus = `T - ${formatDuration(timeToStart)}`; + } + } + + if (followedBy !== null) { + const timeToStart = getTimeToStart(time.clock, followedBy.timeStart, followedBy?.delay ?? 0, runtime.offset); + if (timeToStart < 0) { + followedByStatus = dueText; + } else { + followedByStatus = `T - ${formatDuration(timeToStart)}`; + } + } return (