Merge pull request #12 from cpvalente/feat/oscfeedback

Feat/oscfeedback
This commit is contained in:
Carlos Valente
2021-06-14 10:18:32 +02:00
committed by GitHub
8 changed files with 209 additions and 3361 deletions
+16
View File
@@ -0,0 +1,16 @@
import { stringFromMillis } from '../../src/utils/time';
const t1 = { val: null, result: '...' };
test('test stringFromMillis() on null values', () => {
expect(stringFromMillis(t1.val)).toBe(t1.result);
});
const t2 = { val: 3600000, result: '01:00:00' };
test('test stringFromMillis() on valid millis', () => {
expect(stringFromMillis(t2.val)).toBe(t2.result);
});
const t3 = { val: -3600000, result: '-01:00:00' };
test('test stringFromMillis() on negative millis', () => {
expect(stringFromMillis(t3.val)).toBe(t3.result);
});
+4
View File
@@ -23,8 +23,12 @@
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-simple-import-sort": "^7.0.0" "eslint-plugin-simple-import-sort": "^7.0.0"
}, },
"devDependencies": {
"jest": "^27.0.4"
},
"scripts": { "scripts": {
"nodestart": "NODE_ENV=development node src/app.js", "nodestart": "NODE_ENV=development node src/app.js",
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
"start": "NODE_ENV=development electron .", "start": "NODE_ENV=development electron .",
"pack": "electron-builder --dir", "pack": "electron-builder --dir",
"dist": "electron-builder", "dist": "electron-builder",
+1
View File
@@ -21,6 +21,7 @@ const adapter = new JSONFile(file);
export const db = new Low(adapter); export const db = new Low(adapter);
// dependencies // dependencies
import { Client } from 'node-osc';
import express from 'express'; import express from 'express';
import http from 'http'; import http from 'http';
import cors from 'cors'; import cors from 'cors';
+148 -30
View File
@@ -15,6 +15,10 @@ export class EventTimer extends Timer {
// Socket IO Object // Socket IO Object
io = null; io = null;
// OSC Client
oscClient = null;
_numClients = 0; _numClients = 0;
_interval = null; _interval = null;
@@ -59,7 +63,7 @@ export class EventTimer extends Timer {
numEvents = null; numEvents = null;
_eventlist = null; _eventlist = null;
constructor(httpServer, config) { constructor(httpServer, oscClient, config) {
// call super constructor // call super constructor
super(); super();
@@ -81,6 +85,101 @@ export class EventTimer extends Timer {
// listen to new connections // listen to new connections
this._listenToConnections(); this._listenToConnections();
// set oscClient
this.updateOSCClient(oscClient);
}
/**
* @description Updates the osc client used in the object
* @param {object} oscClient
*/
updateOSCClient(oscClient) {
this.oscClient = oscClient;
}
/**
* @description Sends osc value from predefined messages
* @param {string} event - message to be sent
*/
sendOSC(event) {
if (this.oscClient == null) return;
const add = '/ontime';
const play = 'play';
const pause = 'pause';
const stop = 'stop';
const prev = 'prev';
const next = 'next';
const reload = 'reload';
const finished = 'finished';
const time = this.timeTag;
// TODO: Should this be boolean?
const overtime = this.current > 0 ? 0 : 1;
const title = this.titles.titleNow;
switch (event) {
case 'time':
// Send Timetag Message
this.oscClient.send(add + '/time', time, (err) => {
if (err) console.error(err);
});
break;
case 'finished':
// Runs when timer reaches 0
this.oscClient.send(add, finished, (err) => {
if (err) console.error(err);
});
break;
case 'overtime':
// Whether timer is negative
this.oscClient.send(add + '/overtime', overtime, (err) => {
if (err) console.error(err);
});
break;
case 'title':
// Send Title of current event
this.oscClient.send(add + '/title', title, (err) => {
if (err) console.error(err);
});
break;
case 'play':
// Play Message
this.oscClient.send(add, play, (err) => {
if (err) console.error(err);
});
break;
case 'pause':
// Pause Message
this.oscClient.send(add, pause, (err) => {
if (err) console.error(err);
});
break;
case 'stop':
// Stop Message
this.oscClient.send(add, stop, (err) => {
if (err) console.error(err);
});
break;
case 'prev':
this.oscClient.send(add, prev, (err) => {
if (err) console.error(err);
});
break;
case 'next':
this.oscClient.send(add, next, (err) => {
if (err) console.error(err);
});
break;
case 'reload':
this.oscClient.send(add, reload, (err) => {
if (err) console.error(err);
});
break;
default:
break;
}
} }
/** /**
@@ -93,7 +192,14 @@ export class EventTimer extends Timer {
// send current timer // send current timer
broadcastTimer() { broadcastTimer() {
// through websockets
this.io.emit('timer', this.getObject()); this.io.emit('timer', this.getObject());
// through OSC, only if running
if (this.state === 'start' || this.state === 'roll') {
this.sendOSC('time');
this.sendOSC('overtime');
}
} }
// broadcast state // broadcast state
@@ -119,44 +225,32 @@ export class EventTimer extends Timer {
} }
update() { update() {
// if there is nothing selected, no nothing // if there is nothing selected, do nothing
if (this.selectedEventId == null && this.state !== 'roll') return; if (this.selectedEventId == null && this.state !== 'roll') return;
// only implement roll here // only implement roll here
if (this.state !== 'roll') { if (this.state !== 'roll') {
super.update(); super.update();
return;
}
// get current time
const now = this._getCurrentTime();
this.clock = now;
if (this.selectedEventId && this.current > 0) {
// update timer as usual
this.current = this._finishAt - now;
} else { } else {
// look for event if none is loaded // get current time
if (this.current <= 0 || this.secondaryTimer <= 0) this.rollLoad(); const now = this._getCurrentTime();
this.clock = now;
// count to next event if (this.selectedEventId && this.current > 0) {
// TODO: replace with proper counter // update timer as usual
if (this.secondaryTimer != null) this.secondaryTimer -= 1000; this.current = this._finishAt - now;
} else {
// look for event if none is loaded
if (this.current <= 0 || this.secondaryTimer <= 0) this.rollLoad();
// count to next event
// TODO: replace with proper counter
if (this.secondaryTimer != null) this.secondaryTimer -= 1000;
}
} }
}
start() { // sendOSC on reaching 0
// if there is nothing selected, no nothing if (this.current === 0 && this.state === 'start') this.sendOSC('finished');
if (this.selectedEventId == null) return;
super.start();
this.broadcastState();
}
pause() {
// if there is nothing selected, no nothing
if (this.selectedEventId == null) return;
super.pause();
this.broadcastState();
} }
_setterManager(action, payload) { _setterManager(action, payload) {
@@ -792,19 +886,31 @@ export class EventTimer extends Timer {
} }
start() { start() {
// if there is nothing selected, no nothing
if (this.selectedEventId == null) return;
// call super // call super
super.start(); super.start();
// broadcast current state // broadcast current state
this.broadcastState(); this.broadcastState();
// send OSC
this.sendOSC('play');
} }
pause() { pause() {
// if there is nothing selected, no nothing
if (this.selectedEventId == null) return;
// call super // call super
super.pause(); super.pause();
// broadcast current state // broadcast current state
this.broadcastState(); this.broadcastState();
// send OSC
this.sendOSC('pause');
} }
stop() { stop() {
@@ -813,6 +919,9 @@ export class EventTimer extends Timer {
// broadcast current state // broadcast current state
this.broadcastState(); this.broadcastState();
// send OSC
this.sendOSC('stop');
} }
increment(amount) { increment(amount) {
@@ -906,6 +1015,9 @@ export class EventTimer extends Timer {
return; return;
} }
// send OSC
this.sendOSC('prev');
// change playstate // change playstate
this.pause(); this.pause();
@@ -926,6 +1038,9 @@ export class EventTimer extends Timer {
return; return;
} }
// send OSC
this.sendOSC('next');
// change playstate // change playstate
this.pause(); this.pause();
@@ -953,6 +1068,9 @@ export class EventTimer extends Timer {
// reset playstate // reset playstate
this.pause(); this.pause();
// send OSC
this.sendOSC('reload');
// reload data // reload data
this.loadEvent(this.selectedEventIndex); this.loadEvent(this.selectedEventIndex);
} }
+8 -1
View File
@@ -4,10 +4,13 @@
* *
*/ */
import { stringFromMillis } from '../utils/time.js';
export class Timer { export class Timer {
clock = null; clock = null;
duration = null; duration = null;
current = null; current = null;
timeTag = null;
secondaryTimer = null; secondaryTimer = null;
_finishAt = null; _finishAt = null;
_finishedAt = null; _finishedAt = null;
@@ -133,8 +136,12 @@ export class Timer {
// getObject // getObject
getObject() { getObject() {
// update timer
this.update(); this.update();
// update timetag
this.timeTag = stringFromMillis(this.current);
return { return {
clock: this.clock, clock: this.clock,
running: Timer.toSeconds(this.current), running: Timer.toSeconds(this.current),
@@ -216,4 +223,4 @@ export class Timer {
this._finishedAt = null; this._finishedAt = null;
} }
} }
} }
+2 -1
View File
@@ -11,6 +11,7 @@ export const config = {
}, },
osc: { osc: {
port: 8888, port: 8888,
portOut: 8889, ipOut: '127.0.0.1',
portOut: 9999,
}, },
}; };
+30
View File
@@ -0,0 +1,30 @@
/**
* @description Converts milliseconds to string representing time
* @param {number} ms - time in milliseconds
* @param {boolean} showSeconds - wether to show the seconds
* @param {string} delim - character between HH MM SS
* @param {string} ifNull - what to return if value is null
* @returns {string} String representing time 00:12:02
*/
export const stringFromMillis = (
ms,
showSeconds = true,
delim = ':',
ifNull = '...'
) => {
if (ms === null || isNaN(ms)) return ifNull;
const isNegative = ms < 0 ? '-' : '';
const millis = Math.abs(ms);
const showWith0 = (value) => (value < 10 ? `0${value}` : value);
const hours = showWith0(Math.floor(((millis / (1000 * 60 * 60)) % 60) % 24));
const minutes = showWith0(Math.floor((millis / (1000 * 60)) % 60));
const seconds = showWith0(Math.floor((millis / 1000) % 60));
return showSeconds
? `${isNegative}${
parseInt(hours) ? `${hours}${delim}` : `00${delim}`
}${minutes}${delim}${seconds}`
: `${isNegative}${parseInt(hours) ? `${hours}` : '00'}${delim}${minutes}`;
};
-3329
View File
File diff suppressed because it is too large Load Diff