diff --git a/apps/server/src/classes/simple-timer/SimpleTimer.ts b/apps/server/src/classes/simple-timer/SimpleTimer.ts index cc3e03fde..8ae23cb46 100644 --- a/apps/server/src/classes/simple-timer/SimpleTimer.ts +++ b/apps/server/src/classes/simple-timer/SimpleTimer.ts @@ -37,6 +37,14 @@ export class SimpleTimer { return this.state; } + public addTime(millis: number): SimpleTimerState { + this.state.duration += millis; + // the value of current will be overridden when update is called, + // but if we are in pause or stop state it will not be changed so we do it here + this.state.current += millis; + return this.state; + } + public setDirection(direction: SimpleDirection, timeNow: number): SimpleTimerState { // if we are playing, we need to reset the targets if (this.state.playback === SimplePlayback.Start) { diff --git a/apps/server/src/classes/simple-timer/__tests__/SimpleTimer.test.ts b/apps/server/src/classes/simple-timer/__tests__/SimpleTimer.test.ts index c516eb6fa..cc6c924c8 100644 --- a/apps/server/src/classes/simple-timer/__tests__/SimpleTimer.test.ts +++ b/apps/server/src/classes/simple-timer/__tests__/SimpleTimer.test.ts @@ -177,5 +177,60 @@ describe('SimpleTimer count-down', () => { playback: SimplePlayback.Start, }); }); + + test('adding time affects final result', () => { + timer.reset(); + + timer.setTime(1000); + timer.start(0); + timer.update(100); + expect(timer.state).toMatchObject({ current: 900, duration: 1000 }); + + timer.addTime(1000); + timer.update(200); + expect(timer.state).toMatchObject({ current: 1800, duration: 2000 }); + + timer.update(300); + expect(timer.state).toMatchObject({ current: 1700, duration: 2000 }); + + timer.stop(); + expect(timer.state).toMatchObject({ current: 1000, duration: 1000 }); + }); + + test('adding time affects paused timer', () => { + timer.reset(); + + timer.setTime(1000); + timer.start(0); + timer.update(100); + expect(timer.state).toMatchObject({ current: 900, duration: 1000 }); + + timer.pause(200); + expect(timer.state).toMatchObject({ current: 900, duration: 1000 }); + + timer.addTime(1000); + timer.update(200); + expect(timer.state).toMatchObject({ current: 1900, duration: 2000 }); + + timer.start(300); + expect(timer.state).toMatchObject({ current: 1800, duration: 2000 }); + }); + + test('adding time affects stopped timer, but returns to initial valuses when stopped again', () => { + timer.reset(); + + timer.setTime(1000); + expect(timer.state).toMatchObject({ current: 1000, duration: 1000 }); + + timer.addTime(1000); + expect(timer.state).toMatchObject({ current: 2000, duration: 2000 }); + + timer.start(0); + timer.update(100); + expect(timer.state).toMatchObject({ current: 1900, duration: 2000 }); + + timer.stop(); + expect(timer.state).toMatchObject({ current: 1000, duration: 1000 }); + }); }); }); diff --git a/apps/server/src/services/aux-timer-service/AuxTimerService.ts b/apps/server/src/services/aux-timer-service/AuxTimerService.ts index 396d4cb3b..e0b4c59e5 100644 --- a/apps/server/src/services/aux-timer-service/AuxTimerService.ts +++ b/apps/server/src/services/aux-timer-service/AuxTimerService.ts @@ -1,4 +1,4 @@ -import { SimpleDirection, SimpleTimerState } from 'ontime-types'; +import { SimpleDirection, SimplePlayback, SimpleTimerState } from 'ontime-types'; import { SimpleTimer } from '../../classes/simple-timer/SimpleTimer.js'; import { eventStore } from '../../stores/EventStore.js'; @@ -59,7 +59,11 @@ export class AuxTimerService { @broadcastReturn addTime(millis: number) { - return this.timer.setTime(this.timer.state.current + millis); + if (this.timer.state.playback === SimplePlayback.Start) { + this.timer.addTime(millis); + return this.timer.update(this.getTime()); + } + return this.timer.addTime(millis); } @broadcastReturn