diff --git a/server/app.js b/server/app.js index 428db510e..e844a4d6f 100644 --- a/server/app.js +++ b/server/app.js @@ -14,11 +14,16 @@ const playbackRouter = require('./routes/playbackRouter.js'); const port = process.env.PORT || config.server.port; // Global Objects +const eventlist = require('./data/eventsData.json'); const EventTimer = require('./classes/EventTimer.js'); + // TODO: this should be replaced by some sort of calculation let durationForNow = 5400; global.timer = new EventTimer(); -timer.setupWithSeconds(durationForNow, true); +timer.setupWithEventList(eventlist); +// timer.setupWithSeconds(durationForNow, true); + +console.log(timer.print()); // Socket const initiateSocket = require('./controllers/socketController.js'); diff --git a/server/classes/EventTimer.js b/server/classes/EventTimer.js index 4ffe4c9f9..2b809632f 100644 --- a/server/classes/EventTimer.js +++ b/server/classes/EventTimer.js @@ -18,10 +18,84 @@ class EventTimer extends Timer { visible: false, }; + selectedEvent = null; + selectedEventId = null; + numEvents = null; + constructor() { super(); } + setupWithEventList(eventlist) { + // filter only events + const events = eventlist.filter((e) => e.type === 'event'); + + const numEvents = events.length; + if (numEvents < 1) return; + + // set general + this._eventList = events; + this.numEvents = numEvents; + + // load first event + this.loadEvent(0); + } + + loadEvent(eventIndex) { + // set event specific + const e = this._eventList[eventIndex]; + const start = + e.timeStart == null || e.timeStart === '' ? 0 : new Date(e.timeStart); + const end = + e.timeEnd == null || e.timeEnd === '' ? 0 : new Date(e.timeEnd); + + this._resetTimers(); + this.duration = end - start; + this.current = this.duration; + this.selectedEvent = eventIndex; + this.selectedEventId = e.id; + + } + + print() { + // TODO: better formatting? + return ` + Timer + ========= + + Playback + ------------------------------ + state = ${this.state} + current = ${this.current} + duration = ${this.duration} + + Options + ------------------------------ + showNegative = ${this.showNegative} + + Events + ------------------------------ + selectedEvent = ${this.selectedEvent} + selectedEventId = ${this.selectedEventId} + numEvents = ${this.numEvents} + + Messages + ------------------------------ + presenter text = ${this.presenter.text} + presenter vis = ${this.presenter.visible} + public text = ${this.public.text} + public vis = ${this.public.visible} + + Private + ------------------------------ + finishAt = ${this._finishAt} + startedAt = ${this._startedAt} + pausedAt = ${this._pausedAt} + pausedInterval = ${this._pausedInterval} + pausedTotal = ${this._pausedTotal} + `; + } + set presenterText(text) { this.presenter.text = text; } @@ -46,6 +120,34 @@ class EventTimer extends Timer { return this.public; } + _getEventData() {} + + goto(eventIndex) { + this.loadEvent(eventIndex); + } + + roll() { + console.log('roll: not yet implemented'); + return false; + this.state = 'roll'; + } + + previous() { + const gotoEvent = this.selectedEvent > 0 ? this.selectedEvent - 1 : 0; + + if (gotoEvent === this.selectedEvent) return; + this.goto(gotoEvent); + } + + next() { + const gotoEvent = + this.selectedEvent < this.numEvents - 1 + ? this.selectedEvent + 1 + : this.numEvents - 1; + + if (gotoEvent === this.selectedEvent) return; + this.goto(gotoEvent); + } } module.exports = EventTimer; diff --git a/server/classes/Timer.js b/server/classes/Timer.js index 0c5088f98..e8deb602e 100644 --- a/server/classes/Timer.js +++ b/server/classes/Timer.js @@ -5,13 +5,14 @@ */ class Timer { - _current = null; + duration = null; + current = null; _finishAt = null; _startedAt = null; _pausedAt = null; _pausedInterval = null; _pausedTotal = null; - state = 'pause'; + state = 'stop'; showNegative = false; constructor() {} @@ -22,6 +23,7 @@ class Timer { const now = new Date().getTime(); // populate targets + this.duration = seconds * 1000; this._finishAt = now + seconds * 1000; // start counting @@ -47,15 +49,18 @@ class Timer { case 'start': // update current timer if (!this.showNegative) { - this._current = Math.max(this._finishAt + this._pausedTotal - now, 0); + this.current = Math.max(this._finishAt + this._pausedTotal - now, 0); } else { - (this._current = this._finishAt + this._pausedTotal - now), 0; + (this.current = this._finishAt + this._pausedTotal - now), 0; } break; case 'pause': // update paused time this._pausedInterval = now - this._pausedAt; break; + case 'stop': + // nothing here yet + break; default: console.error('Timer: no playstate on update call', this.state); break; @@ -71,11 +76,20 @@ class Timer { return this._finishAt + (this._pausedInterval + this._pausedTotal); } + _resetTimers() { + this._finishAt = null; + this._startedAt = null; + this._pausedAt = null; + this._pausedInterval = null; + this._pausedTotal = null; + this.state = 'stop'; + } + // getObject getObject() { this.update(); return { - currentSeconds: Timer.toSeconds(this._current), + currentSeconds: Timer.toSeconds(this.current), expectedFinish: this._getExpectedFinish(), startedAt: this._startedAt, }; @@ -85,7 +99,7 @@ class Timer { getCurrentInSeconds() { // update timeStamp this.update(); - return Timer.toSeconds(this._current); + return Timer.toSeconds(this.current); } get playState() { @@ -96,21 +110,21 @@ class Timer { start() { // do we need to change if (this.state === 'start') return; - - // update start time if needed - if (!this._startedAt) { - this._startedAt = new Date().getTime(); + else if (this.state === 'stop') { + const now = new Date().getTime(); + this._startedAt = now; + this._finishAt = now + this.duration; + } else { + // check if there is paused time + if (this._pausedInterval) { + this._pausedTotal += this._pausedInterval; + this._pausedInterval = null; + } } - - // check if there is paused time - if (this._pausedInterval) { - this._pausedTotal += this._pausedInterval; - this._pausedInterval = null; - } - // change state this.state = 'start'; } + pause() { // do we need to change if (this.state === 'pause') return; @@ -122,12 +136,19 @@ class Timer { this.state = 'pause'; } stop() { - console.log('stop: not yet implemented'); - return false; - } - roll() { - console.log('roll: not yet implemented'); - return false; + // do we need to change + if (this.state === 'stop') return; + + // clear all timers + this.current = duration; + this._finishAt = null; + this._startedAt = null; + this._pausedAt = null; + this._pausedInterval = null; + this._pausedTotal = null; + + // change state + this.state = 'stop'; } } diff --git a/server/controllers/playbackController.js b/server/controllers/playbackController.js index 5a3943cbc..09131cd20 100644 --- a/server/controllers/playbackController.js +++ b/server/controllers/playbackController.js @@ -47,13 +47,13 @@ exports.pbRoll = async (req, res) => { // Create controller for GET request to '/playback/previous' // Sets timer object to roll mode exports.pbPrevious = async (req, res) => { - console.log('previous: not implemented'); - res.sendStatus(501); + global.timer.previous(); + res.sendStatus(200); }; // Create controller for GET request to '/playback/next' // Sets timer object to roll mode exports.pbNext = async (req, res) => { - console.log('next: not implemented'); - res.sendStatus(501); + global.timer.next(); + res.sendStatus(200); }; diff --git a/server/controllers/socketController.js b/server/controllers/socketController.js index d909066ab..2115c458f 100644 --- a/server/controllers/socketController.js +++ b/server/controllers/socketController.js @@ -20,11 +20,10 @@ const initiateSocket = (server, config) => { // send current data socket.emit('timer', global.timer.getObject()); - // unsubscribe to timer - socket.on('release-timer', () => { - console.log('Releasing subscription'); - // avoid multiple intervals - if (interval) clearInterval(interval); + socket.on('get-state', () => { + socket.emit('timer', global.timer.getObject()); + socket.emit('playstate', global.timer.playState); + socket.emit('selected-id', global.timer.selectedEventId); }); socket.on('get-timer', () => { @@ -35,6 +34,10 @@ const initiateSocket = (server, config) => { socket.emit('playstate', global.timer.playState); }); + socket.on('get-selected-id', () => { + socket.emit('selected-id', global.timer.selectedEventId); + }); + // playback API socket.on('set-presenter-text', (data) => { global.timer.presenterText = data;