| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- /** @const */
- var POLL_TIMEOUT = 55000;
- /** @interface */
- function ChatSystem() {
- };
- /** */
- ChatSystem.prototype.onRequest = function() {};
- /**
- * @return {string|null}
- **/
- ChatSystem.prototype.getId = function() {};
- /**
- * @return {ChatContext}
- **/
- ChatSystem.prototype.getChatContext = function() {};
- /**
- * Async fetch history
- * @param {Room} chan
- * @param {string} text
- **/
- ChatSystem.prototype.sendMeMsg = function(chan, text) {};
- /**
- * Async fetch history
- * @param {Room} chan
- * @param {string} text
- * @param {Object=} attachments
- **/
- ChatSystem.prototype.sendMsg = function(chan, text, attachments) {};
- /**
- * Async star msg
- * @param {Room} chan
- * @param {string} msgId
- **/
- ChatSystem.prototype.starMsg = function(chan, msgId) {};
- /**
- * Async remove star from msg
- * @param {Room} chan
- * @param {string} msgId
- **/
- ChatSystem.prototype.unstarMsg = function(chan, msgId) {};
- /**
- * Async fetch history
- * @param {Room} chan
- * @param {number} ts
- **/
- ChatSystem.prototype.removeMsg = function(chan, ts) {};
- /**
- * Edit msg
- * @param {Room} chan
- * @param {number} ts
- * @param {string} newText
- **/
- ChatSystem.prototype.editMsg = function(chan, ts, newText) {};
- /**
- * Add reaction
- * @param {Room} chan
- * @param {number} ts
- * @param {string} reaction
- **/
- ChatSystem.prototype.addReaction = function(chan, ts, reaction) {};
- /**
- * Add reaction
- * @param {Room} chan
- * @param {number} ts
- * @param {string} reaction
- **/
- ChatSystem.prototype.removeReaction = function(chan, ts, reaction) {};
- /**
- * Add reaction
- * @param {Room} chan
- * @param {string} contentType
- * @param {function((string|null))} callback
- **/
- ChatSystem.prototype.openUploadFileStream = function(chan, contentType, callback) {};
- /**
- * Async fetch history
- * @param {Room} chan
- **/
- ChatSystem.prototype.fetchHistory = function(chan, cb) {};
- /**
- * @param {Room} chan
- **/
- ChatSystem.prototype.sendTyping = function(chan) {};
- /**
- * @param {Room} chan
- * @param {number} ts
- **/
- ChatSystem.prototype.markRead = function(chan, ts) {};
- /**
- * @param {Room} chan
- * @param {string} cmd
- * @param {string} args
- **/
- ChatSystem.prototype.sendCommand = function(chan, cmd, args) {};
- /**
- * @param {number} knownVersion
- * @param {number} nowTs
- * @param {boolean} withTyping
- * @return {Object|null}
- **/
- ChatSystem.prototype.poll = function(knownVersion, nowTs, withTyping) {};
- /**
- * @param {string} path
- * @return {({url: string, headers: Object})|null} path to get
- **/
- ChatSystem.prototype.getImage = function(path) {};
- /**
- * @constructor
- **/
- function MultiChatManager() {
- /** @type {Array<ChatSystem>} */
- this.contexts = [];
- }
- /**
- * @param {ChatSystem} chatSystem
- **/
- MultiChatManager.prototype.push = function(chatSystem) {
- this.contexts.push(chatSystem);
- };
- /**
- * @param {string} id
- * @return {ChatSystem|null}
- **/
- MultiChatManager.prototype.getById = function(id) {
- for (var i = 0, nbContexts = this.contexts.length; i < nbContexts; i++)
- if (id === this.contexts[i].getId())
- return this.contexts[i];
- return null;
- };
- /**
- * You may want to return true to break the loop
- **/
- MultiChatManager.prototype.foreachChannels = function(cb) {
- for (var i =0, nbCtx =this.contexts.length; i < nbCtx; i++) {
- var ctx = this.contexts[i].getChatContext();
- for (var chanId in ctx.channels)
- if (cb(ctx.channels[chanId], chanId) === true)
- return;
- }
- };
- /**
- * You may want to return true to break the loop
- **/
- MultiChatManager.prototype.foreachContext = function(cb) {
- for (var i =0, nbCtx =this.contexts.length; i < nbCtx; i++)
- if (cb(this.contexts[i].getChatContext()) === true)
- return;
- };
- /**
- * @param {string} chanId
- * @return {ChatSystem|null}
- **/
- MultiChatManager.prototype.getChannelContext = function(chanId) {
- for (var i =0, nbCtx = this.contexts.length; i < nbCtx; i++) {
- var ctx = this.contexts[i].getChatContext();
- if (ctx.channels[chanId])
- return this.contexts[i];
- }
- return null;
- };
- /**
- * @param {string} userId
- * @return {ChatSystem|null}
- **/
- MultiChatManager.prototype.getUserContext = function(userId) {
- for (var i =0, nbCtx = this.contexts.length; i < nbCtx; i++) {
- var ctx = this.contexts[i].getChatContext();
- if (ctx.users[userId])
- return this.contexts[i];
- }
- return null;
- };
- /**
- * @param {string} chanId
- * @return {Room|null}
- **/
- MultiChatManager.prototype.getChannel = function(chanId) {
- for (var i =0, nbCtx = this.contexts.length; i < nbCtx; i++) {
- var chan = this.contexts[i].getChatContext().channels[chanId];
- if (chan)
- return chan;
- }
- return null;
- };
- /**
- * @param {function(Room, ChatSystem, string):boolean=} filter (room, roomId)
- * @return {Array<string>}
- **/
- MultiChatManager.prototype.getChannelIds = function(filter) {
- var ids = [];
- for (var i =0, nbCtx = this.contexts.length; i < nbCtx; i++) {
- var channels = this.contexts[i].getChatContext().channels;
- for (var chanId in channels) {
- if (!filter || filter(channels[chanId], this.contexts[i], chanId)) {
- ids.push(chanId);
- }
- }
- }
- return ids;
- };
- MultiChatManager.prototype.getChatSystem =function(teamId) {
- for (var i =0, nbCtx = this.contexts.length; i < nbCtx; i++) {
- var sys = this.contexts[i]
- ,ctx = sys.getChatContext();
- if (ctx && ctx.team && ctx.team.id === teamId)
- return sys;
- }
- };
- /**
- * @param {string} userId
- * @return {Chatter|null}
- **/
- MultiChatManager.prototype.getUser = function(userId) {
- for (var i =0, nbCtx = this.contexts.length; i < nbCtx; i++) {
- var user = this.contexts[i].getChatContext().users[userId];
- if (user)
- return user;
- }
- return null;
- };
- /**
- * @param {string} userId
- * @return {boolean}
- **/
- MultiChatManager.prototype.isMe = function(userId) {
- for (var i =0, nbCtx = this.contexts.length; i < nbCtx; i++) {
- var ctx = this.contexts[i].getChatContext();
- if (ctx.self && ctx.self.id === userId)
- return true;
- }
- return false;
- };
- MultiChatManager.prototype.pollPeriodical = function(knownVersion, withTyping) {
- var liveFeed
- ,staticFeed
- ,allTyping
- ,v = 0
- ,now = Date.now()
- ,updated = false;
- this.contexts.forEach(function(ctx) {
- var id = ctx.getId();
- if (id) {
- var res = ctx.poll(knownVersion, now, withTyping === undefined ? true : withTyping);
- if (res) {
- if (res["static"]) {
- if (!staticFeed)
- staticFeed = {};
- staticFeed[id] = res["static"];
- }
- if (res["live"])
- if (!liveFeed)
- liveFeed = {};
- for (var i in res["live"]) {
- liveFeed[i] = res["live"][i];
- }
- if (res["typing"]) {
- if (!allTyping)
- allTyping = {};
- for (var i in res["typing"])
- allTyping[i] = res["typing"][i];
- }
- v = Math.max(v, (res["v"] || 0));
- updated = true;
- }
- }
- });
- if (updated)
- return ({
- "live": liveFeed,
- "static": staticFeed,
- "typing": allTyping,
- "v": Math.max(v, knownVersion)
- });
- };
- MultiChatManager.polling = [];
- /**
- * @param {number} knownVersion
- * @param {(function(number, function((Array<{expose:Function, modified: number}>|null))))=} checkConfigUpdate
- * @param {boolean=} withTyping default true
- **/
- MultiChatManager.prototype.poll = function(knownVersion, reqT, checkConfigUpdate, withTyping) {
- var _this = this;
- _this.contexts.forEach(function(ctx) {
- ctx.onRequest();
- });
- var p = new Promise(function(succ, err) {
- function launchPolling() {
- var currentState = _this.pollPeriodical(knownVersion, withTyping);
- if (currentState) {
- succ(currentState);
- } else {
- var timeo = setTimeout(function() {
- for (var i =0, nbCtx = MultiChatManager.polling.length; i < nbCtx; i++) {
- if (MultiChatManager.polling[i].reqT === reqT &&
- MultiChatManager.polling[i].ctx === _this &&
- MultiChatManager.polling[i].knownVersion === knownVersion) {
- MultiChatManager.polling.splice(i, 1);
- break;
- }
- }
- err();
- }, 55000);
- MultiChatManager.polling.push({ ctx: _this, knownVersion: knownVersion, reqT: reqT, checkConfigUpdate: checkConfigUpdate, withTyping: withTyping, promise: succ, timeo: timeo });
- }
- };
- if (checkConfigUpdate) {
- checkConfigUpdate(knownVersion, function(config) {
- if (config) {
- var exposedConfig = [],
- v = 0;
- config.forEach(function(conf) {
- exposedConfig.push(conf.expose());
- v = Math.max(v, conf.modified);
- });
- var res = _this.pollPeriodical(knownVersion, withTyping);
- if (res) {
- res["config"] = exposedConfig;
- succ(res);
- } else {
- succ({
- "config": exposedConfig,
- "v": v
- });
- }
- } else {
- launchPolling();
- }
- });
- } else {
- launchPolling();
- }
- });
- return p;
- };
- MultiChatManager.prototype.containsCtx = function(ctx) {
- for (var i =0, nbCtx = this.contexts.length; i < nbCtx; i++)
- if (ctx === this.contexts[i])
- return true;
- return false;
- };
- /** @param {ChatContext} ctx */
- MultiChatManager.onCtxUpdated = function(ctx) {
- var i =0;
- while (MultiChatManager.polling[i]) {
- var pollingObj = MultiChatManager.polling[i];
- if (pollingObj.ctx.containsCtx(ctx)) {
- var res = pollingObj.ctx.pollPeriodical(pollingObj.knownVersion, pollingObj.withTyping);
- if (res) {
- clearTimeout(pollingObj.timeo);
- pollingObj.promise(res);
- MultiChatManager.polling.splice(i, 1);
- } else {
- i++;
- }
- }
- }
- };
- /** @suppress {undefinedVars,checkTypes} */
- (function() {
- if (typeof module !== "undefined") {
- module.exports.MultiChatManager = MultiChatManager;
- }
- })();
|