fix: handle multiple days

This commit is contained in:
Carlos Valente
2024-08-28 19:00:14 +02:00
committed by Carlos Valente
parent f8ca5b9cef
commit db8ed93d41
5 changed files with 29 additions and 22 deletions
@@ -1,6 +1,6 @@
import { memo } from 'react';
import { useViewportSize } from '@mantine/hooks';
import { isOntimeEvent, MaybeNumber, OntimeEvent } from 'ontime-types';
import { isOntimeEvent, isPlayableEvent, MaybeNumber, OntimeRundown } from 'ontime-types';
import { checkIsNextDay, dayInMs, getLastEvent, MILLIS_PER_HOUR } from 'ontime-utils';
import { useTimelineOverview } from '../../../common/hooks/useSocket';
@@ -14,7 +14,7 @@ import style from './Timeline.module.scss';
interface TimelineProps {
selectedEventId: string | null;
rundown: OntimeEvent[];
rundown: OntimeRundown;
}
export default memo(Timeline);
@@ -27,15 +27,14 @@ function Timeline(props: TimelineProps) {
if (plannedStart === null || plannedEnd === null) {
return null;
}
const { lastEvent } = getLastEvent(rundown);
const startHour = getStartHour(plannedStart);
const endHour = getEndHour(plannedEnd + (lastEvent?.delay ?? 0));
let hasTimelinePassedMidnight = false;
let previousEventStartTime: MaybeNumber = null;
// we use selectedEventId as a signifier on whether the timeline is live
let eventStatus: ProgressStatus = selectedEventId ? 'done' : 'future';
let elapsedDays = 0;
return (
<div className={style.timeline}>
@@ -44,7 +43,7 @@ function Timeline(props: TimelineProps) {
<div className={style.timelineEvents}>
{rundown.map((event) => {
// for now we dont render delays and blocks
if (!isOntimeEvent(event)) {
if (!isOntimeEvent(event) || !isPlayableEvent(event)) {
return null;
}
@@ -56,17 +55,14 @@ function Timeline(props: TimelineProps) {
eventStatus = 'live';
}
if (!hasTimelinePassedMidnight) {
// we need to offset the start to account for midnight
hasTimelinePassedMidnight = previousEventStartTime !== null && event.timeStart < previousEventStartTime;
// we only need to check for next day if we have a previous event
if (
previousEventStartTime !== null &&
checkIsNextDay(previousEventStartTime, event.timeStart, event.duration)
) {
elapsedDays++;
}
// TODO: timeline must accumulate normalised time over days
const isNextDay =
previousEventStartTime !== null
? checkIsNextDay(previousEventStartTime, event.timeStart, event.duration)
: false;
const normalisedStart = hasTimelinePassedMidnight || isNextDay ? event.timeStart + dayInMs : event.timeStart;
previousEventStartTime = normalisedStart;
const normalisedStart = event.timeStart + elapsedDays * dayInMs;
const { left: elementLeftPosition, width: elementWidth } = getElementPosition(
startHour * MILLIS_PER_HOUR,
@@ -76,6 +72,9 @@ function Timeline(props: TimelineProps) {
screenWidth,
);
// prepare values for next iteration
previousEventStartTime = normalisedStart;
return (
<TimelineEntry
key={event.id}
@@ -1,4 +1,4 @@
import { isOntimeEvent, MaybeString, OntimeEvent } from 'ontime-types';
import { isOntimeEvent, MaybeString, OntimeEvent, OntimeRundown } from 'ontime-types';
import {
dayInMs,
getEventWithId,
@@ -87,7 +87,7 @@ export function getStatusLabel(timeToStart: number, status: ProgressStatus): str
return formatDuration(timeToStart);
}
export function getScopedRundown(rundown: OntimeEvent[], selectedEventId: MaybeString): OntimeEvent[] {
export function getScopedRundown(rundown: OntimeRundown, selectedEventId: MaybeString): OntimeRundown {
if (rundown.length === 0) {
return [];
}
@@ -106,7 +106,7 @@ export function getScopedRundown(rundown: OntimeEvent[], selectedEventId: MaybeS
}
if (hideBackstage) {
scopedRundown = scopedRundown.filter((event) => event.isPublic);
scopedRundown = scopedRundown.filter((event) => !isOntimeEvent(event) || event.isPublic);
}
return scopedRundown;
@@ -121,7 +121,7 @@ type UpcomingEvents = {
/**
* Returns upcoming events from current: now, next and followedBy
*/
export function getUpcomingEvents(events: OntimeEvent[], selectedId: MaybeString): UpcomingEvents {
export function getUpcomingEvents(events: OntimeRundown, selectedId: MaybeString): UpcomingEvents {
if (events.length === 0) {
return { now: null, next: null, followedBy: null };
}
+1 -1
View File
@@ -11,7 +11,7 @@ export function isOntimeEvent(event: MaybeEvent): event is OntimeEvent {
}
export function isPlayableEvent(event: OntimeEvent): event is PlayableEvent {
return !event.skip;
return !event?.skip;
}
export function isOntimeDelay(event: MaybeEvent): event is OntimeDelay {
@@ -57,4 +57,11 @@ describe('checkIsNextDay', () => {
const timeStart = 2 * MILLIS_PER_HOUR;
expect(checkIsNextDay(previousStart, timeStart, previousDuration)).toBeTruthy();
});
it('should account for normalised start over multiple days', () => {
const previousStart = 90000000; // 25:00:00
const previousDuration = 1 * MILLIS_PER_HOUR;
const timeStart = 0;
expect(checkIsNextDay(previousStart, timeStart, previousDuration)).toBeTruthy();
});
});
@@ -24,8 +24,9 @@ export function checkIsNextDay(previousStart: number, timeStart: number, previou
return false;
}
if (timeStart <= previousStart) {
const normalisedPreviousEnd = previousStart + previousDuration;
const cappedStart = previousStart % dayInMs;
if (timeStart <= cappedStart) {
const normalisedPreviousEnd = cappedStart + previousDuration;
if (normalisedPreviousEnd === dayInMs) {
return true;
}