From a286bbf1fad26e4fa3aae582f96d6266e2194eb3 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Thu, 25 Apr 2019 19:08:27 +0200 Subject: [PATCH] Exract timeline to sepearte page --- hugvey/central_command.py | 2 + www/index.html | 7 +- www/js/hugvey_console.js | 140 +----------------------------------- www/js/hugvey_timeline.js | 146 ++++++++++++++++++++++++++++++++++++++ www/timeline.html | 53 ++++++++++++++ 5 files changed, 204 insertions(+), 144 deletions(-) create mode 100644 www/js/hugvey_timeline.js create mode 100644 www/timeline.html diff --git a/hugvey/central_command.py b/hugvey/central_command.py index 63a151b..63569e6 100644 --- a/hugvey/central_command.py +++ b/hugvey/central_command.py @@ -425,6 +425,7 @@ class HugveyState(object): self.status = status lightOn = status in [self.STATE_AWAITING, self.STATE_PAUSE, self.STATE_GONE] self.setLightStatus(lightOn) + self.eventLogger.info(f"status: {self.status}") def config(self, hostname, ip): @@ -605,6 +606,7 @@ class HugveyState(object): def shutdown(self, definitive = False): self.logger.info(f"Start shutdown sequence {definitive}") + self.eventLogger.critical(f"error: shutting down") if self.streamer: self.streamer.stop() if self.story: diff --git a/www/index.html b/www/index.html index 4af8a01..9290429 100644 --- a/www/index.html +++ b/www/index.html @@ -7,13 +7,12 @@ - - + - +
@@ -29,7 +28,6 @@ :class="['flag-icon', lang.code]"> {{lang.code}} -
Timeline
-
diff --git a/www/js/hugvey_console.js b/www/js/hugvey_console.js index e352b28..e6396bf 100644 --- a/www/js/hugvey_console.js +++ b/www/js/hugvey_console.js @@ -53,7 +53,6 @@ class Panopticon { return panopticon.change_language(hv.id, lang_code); }, showHugvey: function(hv) { - document.body.classList.remove('showTimeline'); panopticon.hugveys.selectedId = hv.language ? hv.id : null; panopticon.updateSelectedHugvey(); } @@ -65,16 +64,7 @@ class Panopticon { this.socket = new ReconnectingWebSocket( "ws://localhost:8888/ws", null, { debug: false, reconnectInterval: 3000 } ); this.graph = new Graph(); - this.eventDataSet = new vis.DataSet([ - {content: '.', start: new Date(), type: 'point', group: 1} - ]); - this.timeline = false; - document.getElementById('toggleTimeline').addEventListener('click', function(){ - document.body.classList.toggle('showTimeline'); - }); - - this.socket.addEventListener( 'open', ( e ) => { this.send( { action: 'init' } ); } ); @@ -110,112 +100,9 @@ class Panopticon { if(this.hugveys.selectedId) { this.updateSelectedHugvey(); } - - if(!this.timeline) { - console.log('init timeline'); - let groups = []; - for(let hid of msg['hugvey_ids']) { - groups.push({id: parseInt(hid), content: 'Hugvey #'+hid}); - this.eventDataSet.add({content: 'initiate', start: new Date(), type: 'point', group: parseInt(hid)}) - } - let dataGroups = new vis.DataSet(groups); - let options = { -// 'rollingMode': {'follow': true, 'offset': .8 } - }; - console.log('groups', dataGroups, groups, options); - - this.timeline = new vis.Timeline(document.getElementById('timeline'), this.eventDataSet, dataGroups, options); -// - - let startDate = new Date(); - startDate.setMinutes(startDate.getMinutes()-1); - let endDate = new Date(); - endDate.setMinutes(endDate.getMinutes()+20); - setTimeout(function(){ - panopticon.timeline.setWindow(startDate, endDate); - }, 500); - - console.log(startDate, endDate); - this.timelineInterval = setInterval(function(){ - // skip movement if not visible - if(!document.body.classList.contains('showTimeline')) - return; - panopticon.timeline.moveTo(new Date()); - }, 1000); - } break; case 'log': - let hv_id = parseInt(msg['id']); - if(this.timeline) { -// {'action': 'log', 'id':hugvey_id, 'type': items[0], 'info', 'args'} - let d, parts; - switch(msg['type']){ - case 'message': -// info: en-njsm8bwbd "Are you up for a conversation?" - parts = msg['info'].trim().split(' '); - let msgId = parts.shift(); - let msgUuid = parts.shift(); - let msgEvent = parts.shift(); - let msgContent = parts.join(' '); - let mId = 'm-'+msgUuid+'-'+hv_id; - d = this.eventDataSet.get(mId); - console.log(msgId, msgEvent, msgContent); - if(d !== null && msgEvent == 'done'){ - d['end'] = new Date(); - this.eventDataSet.update(d); - console.log('update', d); - } else { - this.eventDataSet.add({id: mId, content: msgContent, title: `${msgContent} (${msgId})`, start: new Date(), group: hv_id, 'className': 'message'}); - } - break; - case 'speaking': -// start/content/end - parts = msg['info'].trim().split(' '); - let info = parts.shift(); - let id = parts.shift(); - let content = parts.join(' '); - let scId = 'sc-'+id+'-'+hv_id; - - if(info.startsWith('start')){ - this.eventDataSet.add({content: info, start: new Date(), type: 'point', group: hv_id, 'className': 'speech'}); - } - if(info.startsWith('content')){ - d = this.eventDataSet.get(scId); - if(d !== null){ - console.log('alter'); - d['content'] = content; - d['end']= new Date(); - d['title'] = content; - this.eventDataSet.update(d); - } else { - console.log('add'); - this.eventDataSet.add({id: scId, content: content, title: content, start: new Date(), group: hv_id, 'className': 'speech'}); - } - } - if(info.startsWith('end')){ - d = this.eventDataSet.get(scId); - if(d !== null){ - d['end'] = new Date(); - this.eventDataSet.update(d); - } - } - - break; - case 'story': -// 'info': 'start'/'finished' - this.eventDataSet.add({content: msg['type'] +': ' + msg['info'] + ': ' + msg['args'], start: new Date(), type: 'point', group: hv_id, 'className': 'story'}); - break; - - case 'condition': - case 'direction': - // don't draw these :-0 - break; - default: - this.eventDataSet.add({content: msg['type'] +': ' + msg['info'] + ': ' + msg['args'], start: new Date(), type: 'point', group: hv_id}); - break; - } - } break; } } ); @@ -224,11 +111,6 @@ class Panopticon { updateSelectedHugvey() { let hv = null; - if(document.body.classList.contains('showTimeline')) { - // skip at all if no hugvey is visbile anyway due to the timeline - return; - } - if(this.hugveys.selectedId) { hv = this.getHugvey(this.hugveys.selectedId); if(hv.language && this.graph.language_code != hv.language) { @@ -2055,24 +1937,4 @@ class Graph { } } // -//class Timeline { -// constructor(el, hugvey_ids) { -// this.el = el; -// this.logbook = [] -// this.hugvey_ids = hugvey_ids; -// -// this.el.innerHTML = ""; -// for(id of this.hugvey_ids) { -// this.el.appendChild(crel( -// 'div', { -// -// } -// )); -// } -// } -// -// log(msg) { -//// {"action": "log", "id": "3", "type": "story", "info": " start"} -// console.log('log!', msg); -// } -//} +// \ No newline at end of file diff --git a/www/js/hugvey_timeline.js b/www/js/hugvey_timeline.js new file mode 100644 index 0000000..7723145 --- /dev/null +++ b/www/js/hugvey_timeline.js @@ -0,0 +1,146 @@ +var ws = new ReconnectingWebSocket( "ws://localhost:8888/ws", null, { debug: false, reconnectInterval: 3000 } ); + +//request close before unloading +window.addEventListener('beforeunload', function(){ + ws.close(); +}); + +ws.addEventListener( 'close', function( e ) { + console.log( 'Closed connection' ); +} ); + +class Timeline{ + constructor(ws, el, nr) { + this.ws = ws; + this.el = el; + this.count = nr; + this.eventDataSet = new vis.DataSet([ + {content: '.', start: new Date(), type: 'point', group: 1} + ]); + console.log('init timeline'); + + let groups = []; + for(let hid = 1; hid<=this.count; hid++) { + groups.push({id: parseInt(hid), content: 'Hugvey #'+hid}); + this.eventDataSet.add({content: 'initiate', start: new Date(), type: 'point', group: parseInt(hid)}) + } + + let dataGroups = new vis.DataSet(groups); + let options = { +// 'rollingMode': {'follow': true, 'offset': .8 } + }; + console.log('groups', dataGroups, groups, options); + + this.timeline = new vis.Timeline(this.el, this.eventDataSet, dataGroups, options); + + let tl = this.timeline; + let startDate = new Date(); + startDate.setMinutes(startDate.getMinutes()-1); + let endDate = new Date(); + endDate.setMinutes(endDate.getMinutes()+20); + setTimeout(function(){ + tl.setWindow(startDate, endDate); + }, 500); + + this.moveInterval = setInterval(function(){ + // skip movement if not visible + tl.moveTo(new Date()); + }, 1000); + + + ws.addEventListener( 'message', this); + } + + handleEvent(e) { + console.log('handle', e, this); + if(e.type == 'message') { + this.wsOnMessage(e) + } + } + + wsOnMessage(e) { + let msg = JSON.parse( e.data ); + + if ( typeof msg['action'] === 'undefined' ) { + console.error( "not a valid message: " + e.data ); + return; + } + + if(msg['action'] != 'log') { + return; + } + + console.debug(msg, this); + + let hv_id = parseInt(msg['id']); +// {'action': 'log', 'id':hugvey_id, 'type': items[0], 'info', 'args'} + let d, parts; + switch(msg['type']){ + case 'message': +// info: en-njsm8bwbd "Are you up for a conversation?" + parts = msg['info'].trim().split(' '); + let msgId = parts.shift(); + let msgUuid = parts.shift(); + let msgEvent = parts.shift(); + let msgContent = parts.join(' '); + let mId = 'm-'+msgUuid+'-'+hv_id; + d = this.eventDataSet.get(mId); + console.log(msgId, msgEvent, msgContent); + if(d !== null && msgEvent == 'done'){ + d['end'] = new Date(); + this.eventDataSet.update(d); + console.log('update', d); + } else { + this.eventDataSet.add({id: mId, content: msgContent, title: `${msgContent} (${msgId})`, start: new Date(), group: hv_id, 'className': 'message'}); + } + break; + case 'speaking': +// start/content/end + parts = msg['info'].trim().split(' '); + let info = parts.shift(); + let id = parts.shift(); + let content = parts.join(' '); + let scId = 'sc-'+id+'-'+hv_id; + + if(info.startsWith('start')){ + this.eventDataSet.add({content: info, start: new Date(), type: 'point', group: hv_id, 'className': 'speech'}); + } + if(info.startsWith('content')){ + d = this.eventDataSet.get(scId); + if(d !== null){ + console.log('alter'); + d['content'] = content; + d['end']= new Date(); + d['title'] = content; + this.eventDataSet.update(d); + } else { + console.log('add'); + this.eventDataSet.add({id: scId, content: content, title: content, start: new Date(), group: hv_id, 'className': 'speech'}); + } + } + if(info.startsWith('end')){ + d = this.eventDataSet.get(scId); + if(d !== null){ + d['end'] = new Date(); + this.eventDataSet.update(d); + } + } + + break; + case 'story': +// 'info': 'start'/'finished' + this.eventDataSet.add({content: msg['type'] +': ' + msg['info'] + ': ' + msg['args'], start: new Date(), type: 'point', group: hv_id, 'className': 'story'}); + break; + + case 'condition': + case 'direction': + // don't draw these :-0 + break; + default: + this.eventDataSet.add({content: msg['type'] +': ' + msg['info'] + ': ' + msg['args'], start: new Date(), type: 'point', group: hv_id}); + break; + } + } +} + +var tl = new Timeline(ws, document.getElementById('line'), 25); diff --git a/www/timeline.html b/www/timeline.html new file mode 100644 index 0000000..890b159 --- /dev/null +++ b/www/timeline.html @@ -0,0 +1,53 @@ + + +Pillow Talk - Timeline + + + + + + + +
+ + + + \ No newline at end of file