look up older messages in DB for reactions

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/parser/MessageParser.java        | 58 
src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java | 40 
2 files changed, 82 insertions(+), 16 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/parser/MessageParser.java 🔗

@@ -1120,25 +1120,49 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
                     final var occupant =
                             mucOptions.occupantId() ? packet.getExtension(OccupantId.class) : null;
                     final var occupantId = occupant == null ? null : occupant.getId();
-                    final var message = conversation.findMessageWithServerMsgId(reactingTo);
-                    // TODO use occupant id for isSelf assessment
-                    final boolean isReceived = !mucOptions.isSelf(counterpart);
-                    if (occupantId != null && message != null) {
-                        final var combinedReactions =
-                                Reaction.withOccupantId(
-                                        message.getReactions(),
-                                        reactions.getReactions(),
-                                        isReceived,
-                                        counterpart,
-                                        null,
-                                        occupantId);
-                        message.setReactions(combinedReactions);
-                        mXmppConnectionService.updateMessage(message, false);
+                    if (occupantId != null) {
+                        // TODO use occupant id for isSelf assessment
+                        final boolean isReceived = !mucOptions.isSelf(counterpart);
+                        final Message message;
+                        final var inMemoryMessage =
+                                conversation.findMessageWithServerMsgId(reactingTo);
+                        if (inMemoryMessage != null) {
+                            message = inMemoryMessage;
+                        } else {
+                            message =
+                                    mXmppConnectionService.databaseBackend
+                                            .getMessageWithServerMsgId(conversation, reactingTo);
+                        }
+                        if (message != null) {
+                            final var combinedReactions =
+                                    Reaction.withOccupantId(
+                                            message.getReactions(),
+                                            reactions.getReactions(),
+                                            isReceived,
+                                            counterpart,
+                                            null,
+                                            occupantId);
+                            message.setReactions(combinedReactions);
+                            mXmppConnectionService.updateMessage(message, false);
+                        } else {
+                            Log.d(Config.LOGTAG, "message with id " + reactingTo + " not found");
+                        }
                     } else {
-                        Log.d(Config.LOGTAG,"not found occupant or message");
+                        Log.d(
+                                Config.LOGTAG,
+                                "received reaction in channel w/o occupant ids. ignoring");
                     }
                 } else if (conversation.getMode() == Conversational.MODE_SINGLE) {
-                    final var message = conversation.findMessageWithUuidOrRemoteId(reactingTo);
+                    final Message message;
+                    final var inMemoryMessage =
+                            conversation.findMessageWithUuidOrRemoteId(reactingTo);
+                    if (inMemoryMessage != null) {
+                        message = inMemoryMessage;
+                    } else {
+                        message =
+                                mXmppConnectionService.databaseBackend.getMessageWithUuidOrRemoteId(
+                                        conversation, reactingTo);
+                    }
                     final boolean isReceived;
                     final Jid reactionFrom;
                     if (packet.fromAccount(account)) {
@@ -1158,6 +1182,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
                                         reactionFrom);
                         message.setReactions(combinedReactions);
                         mXmppConnectionService.updateMessage(message, false);
+                    } else {
+                        Log.d(Config.LOGTAG, "message with id " + reactingTo + " not found");
                     }
                 }
             }

src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java 🔗

@@ -925,6 +925,46 @@ public class DatabaseBackend extends SQLiteOpenHelper {
         return filesPaths;
     }
 
+    public Message getMessageWithServerMsgId(
+            final Conversation conversation, final String messageId) {
+        final var db = this.getReadableDatabase();
+        final String sql =
+                "select * from messages where conversationUuid=? and serverMsgId=? LIMIT 1";
+        final String[] args = {conversation.getUuid(), messageId};
+        final Cursor cursor = db.rawQuery(sql, args);
+        if (cursor == null) {
+            return null;
+        }
+        final Message message;
+        if (cursor.moveToFirst()) {
+            message = Message.fromCursor(cursor, conversation);
+        } else {
+            message = null;
+        }
+        cursor.close();
+        return message;
+    }
+
+    public Message getMessageWithUuidOrRemoteId(
+            final Conversation conversation, final String messageId) {
+        final var db = this.getReadableDatabase();
+        final String sql =
+                "select * from messages where conversationUuid=? and (uuid=? OR remoteMsgId=?) LIMIT 1";
+        final String[] args = {conversation.getUuid(), messageId, messageId};
+        final Cursor cursor = db.rawQuery(sql, args);
+        if (cursor == null) {
+            return null;
+        }
+        final Message message;
+        if (cursor.moveToFirst()) {
+            message = Message.fromCursor(cursor, conversation);
+        } else {
+            message = null;
+        }
+        cursor.close();
+        return message;
+    }
+
     public static class FilePath {
         public final UUID uuid;
         public final String path;