diff --git a/apps/client/src/features/overview/Overview.tsx b/apps/client/src/features/overview/Overview.tsx index 181d12f1b..742d39c9e 100644 --- a/apps/client/src/features/overview/Overview.tsx +++ b/apps/client/src/features/overview/Overview.tsx @@ -116,7 +116,7 @@ function RuntimeOverview() { const { clock, offset } = useRuntimePlaybackOverview(); const offsetText = getOffsetText(offset); - const offsetClasses = offset === null ? undefined : offset > 0 ? style.behind : style.ahead; + const offsetClasses = offset === null ? undefined : offset <= 0 ? style.behind : style.ahead; return ( <> diff --git a/apps/client/src/features/overview/overviewUtils.ts b/apps/client/src/features/overview/overviewUtils.ts index f766f1709..8b74f2e75 100644 --- a/apps/client/src/features/overview/overviewUtils.ts +++ b/apps/client/src/features/overview/overviewUtils.ts @@ -38,10 +38,5 @@ export function getOffsetText(offset: MaybeNumber): string { if (offset === null) { return enDash; } - const isAhead = offset <= 0; - let offsetText = millisToString(Math.abs(offset), { fallback: enDash }); - if (offsetText !== enDash) { - offsetText = isAhead ? `+${offsetText}` : `${enDash}${offsetText}`; - } - return offsetText; + return millisToString(offset, { fallback: enDash }); } diff --git a/apps/server/src/services/__tests__/timerUtils.test.ts b/apps/server/src/services/__tests__/timerUtils.test.ts index 58524b3d7..7a83936ce 100644 --- a/apps/server/src/services/__tests__/timerUtils.test.ts +++ b/apps/server/src/services/__tests__/timerUtils.test.ts @@ -1421,19 +1421,19 @@ describe('getRuntimeOffset()', () => { } as RuntimeState; const offset = getRuntimeOffset(state); - expect(offset).toBe(50); + expect(offset).toBe(-50); }); - it('added time adds time ahead (negative offset)', () => { + it('added time adds time ahead (positive offset)', () => { const state = { eventNow: { id: '1', timeStart: 100, }, timer: { - startedAt: 150, - addedTime: 10, - current: 10, + startedAt: 150, // we started 50ms delayed + addedTime: 10, // we compensated with 10ms + current: 10, // we are 10ms into the timer }, _timer: { pausedAt: null, @@ -1444,10 +1444,10 @@ describe('getRuntimeOffset()', () => { } as RuntimeState; const offset = getRuntimeOffset(state); - expect(offset).toBe(40); + expect(offset).toBe(-40); }); - it('considers running overtime (positive offset)', () => { + it('considers running overtime (negative offset)', () => { const state = { eventNow: { id: '1', @@ -1468,10 +1468,10 @@ describe('getRuntimeOffset()', () => { } as RuntimeState; const offset = getRuntimeOffset(state); - expect(offset).toBe(10); + expect(offset).toBe(-10); }); - it('accounts for paused time', () => { + it('paused time is delayed time (negative offset)', () => { const state = { eventNow: { id: '1', @@ -1480,12 +1480,12 @@ describe('getRuntimeOffset()', () => { }, clock: 150, timer: { - startedAt: 100, - current: 25, + startedAt: 100, // started on time + current: 25, // are 25ms into it addedTime: 0, }, _timer: { - pausedAt: 125, + pausedAt: 125, // we have been paused for 25ms (see clock) }, runtime: { actualStart: 100, @@ -1493,33 +1493,19 @@ describe('getRuntimeOffset()', () => { } as RuntimeState; const offset = getRuntimeOffset(state); - expect(offset).toBe(25); + expect(offset).toBe(-25); }); - it('can only count once started', () => { + it('offset doesnt exist if we havent started', () => { const state = { clock: 78480789, eventNow: { id: 'd6a2ce', - type: 'event', - title: '', timeStart: 77400000, timeEnd: 81000000, duration: 3600000, timeStrategy: 'lock-duration', linkStart: null, - endAction: 'none', - timerType: 'count-down', - isPublic: true, - skip: false, - note: '', - colour: '', - cue: '1', - revision: 0, - timeWarning: 120000, - timeDanger: 60000, - custom: {}, - delay: 0, }, runtime: { selectedEventIndex: 0, @@ -1553,8 +1539,6 @@ describe('getRuntimeOffset()', () => { clock: 79521653, eventNow: { id: '835242', - type: 'event', - title: '', timeStart: 81000000, timeEnd: 84600000, duration: 3600000, @@ -1562,15 +1546,6 @@ describe('getRuntimeOffset()', () => { linkStart: null, endAction: 'none', timerType: 'count-down', - isPublic: true, - skip: false, - note: '', - colour: '', - cue: '2', - revision: 0, - timeWarning: 120000, - timeDanger: 60000, - custom: {}, delay: 0, }, runtime: { @@ -1597,10 +1572,10 @@ describe('getRuntimeOffset()', () => { } as RuntimeState; const offset = getRuntimeOffset(state); - expect(offset).toBe(79521653 - 81000000); + expect(offset).toBe(81000000 - 79521653); // clock - timestart }); - it('handles time-to-end', () => { + it('with time-to-end, offsets dont exist if we are not in overtime', () => { const state = { clock: 80000000, // 22:13:20 eventNow: { @@ -1652,7 +1627,7 @@ describe('getRuntimeOffset()', () => { expect(offset).toBe(0); }); - it('handles time-to-end with delays', () => { + it('with time-to-end, offset is the overtime', () => { const state = { clock: 82000000, // 22:46:40 eventNow: { @@ -1709,25 +1684,13 @@ describe('getRuntimeOffset()', () => { clock: 82000000, // 22:46:40 <--- starting 16 min after the scheduled end eventNow: { id: 'd6a2ce', - type: 'event', - title: '', timeStart: 77400000, // 21:30:00 timeEnd: 81000000, // 22:30:00 duration: 3600000, // 01:00:00 timeStrategy: TimeStrategy.LockEnd, linkStart: null, endAction: EndAction.None, - timerType: TimerType.TimeToEnd, - isPublic: true, - skip: false, - note: '', - colour: '', - cue: '1', - revision: 0, - timeWarning: 120000, - timeDanger: 60000, - custom: {}, - delay: 0, + timerType: TimerType.TimeToEnd, // <--- but this is time to end }, runtime: { selectedEventIndex: 0, diff --git a/apps/server/src/services/timerUtils.ts b/apps/server/src/services/timerUtils.ts index f146d0f3d..96e635d97 100644 --- a/apps/server/src/services/timerUtils.ts +++ b/apps/server/src/services/timerUtils.ts @@ -293,12 +293,11 @@ export const updateRoll = (state: RuntimeState) => { /** * Calculates difference between the runtime and the schedule of an event - * Positive offset is a delay - * Negative offset is time ahead - * @param state - * @returns + * Positive offset is time ahead + * Negative offset is time delayed */ export function getRuntimeOffset(state: RuntimeState): MaybeNumber { + // nothing to calculate if there are no loaded events or if we havent started if (state.eventNow === null || state.runtime.actualStart === null) { return null; } @@ -307,9 +306,10 @@ export function getRuntimeOffset(state: RuntimeState): MaybeNumber { const { timeStart, timerType } = state.eventNow; const { addedTime, current, startedAt } = state.timer; - // if we havent started, the offset is the difference to the schedule + // if we havent started, but the timer is armed + // the offset is the difference to the schedule if (startedAt === null) { - return clock - timeStart; + return timeStart - clock; } const overtime = Math.abs(Math.min(current, 0)); @@ -318,10 +318,14 @@ export function getRuntimeOffset(state: RuntimeState): MaybeNumber { return overtime; } - const startOffset = startedAt - timeStart; + const startOffset = timeStart - startedAt; const pausedTime = state._timer.pausedAt === null ? 0 : clock - state._timer.pausedAt; - return startOffset - addedTime + pausedTime + overtime; + // startOffset - difference between scheduled start and actual start + // addedTime - time added by user (positive offset) + // pausedTime - time the playback was paused (negative offset) + // overtime - how long the timer has been over-running (negative offset) + return startOffset + addedTime - pausedTime - overtime; } /** diff --git a/apps/server/src/stores/__tests__/runtimeState.test.ts b/apps/server/src/stores/__tests__/runtimeState.test.ts index 4357c8a03..3def373d3 100644 --- a/apps/server/src/stores/__tests__/runtimeState.test.ts +++ b/apps/server/src/stores/__tests__/runtimeState.test.ts @@ -161,7 +161,7 @@ describe('mutation on runtimeState', () => { newState = getState(); const firstStart = newState.clock; expect(newState.runtime.actualStart).toBe(newState.clock); - expect(newState.runtime.offset).toBe(newState.clock - event1.timeStart); + expect(newState.runtime.offset).toBe(event1.timeStart - newState.clock); expect(newState.runtime.expectedEnd).toBe(newState.runtime.offset + event2.timeEnd); // 3. Next event @@ -170,7 +170,7 @@ describe('mutation on runtimeState', () => { newState = getState(); expect(newState.runtime.actualStart).toBe(firstStart); // we are over-under, the difference between the schedule and the actual start - const delayBefore = newState.clock - event2.timeStart; + const delayBefore = event2.timeStart - newState.clock; expect(newState.runtime.offset).toBe(delayBefore); // finish is the difference between the runtime and the schedule expect(newState.runtime.expectedEnd).toBe(event2.timeEnd + newState.runtime.offset);