mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-13 19:33:46 +00:00
Invert overtime (#1715)
* refactor: invert offset calculation * chore: update tests * chore: flip offset in UI * fix seconds display on group target duration * update comment * fix rebase
This commit is contained in:
committed by
Carlos Valente
parent
4665f9c2f7
commit
e0149c1cbf
@@ -742,7 +742,7 @@ describe('getRuntimeOffset()', () => {
|
||||
} as RuntimeState;
|
||||
|
||||
const { offsetAbs } = getRuntimeOffset(state);
|
||||
expect(offsetAbs).toBe(-50);
|
||||
expect(offsetAbs).toBe(50);
|
||||
});
|
||||
|
||||
it('added time subtracts time offset (positive offset)', () => {
|
||||
@@ -766,7 +766,7 @@ describe('getRuntimeOffset()', () => {
|
||||
} as RuntimeState;
|
||||
|
||||
const { offsetAbs } = getRuntimeOffset(state);
|
||||
expect(offsetAbs).toBe(-60);
|
||||
expect(offsetAbs).toBe(60);
|
||||
});
|
||||
|
||||
it('considers running overtime (negative offset)', () => {
|
||||
@@ -791,7 +791,7 @@ describe('getRuntimeOffset()', () => {
|
||||
} as RuntimeState;
|
||||
|
||||
const { offsetAbs } = getRuntimeOffset(state);
|
||||
expect(offsetAbs).toBe(-10);
|
||||
expect(offsetAbs).toBe(10);
|
||||
});
|
||||
|
||||
it('paused time is delayed time (negative offset)', () => {
|
||||
@@ -817,7 +817,7 @@ describe('getRuntimeOffset()', () => {
|
||||
} as RuntimeState;
|
||||
|
||||
const { offsetAbs } = getRuntimeOffset(state);
|
||||
expect(offsetAbs).toBe(-25);
|
||||
expect(offsetAbs).toBe(25);
|
||||
});
|
||||
|
||||
it('offset doesnt exist if we havent started', () => {
|
||||
@@ -857,46 +857,6 @@ describe('getRuntimeOffset()', () => {
|
||||
expect(offsetAbs).toBe(0);
|
||||
});
|
||||
|
||||
it('handles loaded event', () => {
|
||||
const state = {
|
||||
clock: 79521653,
|
||||
eventNow: {
|
||||
id: '835242',
|
||||
timeStart: 81000000,
|
||||
timeEnd: 84600000,
|
||||
duration: 3600000,
|
||||
timeStrategy: 'lock-duration',
|
||||
linkStart: false,
|
||||
endAction: 'none',
|
||||
timerType: 'count-down',
|
||||
delay: 0,
|
||||
},
|
||||
runtime: {
|
||||
selectedEventIndex: 1,
|
||||
numEvents: 2,
|
||||
offsetAbs: -81000000,
|
||||
plannedStart: 77400000,
|
||||
plannedEnd: 84600000,
|
||||
actualStart: 79443403,
|
||||
expectedEnd: null,
|
||||
},
|
||||
timer: {
|
||||
addedTime: 0,
|
||||
current: 3600000,
|
||||
duration: 3600000,
|
||||
elapsed: null,
|
||||
expectedFinish: null,
|
||||
playback: 'armed',
|
||||
secondaryTimer: null,
|
||||
startedAt: null,
|
||||
},
|
||||
_timer: { pausedAt: null },
|
||||
} as RuntimeState;
|
||||
|
||||
const { offsetAbs } = getRuntimeOffset(state);
|
||||
expect(offsetAbs).toBe(81000000 - 79521653); // clock - timestart
|
||||
});
|
||||
|
||||
it('with time-to-end, offsets dont exist if we are not in overtime', () => {
|
||||
const state = {
|
||||
clock: 80000000, // 22:13:20
|
||||
@@ -996,7 +956,7 @@ describe('getRuntimeOffset()', () => {
|
||||
} as RuntimeState;
|
||||
|
||||
const { offsetAbs } = getRuntimeOffset(state);
|
||||
expect(offsetAbs).toBe(-400000); // <--- offset is always the overtime
|
||||
expect(offsetAbs).toBe(400000); // <--- offset is always the overtime
|
||||
});
|
||||
|
||||
it('handles time-to-end started after the end time', () => {
|
||||
@@ -1038,8 +998,8 @@ describe('getRuntimeOffset()', () => {
|
||||
const updateCurrent = getCurrent(state);
|
||||
state.timer.current = updateCurrent;
|
||||
const { offsetAbs } = getRuntimeOffset(state);
|
||||
expect(millisToString(offsetAbs)).toBe('-00:16:40');
|
||||
expect(offsetAbs).toBe(81000000 - 82000000); // <-- planned end - now
|
||||
expect(millisToString(offsetAbs)).toBe('00:16:40');
|
||||
expect(offsetAbs).toBe(82000000 - 81000000); // <-- now - planned end
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1089,7 +1049,7 @@ describe('getoffsetRel()', () => {
|
||||
} as RuntimeState;
|
||||
|
||||
const { offsetAbs, offsetRel } = getRuntimeOffset(state);
|
||||
expect(offsetAbs).toBe(-50);
|
||||
expect(offsetAbs).toBe(50);
|
||||
expect(offsetRel).toBe(0);
|
||||
});
|
||||
it('relative offset is 0 when starting before the planed time', () => {
|
||||
@@ -1113,7 +1073,7 @@ describe('getoffsetRel()', () => {
|
||||
} as RuntimeState;
|
||||
|
||||
const { offsetAbs, offsetRel } = getRuntimeOffset(state);
|
||||
expect(offsetAbs).toBe(50);
|
||||
expect(offsetAbs).toBe(-50);
|
||||
expect(offsetRel).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,57 +109,44 @@ export function skippedOutOfEvent(state: RuntimeState, previousTime: number, ski
|
||||
|
||||
/**
|
||||
* Calculates difference between the runtime and the schedule of an event
|
||||
* Positive offset is time ahead
|
||||
* Negative offset is time delayed
|
||||
* Positive offset is over time / behind schedule
|
||||
* Negative offset is under time / ahead of schedule
|
||||
*/
|
||||
export function getRuntimeOffset(state: RuntimeState): { offsetAbs: number; offsetRel: number } {
|
||||
const { eventNow, clock } = state;
|
||||
const { addedTime, current, startedAt } = state.timer;
|
||||
// nothing to calculate if there are no loaded events or if we havent started
|
||||
if (state.eventNow === null || state.runtime.actualStart === null) {
|
||||
if (eventNow === null || startedAt === null) {
|
||||
return { offsetAbs: 0, offsetRel: 0 };
|
||||
}
|
||||
|
||||
const { clock } = state;
|
||||
const { countToEnd, timeStart } = state.eventNow;
|
||||
const { addedTime, current, startedAt } = state.timer;
|
||||
const { actualStart, plannedStart } = state.runtime;
|
||||
const { countToEnd, timeStart } = eventNow;
|
||||
const { plannedStart, actualStart } = state.runtime;
|
||||
|
||||
// eslint-disable-next-line no-unused-labels -- dev code path
|
||||
DEV: {
|
||||
// we know current exists as long as eventNow exists
|
||||
if (current === null) throw new Error('timerUtils.getRuntimeOffset: state.timer.current must be set');
|
||||
if (plannedStart === null) throw new Error('timerUtils.getRuntimeOffset: state.runtime.plannedStart must be set');
|
||||
if (actualStart === null) throw new Error('timerUtils.getRuntimeOffset: state.runtime.actualStart must be set');
|
||||
}
|
||||
|
||||
// if we havent started, but the timer is armed
|
||||
// the offset is the difference to the schedule
|
||||
if (startedAt === null) {
|
||||
return { offsetAbs: timeStart - clock, offsetRel: 0 };
|
||||
}
|
||||
// difference between planned event start and actual event start (will be positive if we stared behind )
|
||||
const eventStartOffset = startedAt - timeStart;
|
||||
|
||||
const overtime = Math.min(current, 0);
|
||||
// in time-to-end, offset is overtime
|
||||
// how long has the event been running over (is a negative number when in over timer so inverted before adding to offset)
|
||||
const overtime = Math.abs(Math.min(current, 0));
|
||||
|
||||
const startOffset = timeStart - startedAt;
|
||||
// time the playback was paused, the different from now to when we paused is added to the offset TODO: brakes when crossing midnight
|
||||
const pausedTime = state._timer.pausedAt === null ? 0 : clock - state._timer.pausedAt;
|
||||
|
||||
// startOffset - difference between scheduled start and actual start
|
||||
// addedTime - time added by user (negative offset)
|
||||
// pausedTime - time the playback was paused (negative offset)
|
||||
// overtime - how long the timer has been over-running (negative offset)
|
||||
const offset = startOffset - addedTime - pausedTime + overtime;
|
||||
const offsetAbs = eventStartOffset + overtime + pausedTime + addedTime;
|
||||
|
||||
// offset between planned rundown start and actual rundown start
|
||||
const rundownStartOffset = actualStart - plannedStart;
|
||||
// the relative offset i the same as the absolute offset but adjusted relative to the actual start time
|
||||
const offsetRel = offsetAbs + plannedStart - actualStart;
|
||||
|
||||
// offset offset relative to the actual rundown start
|
||||
const offsetRel = offset + rundownStartOffset;
|
||||
|
||||
// in time-to-end, offset is overtime
|
||||
if (countToEnd) {
|
||||
return { offsetAbs: overtime, offsetRel };
|
||||
}
|
||||
|
||||
return { offsetAbs: offset, offsetRel };
|
||||
// in case of count to end, the absolute offset is just the overtime
|
||||
return countToEnd ? { offsetAbs: overtime, offsetRel } : { offsetAbs, offsetRel };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user