UNPKG

dhxmvp

Version:

A complete boilerplate for building online, offline and syncable MVP Single Page Applications using DHTMLX.

339 lines (296 loc) 13 kB
(function(namespace) { 'use strict'; })(window.$dhx = window.$dhx || {}); (function(namespace) { 'use strict'; })($dhx.ui = $dhx.ui || {}); /** $dhx.ui.Mediator Mediate messages between connected actors @namespace $dhx.ui @class $dhx.ui.Mediator @constructor **/ $dhx.ui.Mediator = (function(root){ var pubsub = $dhx.MQ, PubNub = (function(){ var full = function(args) { var chan = args.channel || 'questions', callback = args.data || function() {}, error = args.error || function() {}, limit = +args.limit || 5000, start = 0, count = 100, history = [], params = { channel: chan, count: count, callback: function(messages) { var msgs = messages[0]; start = messages[1]; params.start = start; PUBNUB.each(msgs.reverse(), function(m) { history.push(m); }); if (history.length >= limit) return callback(history); if (msgs.length < count) return callback(history); count = 100; add_messages(); }, error: function(e) { callback(history); error(history); } }, add_messages = function () { pubnub.history(params); }; add_messages(); }, hourly = function(setup) { var limit = 24; var count = 0; var chan = setup.channel || 'questions'; var cb = setup.data || function() {}; var eb = setup.error || function() {}; var now = new Date(); now.setUTCHours(0); now.setUTCMinutes(0); now.setUTCSeconds(0); now.setUTCMilliseconds(0); var utc_now = now.getTime(); var vectors = []; PUBNUB.each((new Array(limit)).join(',').split(','), function(_, d) { var day = utc_now - 3600000 * d; pubnub.history({ limit: 1, channel: chan, start: day * 10000, error: function() { count++; eb(); }, callback: function(messages) { // DONE? if (++count == limit) return cb(vectors); // ADD TIME SLICES var res = +(((messages[0][0] || {}).ticker || {}).avg || {}).value; var dt = (new Date(day)).getUTCHours(); var rdt = [dt, res]; //res && vectors.push(rdt); if( res ) vectors.push(rdt); // KEEP IT SORTED vectors.sort(function(a, b) { return a[0] > b[0] && -1 || 1; }); } }); }); }, API = { publish: function( message, callback) { //console.log(message); if( typeof message.collection === 'undefined' ) { throw "Mediator alerts: Your message does not specify a collection."; } return root.pubnub.publish({ channel: message.collection, message: message, callback : callback || function(m){ console.log(m); } }); }, history: { hourly: hourly, full: full } }; return API; })(), _private = { _settingListenerUp: false, _listeners: [], listening: [], _make_listener: function( pattern, fn, onConnect, subscriber_token ){ var self = this, event, collection; event = pattern.split(':')[1]; collection = pattern.split(':')[0]; //console.info( '$dhx.ui.Mediator registered listener #'+subscriber_token+' event '+event+' for '+ collection + ': ', arguments ); //subscriber_token = pubsub.subscribe(event, fn); if( ! API.live ) { console.warn("Mediator is performing offline operations."); self._settingListenerUp = false; if( onConnect ) onConnect( subscriber_token ); } else { if( _private.listening.contains( collection ) ) { return; } var state = { age: $dhx.ui.session.age(), full: $dhx.ui.session.name(), country: $dhx.ui.session.country(), appstate: 'foreground', latlong: '51.5072° N, 0.1275° W' }; pubnub.subscribe({ channel : collection, state: state, message : function( message, env, channel ){ console.info('Mediator received message sent by '+( message.client_id == $dhx.ui.session.client_id() ? 'this' : 'other' )+' client from PubNub #'+channel+'. Forwarding to pusub now.'); pubsub.publish(message.event, message); }, connect : function(channel){ _private.listening.push( channel ); self._settingListenerUp = false; console.info('Listening to #'+channel+' collection channel on PubNub.'); //console.warn("Mediator is now performing online operations through PubNub."); /*pubnub.state({ channel : channel, state : state, callback : function(m){ console.log(m) }, error : function(m){ console.log(m) } });*/ if( onConnect ) onConnect( subscriber_token ); }, disconnect : function(){ console.log("Disconnected"); }, reconnect : function(){ console.log("Reconnected"); }, error : function(){ console.log("Network Error"); }, presence : function(m){ //console.log('presence: ', m); if(m.data) dhtmlx.message(m.data.full + ' is online.'); } }); } return subscriber_token; }, _add_listener: function( list ){ var self = this, listener; for( var x = 0; x < self._listeners.length; x++ ) { listener = self._listeners[ x ]; if( listener.fn == list.fn && listener.pattern == list.pattern) { return; } } listener = { pattern: list.pattern, fn: list.fn, onConnect: list.onConnect }; self._listeners.push( listener ); }, waitForListener: function (listener, callback, interval) { interval = +interval || 1000; if ( ! self._settingListenerUp ) { callback(listener); } else { setTimeout(function () { waitForConnection(listener, callback, interval); }, interval); } }, }, API = { PubNub: PubNub, live: true, compose_message: function(event, collection, method, model, options) { var message; message = { client_id: $dhx.ui.session.client_id(), method: method || null, model: model || null, options: options || null, event: event || null, collection: collection, uuid: $dhx.guid() }; return message; }, /** Notify others on an occurrence of an event by setting up a publish point with a string @method notify @param {String} event Event to publish @param {Array} params **/ notify : function(event, params) { var message; if( typeof event === 'undefined' ) { throw "Mediator alerts: Can not notify without a event"; } if( typeof params === 'undefined' ) { throw "Mediator alerts: Can not notify without message params"; } message = this.compose_message(event, params.collection, params.method, params.model, params.options); //console.log('publishing: ', message); if( API.live ) { PubNub.publish( message, function(){ console.info('Message published to PubNub #'+ message.collection, message); } ); } else { console.info('Message published to pubsub #'+ event, message); pubsub.publish(event, message); } }, /** listen to the events published by others by registering a callback on a named event @method listen @param {String} event Event to subscribe the callback function @param {Function} fn Callback function **/ // pattern collectionName:changeModel listen : function(pattern, fn, onConnect) { var self = this, event, collection, subscriber_token; event = pattern.split(':')[1]; collection = pattern.split(':')[0]; console.warn('Setting up listener to listen to #'+ collection +' on PubNub'); subscriber_token = pubsub.subscribe(event, fn); _private._settingListenerUp = true; var listener = { pattern: pattern, fn: fn, onConnect: onConnect }; _private._add_listener( listener ); _private.waitForListener(listener, function( listener ){ _private._make_listener( listener.pattern, listener.fn, listener.onConnect, subscriber_token ); }); return subscriber_token; }, /** Unlisten to the events published by others @method unlisten @param {String} event Event to subscribe the callback function **/ unlisten : function(token) { pubsub.unsubscribe(token); } }; return API; })(window);