App-SlideServer
view release on metacpan or search on metacpan
share/public/slides.js view on Meta::CPAN
_handle_connect: function(event, url, mode) {
this.root.find('.reconnect-btn').hide()
this._set_conn_note('<p>Connected</p>', 1500)
if (this.config.mode == 'obs')
this.enableFollow(true);
},
_handle_disconnect: function(event) {
this.root.find('.reconnect-btn').show()
this._set_conn_note('<p>Lost connection</p>')
delete this.ws;
},
_handle_ws_event: function(event) {
//console.log('ws event: ', event);
if (event.state) {
this.sharedState= event.state;
if (this.following)
this.goToLeaderSlide();
}
if (event.roles) {
this.roles= {};
for (var i=0; i < event.roles.length; i++)
this.roles[event.roles[i]]= 1;
if (this.roles.lead) {
this.enableFollow(false);
this.root.find('.status-actions .follow').show();
this.root.find('.status-actions .lead').show();
this.root.find('.status-actions .notes').show();
} else {
// initial state for non-lead is to follow
this.enableFollow(true);
}
if (this.roles.navigate || this.roles.lead) {
this.root.find('.status-actions .navigate').show();
}
}
if (event.key_incorrect) {
// TODO: create a password entry form on the sidebar and a login sequence
// that happens over the websocket.
this._set_conn_note('<p>Incorrect Key</p>');
this.config.key= null;
this.root.find('.status-actions > .login').show();
this.root.find('.reconnect-btn').show()
}
if (event.page_changed) {
window.location.reload();
}
if (event.slides_changed) {
console.log('slides_changed', event.slides_changed);
for (var i=0; i < event.slides_changed.length; i++)
this.replaceSlide(event.slides_changed[i].idx+1, $(event.slides_changed[i].html)[0]);
}
},
send_ws_message: function(obj) {
if (this.ws)
this.ws.send( JSON.stringify(obj) );
else
console.log("Can't send: ", obj);
},
// Return true if the input event is destined for a DOM node that takes input
_event_is_for_input: function(e) {
return (e.target.tagName == "INPUT"
|| (e.target.tagName == "BUTTON" && e.type == 'click')
|| e.target.tagName == "TEXTAREA"
) || (e.originalEvent && this._event_is_for_input(e.originalEvent));
},
_handle_key: function(e) {
// Ignore navigation unless granted navigate role
if (!this.roles.navigate)
return true;
// Ignore keys for input elements within the slides
else if (this._event_is_for_input(e))
return true;
else if (e.keyCode == 39) // ArrowRight
this.navNext();
else if (e.keyCode == 37) // ArrowLeft
this.navPrev();
else if (e.keyCode == 40 || e.keyCode == 32) // ArrowDown, Space
this.step(1);
else if (e.keyCode == 38) // ArrowUp
this.step(-1);
else
return true;
return false;
},
_handle_click: function(e) {
// Ignore clicks for input elements within the slides
if (!this._event_is_for_input(e)) {
// Did they click a slide?
var slide= e.currentTarget.dataset.slide;
if (slide && this.root.find('.slides-sidebar').hasClass('open')) {
// The menu is open. close it.
// If allowed to navigate, change the current slide to the one clicked
this.togglemenu(this.roles.navigate? slide : null);
return false;
}
}
return true;
},
getSlide: function(slide_num) {
//console.log('getSlide', slide_num);
if (slide_num < 0)
slide_num= this.slides.length + 1 + slide_num;
if (slide_num < 1)
slide_num= 1;
else if (slide_num > this.slides.length)
slide_num= this.slides.length;
return this.slides[slide_num-1];
},
goToSlide: function(slide_num, step_num) {
var slide= this.getSlide(slide_num);
slide_num= slide.num;
if (step_num == null)
step_num= slide.cur_step;
else {
if (step_num < 0)
step_num= slide.max_step + 1 + step_num;
if (step_num < 1)
step_num= 1;
else if (step_num > slide.max_step)
step_num= slide.max_step;
}
( run in 0.747 second using v1.01-cache-2.11-cpan-39bf76dae61 )