From f309bf40f8a3eff620d015771540de3fa3e1c8a3 Mon Sep 17 00:00:00 2001
From: William Grant <willmgrant@gmail.com>
Date: Mon, 29 Aug 2022 17:44:58 +1000
Subject: [PATCH] fix: repaired reaction notifications for 1-1s

---
 ts/receiver/dataMessage.ts |  10 ++
 ts/receiver/queuedJob.ts   | 198 +++++++++++++++++--------------------
 ts/util/reactions.ts       |   9 +-
 3 files changed, 107 insertions(+), 110 deletions(-)

diff --git a/ts/receiver/dataMessage.ts b/ts/receiver/dataMessage.ts
index 3c0ccdac0..59c98d431 100644
--- a/ts/receiver/dataMessage.ts
+++ b/ts/receiver/dataMessage.ts
@@ -22,6 +22,7 @@ import { appendFetchAvatarAndProfileJob } from './userProfileImageUpdates';
 import { toLogFormat } from '../types/attachments/Errors';
 import { ConversationTypeEnum } from '../models/conversationAttributes';
 import { handleMessageReaction } from '../util/reactions';
+import { Action, Reaction } from '../types/Reaction';
 
 function cleanAttachment(attachment: any) {
   return {
@@ -326,6 +327,15 @@ async function handleSwarmMessage(
         msgModel.get('source'),
         isUsFromCache(msgModel.get('source'))
       );
+      if (
+        convoToAddMessageTo.isPrivate() &&
+        msgModel.get('unread') &&
+        rawDataMessage.reaction.action === Action.REACT
+      ) {
+        msgModel.set('reaction', rawDataMessage.reaction as Reaction);
+        convoToAddMessageTo.throttledNotify(msgModel);
+      }
+
       confirm();
       return;
     }
diff --git a/ts/receiver/queuedJob.ts b/ts/receiver/queuedJob.ts
index 03b4a67dc..f1bb88927 100644
--- a/ts/receiver/queuedJob.ts
+++ b/ts/receiver/queuedJob.ts
@@ -16,7 +16,6 @@ import { GoogleChrome } from '../util';
 import { appendFetchAvatarAndProfileJob } from './userProfileImageUpdates';
 import { ConversationTypeEnum } from '../models/conversationAttributes';
 import { getUsBlindedInThatServer } from '../session/apis/open_group_api/sogsv3/knownBlindedkeys';
-import { Action, Reaction } from '../types/Reaction';
 
 function contentTypeSupported(type: string): boolean {
   const Chrome = GoogleChrome;
@@ -339,116 +338,103 @@ export async function handleMessageJob(
     ) || messageModel.get('timestamp')} in conversation ${conversation.idForLogging()}`
   );
 
-  if (!messageModel.get('isPublic') && regularDataMessage.reaction) {
-    if (
-      regularDataMessage.reaction.action === Action.REACT &&
-      conversation.isPrivate() &&
-      messageModel.get('unread')
-    ) {
-      messageModel.set('reaction', regularDataMessage.reaction as Reaction);
-      conversation.throttledNotify(messageModel);
-    }
-
-    confirm?.();
-  } else {
-    const sendingDeviceConversation = await getConversationController().getOrCreateAndWait(
-      source,
-      ConversationTypeEnum.PRIVATE
-    );
-    try {
-      messageModel.set({ flags: regularDataMessage.flags });
-      if (messageModel.isExpirationTimerUpdate()) {
-        const { expireTimer } = regularDataMessage;
-        const oldValue = conversation.get('expireTimer');
-        if (expireTimer === oldValue) {
-          confirm?.();
-          window?.log?.info(
-            'Dropping ExpireTimerUpdate message as we already have the same one set.'
-          );
-          return;
-        }
-        await handleExpirationTimerUpdateNoCommit(conversation, messageModel, source, expireTimer);
-      } else {
-        // this does not commit to db nor UI unless we need to approve a convo
-        await handleRegularMessage(
-          conversation,
-          sendingDeviceConversation,
-          messageModel,
-          regularDataMessage,
-          source,
-          messageHash
+  const sendingDeviceConversation = await getConversationController().getOrCreateAndWait(
+    source,
+    ConversationTypeEnum.PRIVATE
+  );
+  try {
+    messageModel.set({ flags: regularDataMessage.flags });
+    if (messageModel.isExpirationTimerUpdate()) {
+      const { expireTimer } = regularDataMessage;
+      const oldValue = conversation.get('expireTimer');
+      if (expireTimer === oldValue) {
+        confirm?.();
+        window?.log?.info(
+          'Dropping ExpireTimerUpdate message as we already have the same one set.'
         );
+        return;
       }
+      await handleExpirationTimerUpdateNoCommit(conversation, messageModel, source, expireTimer);
+    } else {
+      // this does not commit to db nor UI unless we need to approve a convo
+      await handleRegularMessage(
+        conversation,
+        sendingDeviceConversation,
+        messageModel,
+        regularDataMessage,
+        source,
+        messageHash
+      );
+    }
 
-      // save the message model to the db and it save the messageId generated to our in-memory copy
-      const id = await messageModel.commit();
-      messageModel.set({ id });
-
-      // Note that this can save the message again, if jobs were queued. We need to
-      //   call it after we have an id for this message, because the jobs refer back
-      //   to their source message.
-
-      const unreadCount = await conversation.getUnreadCount();
-      conversation.set({ unreadCount });
-      conversation.set({
-        active_at: Math.max(conversation.attributes.active_at, messageModel.get('sent_at') || 0),
-      });
-      // this is a throttled call and will only run once every 1 sec at most
-      conversation.updateLastMessage();
-      await conversation.commit();
-
-      if (conversation.id !== sendingDeviceConversation.id) {
-        await sendingDeviceConversation.commit();
-      }
+    // save the message model to the db and it save the messageId generated to our in-memory copy
+    const id = await messageModel.commit();
+    messageModel.set({ id });
 
-      void queueAttachmentDownloads(messageModel, conversation);
-      // Check if we need to update any profile names
-      // the only profile we don't update with what is coming here is ours,
-      // as our profile is shared accross our devices with a ConfigurationMessage
-      if (messageModel.isIncoming() && regularDataMessage.profile) {
-        void appendFetchAvatarAndProfileJob(
-          sendingDeviceConversation,
-          regularDataMessage.profile,
-          regularDataMessage.profileKey
-        );
-      }
+    // Note that this can save the message again, if jobs were queued. We need to
+    //   call it after we have an id for this message, because the jobs refer back
+    //   to their source message.
 
-      // even with all the warnings, I am very sus about if this is usefull or not
-      // try {
-      //   // We go to the database here because, between the message save above and
-      //   // the previous line's trigger() call, we might have marked all messages
-      //   // unread in the database. This message might already be read!
-      //   const fetched = await getMessageById(messageModel.get('id'));
-
-      //   const previousUnread = messageModel.get('unread');
-
-      //   // Important to update message with latest read state from database
-      //   messageModel.merge(fetched);
-
-      //   if (previousUnread !== messageModel.get('unread')) {
-      //     window?.log?.warn(
-      //       'Caught race condition on new message read state! ' + 'Manually starting timers.'
-      //     );
-      //     // We call markRead() even though the message is already
-      //     // marked read because we need to start expiration
-      //     // timers, etc.
-      //     await messageModel.markRead(Date.now());
-      //   }
-      // } catch (error) {
-      //   window?.log?.warn(
-      //     'handleMessageJob: Message',
-      //     messageModel.idForLogging(),
-      //     'was deleted'
-      //   );
-      // }
-
-      if (messageModel.get('unread')) {
-        conversation.throttledNotify(messageModel);
-      }
-      confirm?.();
-    } catch (error) {
-      const errorForLog = error && error.stack ? error.stack : error;
-      window?.log?.error('handleMessageJob', messageModel.idForLogging(), 'error:', errorForLog);
+    const unreadCount = await conversation.getUnreadCount();
+    conversation.set({ unreadCount });
+    conversation.set({
+      active_at: Math.max(conversation.attributes.active_at, messageModel.get('sent_at') || 0),
+    });
+    // this is a throttled call and will only run once every 1 sec at most
+    conversation.updateLastMessage();
+    await conversation.commit();
+
+    if (conversation.id !== sendingDeviceConversation.id) {
+      await sendingDeviceConversation.commit();
+    }
+
+    void queueAttachmentDownloads(messageModel, conversation);
+    // Check if we need to update any profile names
+    // the only profile we don't update with what is coming here is ours,
+    // as our profile is shared accross our devices with a ConfigurationMessage
+    if (messageModel.isIncoming() && regularDataMessage.profile) {
+      void appendFetchAvatarAndProfileJob(
+        sendingDeviceConversation,
+        regularDataMessage.profile,
+        regularDataMessage.profileKey
+      );
+    }
+
+    // even with all the warnings, I am very sus about if this is usefull or not
+    // try {
+    //   // We go to the database here because, between the message save above and
+    //   // the previous line's trigger() call, we might have marked all messages
+    //   // unread in the database. This message might already be read!
+    //   const fetched = await getMessageById(messageModel.get('id'));
+
+    //   const previousUnread = messageModel.get('unread');
+
+    //   // Important to update message with latest read state from database
+    //   messageModel.merge(fetched);
+
+    //   if (previousUnread !== messageModel.get('unread')) {
+    //     window?.log?.warn(
+    //       'Caught race condition on new message read state! ' + 'Manually starting timers.'
+    //     );
+    //     // We call markRead() even though the message is already
+    //     // marked read because we need to start expiration
+    //     // timers, etc.
+    //     await messageModel.markRead(Date.now());
+    //   }
+    // } catch (error) {
+    //   window?.log?.warn(
+    //     'handleMessageJob: Message',
+    //     messageModel.idForLogging(),
+    //     'was deleted'
+    //   );
+    // }
+
+    if (messageModel.get('unread')) {
+      conversation.throttledNotify(messageModel);
     }
+    confirm?.();
+  } catch (error) {
+    const errorForLog = error && error.stack ? error.stack : error;
+    window?.log?.error('handleMessageJob', messageModel.idForLogging(), 'error:', errorForLog);
   }
 }
diff --git a/ts/util/reactions.ts b/ts/util/reactions.ts
index 7cf1a759c..44ad176ea 100644
--- a/ts/util/reactions.ts
+++ b/ts/util/reactions.ts
@@ -125,10 +125,11 @@ export const sendMessageReaction = async (messageId: string, emoji: string) => {
       emoji,
       'reaction for message',
       id,
-      found.get('isPublic') &&
-        `on ${conversationModel.toOpenGroupV2().serverUrl}/${
-          conversationModel.toOpenGroupV2().roomId
-        }`
+      found.get('isPublic')
+        ? `on ${conversationModel.toOpenGroupV2().serverUrl}/${
+            conversationModel.toOpenGroupV2().roomId
+          }`
+        : ''
     );
     return reaction;
   } else {