/** * @constructor * @extends {RoomHistory} * @param {Room|string} room or roomId * @param {number} keepMessages number of messages to keep in memory * @param {Array|undefined} evts * @param {number|undefined} now **/ function UiRoomHistory(room, keepMessages, evts, now) { RoomHistory.call(this, room, keepMessages, evts, now); } UiRoomHistory.prototype = Object.create(RoomHistory.prototype); UiRoomHistory.prototype.constructor = UiRoomHistory; UiRoomHistory.prototype.messageFactory = function(ev, ts) { if (ev["isMeMessage"] === true) return new UiMeMessage(this.id, ev, ts); if (ev["isNotice"] === true) return new UiNoticeMessage(this.id, ev, ts); return new UiMessage(this.id, ev, ts); } /** @interface */ function IUiMessage() {}; /** * @return {Element} **/ IUiMessage.prototype.getDom = function() {}; /** * @return {IUiMessage} **/ IUiMessage.prototype.removeDom = function() {}; /** * @return {IUiMessage} **/ IUiMessage.prototype.invalidate = function() {}; /** * @return {IUiMessage} **/ IUiMessage.prototype.createDom = function() {}; /** * @return {IUiMessage} **/ IUiMessage.prototype.updateDom = function() {}; /** * @return {Element} **/ IUiMessage.prototype.duplicateDom = function() {}; /** @const */ var AbstractUiMessage = (function() { var updateReactions = function(_this, channelId) { var reactionFrag = document.createDocumentFragment(); if (_this.reactions) { for (var reaction in _this.reactions) { var reac = createReactionDom(channelId, _this.id, reaction, _this.reactions[reaction]); if (reac) reactionFrag.appendChild(reac); } } _this.dom.reactions.textContent = ''; _this.dom.reactions.appendChild(reactionFrag); }, updateAttachments = function(_this, channelId) { var attachmentFrag = document.createDocumentFragment(); for (var i =0, nbAttachments = _this.attachments.length; i < nbAttachments; i++) { var attachment = _this.attachments[i]; if (attachment) { var domAttachment = createAttachmentDom(channelId, _this, attachment, i); if (domAttachment) attachmentFrag.appendChild(domAttachment); } } _this.dom.attachments.textContent = ''; _this.dom.attachments.appendChild(attachmentFrag); }, updateCommon = function(_this, sender) { _this.dom.ts.innerHTML = locale.formatDate(_this.ts); _this.dom.textDom.innerHTML = formatText(_this.text); _this.dom.authorName.textContent = sender ? sender.name : (_this.username || "?"); }; return { /** @type {Element|null} * dom: null, /** @type {boolean} * uiNeedRefresh: true, */ /** @param {IUiMessage} _this */ invalidate: function(_this) { _this.uiNeedRefresh = true; return _this; }, /** @param {UiMessage|UiMeMessage|UiNoticeMessage} _this */ removeDom: function(_this) { if (_this.dom && _this.dom.parentElement) { _this.dom.remove(); delete(_this.dom); } return _this; }, /** @param {UiMessage|UiMeMessage|UiNoticeMessage} _this */ getDom: function(_this) { if (!_this.dom) { _this.createDom().updateDom(); } else if (_this.uiNeedRefresh) { _this.uiNeedRefresh = false; _this.updateDom(); } return _this.dom; }, /** @param {UiMessage|UiMeMessage|UiNoticeMessage} _this */ updateDom: function(_this) { var sender = SLACK.context.users[_this.userId]; updateCommon(_this, sender); updateAttachments(_this, _this.channelId); updateReactions(_this, _this.channelId); if (_this.edited) _this.dom.classList.add(R.klass.msg.editedStatus); return _this; }, duplicateDom: function(_this) { return _this.dom.cloneNode(true); } }; })(); /** * @constructor * @implements {IUiMessage} * @extends {MeMessage} * @param {*} ev * @param {number} ts **/ function UiMeMessage(channelId, ev, ts) { // Extends AbstractUiMessage and MeMessage MeMessage.call(this, ev, ts); /** @type {string} @const */ this.channelId = channelId; this.dom = AbstractUiMessage.dom; this.uiNeedRefresh = AbstractUiMessage.uiNeedRefresh; } UiMeMessage.prototype = Object.create(MeMessage.prototype); UiMeMessage.prototype.constructor = UiMeMessage; UiMeMessage.prototype.invalidate = function() { return AbstractUiMessage.invalidate(this); }; UiMeMessage.prototype.removeDom = function() { return AbstractUiMessage.removeDom(this); }; UiMeMessage.prototype.getDom = function() { return AbstractUiMessage.getDom(this); }; UiMeMessage.prototype.createDom = function() { this.dom = doCreateMessageDom(this, false); this.dom.classList.add(R.klass.msg.meMessage); return this; }; UiMeMessage.prototype.duplicateDom = function() { return AbstractUiMessage.duplicateDom(this); }; UiMeMessage.prototype.updateDom = function() { AbstractUiMessage.updateDom(this); return this; }; UiMeMessage.prototype.update = function(ev, ts) { MeMessage.prototype.update.call(this, ev, ts); this.invalidate(); }; /** * @constructor * @implements {IUiMessage} * @extends {Message} * @param {*} ev * @param {number} ts **/ function UiMessage(channelId, ev, ts) { // Extends AbstractUiMessage and Message Message.call(this, ev, ts); /** @type {string} @const */ this.channelId = channelId; /** @type {Element} */ this.dom = AbstractUiMessage.dom; /** @type {boolean} */ this.uiNeedRefresh = AbstractUiMessage.uiNeedRefresh; } UiMessage.prototype = Object.create(Message.prototype); UiMessage.prototype.constructor = UiMessage; UiMessage.prototype.invalidate = function() { return AbstractUiMessage.invalidate(this); }; UiMessage.prototype.removeDom = function() { return AbstractUiMessage.removeDom(this); }; UiMessage.prototype.getDom = function() { return AbstractUiMessage.getDom(this); }; UiMessage.prototype.createDom = function() { this.dom = doCreateMessageDom(this, false); return this; }; UiMessage.prototype.duplicateDom = function() { return AbstractUiMessage.duplicateDom(this); }; UiMessage.prototype.updateDom = function() { AbstractUiMessage.updateDom(this); return this; }; UiMessage.prototype.update = function(ev, ts) { Message.prototype.update.call(this, ev, ts); this.invalidate(); }; /** * @constructor * @implements {IUiMessage} * @extends {NoticeMessage} * @param {*} ev * @param {number} ts **/ function UiNoticeMessage(channelId, ev, ts) { // Extends AbstractUiMessage and NoticeMessage NoticeMessage.call(this, ev, ts); /** @type {string} @const */ this.channelId = channelId; this.dom = AbstractUiMessage.dom; /** @type {Element} */ this.domWrapper = null; this.uiNeedRefresh = AbstractUiMessage.uiNeedRefresh; } UiNoticeMessage.prototype = Object.create(NoticeMessage.prototype); UiNoticeMessage.prototype.constructor = UiNoticeMessage; UiNoticeMessage.prototype.invalidate = function() { return AbstractUiMessage.invalidate(this); }; UiNoticeMessage.prototype.removeDom = function() { if (this.domWrapper && this.domWrapper.parentElement) { this.domWrapper.remove(); delete(this.domWrapper); } if (this.dom) delete(this.dom); return this; }; UiNoticeMessage.prototype.getDom = function() { AbstractUiMessage.getDom(this); return this.domWrapper; }; UiNoticeMessage.prototype.duplicateDom = function() { return this.domWrapper.cloneNode(true); }; UiNoticeMessage.prototype.createDom = function() { this.dom = doCreateMessageDom(this, false); this.domWrapper = document.createElement("span"); this.dom.classList.add(R.klass.msg.notice); this.domWrapper.className = R.klass.msg.notice; this.domWrapper.textContent = locale.onlyVisible; return this; }; UiNoticeMessage.prototype.updateDom = function() { AbstractUiMessage.updateDom(this); return this; }; UiNoticeMessage.prototype.update = function(ev, ts) { NoticeMessage.prototype.update.call(this, ev, ts); this.invalidate(); };