/** * @constructor **/ function ChatInfo(id) { /** @const @type {string} */ this.id = id; /** @type {string} */ this.name; /** @type {number} */ this.version = 0; }; ChatInfo.prototype.toStatic = function(t) { return t >= this.version ? undefined : { "id": this.id ,"name": this.name }; }; ChatInfo.prototype.update = function(data, t) { if (data["name"] !== undefined) this.name = data["name"]; this.version = Math.max(this.version, t); }; /** * @constructor * @param {*} data **/ function Command(data) { /** @const @type {string} */ this.desc = data["desc"]; /** @const @type {string} */ this.name = data["name"]; /** @const @type {string} */ this.type = data["type"]; /** @const @type {string} */ this.usage = data["usage"]; /** @const @type {string} */ this.category = data["category"]; }; /** * @param {number} t * @return {Object} **/ Command.prototype.toStatic = function(t) { return { "desc": this.desc ,"name": this.name ,"type": this.type ,"usage": this.usage ,"category": this.category }; }; /** * @constructor **/ function SelfPreferences() { /** @type {Object.} */ this.favoriteEmojis = {}; /** @type {Array.} */ this.highlights = []; }; /** * @param {*} prefs **/ SelfPreferences.prototype.update = function(prefs, t) { this.favoriteEmojis = /** @type {Object} */ (JSON.parse(prefs["emoji_use"])); if (prefs["highlight_words"]) this.highlights = (prefs["highlight_words"]||"").split(',').filter(function(i) { return i.trim() !== ''; }); else if (prefs["highlights"]) this.highlights = prefs["highlights"]; this.version = Math.max(this.version, t); }; SelfPreferences.prototype.toStatic = function(t) { return this.version > t ? null : { "emoji_use": JSON.stringify(this.favoriteEmojis) ,"highlights": this.highlights }; }; /** * @constructor **/ function ChatContext() { /** @type {ChatInfo} */ this.team = null; /** @type {Object.} */ this.channels = {}; /** @type {Object.} */ this.users = {}; /** @type {Chatter} */ this.self = null; /** @type {{version: number, data: Object.}} */ this.emojis = { version: 0, data: {} }; /** @type {{version: number, data: Object.}} */ this.commands = {version: 0, data: {} }; /** @type {Object.>} */ this.typing = {}; /** @type {number} */ this.staticV = 0; /** @type {number} */ this.liveV = 0; }; ChatContext.prototype.userFactory = function(userData) { return new Chatter(userData["id"]); }; ChatContext.prototype.roomFactory = function(roomData) { return roomData["pv"] ? new PrivateMessageRoom(roomData["id"], this.users[roomData["user"]]) : new Room(roomData["id"]); }; ChatContext.prototype.teamFactory = function(id) { return new ChatInfo(id); }; ChatContext.prototype.commandFactory = function(data) { return new Command(data); }; /** * @param {*} data * @param {number} t **/ ChatContext.prototype.updateStatic = function(data, t) { if (data["users"]) for (var i =0, nbUsers = data["users"].length; i < nbUsers; i++) { var userObj = this.users[data["users"][i]["id"]]; if (!userObj) userObj = this.users[data["users"][i]["id"]] = this.userFactory(data["users"][i]); userObj.update(data["users"][i], t); } if (data["channels"]) for (var i =0, nbChan = data["channels"].length; i < nbChan; i++) { var chanObj = this.channels[data["channels"][i]["id"]]; if (!chanObj) chanObj = this.channels[data["channels"][i]["id"]] = this.roomFactory(data["channels"][i]); chanObj.update(data["channels"][i], this, t); } if (data["emojis"]) { this.emojis.data = data["emojis"]; this.emojis.version = t; } if (data["commands"] !== undefined){ this.commands.data = {}; for (var i in data["commands"]) { this.commands.data[i] = this.commandFactory(data["commands"][i]); } this.commands.version = t; } if (data["team"]) { if (!this.team) this.team = this.teamFactory(data["team"]["id"]); this.team.update(data["team"], t); } this.staticV = Math.max(this.staticV, t); if (data["self"]) { this.self = this.users[data["self"]["id"]] || null; if (this.self) { if (!this.self.prefs) this.self.prefs = new SelfPreferences(); this.self.prefs.update(data["self"]["prefs"], t); } else { this.staticV = 0; } } if (data["typing"] !== undefined) { this.typing = {}; for (var i in data["typing"]) { this.typing[i] = {}; for (var j in data["typing"][i]) this.typing[i][j] = t; } } }; /** * @param {number} t * @param {number} now **/ ChatContext.prototype.toStatic = function(t, now) { var channels = [] ,users = []; var res = { "team": this.team.toStatic(t) ,"self": { "id": this.self.id ,"prefs": this.self.prefs.toStatic(t) } ,"emojis": this.emojis.version > t ? this.emojis.data : undefined }; if (this.commands.version > t) { res["commands"] = {}; for (var i in this.commands.data) res["commands"][i] = this.commands.data[i].toStatic(t); } for (var chanId in this.channels) { var chan = this.channels[chanId].toStatic(t); if (chan) channels.push(chan); } if (channels.length) res["channels"] = channels; for (var userId in this.users) { var user = this.users[userId].toStatic(t); if (user) users.push(user); } if (users.length) res["users"] = users; for (var typingChan in this.typing) { var tChan = null; for (var typingUser in this.typing[typingChan]) { if (this.typing[typingChan][typingUser] +3000 >= now) { if (!tChan) tChan = {}; tChan[typingUser] = 1; } else { delete this.typing[typingChan][typingUser]; } } if (tChan) { if (res["typing"] === undefined) res["typing"] = {}; res["typing"][typingChan] = tChan; } else delete this.typing[typingChan]; } return res; }; /** * @param {number} now **/ ChatContext.prototype.cleanTyping = function(now) { var updated = false; for (var typingChan in this.typing) { var chanEmpty = true; for (var typingUser in this.typing[typingChan]) { if (this.typing[typingChan][typingUser] +3000 < now) { delete this.typing[typingChan][typingUser]; updated = true; } else { chanEmpty = false; } } if (chanEmpty) { delete this.typing[typingChan]; updated = true; } } return updated; }; /** @suppress {undefinedVars,checkTypes} */ (function() { if (typeof module !== "undefined") { module.exports.ChatContext = ChatContext; module.exports.ChatInfo = ChatInfo; module.exports.Command = Command; } })();