%PDF- %PDF-
| Direktori : /home/vacivi36/intranet.vacivitta.com.br/assets/6fd3b69d/js/ |
| Current File : /home/vacivi36/intranet.vacivitta.com.br/assets/6fd3b69d/js/humhub.live.poll.js |
humhub.module('live.poll', function (module, require, $) {
var client = require('client');
var event = require('event');
var object = require('util').object;
var DEFAULT_MIN_INTERVAL = 10;
var DEFAULT_MAX_INTERVAL = 45;
var DEFAULT_IDLE_FACTOR = 0.1;
var DEFAULT_IDLE_INTERVAL = 20;
var EVENT_TYPE_REQUEST = 'request';
var EVENT_TYPE_FOCUS = 'focus';
var EVENT_TYPE_UPDATE = 'update';
var counter = {
requests: 0,
updates: 0
};
var PollClient = function (options) {
if (!options) {
module.log.error('Could not initialize PollClient. No options given!');
return;
}
this.options = options;
this.options.minInterval = options.minInterval || DEFAULT_MIN_INTERVAL;
this.options.maxInterval = options.maxInterval || DEFAULT_MAX_INTERVAL;
this.options.idleFactor = options.idleFactor || DEFAULT_IDLE_FACTOR;
this.options.idleInterval = options.idleDelay || DEFAULT_IDLE_INTERVAL;
this.options.initTime = options.initTime || Date.now();
this.init();
};
PollClient.prototype.init = function () {
if (!this.options.url) {
module.log.error('Could not initialize PollClient. No url option given!');
return;
}
this.subscriberId = this.generateSubscriberId();
this.focus = true;
this.delay = this.options.minInterval;
this.call = this.update.bind(this);
this.handle = this.handleUpdate.bind(this);
this.handleError = this.handleUpdateError.bind(this);
this.lastTs = this.options.initTime;
$(window)
.on('blur', this.onWindowBlur.bind(this))
.on('focus',this.onWindowFocus.bind(this));
var that = this;
$(document).on('mousemove keydown mousedown touchstart', object.debounce(function() {
that.stopIdle();
}, 200));
this.resetPollTimeout();
this.startIdleTimer();
this.initBroadCast();
};
PollClient.prototype.generateSubscriberId = function () {
return '_' + Math.random().toString(36).substr(2, 9);
};
PollClient.prototype.initBroadCast = function () {
if(!window.BroadcastChannel) {
return;
}
this.channel = new BroadcastChannel('live.poll');
var that = this;
this.channel.onmessage = function(evt) {
if(!evt.data) {
return;
}
if(evt.data.subscriberId === that.subscriberId) {
// We triggered the event, so nothing todo
return;
}
if(!that.focus) {
// Seems this is an inactive tab, so let others do the job...
that.resetPollTimeout(that.options.maxInterval);
}
switch (evt.data.type) {
case EVENT_TYPE_REQUEST:
// Another tab just started a request, so delay the timeout
that.resetPollTimeout();
break;
case EVENT_TYPE_FOCUS:
// Another tab was focused, so increase delay and reset timeout
that.resetPollTimeout(that.options.maxInterval);
break;
case EVENT_TYPE_UPDATE:
// We received a response from another tab
that.handleUpdate(evt.data);
break;
}
}
};
/**
* Handler called once the window was focused
*/
PollClient.prototype.onWindowFocus = function () {
this.focus = true;
this.stopIdle();
this.broadCast(EVENT_TYPE_FOCUS);
};
/**
* Handler called once the window was blurred
*/
PollClient.prototype.onWindowBlur = function () {
this.focus = false;
this.updateIdle();
};
/**
* Resets current timeout if set and starts polling with current delay
*/
PollClient.prototype.resetPollTimeout = function (delay) {
clearTimeout(this.timeout);
if(delay) {
this.setDelay(delay);
}
this.timeout = setTimeout(this.call, this.getDelay());
};
/**
* Resets current timeout if set and starts polling with current delay
*/
PollClient.prototype.startIdleTimer = function () {
setInterval($.proxy(this.updateIdle, this), (this.options.idleInterval * 1000));
};
/**
* Stops the idle behavior by resetting the delay to the min delay
*/
PollClient.prototype.stopIdle = function () {
this.setDelay(this.options.minInterval);
// Make sure we do not have to wait too long after idle end.
if (new Date() - this.lastTs > this.options.minInterval) {
this.resetPollTimeout();
}
};
/**
* Updates the delay by means of the idleFactor.
*/
PollClient.prototype.updateIdle = function () {
if (this.delay < this.options.maxInterval) {
this.setDelay(Math.ceil(this.delay + (this.delay * this.options.idleFactor)));
}
if (this.delay > this.options.maxInterval) {
this.setDelay(this.options.maxInterval);
}
};
/**
* Runs an live update call and resets the timeout.
*/
PollClient.prototype.update = function () {
this.broadCast(EVENT_TYPE_REQUEST);
counter.requests++;
client.get(this.getCallOptions())
.then(this.handle)
.catch(this.handleError);
};
/**
* Returns the ajax call options
*/
PollClient.prototype.getCallOptions = function () {
return {
url: this.options.url,
data: {
last: this.lastTs
}
};
};
/**
* Handles the live update response.
*/
PollClient.prototype.handleUpdate = function (response) {
if(this.lastTs >= response.queryTime) {
// We already have a more recent update
return;
}
if(this.subscriberId === response.subscriberId) {
// Just to make sure we do not handle our own broadcast event
return;
}
// used for debugging only
counter.updates++;
this.lastTs = response.queryTime;
this.resetPollTimeout();
if(!response.subscriberId) {
// If subscriberId is present, this data was already sent
this.broadCast(EVENT_TYPE_UPDATE, {
queryTime: response.queryTime,
events: response.events
});
}
this.triggerEventUpdates(response);
};
PollClient.prototype.triggerEventUpdates = function(response) {
if(object.isObject(response.events)) {
var events = this.groupEvents(response.events);
$.each(events, function (type, events) {
try {
// humhub.module.bla -> humhub:module:bla
event.trigger(type.replace(/\./g, ':'), [events, response]);
} catch (e) {
module.log.error(e);
}
});
this.lastIds = Object.keys(response.events);
}
};
PollClient.prototype.broadCast = function (type, data) {
data = data || {};
if(!this.channel || data.subscriberId) {
return;
}
data.subscriberId = this.subscriberId;
data.type = type;
this.channel.postMessage(data);
};
/**
* Groups the liveEvents by type and filters out duplicates.
*/
PollClient.prototype.groupEvents = function (events) {
var result = {};
var that = this;
$.each(events, function (id, liveEvent) {
// Filter out already triggered events.
if(that.lastIds && that.lastIds.indexOf(id) > -1) {
return; // continue
}
if (!result[liveEvent.type]) {
result[liveEvent.type] = [liveEvent];
} else {
result[liveEvent.type].push(liveEvent);
}
});
return result;
};
PollClient.prototype.handleUpdateError = function (e) {
if(!navigator.onLine) {
this.resetPollTimeout(this.options.maxInterval);
module.log.info('Poll request blocked due to offline status');
} else {
module.log.error(e);
}
};
/**
* Returns the delay in milliseconds.
* @returns {Number}
*/
PollClient.prototype.getDelay = function () {
return this.delay * 1000;
};
/**
* Sets the delay in seconds
* @returns {Number}
*/
PollClient.prototype.setDelay = function (seconds) {
this.delay = seconds;
};
module.export({
PollClient: PollClient
});
});