diff --git a/client/src/features/viewers/timer/MinimalTimer.jsx b/client/src/features/viewers/timer/MinimalTimer.jsx
index 30d32a4f1..e7a36d2f4 100644
--- a/client/src/features/viewers/timer/MinimalTimer.jsx
+++ b/client/src/features/viewers/timer/MinimalTimer.jsx
@@ -18,11 +18,7 @@ export default function MinimalTimer(props) {
return (
-
+
@@ -30,7 +26,7 @@ export default function MinimalTimer(props) {
style={{ fontSize: `${89 / (clean.length - 1)}vw` }}
className={isPlaying ? style.timer : style.timerPaused}
>
- {time.running < 0 ? `-${timer}` : timer}
+ {time.isNegative ? `-${timer}` : timer}
);
diff --git a/client/src/features/viewers/timer/Timer.jsx b/client/src/features/viewers/timer/Timer.jsx
index fbf92b04f..1672394be 100644
--- a/client/src/features/viewers/timer/Timer.jsx
+++ b/client/src/features/viewers/timer/Timer.jsx
@@ -37,7 +37,11 @@ export default function Timer(props) {
// show timer if end message is empty
const endMessage =
general.endMessage == null || general.endMessage === '' ? (
-
+
) : (
general.endMessage
);
diff --git a/server/src/classes/EventTimer.js b/server/src/classes/EventTimer.js
index 4684ed7ff..72701aa8a 100644
--- a/server/src/classes/EventTimer.js
+++ b/server/src/classes/EventTimer.js
@@ -1,11 +1,6 @@
import { Timer } from './Timer.js';
import { Server } from 'socket.io';
-import {
- DAY_TO_MS,
- getSelectionByRoll,
- replacePlaceholder,
- updateRoll,
-} from './classUtils.js';
+import { DAY_TO_MS, getSelectionByRoll, replacePlaceholder, updateRoll } from './classUtils.js';
import { OSCIntegration } from './integrations/Osc.js';
import { HTTPIntegration } from './integrations/Http.js';
import { cleanURL } from '../utils/url.js';
@@ -90,10 +85,7 @@ export class EventTimer extends Timer {
});
// set recurrent emits
- this._interval = setInterval(
- () => this.runCycle(),
- timerConfig?.refresh || 1000
- );
+ this._interval = setInterval(() => this.runCycle(), timerConfig?.refresh || 1000);
// listen to new connections
this._listenToConnections();
@@ -306,10 +298,7 @@ export class EventTimer extends Timer {
// _finish at is only set when an event is loaded
if (this._finishAt > 0) {
this.sendOsc(this.osc.implemented.play);
- this.sendOsc(
- this.osc.implemented.eventNumber,
- this.selectedEventIndex || 0
- );
+ this.sendOsc(this.osc.implemented.eventNumber, this.selectedEventIndex || 0);
}
// check integrations - http
if (h?.onLoad?.enabled) {
@@ -330,18 +319,9 @@ export class EventTimer extends Timer {
if (this.state === 'start' || this.state === 'roll') {
if (this.current != null && this.secondaryTimer == null) {
this.sendOsc(this.osc.implemented.time, this.timeTag);
- this.sendOsc(
- this.osc.implemented.overtime,
- this.current > 0 ? 0 : 1
- );
- this.sendOsc(
- this.osc.implemented.title,
- this.titles?.titleNow || ''
- );
- this.sendOsc(
- this.osc.implemented.presenter,
- this.titles?.presenterNow || ''
- );
+ this.sendOsc(this.osc.implemented.overtime, this.current > 0 ? 0 : 1);
+ this.sendOsc(this.osc.implemented.title, this.titles?.titleNow || '');
+ this.sendOsc(this.osc.implemented.presenter, this.titles?.presenterNow || '');
}
}
@@ -474,17 +454,13 @@ export class EventTimer extends Timer {
selectedEventId: this.selectedEventId,
current: this.current,
// safeguard on midnight rollover
- _finishAt:
- this._finishAt >= this._startedAt
- ? this._finishAt
- : this._finishAt + DAY_TO_MS,
+ _finishAt: this._finishAt >= this._startedAt ? this._finishAt : this._finishAt + DAY_TO_MS,
clock: this.clock,
secondaryTimer: this.secondaryTimer,
_secondaryTarget: this._secondaryTarget,
};
- const { updatedTimer, updatedSecondaryTimer, doRollLoad, isFinished } =
- updateRoll(u);
+ const { updatedTimer, updatedSecondaryTimer, doRollLoad, isFinished } = updateRoll(u);
this.current = updatedTimer;
this.secondaryTimer = updatedSecondaryTimer;
@@ -560,9 +536,7 @@ export class EventTimer extends Timer {
// keep track of connections
this._numClients++;
this._clientNames[socket.id] = getRandomName();
- const m = `${this._numClients} Clients with new connection: ${
- this._clientNames[socket.id]
- }`;
+ const m = `${this._numClients} Clients with new connection: ${this._clientNames[socket.id]}`;
this.info('CLIENT', m);
// send state
@@ -579,9 +553,7 @@ export class EventTimer extends Timer {
/********************************/
socket.on('disconnect', () => {
this._numClients--;
- const m = `${this._numClients} Clients with disconnection: ${
- this._clientNames[socket.id]
- }`;
+ const m = `${this._numClients} Clients with disconnection: ${this._clientNames[socket.id]}`;
delete this._clientNames[socket.id];
this.info('CLIENT', m);
});
@@ -807,9 +779,7 @@ export class EventTimer extends Timer {
} else if (this.selectedEventId != null) {
// handle reload selected
// Look for event (order might have changed)
- const eventIndex = this._eventlist.findIndex(
- (e) => e.id === this.selectedEventId
- );
+ const eventIndex = this._eventlist.findIndex((e) => e.id === this.selectedEventId);
// Maybe is missing
if (eventIndex === -1) {
@@ -849,10 +819,7 @@ export class EventTimer extends Timer {
if (e.id === this.selectedEventId) {
// handle reload selected
// Reload data if running
- let type =
- this.selectedEventId === id && this._startedAt != null
- ? 'reload'
- : 'load';
+ let type = this.selectedEventId === id && this._startedAt != null ? 'reload' : 'load';
this.loadEvent(this.selectedEventIndex, type);
} else if (e.id === this.nextEventId) {
// roll needs to recalculate
@@ -898,9 +865,7 @@ export class EventTimer extends Timer {
}
// update selected event index
- this.selectedEventIndex = this._eventlist.findIndex(
- (e) => e.id === this.selectedEventId
- );
+ this.selectedEventIndex = this._eventlist.findIndex((e) => e.id === this.selectedEventId);
// reload titles if necessary
if (eventId === this.nextEventId || eventId === this.nextPublicEventId) {
@@ -1005,10 +970,7 @@ export class EventTimer extends Timer {
// iterate backwards to find it
for (let i = this.selectedEventIndex; i >= 0; i--) {
- if (
- this._eventlist[i].type === 'event' &&
- this._eventlist[i].isPublic
- ) {
+ if (this._eventlist[i].type === 'event' && this._eventlist[i].isPublic) {
this._loadThisTitles(this._eventlist[i], 'now-public');
break;
}
@@ -1221,15 +1183,8 @@ export class EventTimer extends Timer {
this._resetSelection();
}
- const {
- nowIndex,
- nowId,
- publicIndex,
- nextIndex,
- publicNextIndex,
- timers,
- timeToNext,
- } = getSelectionByRoll(this._eventlist, now);
+ const { nowIndex, nowId, publicIndex, nextIndex, publicNextIndex, timers, timeToNext } =
+ getSelectionByRoll(this._eventlist, now);
// nothing to play, unload
if (nowIndex === null && nextIndex === null) {
@@ -1334,8 +1289,7 @@ export class EventTimer extends Timer {
// change playstate
this.pause();
- const gotoEvent =
- this.selectedEventIndex > 0 ? this.selectedEventIndex - 1 : 0;
+ const gotoEvent = this.selectedEventIndex > 0 ? this.selectedEventIndex - 1 : 0;
if (gotoEvent === this.selectedEventIndex) return;
this.loadEvent(gotoEvent);
diff --git a/server/src/classes/Timer.js b/server/src/classes/Timer.js
index fd1d61d50..f8ee8f5b7 100644
--- a/server/src/classes/Timer.js
+++ b/server/src/classes/Timer.js
@@ -50,8 +50,7 @@ export class Timer {
if (this._startedAt == null) this._startedAt = now;
// update current timer
- this.current =
- this._startedAt + this.duration + this._pausedTotal - now;
+ this.current = this._startedAt + this.duration + this._pausedTotal - now;
// enable flag
checkFinish = true;
@@ -93,8 +92,8 @@ export class Timer {
// helpers
static toSeconds(millis) {
- if (millis == null) return null;
- return Math.ceil(millis * 0.001);
+ if (millis == null) return 0;
+ return millis < 0 ? Math.ceil(millis * 0.001) : Math.floor(millis * 0.001);
}
// get current time in epoc
@@ -151,6 +150,7 @@ export class Timer {
getTimeObject() {
return {
clock: this.clock,
+ isNegative: this.current < 0,
running: Timer.toSeconds(this.current),
secondary: Timer.toSeconds(this.secondaryTimer),
durationSeconds: Timer.toSeconds(this.duration),
diff --git a/server/src/classes/__tests__/timer.test.js b/server/src/classes/__tests__/timer.test.js
index 7d27f817c..7ff7ade44 100644
--- a/server/src/classes/__tests__/timer.test.js
+++ b/server/src/classes/__tests__/timer.test.js
@@ -1,4 +1,4 @@
-import {Timer} from "../Timer";
+import { Timer } from '../Timer';
test('object instantiates correctly', () => {
const t = new Timer();
@@ -21,15 +21,15 @@ test('object instantiates correctly', () => {
test('convert between mills and seconds correctly', () => {
expect(Timer.toSeconds(10000)).toBe(10);
- expect(Timer.toSeconds(9016)).toBe(10);
- expect(Timer.toSeconds(8016)).toBe(9);
- expect(Timer.toSeconds(7010)).toBe(8);
- expect(Timer.toSeconds(6006)).toBe(7);
- expect(Timer.toSeconds(4999)).toBe(5);
- expect(Timer.toSeconds(2995)).toBe(3);
- expect(Timer.toSeconds(1991)).toBe(2);
- expect(Timer.toSeconds(992)).toBe(1);
- expect(Timer.toSeconds(127)).toBe(1);
+ expect(Timer.toSeconds(9016)).toBe(9);
+ expect(Timer.toSeconds(8016)).toBe(8);
+ expect(Timer.toSeconds(7010)).toBe(7);
+ expect(Timer.toSeconds(6006)).toBe(6);
+ expect(Timer.toSeconds(4999)).toBe(4);
+ expect(Timer.toSeconds(2995)).toBe(2);
+ expect(Timer.toSeconds(1991)).toBe(1);
+ expect(Timer.toSeconds(992)).toBe(0);
+ expect(Timer.toSeconds(127)).toBe(0);
expect(Timer.toSeconds(0)).toBe(0);
expect(Timer.toSeconds(-0)).toBe(-0);
expect(Timer.toSeconds(-127)).toBe(-0);
@@ -41,4 +41,14 @@ test('convert between mills and seconds correctly', () => {
expect(Timer.toSeconds(-7010)).toBe(-7);
expect(Timer.toSeconds(-8016)).toBe(-8);
expect(Timer.toSeconds(-10000)).toBe(-10);
-});
\ No newline at end of file
+});
+
+test('converting between millis to seconds handles partials correctly', () => {
+ const finish = 82162001;
+ const now = 80364519;
+ const runningMs = finish - now;
+ expect(Timer.toSeconds(runningMs)).toBe(1797);
+
+ expect(Timer.toSeconds(1800000)).toBe(1800);
+ expect(Timer.toSeconds(1799761)).toBe(1799);
+});
diff --git a/server/utils/__tests__/time.tests.js b/server/utils/__tests__/time.tests.js
index 38b5735de..5f11bb933 100644
--- a/server/utils/__tests__/time.tests.js
+++ b/server/utils/__tests__/time.tests.js
@@ -57,6 +57,17 @@ describe('test string to millis function', () => {
});
});
+describe('test stringFromMillis handles partial secs', () => {
+ it('test with 1795829', () => {
+ const t = { val: 1795829, result: '00:29:55' };
+ expect(stringFromMillis(t.val)).toBe(t.result);
+ });
+ it('test with 1797482', () => {
+ const t = { val: 1797482, result: '00:29:57' };
+ expect(stringFromMillis(t.val)).toBe(t.result);
+ });
+});
+
describe('test excel date parser', () => {
it('handles an invalid date string', () => {
const s = 'hello';