mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-19 14:14:17 +00:00
Expected time for views (#1798)
* refactor: use correct metadata in op view * refactor: use correct metadata in backstage view * remove uneeded test * fix: correct offset colour * refactor: use correct metadata in timline view * refactor: schedule item dont pass the whole event * chore: lint
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { cx } from '../../../common/utils/styleUtils';
|
||||
|
||||
import { getScheduledTimes } from './schedule.utils';
|
||||
import { useSchedule } from './ScheduleContext';
|
||||
import ScheduleItem from './ScheduleItem';
|
||||
|
||||
@@ -20,17 +19,20 @@ export default function Schedule({ className }: ScheduleProps) {
|
||||
return (
|
||||
<ul className={cx(['schedule', className])} ref={containerRef}>
|
||||
{events.map((event) => {
|
||||
const { timeStart, timeEnd, delay } = getScheduledTimes(event);
|
||||
|
||||
return (
|
||||
<ScheduleItem
|
||||
key={event.id}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
title={event.title}
|
||||
timeStart={event.timeStart}
|
||||
dayOffset={event.dayOffset}
|
||||
delay={event.delay}
|
||||
totalGap={event.totalGap}
|
||||
isLinkedToLoaded={event.isLinkedToLoaded}
|
||||
countToEnd={event.countToEnd}
|
||||
duration={event.duration}
|
||||
colour={event.colour}
|
||||
skip={event.skip}
|
||||
delay={delay}
|
||||
title={event.title}
|
||||
timeEnd={event.timeEnd}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -2,11 +2,12 @@ import { createContext, PropsWithChildren, RefObject, use, useEffect, useLayoutE
|
||||
import { EntryId, isOntimeEvent, OntimeEntry, OntimeEvent } from 'ontime-types';
|
||||
|
||||
import { usePartialRundown } from '../../../common/hooks-query/useRundown';
|
||||
import { ExtendedEntry } from '../../../common/utils/rundownMetadata';
|
||||
|
||||
import { useScheduleOptions } from './schedule.options';
|
||||
|
||||
interface ScheduleContextState {
|
||||
events: OntimeEvent[];
|
||||
events: ExtendedEntry<OntimeEvent>[];
|
||||
selectedEventId: string | null;
|
||||
numPages: number;
|
||||
visiblePage: number;
|
||||
@@ -21,7 +22,7 @@ interface ScheduleProviderProps {
|
||||
|
||||
export const ScheduleProvider = ({ children, selectedEventId }: PropsWithChildren<ScheduleProviderProps>) => {
|
||||
const { cycleInterval, stopCycle, filter } = useScheduleOptions();
|
||||
const { data: events } = usePartialRundown((entry: OntimeEntry) => {
|
||||
const { data: events } = usePartialRundown((entry: ExtendedEntry<OntimeEntry>) => {
|
||||
if (filter) {
|
||||
// custom keys are prepended with custom-
|
||||
const customKey = filter.startsWith('custom-') ? filter.slice('custom-'.length) : filter;
|
||||
@@ -133,7 +134,7 @@ export const ScheduleProvider = ({ children, selectedEventId }: PropsWithChildre
|
||||
return (
|
||||
<ScheduleContext
|
||||
value={{
|
||||
events: viewEvents as OntimeEvent[],
|
||||
events: viewEvents as ExtendedEntry<OntimeEvent>[],
|
||||
selectedEventId,
|
||||
numPages,
|
||||
visiblePage,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { useRuntimeOffset } from '../../../common/hooks/useSocket';
|
||||
import { OntimeEvent } from 'ontime-types';
|
||||
|
||||
import { useExpectedStartData } from '../../../common/hooks/useSocket';
|
||||
import { getOffsetState } from '../../../common/utils/offset';
|
||||
import { ExtendedEntry } from '../../../common/utils/rundownMetadata';
|
||||
import { cx } from '../../../common/utils/styleUtils';
|
||||
import { formatTime } from '../../../common/utils/time';
|
||||
import { formatTime, getExpectedTimesFromExtendedEvent } from '../../../common/utils/time';
|
||||
import SuperscriptTime from '../../../features/viewers/common/superscript-time/SuperscriptTime';
|
||||
|
||||
import { useScheduleOptions } from './schedule.options';
|
||||
@@ -13,27 +16,49 @@ const formatOptions = {
|
||||
format24: 'HH:mm',
|
||||
};
|
||||
|
||||
interface ScheduleItemProps {
|
||||
timeStart: number;
|
||||
timeEnd: number;
|
||||
title: string;
|
||||
colour?: string;
|
||||
skip?: boolean;
|
||||
delay: number;
|
||||
}
|
||||
type ScheduleItemProps = Pick<
|
||||
ExtendedEntry<OntimeEvent>,
|
||||
| 'timeStart'
|
||||
| 'dayOffset'
|
||||
| 'delay'
|
||||
| 'totalGap'
|
||||
| 'isLinkedToLoaded'
|
||||
| 'countToEnd'
|
||||
| 'duration'
|
||||
| 'colour'
|
||||
| 'skip'
|
||||
| 'title'
|
||||
| 'timeEnd'
|
||||
>;
|
||||
|
||||
export default function ScheduleItem({ timeStart, timeEnd, title, colour, skip, delay }: ScheduleItemProps) {
|
||||
export default function ScheduleItem({
|
||||
timeStart,
|
||||
dayOffset,
|
||||
delay,
|
||||
totalGap,
|
||||
isLinkedToLoaded,
|
||||
countToEnd,
|
||||
colour,
|
||||
duration,
|
||||
skip,
|
||||
title,
|
||||
timeEnd,
|
||||
}: ScheduleItemProps) {
|
||||
const { showExpected } = useScheduleOptions();
|
||||
|
||||
if (showExpected) {
|
||||
return (
|
||||
<ExpectedScheduleItem
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
title={title}
|
||||
dayOffset={dayOffset}
|
||||
delay={delay}
|
||||
totalGap={totalGap}
|
||||
isLinkedToLoaded={isLinkedToLoaded}
|
||||
countToEnd={countToEnd}
|
||||
duration={duration}
|
||||
colour={colour}
|
||||
skip={skip}
|
||||
delay={delay}
|
||||
title={title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -42,11 +67,11 @@ export default function ScheduleItem({ timeStart, timeEnd, title, colour, skip,
|
||||
return (
|
||||
<DelayedScheduleItem
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
title={title}
|
||||
delay={delay}
|
||||
colour={colour}
|
||||
skip={skip}
|
||||
delay={delay}
|
||||
timeEnd={timeEnd}
|
||||
title={title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -66,7 +91,14 @@ export default function ScheduleItem({ timeStart, timeEnd, title, colour, skip,
|
||||
);
|
||||
}
|
||||
|
||||
function DelayedScheduleItem({ timeStart, timeEnd, title, colour, skip, delay }: ScheduleItemProps) {
|
||||
function DelayedScheduleItem({
|
||||
timeStart,
|
||||
timeEnd,
|
||||
title,
|
||||
colour,
|
||||
skip,
|
||||
delay,
|
||||
}: Pick<ScheduleItemProps, 'timeStart' | 'timeEnd' | 'title' | 'colour' | 'skip' | 'delay'>) {
|
||||
const start = formatTime(timeStart, formatOptions);
|
||||
const end = formatTime(timeEnd, formatOptions);
|
||||
const delayedStart = formatTime(timeStart + delay, formatOptions);
|
||||
@@ -92,14 +124,39 @@ function DelayedScheduleItem({ timeStart, timeEnd, title, colour, skip, delay }:
|
||||
);
|
||||
}
|
||||
|
||||
function ExpectedScheduleItem({ timeStart, timeEnd, title, colour, skip, delay }: ScheduleItemProps) {
|
||||
function ExpectedScheduleItem({
|
||||
timeStart,
|
||||
dayOffset,
|
||||
delay,
|
||||
totalGap,
|
||||
isLinkedToLoaded,
|
||||
countToEnd,
|
||||
colour,
|
||||
duration,
|
||||
skip,
|
||||
title,
|
||||
}: Omit<ScheduleItemProps, 'timeEnd'>) {
|
||||
const expectedStartData = useExpectedStartData();
|
||||
const { expectedStart, expectedEnd, plannedEnd } = getExpectedTimesFromExtendedEvent(
|
||||
{
|
||||
timeStart,
|
||||
dayOffset,
|
||||
delay,
|
||||
totalGap,
|
||||
isLinkedToLoaded,
|
||||
countToEnd,
|
||||
duration,
|
||||
},
|
||||
expectedStartData,
|
||||
);
|
||||
|
||||
return (
|
||||
<li className={cx(['entry', skip && 'entry--skip'])}>
|
||||
<div className='entry-times'>
|
||||
<span className='entry-colour' style={{ backgroundColor: colour }} />
|
||||
<ExpectedTime time={timeStart} delay={delay} />
|
||||
<ExpectedTime expectedTime={expectedStart} plannedTime={timeStart} />
|
||||
→
|
||||
<ExpectedTime time={timeEnd} delay={delay} />
|
||||
<ExpectedTime expectedTime={expectedEnd} plannedTime={plannedEnd} />
|
||||
</div>
|
||||
<div className='entry-title'>{title}</div>
|
||||
</li>
|
||||
@@ -107,16 +164,12 @@ function ExpectedScheduleItem({ timeStart, timeEnd, title, colour, skip, delay }
|
||||
}
|
||||
|
||||
interface ExpectedTimeProps {
|
||||
time: number;
|
||||
delay: number;
|
||||
expectedTime: number;
|
||||
plannedTime: number;
|
||||
}
|
||||
|
||||
function ExpectedTime({ time, delay }: ExpectedTimeProps) {
|
||||
const { offset } = useRuntimeOffset();
|
||||
|
||||
const expectedOffset = offset - delay;
|
||||
const expectedTime = formatTime(time + offset, formatOptions);
|
||||
const expectedState = getOffsetState(expectedOffset);
|
||||
|
||||
return <SuperscriptTime className={`entry-times--${expectedState}`} time={expectedTime} />;
|
||||
function ExpectedTime({ expectedTime, plannedTime }: ExpectedTimeProps) {
|
||||
const timeDisplay = formatTime(expectedTime);
|
||||
const expectedState = getOffsetState(expectedTime - plannedTime);
|
||||
return <SuperscriptTime className={`entry-times--${expectedState}`} time={timeDisplay} />;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { OntimeEvent } from 'ontime-types';
|
||||
|
||||
/**
|
||||
* Gather rules for how to present scheduled times
|
||||
*/
|
||||
export function getScheduledTimes(event: OntimeEvent) {
|
||||
return {
|
||||
timeStart: event.timeStart,
|
||||
timeEnd: event.timeEnd,
|
||||
delay: event.skip ? 0 : event.delay,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user