Relative mode (#1764)

* feat: add group start time to state

* refactor: calculate expected times when offset mode changes

* feat: show relative data in ui

* fixup! feat: add group start time to state

* fixup! refactor: calculate expected times when offset mode changes

* fixup! feat: show relative data in ui

* try to handle multiday

* show planed/expected rundown end day offset values

* refactor: style tweaks to timers

* refactor: cleanup data use

* day offset

* update tests

* test getExpectedStart multiday

* write start epoch to restore file

* current day in relative mode

* remove todo

* move find day offset to utils

---------

Co-authored-by: arc-alex <ac@omnivox.dk>
This commit is contained in:
Carlos Valente
2025-09-17 11:20:14 +02:00
parent 313590905f
commit 8d2db7ffcd
24 changed files with 364 additions and 79 deletions
@@ -1,6 +1,6 @@
import { OffsetMode } from 'ontime-types';
import { dayInMs } from './conversionUtils';
import { dayInMs, MILLIS_PER_HOUR } from './conversionUtils';
import { getExpectedStart } from './getExpectedStart';
describe('getExpectedStart()', () => {
@@ -277,4 +277,41 @@ describe('getExpectedStart()', () => {
// the overlap will be pushed out to the expected available time
expect(getExpectedStart(testEvent, { ...testState, totalGap: -5 })).toBe(110);
});
test('we started on the day before', () => {
const testEvent = {
timeStart: 5,
dayOffset: 0,
delay: 0,
};
const testState = {
currentDay: -1,
actualStart: 23 * MILLIS_PER_HOUR,
plannedStart: 0,
offset: -1 * MILLIS_PER_HOUR,
mode: OffsetMode.Absolute,
isLinkedToLoaded: true,
totalGap: 0,
};
expect(getExpectedStart(testEvent, { ...testState })).toBe(23 * MILLIS_PER_HOUR + 5);
});
test('next day in multi-day rundown', () => {
const testEvent = {
timeStart: 5,
dayOffset: 1,
delay: 0,
};
const testState = {
currentDay: -1,
actualStart: 23 * MILLIS_PER_HOUR,
plannedStart: 0,
offset: -1 * MILLIS_PER_HOUR,
mode: OffsetMode.Absolute,
isLinkedToLoaded: true,
totalGap: 0,
};
expect(getExpectedStart(testEvent, { ...testState })).toBe(23 * MILLIS_PER_HOUR + 5 + dayInMs);
expect(getExpectedStart(testEvent, { ...testState, currentDay: 0 })).toBe(23 * MILLIS_PER_HOUR + 5);
});
});
@@ -15,7 +15,7 @@ import { dayInMs } from './conversionUtils.js';
export function getExpectedStart(
event: Pick<OntimeEvent, 'timeStart' | 'dayOffset' | 'delay'>,
state: {
currentDay: number;
currentDay: number; // the current day from the rundown
totalGap: number;
isLinkedToLoaded: boolean;
offset: number;
@@ -38,7 +38,7 @@ export function getExpectedStart(
let relativeStartOffset = 0;
if (mode === OffsetMode.Relative) {
relativeStartOffset = (actualStart ?? 0) - (plannedStart ?? 0);
relativeStartOffset = (actualStart ?? 0) + currentDay * dayInMs - (plannedStart ?? 0);
}
const scheduledStartTime = normalisedTimeStart + relativeStartOffset;