hugvey/www/js/hugvey_timeline.js
2019-11-12 09:54:55 +01:00

226 lines
6.3 KiB
JavaScript

var ws = new ReconnectingWebSocket( window.location.origin.replace('http', 'ws') +'/ws', null, { debug: false, reconnectInterval: 3000 } );
var seeme = true;
var error_audio = new Audio('siren.wav');
var playSoundOnError = true;
var checkbox_sound = document.getElementById('play_sound_on_error')
if(checkbox_sound != null) {
checkbox_sound.addEventListener('change', (event) => {
if (event.target.checked) {
playSoundOnError = true;
} else {
playSoundOnError = false;
}
})
}
//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)})
}
this.dataGroups = new vis.DataSet(groups);
let options = {
maxHeight: '100%',
height: '100%',
margin : {
item: {
horizontal: 0,
vertical: 5
}
},
zoomMax: 3600000 // 1 h
// 'rollingMode': {'follow': true, 'offset': .8 }
};
// console.log('groups', this.dataGroups, groups, options);
this.timeline = new vis.Timeline(this.el, this.eventDataSet, this.dataGroups, options);
let tl = this.timeline;
let startDate = new Date();
startDate.setMinutes(startDate.getMinutes()-1);
let endDate = new Date();
endDate.setMinutes(endDate.getMinutes()+20);
//follow the timeline or not if checkbox is checked
setTimeout(function(){
tl.setWindow(startDate, endDate);
}, 500);
this.moveInterval = setInterval(function(){
// skip movement if not visible
tl.moveTo(new Date());
}, 1000);
var checkbox = document.getElementById('follow_checkbox')
checkbox.addEventListener('change', (event) => {
if (event.target.checked) {
this.moveInterval = setInterval(function(){
// skip movement if not visible
tl.moveTo(new Date());
}, 1000);
} else {
clearInterval(this.moveInterval)
}
});
ws.addEventListener( 'message', this);
}
handleEvent(e) {
// console.log('handle it', 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'] == 'status') {
for(let hv of msg['hugveys']){
console.log(hv['language'], hv['status']);
let evenOdd = parseInt(hv['id'])%2 ? 'odd': 'even';
let availableClass = hv['available'] ? 'is-available' : 'is-not-available'
this.dataGroups.update({id: parseInt(hv['id']), content: `<div class='title'>Hugvey #${hv['id']}</div><div class='times'><span>${hv['time_since_hugvey_spoke']}</span><span>${hv['time_since_visitor_spoke']}</span></div>`, className: `status-${hv['status']} ${availableClass} lang-${hv['language']} ${evenOdd}`})
}
}
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(), end: new Date(Date.now()+5000), 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(), end: new Date(Date.now() + 1000), 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(), end: new Date(Date.now() + 1000), 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({
title: msg['type'] +': ' + msg['info'] + (msg.hasOwnProperty('args')? ': '+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({
title: msg['type'] +': ' + msg['info'] + (msg.hasOwnProperty('args')? ': '+msg['args'] : ""),
start: new Date(), type: 'point', group: hv_id, 'className': msg['lvlname']});
if (msg['lvlname'] == 'CRITICAL' && playSoundOnError) {
// error_audio.play();
}
break;
}
}
}
var tl = new Timeline(ws, document.getElementById('line'), 29);
window.addEventListener('keypress', function(e){
console.log(e.keyCode)
if(e.keyCode==46){
if(seeme){
seeme = false;
let options = {
showTooltips: false
};
tl.timeline.setOptions(options)
}
else{
seeme = true;
let options = {
showTooltips: true
};
tl.timeline.setOptions(options)
}
}
});