mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-11 10:23:54 +00:00
V1 (#118)
* chore: upgrade minor versions * chore: upgrade cypress * chore: upgrade fe dependencies * update readme * update osx images * update readme * upgrade dependencies * upgrade test dependency * feat: add option to input autofill * feat: autofill to the left * chore: update docs * chore: cleanup ci * version bump * style: prevent zero height bar * fix: prevent loosing menu * ux: improve input, no spellcheck or autocomplete * small ux improvements in cuesheets * feat 111/increase maximum number of events * fix: optimistic delete issue with filter * refact: pincode workflow * chore: add versioning to packages
This commit is contained in:
@@ -186,7 +186,6 @@ export class EventTimer extends Timer {
|
||||
* @returns {boolean} Whether action was called
|
||||
*/
|
||||
trigger(action) {
|
||||
// Todo: reply should come from status change
|
||||
let reply = true;
|
||||
switch (action) {
|
||||
case 'start':
|
||||
@@ -280,7 +279,6 @@ export class EventTimer extends Timer {
|
||||
// broadcast change
|
||||
this.broadcastState();
|
||||
|
||||
// Todo: wrap in reusable function
|
||||
// check integrations - http
|
||||
if (h?.onLoad?.enabled) {
|
||||
if (h?.onLoad?.url != null || h?.onLoad?.url !== '') {
|
||||
@@ -416,19 +414,11 @@ export class EventTimer extends Timer {
|
||||
|
||||
update() {
|
||||
// if there is nothing selected, update clock
|
||||
const now = this._getCurrentTime();
|
||||
this.clock = this._getCurrentTime();
|
||||
|
||||
// if we are not updating, send the timers
|
||||
if (this.ontimeCycle !== this.cycleState.onUpdate) {
|
||||
this.clock = now;
|
||||
this.broadcastThis('timer', {
|
||||
clock: now,
|
||||
running: Timer.toSeconds(this.current),
|
||||
secondary: Timer.toSeconds(this.secondaryTimer),
|
||||
durationSeconds: Timer.toSeconds(this.duration),
|
||||
expectedFinish: this._getExpectedFinish(),
|
||||
startedAt: this._startedAt,
|
||||
});
|
||||
this.io.emit('timer', this.getTimeObject());
|
||||
}
|
||||
|
||||
// Have we skipped onStart?
|
||||
@@ -588,7 +578,7 @@ export class EventTimer extends Timer {
|
||||
});
|
||||
|
||||
socket.on('increment-timer', (data) => {
|
||||
if (isNaN(parseInt(data))) return;
|
||||
if (isNaN(parseInt(data, 10))) return;
|
||||
if (data < -5 || data > 5) return;
|
||||
this.increment(data * 1000 * 60);
|
||||
});
|
||||
@@ -833,7 +823,6 @@ export class EventTimer extends Timer {
|
||||
|
||||
// load titles
|
||||
if ('title' in e || 'subtitle' in e || 'presenter' in e) {
|
||||
// TODO: should be more selective on the need to load titles
|
||||
this._loadTitlesNext();
|
||||
this._loadTitlesNow();
|
||||
}
|
||||
@@ -951,6 +940,10 @@ export class EventTimer extends Timer {
|
||||
this.ontimeCycle = this.cycleState.onLoad;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description loads given title (now)
|
||||
* @private
|
||||
*/
|
||||
_loadTitlesNow() {
|
||||
const e = this._eventlist[this.selectedEventIndex];
|
||||
if (e == null) return;
|
||||
@@ -981,6 +974,12 @@ export class EventTimer extends Timer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description loads given title
|
||||
* @param e
|
||||
* @param type
|
||||
* @private
|
||||
*/
|
||||
_loadThisTitles(e, type) {
|
||||
if (e == null) return;
|
||||
|
||||
@@ -1049,6 +1048,10 @@ export class EventTimer extends Timer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description look for next titles to load
|
||||
* @private
|
||||
*/
|
||||
_loadTitlesNext() {
|
||||
// maybe there is nothing to load
|
||||
if (this.selectedEventIndex == null) return;
|
||||
@@ -1091,6 +1094,10 @@ export class EventTimer extends Timer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description resets selected event data
|
||||
* @private
|
||||
*/
|
||||
_resetSelection() {
|
||||
this.titles = {
|
||||
titleNow: null,
|
||||
@@ -1129,6 +1136,9 @@ export class EventTimer extends Timer {
|
||||
this.broadcastThis('onAir', onAir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description start timer
|
||||
*/
|
||||
start() {
|
||||
// do we need to change
|
||||
if (this.state === 'start') return;
|
||||
@@ -1143,6 +1153,9 @@ export class EventTimer extends Timer {
|
||||
this.ontimeCycle = this.cycleState.onStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description pause timer
|
||||
*/
|
||||
pause() {
|
||||
// do we need to change
|
||||
if (this.state === 'pause') return;
|
||||
@@ -1157,6 +1170,9 @@ export class EventTimer extends Timer {
|
||||
this.ontimeCycle = this.cycleState.onPause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description stop timer
|
||||
*/
|
||||
stop() {
|
||||
// do we need to change
|
||||
if (this.state === 'stop') return;
|
||||
@@ -1168,6 +1184,10 @@ export class EventTimer extends Timer {
|
||||
this.ontimeCycle = this.cycleState.onStop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description increment timer by amount
|
||||
* @param amount
|
||||
*/
|
||||
increment(amount) {
|
||||
// call super
|
||||
super.increment(amount);
|
||||
@@ -1176,6 +1196,9 @@ export class EventTimer extends Timer {
|
||||
this.runCycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Look for current event considering local clock
|
||||
*/
|
||||
rollLoad() {
|
||||
const now = this._getCurrentTime();
|
||||
const prevLoaded = this.selectedEventId;
|
||||
@@ -1336,6 +1359,9 @@ export class EventTimer extends Timer {
|
||||
this.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description reloads current event
|
||||
*/
|
||||
reload() {
|
||||
if (this.numEvents === 0 || this.numEvents == null) return;
|
||||
|
||||
@@ -1429,7 +1455,6 @@ export class EventTimer extends Timer {
|
||||
* @param {any} [payload]
|
||||
*/
|
||||
async sendOsc(message, payload) {
|
||||
// Todo: add disabled osc check
|
||||
const reply = await this.osc.send(message, payload);
|
||||
if (!reply.success) {
|
||||
this.error('TX', reply.message);
|
||||
|
||||
+53
-11
@@ -1,11 +1,9 @@
|
||||
import { stringFromMillis } from '../utils/time.js';
|
||||
|
||||
/*
|
||||
* Timer implements simple countdown timer functions
|
||||
* User needs to use setup function to be able to use
|
||||
*
|
||||
/**
|
||||
* @description Implements simple countdown timer functions
|
||||
* @class
|
||||
*/
|
||||
|
||||
export class Timer {
|
||||
constructor() {
|
||||
this.clock = null;
|
||||
@@ -13,7 +11,11 @@ export class Timer {
|
||||
this.state = 'stop';
|
||||
}
|
||||
|
||||
// call setup separately
|
||||
/**
|
||||
* @description initiates a timer with given seconds
|
||||
* @param seconds
|
||||
* @param autoStart
|
||||
*/
|
||||
setupWithSeconds(seconds, autoStart = false) {
|
||||
// aux
|
||||
const now = this._getCurrentTime();
|
||||
@@ -36,7 +38,9 @@ export class Timer {
|
||||
this.update();
|
||||
}
|
||||
|
||||
// update()
|
||||
/**
|
||||
* @description updates the running timer
|
||||
*/
|
||||
update() {
|
||||
// get current time
|
||||
const now = this._getCurrentTime();
|
||||
@@ -87,12 +91,21 @@ export class Timer {
|
||||
}
|
||||
|
||||
// helpers
|
||||
/**
|
||||
* @description converts a value in millis to seconds
|
||||
* @param millis
|
||||
* @return {number}
|
||||
*/
|
||||
static toSeconds(millis) {
|
||||
if (millis == null) return 0;
|
||||
return millis < 0 ? Math.ceil(millis * 0.001) : Math.floor(millis * 0.001);
|
||||
}
|
||||
|
||||
// get current time in epoc
|
||||
/**
|
||||
* @description get current time in epoc
|
||||
* @return {number}
|
||||
* @private
|
||||
*/
|
||||
_getCurrentTime() {
|
||||
const now = new Date();
|
||||
|
||||
@@ -105,6 +118,11 @@ export class Timer {
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description when is timer finishing
|
||||
* @return {null|*|null|number}
|
||||
* @private
|
||||
*/
|
||||
_getExpectedFinish() {
|
||||
if (this._startedAt == null) return null;
|
||||
if (this._finishedAt) return this._finishedAt;
|
||||
@@ -115,6 +133,11 @@ export class Timer {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description resets timer parameters
|
||||
* @param total
|
||||
* @private
|
||||
*/
|
||||
_resetTimers(total = false) {
|
||||
if (total) this.duration = null;
|
||||
this.current = this.duration;
|
||||
@@ -131,13 +154,16 @@ export class Timer {
|
||||
this._pausedTotal = null;
|
||||
}
|
||||
|
||||
// get elapsed time
|
||||
/**
|
||||
* @description get elapsed time
|
||||
* @return {number}
|
||||
*/
|
||||
getElapsed() {
|
||||
return this.duration - this.current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds time object
|
||||
* @description Builds time object
|
||||
* @returns {{running: number, secondary: number, expectedFinish: number, durationSeconds: number, startedAt: null, clock: null}}
|
||||
*/
|
||||
getTimeObject() {
|
||||
@@ -152,7 +178,10 @@ export class Timer {
|
||||
};
|
||||
}
|
||||
|
||||
// current time in seconds
|
||||
/**
|
||||
* @description get current time in seconds
|
||||
* @return {number|number}
|
||||
*/
|
||||
getCurrentInSeconds() {
|
||||
// update timeStamp
|
||||
this.update();
|
||||
@@ -160,6 +189,9 @@ export class Timer {
|
||||
}
|
||||
|
||||
// playback
|
||||
/**
|
||||
* @description start current time
|
||||
*/
|
||||
start() {
|
||||
// do we need to change
|
||||
if (this.state === 'start') return;
|
||||
@@ -185,6 +217,9 @@ export class Timer {
|
||||
this.state = 'start';
|
||||
}
|
||||
|
||||
/**
|
||||
* @description pause current timer
|
||||
*/
|
||||
pause() {
|
||||
// do we need to change
|
||||
if (this.state === 'pause') return;
|
||||
@@ -201,6 +236,9 @@ export class Timer {
|
||||
this.state = 'pause';
|
||||
}
|
||||
|
||||
/**
|
||||
* @description stop current timer
|
||||
*/
|
||||
stop() {
|
||||
// do we need to change
|
||||
if (this.state === 'stop') return;
|
||||
@@ -212,6 +250,10 @@ export class Timer {
|
||||
this.state = 'stop';
|
||||
}
|
||||
|
||||
/**
|
||||
* @description increments a given amout to the timer
|
||||
* @param amount
|
||||
*/
|
||||
increment(amount) {
|
||||
this.duration += amount;
|
||||
|
||||
|
||||
@@ -78,13 +78,13 @@ test('object instantiates correctly', async () => {
|
||||
describe('test triggers behaviour', () => {
|
||||
const t = new EventTimer(server, timerConfig);
|
||||
|
||||
test('ignores bad commands', async(done) => {
|
||||
test('ignores bad commands', (done) => {
|
||||
const success = t.trigger('test');
|
||||
expect(success).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
|
||||
test('does not allow triggering events with an empty list', async(done) => {
|
||||
test('does not allow triggering events with an empty list', (done) => {
|
||||
expect(t.numEvents).toBe(0);
|
||||
|
||||
expect(t.trigger('start')).toBeFalsy();
|
||||
@@ -103,7 +103,7 @@ describe('test triggers behaviour', () => {
|
||||
done();
|
||||
});
|
||||
|
||||
test('...and is consistent by calling the class methods', async (done) => {
|
||||
test('...and is consistent by calling the class methods', (done) => {
|
||||
expect(t.numEvents).toBe(0);
|
||||
expect(t.state).toBe('stop');
|
||||
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
/** Class contains logic towards outgoing HTTP communications. */
|
||||
import * as http from 'http';
|
||||
|
||||
/**
|
||||
* @description Class contains logic towards outgoing HTTP communications
|
||||
* @class
|
||||
*/
|
||||
export class HTTPIntegration {
|
||||
|
||||
constructor() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description Initializes oscClient
|
||||
* @param {object} httpConfig - Http configurations options
|
||||
*/
|
||||
init(httpConfig) {
|
||||
|
||||
}
|
||||
init(httpConfig) {}
|
||||
|
||||
/**
|
||||
* @description Sends http get request from predefined messages
|
||||
@@ -29,8 +28,8 @@ export class HTTPIntegration {
|
||||
const options = new URL(path);
|
||||
let str = '';
|
||||
|
||||
const req = http.request(options, res => {
|
||||
console.log(`statusCode: ${res.statusCode}`)
|
||||
const req = http.request(options, (res) => {
|
||||
console.log(`statusCode: ${res.statusCode}`);
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
str += chunk;
|
||||
@@ -39,14 +38,16 @@ export class HTTPIntegration {
|
||||
res.on('end', function () {
|
||||
console.log(str);
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
req.on('error', error => {
|
||||
console.error(error)
|
||||
})
|
||||
req.on('error', (error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
req.end()
|
||||
req.end();
|
||||
}
|
||||
|
||||
shutdown() { /* Nothing to shutdown */ }
|
||||
}
|
||||
shutdown() {
|
||||
/* Nothing to shutdown */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/** Class contains logic towards outgoing OSC communications. */
|
||||
import { Client, Message } from 'node-osc';
|
||||
|
||||
/**
|
||||
* @description Class contains logic towards outgoing OSC communications
|
||||
* @class
|
||||
*/
|
||||
export class OSCIntegration {
|
||||
constructor() {
|
||||
// OSC Client
|
||||
|
||||
Reference in New Issue
Block a user