diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index d01aa2f0..a046aa39 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -757,15 +757,16 @@ class Chat { addMessage(message, win = null) { // eslint-disable-next-line no-param-reassign if (win === null) win = this.mainwindow; + const previousMessage = win.getPreviousMessage(message); // Break the current combo if this message is not an emote // We don't need to check what type the current message is, we just know that its a new message, so the combo is invalid. if ( - win.lastmessage && - win.lastmessage.type === MessageTypes.EMOTE && - win.lastmessage.emotecount > 1 + previousMessage && + previousMessage.type === MessageTypes.EMOTE && + previousMessage.emotecount > 1 ) - win.lastmessage.completeCombo(); + previousMessage.completeCombo(); // Populate the tag and mentioned users for this $message. if ( @@ -798,16 +799,11 @@ class Chat { // Populate highlight for this $message if (message.type === MessageTypes.USER) { // check if the last message was from the same user - message.continued = win.isContinued(message); + message.continued = win.isContinued(message, previousMessage); // set highlighted state message.highlighted = this.shouldHighlightMessage(message); } - // This looks odd, although it would be a correct implementation - /* else if(win.lastmessage && win.lastmessage.type === message.type && [MessageTypes.ERROR,MessageTypes.INFO,MessageTypes.COMMAND,MessageTypes.STATUS].indexOf(message.type)){ - message.continued = true - } */ - // The point where we actually add the message dom win.addMessage(this, message); @@ -1147,23 +1143,25 @@ class Chat { const textonly = this.removeSlashCmdFromText(data.data); const usr = this.users.get(data.nick.toLowerCase()); const win = this.mainwindow; + const message = MessageBuilder.message(data.data, usr, data.timestamp); + const previousMessage = win.getPreviousMessage(message); const isCombo = this.emoteService.canUserUseEmote(usr, textonly) && - this.removeSlashCmdFromText(win.lastmessage?.message) === textonly; + this.removeSlashCmdFromText(previousMessage?.message) === textonly; - if (isCombo && win.lastmessage?.type === MessageTypes.EMOTE) { - win.lastmessage.incEmoteCount(); + if (isCombo && previousMessage?.type === MessageTypes.EMOTE) { + previousMessage.incEmoteCount(); if (this.user.equalWatching(usr.watching)) { - win.lastmessage.ui.classList.toggle('watching-same', true); + previousMessage.ui.classList.toggle('watching-same', true); } this.mainwindow.update(); return; } - if (isCombo && win.lastmessage?.type === MessageTypes.USER) { - win.removeLastMessage(); + if (isCombo && previousMessage?.type === MessageTypes.USER) { + win.removeMessage(previousMessage); const msg = MessageBuilder.emote(textonly, data.timestamp, 2).into(this); if (this.user.equalWatching(usr.watching)) { @@ -1173,7 +1171,7 @@ class Chat { } if (!this.resolveMessage(data.nick, data.data)) { - MessageBuilder.message(data.data, usr, data.timestamp).into(this); + message.into(this); } } diff --git a/assets/chat/js/window.js b/assets/chat/js/window.js index b1b5a1ff..5d1fce4d 100644 --- a/assets/chat/js/window.js +++ b/assets/chat/js/window.js @@ -82,34 +82,46 @@ class ChatWindow extends EventEmitter { message.afterRender(chat); // Get index of where the message should be based on timestamp. - const index = this.messages.findLastIndex( - (m) => m.timestamp.valueOf() <= message.timestamp.valueOf(), - ); + const index = this.getMessageIndex(message); /** - * If message index is < 0 then add message to the top of chat. - * - * If message index + 1 >= the length of messages array, - * it is a new message so add to bottom of chat. - * - * Otherwise the message is inbetween so insert in correct place. + * If the index of the message is 0 then prepend. + * If it's equal the length of the array then append. + * Otherwise insert at index. */ - if (index < 0) { + if (index === 0) { this.lines.prepend(message.ui); this.messages.unshift(message); - } else if (index + 1 >= this.messages.length) { + } else if (index === this.messages.length) { this.lines.append(message.ui); this.messages.push(message); this.lastmessage = message; } else { - this.lines.insertBefore(message.ui, this.messages[index + 1].ui); - this.messages.splice(index + 1, 0, message); + this.lines.insertBefore(message.ui, this.messages[index].ui); + this.messages.splice(index, 0, message); } this.linecount += 1; this.cleanupThrottle(); } + getMessageIndex(message) { + return ( + this.messages.findLastIndex( + (m) => m.timestamp.valueOf() <= message.timestamp.valueOf(), + ) + 1 + ); + } + + getPreviousMessage(message) { + const index = this.getMessageIndex(message); + if (index === 0) { + return null; + } + + return this.messages[index - 1]; + } + containsMessage(message) { return this.messages.find((msg) => msg.md5 === message.md5); } @@ -200,9 +212,9 @@ class ChatWindow extends EventEmitter { } } - removeLastMessage() { - this.lastmessage.remove(); - this.messages = this.messages.filter((m) => m !== this.lastmessage); + removeMessage(message) { + message.remove(); + this.messages = this.messages.filter((m) => m !== message); } /**