diff --git a/apps/client/src/features/rundown/event-block/EventBlock.tsx b/apps/client/src/features/rundown/event-block/EventBlock.tsx
index 0e005b00c..8e3fb9e85 100644
--- a/apps/client/src/features/rundown/event-block/EventBlock.tsx
+++ b/apps/client/src/features/rundown/event-block/EventBlock.tsx
@@ -242,13 +242,7 @@ export default function EventBlock(props: EventBlockProps) {
onContextMenu={onContextMenu}
id='event-block'
>
-
+
diff --git a/apps/client/src/features/rundown/event-block/EventBlock.utils.ts b/apps/client/src/features/rundown/event-block/EventBlock.utils.ts
index 6213f2f87..86ddce331 100644
--- a/apps/client/src/features/rundown/event-block/EventBlock.utils.ts
+++ b/apps/client/src/features/rundown/event-block/EventBlock.utils.ts
@@ -10,24 +10,41 @@ export function formatDelay(timeStart: number, delay: number): string | undefine
return `New start ${timeTag}`;
}
+/**
+ * Utility function checks whether a given event is the day after from its predecessor
+ * We consider an event to be the day after, if it begins before the start of the previous
+ * @example day after
+ * // 09:00 - 10:00
+ * // 08:00 - 10:30 <--- day after
+ * @example same day
+ * // 09:00 - 10:00
+ * // 09:30 - 10:30 <--- same day
+ */
+function checkIsNextDay(previousStart: number, timeStart: number): boolean {
+ return timeStart < previousStart;
+}
+
export function formatOverlap(
previousStart: MaybeNumber,
previousEnd: MaybeNumber,
timeStart: number,
- timeEnd: number,
): string | undefined {
- if (previousEnd === null) return;
+ const noPreviousElement = previousEnd === null || previousStart === null;
+ if (noPreviousElement) return;
const overlap = previousEnd - timeStart;
if (overlap === 0) return;
- if (previousStart && timeStart < previousEnd) {
- const overlap = timeEnd - previousStart;
- if (overlap > 0) {
- const overlapString = removeLeadingZero(millisToString(Math.abs(overlap)));
- return `Overlap ${overlapString}`;
- }
- const gap = timeStart + dayInMs - previousEnd;
+ const previousCrossMidnight = previousStart > previousEnd;
+ const isNextDay = previousCrossMidnight
+ ? checkIsNextDay(previousEnd, timeStart) || previousEnd == 0 // exception for when previousEnd is precisely midnight
+ : checkIsNextDay(previousStart, timeStart);
+
+ const correctedPreviousEnd = previousCrossMidnight ? previousEnd + dayInMs : previousEnd;
+
+ if (isNextDay) {
+ const gap = dayInMs - correctedPreviousEnd + timeStart;
+ if (gap === 0) return;
const gapString = removeLeadingZero(millisToString(Math.abs(gap)));
return `Gap ${gapString} (next day)`;
}
diff --git a/apps/client/src/features/rundown/event-block/RundownIndicators.tsx b/apps/client/src/features/rundown/event-block/RundownIndicators.tsx
index 5f3120cbb..9cfa7afae 100644
--- a/apps/client/src/features/rundown/event-block/RundownIndicators.tsx
+++ b/apps/client/src/features/rundown/event-block/RundownIndicators.tsx
@@ -6,16 +6,15 @@ import style from './RundownIndicators.module.scss';
interface RundownIndicatorProps {
timeStart: number;
- timeEnd: number;
previousStart: MaybeNumber;
previousEnd: MaybeNumber;
delay: number;
}
export default function RundownIndicators(props: RundownIndicatorProps) {
- const { timeStart, timeEnd, previousStart, previousEnd, delay } = props;
+ const { timeStart, previousStart, previousEnd, delay } = props;
- const hasOverlap = formatOverlap(previousStart, previousEnd, timeStart, timeEnd);
+ const hasOverlap = formatOverlap(previousStart, previousEnd, timeStart);
const hasDelay = formatDelay(timeStart, delay);
return (
diff --git a/apps/client/src/features/rundown/event-block/__tests__/EventBlock.utils.test.ts b/apps/client/src/features/rundown/event-block/__tests__/EventBlock.utils.test.ts
index ae3ff002e..cc5982646 100644
--- a/apps/client/src/features/rundown/event-block/__tests__/EventBlock.utils.test.ts
+++ b/apps/client/src/features/rundown/event-block/__tests__/EventBlock.utils.test.ts
@@ -1,3 +1,5 @@
+import { MILLIS_PER_HOUR } from 'ontime-utils';
+
import { formatDelay, formatOverlap } from '../EventBlock.utils';
describe('formatDelay()', () => {
@@ -14,35 +16,47 @@ describe('formatOverlap()', () => {
const previousStart = 0;
const previousEnd = 60000; // 1 min
const timeStart = 30000; // 30 sec
- const timeEnd = 90000; // 1:30 min
- const result = formatOverlap(previousStart, previousEnd, timeStart, timeEnd);
+ const result = formatOverlap(previousStart, previousEnd, timeStart);
expect(result).toEqual('Overlap 0:30');
});
+ it('bug #949 recognises an overlap between two times', () => {
+ const previousStart = 46800000; // 13:00:00
+ const previousEnd = 48600000; // 13:30:00
+ const timeStart = 48300000; // 13:25:00
+ const result = formatOverlap(previousStart, previousEnd, timeStart);
+ expect(result).toEqual('Overlap 5:00');
+ });
+
it('handles events the day after, without overlap', () => {
- const previousStart = new Date(0).setUTCHours(11);
- const previousEnd = new Date(0).setUTCHours(12);
- const timeStart = new Date(0).setUTCHours(6);
- const timeEnd = new Date(0).setUTCHours(10);
- const result = formatOverlap(previousStart, previousEnd, timeStart, timeEnd);
+ const previousStart = 11 * MILLIS_PER_HOUR;
+ const previousEnd = 12 * MILLIS_PER_HOUR;
+ const timeStart = 6 * MILLIS_PER_HOUR;
+ const result = formatOverlap(previousStart, previousEnd, timeStart);
expect(result).toBe('Gap 18:00:00 (next day)');
});
- it('handles events the day after, with overlap', () => {
- const previousStart = new Date(0).setUTCHours(9);
- const previousEnd = new Date(0).setUTCHours(10);
- const timeStart = new Date(0).setUTCHours(6);
- const timeEnd = new Date(0).setUTCHours(11);
- const result = formatOverlap(previousStart, previousEnd, timeStart, timeEnd);
- expect(result).toBe('Overlap 02:00:00');
- });
-
it('handles events the day after, with gap', () => {
- const previousStart = new Date(0).setUTCHours(17);
- const previousEnd = new Date(0).setUTCHours(23);
- const timeStart = new Date(0).setUTCHours(9);
- const timeEnd = new Date(0).setUTCHours(11);
- const result = formatOverlap(previousStart, previousEnd, timeStart, timeEnd);
+ const previousStart = 17 * MILLIS_PER_HOUR;
+ const previousEnd = 23 * MILLIS_PER_HOUR;
+ const timeStart = 9 * MILLIS_PER_HOUR;
+ const result = formatOverlap(previousStart, previousEnd, timeStart);
expect(result).toBe('Gap 10:00:00 (next day)');
});
+
+ it('handles events the day after, with previous ending at midnight', () => {
+ const previousStart = 23 * MILLIS_PER_HOUR; // 23:00:00
+ const previousEnd = 0; // 00:00:00
+ const timeStart = 1 * MILLIS_PER_HOUR; // 01:00:00
+ const result = formatOverlap(previousStart, previousEnd, timeStart);
+ expect(result).toBe('Gap 01:00:00 (next day)');
+ });
+
+ it('handles events the day after, with previous ending over midnight', () => {
+ const previousStart = 23 * MILLIS_PER_HOUR;
+ const previousEnd = 1 * MILLIS_PER_HOUR;
+ const timeStart = 2 * MILLIS_PER_HOUR;
+ const result = formatOverlap(previousStart, previousEnd, timeStart);
+ expect(result).toBe('Gap 01:00:00');
+ });
});