Bug 1649445 - Unify code-paths for displaying incoming IRC messages. r=mkmelin a=wsmwk
authorPatrick Cloke <clokep@gmail.com>
Tue, 07 Jul 2020 16:50:49 -0400
changeset 39538 c3c605e5447ba92d243614d329c0efe9888e09c9
parent 39537 b6f5860251492af1943b00ff66beb315014fed7f
child 39539 cd4a02a719989f0275d4624add4a7c2cf4a3dc28
push id12
push userthunderbird@calypsoblue.org
push dateFri, 17 Jul 2020 02:47:50 +0000
treeherdercomm-esr78@c3c605e5447b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, wsmwk
bugs1649445
Bug 1649445 - Unify code-paths for displaying incoming IRC messages. r=mkmelin a=wsmwk
chat/protocols/irc/ircBase.jsm
chat/protocols/irc/ircCTCP.jsm
chat/protocols/irc/ircCommands.jsm
chat/protocols/irc/ircUtils.jsm
--- a/chat/protocols/irc/ircBase.jsm
+++ b/chat/protocols/irc/ircBase.jsm
@@ -23,53 +23,20 @@ var { setTimeout, clearTimeout, nsSimple
   "resource:///modules/imXPCOMUtils.jsm"
 );
 var { Services } = ChromeUtils.import("resource:///modules/imServices.jsm");
 var { ircHandlers } = ChromeUtils.import("resource:///modules/ircHandlers.jsm");
 var {
   _,
   ctcpFormatToText,
   conversationErrorMessage,
+  displayMessage,
   kListRefreshInterval,
 } = ChromeUtils.import("resource:///modules/ircUtils.jsm");
 
-function privmsg(aAccount, aMessage, aIsNotification) {
-  let params = { tags: aMessage.tags };
-  // If the the message is from our nick, it is outgoing to the conversation it
-  // is targeting. Otherwise, the message is incoming, but could be for a
-  // private message or a channel.
-  //
-  // Note that the only time it is expected to receive a message from us is if
-  // the echo-message capability is enabled.
-  let convName;
-  if (
-    aAccount.normalizeNick(aMessage.origin) ==
-    aAccount.normalizeNick(aAccount._nickname)
-  ) {
-    params.outgoing = true;
-    // The conversation name is who it is being sent to.
-    convName = aMessage.params[0];
-  } else {
-    params.incoming = true;
-    // If the target is a MUC name, use the target as the conversation name.
-    // Otherwise, this is a private message: use the sender as the conversation
-    // name.
-    convName = aAccount.isMUCName(aMessage.params[0])
-      ? aMessage.params[0]
-      : aMessage.origin;
-  }
-  if (aIsNotification) {
-    params.notification = true;
-  }
-  aAccount
-    .getConversation(convName)
-    .writeMessage(aMessage.origin, aMessage.params[1], params);
-  return true;
-}
-
 // Display the message and remove them from the rooms they're in.
 function leftRoom(aAccount, aNicks, aChannels, aSource, aReason, aKicked) {
   let msgId = "message." + (aKicked ? "kicked" : "parted");
   // If a part message was included, include it.
   let reason = aReason ? _(msgId + ".reason", aReason) : "";
   function __(aNick, aYou) {
     // If the user is kicked, we need to say who kicked them.
     let msgId2 = msgId + (aYou ? ".you" : "");
@@ -331,17 +298,17 @@ var ircBase = {
     },
     NOTICE(aMessage) {
       // NOTICE <msgtarget> <text>
       // If the message is from the server, don't show it unless the user wants
       // to see it.
       if (!this.connected || aMessage.origin == this._currentServerName) {
         return serverMessage(this, aMessage);
       }
-      return privmsg(this, aMessage, true);
+      return displayMessage(this, aMessage, true);
     },
     PART(aMessage) {
       // PART <channel> *( "," <channel> ) [ <Part Message> ]
       return leftRoom(
         this,
         [aMessage.origin],
         aMessage.params[0].split(","),
         aMessage.source,
@@ -364,17 +331,17 @@ var ircBase = {
         return true;
       }
       // Otherwise, the ping was from a user command.
       return this.handlePingReply(aMessage.origin, pongTime);
     },
     PRIVMSG(aMessage) {
       // PRIVMSG <msgtarget> <text to be sent>
       // Display message in conversation
-      return privmsg(this, aMessage);
+      return displayMessage(this, aMessage);
     },
     QUIT(aMessage) {
       // QUIT [ < Quit Message> ]
       // Some IRC servers automatically prefix a "Quit: " string. Remove the
       // duplication and use a localized version.
       let quitMsg = aMessage.params[0] || "";
       if (quitMsg.startsWith("Quit: ")) {
         quitMsg = quitMsg.slice(6); // "Quit: ".length
--- a/chat/protocols/irc/ircCTCP.jsm
+++ b/chat/protocols/irc/ircCTCP.jsm
@@ -9,17 +9,19 @@
  */
 
 const EXPORTED_SYMBOLS = ["ircCTCP", "ctcpBase"];
 
 const { Services } = ChromeUtils.import("resource:///modules/imServices.jsm");
 const { ircHandlers } = ChromeUtils.import(
   "resource:///modules/ircHandlers.jsm"
 );
-var { _ } = ChromeUtils.import("resource:///modules/ircUtils.jsm");
+var { _, displayMessage } = ChromeUtils.import(
+  "resource:///modules/ircUtils.jsm"
+);
 
 // Split into a CTCP message which is a single command and a single parameter:
 //   <command> " " <parameter>
 // The high level dequote is to unescape \001 in the message content.
 function CTCPMessage(aMessage, aRawCTCPMessage) {
   let message = Object.assign({}, aMessage);
   message.ctcp = {};
   message.ctcp.rawMessage = aRawCTCPMessage;
@@ -131,25 +133,22 @@ var ctcpBase = {
   priority: ircHandlers.DEFAULT_PRIORITY,
   isEnabled: () => true,
 
   // These represent CTCP commands.
   commands: {
     ACTION(aMessage) {
       // ACTION <text>
       // Display message in conversation
-      this.getConversation(
-        this.isMUCName(aMessage.params[0])
-          ? aMessage.params[0]
-          : aMessage.origin
-      ).writeMessage(aMessage.origin, "/me " + aMessage.ctcp.param, {
-        incoming: true,
-        tags: aMessage.tags,
-      });
-      return true;
+      return displayMessage(
+        this,
+        aMessage,
+        false,
+        "/me " + aMessage.ctcp.param
+      );
     },
 
     // Used when an error needs to be replied with.
     ERRMSG(aMessage) {
       this.WARN(
         aMessage.origin +
           " failed to handle CTCP message: " +
           aMessage.ctcp.param
--- a/chat/protocols/irc/ircCommands.jsm
+++ b/chat/protocols/irc/ircCommands.jsm
@@ -130,18 +130,25 @@ function actionCommand(aMsg, aConv) {
     conv.writeMessage(
       account._currentServerName,
       _("error.sendMessageFailed"),
       { error: true, system: true }
     );
     return true;
   }
 
-  // Show the action on our conversation.
-  conv.writeMessage(account._nickname, "/me " + om.message, { outgoing: true });
+  // By default the server doesn't send the message back, but this can be
+  // enabled with the echo-message capability. If this is not enabled, just
+  // assume the message was received and immediately show it.
+  if (!this._account._activeCAPs.has("echo-message")) {
+    // Show the action on our conversation.
+    conv.writeMessage(account._nickname, "/me " + om.message, {
+      outgoing: true,
+    });
+  }
   return true;
 }
 
 // This will open the conversation, and send and display the text.
 // aReturnedConv is optional and returns the resulting conversation.
 // aIsNotice is optional and sends a NOTICE instead of a PRIVMSG.
 function privateMessage(aConv, aMsg, aNickname, aReturnedConv, aIsNotice) {
   if (!aMsg.length) {
--- a/chat/protocols/irc/ircUtils.jsm
+++ b/chat/protocols/irc/ircUtils.jsm
@@ -2,16 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const EXPORTED_SYMBOLS = [
   "_",
   "ctcpFormatToText",
   "ctcpFormatToHTML",
   "conversationErrorMessage",
+  "displayMessage",
   "kListRefreshInterval",
 ];
 
 var { XPCOMUtils, l10nHelper } = ChromeUtils.import(
   "resource:///modules/imXPCOMUtils.jsm"
 );
 
 XPCOMUtils.defineLazyGetter(this, "_", () =>
@@ -258,8 +259,45 @@ function conversationErrorMessage(
     // chatRoomFields.
     if (!aRejoinable) {
       delete conv.chatRoomFields;
     }
   }
 
   return true;
 }
+
+/**
+ * Display a PRIVMSG or NOTICE in a conversation.
+ */
+function displayMessage(aAccount, aMessage, aIsNotification, aText) {
+  let params = { tags: aMessage.tags };
+  if (aIsNotification) {
+    params.notification = true;
+  }
+  // If the the message is from our nick, it is outgoing to the conversation it
+  // is targeting. Otherwise, the message is incoming, but could be for a
+  // private message or a channel.
+  //
+  // Note that the only time it is expected to receive a message from us is if
+  // the echo-message capability is enabled.
+  let convName;
+  if (
+    aAccount.normalizeNick(aMessage.origin) ==
+    aAccount.normalizeNick(aAccount._nickname)
+  ) {
+    params.outgoing = true;
+    // The conversation name is who it is being sent to.
+    convName = aMessage.params[0];
+  } else {
+    params.incoming = true;
+    // If the target is a MUC name, use the target as the conversation name.
+    // Otherwise, this is a private message: use the sender as the conversation
+    // name.
+    convName = aAccount.isMUCName(aMessage.params[0])
+      ? aMessage.params[0]
+      : aMessage.origin;
+  }
+  aAccount
+    .getConversation(convName)
+    .writeMessage(aMessage.origin, aText || aMessage.params[1], params);
+  return true;
+}