mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-06 16:03:52 +00:00
Merge pull request #12 from cpvalente/feat/oscfeedback
Feat/oscfeedback
This commit is contained in:
@@ -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);
|
||||
});
|
||||
@@ -23,8 +23,12 @@
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^27.0.4"
|
||||
},
|
||||
"scripts": {
|
||||
"nodestart": "NODE_ENV=development node src/app.js",
|
||||
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
|
||||
"start": "NODE_ENV=development electron .",
|
||||
"pack": "electron-builder --dir",
|
||||
"dist": "electron-builder",
|
||||
|
||||
@@ -21,6 +21,7 @@ const adapter = new JSONFile(file);
|
||||
export const db = new Low(adapter);
|
||||
|
||||
// dependencies
|
||||
import { Client } from 'node-osc';
|
||||
import express from 'express';
|
||||
import http from 'http';
|
||||
import cors from 'cors';
|
||||
|
||||
@@ -15,6 +15,10 @@ export class EventTimer extends Timer {
|
||||
|
||||
// Socket IO Object
|
||||
io = null;
|
||||
|
||||
// OSC Client
|
||||
oscClient = null;
|
||||
|
||||
_numClients = 0;
|
||||
_interval = null;
|
||||
|
||||
@@ -59,7 +63,7 @@ export class EventTimer extends Timer {
|
||||
numEvents = null;
|
||||
_eventlist = null;
|
||||
|
||||
constructor(httpServer, config) {
|
||||
constructor(httpServer, oscClient, config) {
|
||||
// call super constructor
|
||||
super();
|
||||
|
||||
@@ -81,6 +85,101 @@ export class EventTimer extends Timer {
|
||||
|
||||
// listen to new connections
|
||||
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
|
||||
broadcastTimer() {
|
||||
// through websockets
|
||||
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
|
||||
@@ -119,44 +225,32 @@ export class EventTimer extends Timer {
|
||||
}
|
||||
|
||||
update() {
|
||||
// if there is nothing selected, no nothing
|
||||
// if there is nothing selected, do nothing
|
||||
if (this.selectedEventId == null && this.state !== 'roll') return;
|
||||
|
||||
// only implement roll here
|
||||
if (this.state !== 'roll') {
|
||||
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 {
|
||||
// look for event if none is loaded
|
||||
if (this.current <= 0 || this.secondaryTimer <= 0) this.rollLoad();
|
||||
// get current time
|
||||
const now = this._getCurrentTime();
|
||||
this.clock = now;
|
||||
|
||||
// count to next event
|
||||
// TODO: replace with proper counter
|
||||
if (this.secondaryTimer != null) this.secondaryTimer -= 1000;
|
||||
if (this.selectedEventId && this.current > 0) {
|
||||
// update timer as usual
|
||||
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() {
|
||||
// if there is nothing selected, no nothing
|
||||
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();
|
||||
// sendOSC on reaching 0
|
||||
if (this.current === 0 && this.state === 'start') this.sendOSC('finished');
|
||||
}
|
||||
|
||||
_setterManager(action, payload) {
|
||||
@@ -792,19 +886,31 @@ export class EventTimer extends Timer {
|
||||
}
|
||||
|
||||
start() {
|
||||
// if there is nothing selected, no nothing
|
||||
if (this.selectedEventId == null) return;
|
||||
|
||||
// call super
|
||||
super.start();
|
||||
|
||||
// broadcast current state
|
||||
this.broadcastState();
|
||||
|
||||
// send OSC
|
||||
this.sendOSC('play');
|
||||
}
|
||||
|
||||
pause() {
|
||||
// if there is nothing selected, no nothing
|
||||
if (this.selectedEventId == null) return;
|
||||
|
||||
// call super
|
||||
super.pause();
|
||||
|
||||
// broadcast current state
|
||||
this.broadcastState();
|
||||
|
||||
// send OSC
|
||||
this.sendOSC('pause');
|
||||
}
|
||||
|
||||
stop() {
|
||||
@@ -813,6 +919,9 @@ export class EventTimer extends Timer {
|
||||
|
||||
// broadcast current state
|
||||
this.broadcastState();
|
||||
|
||||
// send OSC
|
||||
this.sendOSC('stop');
|
||||
}
|
||||
|
||||
increment(amount) {
|
||||
@@ -906,6 +1015,9 @@ export class EventTimer extends Timer {
|
||||
return;
|
||||
}
|
||||
|
||||
// send OSC
|
||||
this.sendOSC('prev');
|
||||
|
||||
// change playstate
|
||||
this.pause();
|
||||
|
||||
@@ -926,6 +1038,9 @@ export class EventTimer extends Timer {
|
||||
return;
|
||||
}
|
||||
|
||||
// send OSC
|
||||
this.sendOSC('next');
|
||||
|
||||
// change playstate
|
||||
this.pause();
|
||||
|
||||
@@ -953,6 +1068,9 @@ export class EventTimer extends Timer {
|
||||
// reset playstate
|
||||
this.pause();
|
||||
|
||||
// send OSC
|
||||
this.sendOSC('reload');
|
||||
|
||||
// reload data
|
||||
this.loadEvent(this.selectedEventIndex);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { stringFromMillis } from '../utils/time.js';
|
||||
|
||||
export class Timer {
|
||||
clock = null;
|
||||
duration = null;
|
||||
current = null;
|
||||
timeTag = null;
|
||||
secondaryTimer = null;
|
||||
_finishAt = null;
|
||||
_finishedAt = null;
|
||||
@@ -133,8 +136,12 @@ export class Timer {
|
||||
|
||||
// getObject
|
||||
getObject() {
|
||||
// update timer
|
||||
this.update();
|
||||
|
||||
// update timetag
|
||||
this.timeTag = stringFromMillis(this.current);
|
||||
|
||||
return {
|
||||
clock: this.clock,
|
||||
running: Timer.toSeconds(this.current),
|
||||
@@ -216,4 +223,4 @@ export class Timer {
|
||||
this._finishedAt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ export const config = {
|
||||
},
|
||||
osc: {
|
||||
port: 8888,
|
||||
portOut: 8889,
|
||||
ipOut: '127.0.0.1',
|
||||
portOut: 9999,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user