| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /** @const */
- var TYPING_DELAY = 6500;
- /**
- * @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.<string, number>} */
- this.favoriteEmojis = {};
- /** @type {Array.<string>} */
- this.highlights = [];
- /** @type {number} */
- this.version = 0;
- };
- /**
- * @param {*} prefs
- **/
- SelfPreferences.prototype.update = function(prefs, t) {
- if (prefs["emoji_use"])
- this.favoriteEmojis = /** @type {Object<string,number>} */ (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 ? undefined : {
- "emoji_use": JSON.stringify(this.favoriteEmojis)
- ,"highlights": this.highlights
- };
- };
- /**
- * @constructor
- **/
- function ChatContext() {
- /** @type {ChatInfo} */
- this.team = null;
- /** @type {Object.<string, Room>} */
- this.channels = {};
- /** @type {Object.<string, Chatter>} */
- this.users = {};
- /** @type {Chatter} */
- this.self = null;
- /** @type {{version: number, data: Object.<string, string>}} */
- this.emojis = { version: 0, data: {} };
- /** @type {{version: number, data: Object.<string, Command>}} */
- this.commands = {version: 0, data: {} };
- /** @type {Object.<string, Object.<string, number>>} */
- this.typing = {};
- /** @type {Object<string, boolean>!} capacities */
- this.capacities = {};
- /** @type {number} */
- this.staticV = 0;
- /** @type {number} */
- this.liveV = 0;
- /** @type {number} */
- this.typingVersion = 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
- * @param {string=} idPrefix
- **/
- ChatContext.prototype.updateStatic = function(data, t, idPrefix) {
- idPrefix = idPrefix || "";
- if (data["team"]) {
- if (!this.team) this.team = this.teamFactory(data["team"]["id"]);
- this.team.update(data["team"], t);
- }
- if (data["users"]) for (var i =0, nbUsers = data["users"].length; i < nbUsers; i++) {
- var userObj = this.users[idPrefix +data["users"][i]["id"]];
- if (!userObj)
- userObj = this.users[idPrefix +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[idPrefix +data["channels"][i]["id"]];
- if (!chanObj)
- chanObj = this.channels[idPrefix +data["channels"][i]["id"]] = this.roomFactory(data["channels"][i]);
- chanObj.update(data["channels"][i], this, t, idPrefix);
- }
- 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["self"]) {
- this.self = this.users[idPrefix +data["self"]["id"]] || null;
- if (!this.self.prefs)
- this.self.prefs = new SelfPreferences();
- if (data["self"]["prefs"]) {
- this.self.prefs.update(data["self"]["prefs"], t);
- }
- }
- if (data["capacities"]) {
- this.capacities = {};
- data["capacities"].forEach(function(i) {
- this.capacities[i] = true;
- }, this);
- }
- this.staticV = Math.max(this.staticV, t);
- };
- ChatContext.prototype.updateTyping = function(typing, now) {
- var updated = false;
- if (this.typing)
- for (var i in this.typing)
- if (typing && !typing[i]) {
- delete (this.typing[i]);
- updated = true;
- }
- if (typing) {
- for (var i in typing) {
- if (this.channels[i]) {
- if (!this.typing[i])
- this.typing[i] = {};
- for (var j in typing[i]) {
- if (!this.typing[i][j])
- updated = true;
- this.typing[i][j] = now;
- }
- }
- }
- }
- if (updated)
- this.typingVersion = now;
- return updated;
- };
- /**
- * @param {number} t
- **/
- ChatContext.prototype.toStatic = function(t) {
- var channels = []
- ,users = [];
- var res = {
- "team": this.team.toStatic(t)
- ,"self": {
- "id": this.self.id
- ,"prefs": this.self.prefs ? this.self.prefs.toStatic(t) : undefined
- }
- ,"emojis": this.emojis.version > t ? this.emojis.data : undefined
- };
- if (this.staticV > t) {
- res["capacities"] = Object.keys(this.capacities);
- }
- 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;
- return res;
- };
- /**
- * @param {number} version
- * @return {Object<Object<string, number>>|undefined}
- **/
- ChatContext.prototype.getWhoIsTyping = function(version, now) {
- var res;
- this.cleanTyping(now);
- if (this.typingVersion > version) {
- res = {};
- for (var typingChan in this.typing) {
- res[typingChan] = {};
- for (var typingUser in this.typing[typingChan])
- res[typingChan][typingUser] = 1;
- }
- }
- return res;
- };
- /**
- * @param {string} chanNameOrUserName
- * @return {Room|null}
- **/
- ChatContext.prototype.getRoom = function(chanNameOrUserName) {
- var chans = this.getChannelsWithName(chanNameOrUserName);
- if (chans.length)
- return chans[0];
- var users = this.getUsersWithName(chanNameOrUserName);
- if (users.length)
- for (var i =0, nbUsers = users.length; i < nbUsers; i++)
- if (users[i].privateRoom)
- return users[i].privateRoom;
- return null;
- };
- ChatContext.prototype.getChannelsWithName = function(name) {
- var chans = [];
- if (name[0] === '#')
- name = name.substr(1);
- for (var i in this.channels)
- if (this.channels[i].name === name)
- chans.push(this.channels[i]);
- return chans;
- };
- ChatContext.prototype.getUsersWithName = function(name) {
- var users = [];
- if (name[0] === '@')
- name = name.substr(1);
- for (var i in this.users)
- if (this.users[i].getName() === name)
- users.push(this.channels[i]);
- return users;
- };
- /**
- * @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] +TYPING_DELAY < now) {
- delete this.typing[typingChan][typingUser];
- updated = true;
- } else {
- chanEmpty = false;
- }
- }
- if (chanEmpty) {
- delete this.typing[typingChan];
- updated = true;
- }
- }
- if (updated)
- this.typingVersion = now;
- return updated;
- };
- ChatContext.prototype.stopTyping = function(chanId, userId, t) {
- if (this.typing[chanId] && this.typing[chanId][userId]) {
- delete this.typing[chanId][userId];
- var empty = true;
- for (var i in this.typing[chanId]) {
- empty = false;
- break;
- }
- if (empty)
- delete this.typing[chanId];
- this.typingVersion = t;
- }
- };
- /** @suppress {undefinedVars,checkTypes} */
- (function() {
- if (typeof module !== "undefined") {
- module.exports.ChatContext = ChatContext;
- module.exports.ChatInfo = ChatInfo;
- module.exports.Command = Command;
- }
- })();
|