| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- /** @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
- * @return {Object|null}
- **/
- ChatSystem.prototype.poll = function(knownVersion, nowTs) {};
- /**
- * @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;
- };
- /**
- * @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++)
- if (this.contexts[i].getChatContext().self.id === userId)
- return true;
- return false;
- };
- MultiChatManager.prototype.pollPeriodical = function(knownVersion) {
- 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);
- 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.prototype.startPolling = function(knownVersion, reqT, callback) {
- var _this = this;
- var res = _this.pollPeriodical(knownVersion),
- now = Date.now();
- if (res) {
- callback(res);
- } else if (now -reqT > POLL_TIMEOUT) {
- callback({
- "v": knownVersion
- });
- } else {
- setTimeout(function() { _this.startPolling(knownVersion, reqT, callback); }, 2000);
- }
- };
- /**
- * @param {number} knownVersion
- * @param {Function} callback
- * @param {(function(number, function((Array<{expose:Function, modified: number}>|null))))=} checkConfigUpdate
- **/
- MultiChatManager.prototype.poll = function(knownVersion, reqT, callback, checkConfigUpdate) {
- this.contexts.forEach(function(ctx) {
- ctx.onRequest();
- });
- var _this = this;
- 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);
- if (res) {
- res["config"] = exposedConfig;
- callback(res);
- } else {
- callback({
- "config": exposedConfig,
- "v": v
- });
- }
- } else {
- _this.startPolling(knownVersion, reqT, callback);
- }
- });
- } else {
- _this.startPolling(knownVersion, reqT, callback);
- }
- };
- /** @suppress {undefinedVars,checkTypes} */
- (function() {
- if (typeof module !== "undefined") {
- module.exports.MultiChatManager = MultiChatManager;
- }
- })();
|