Browse Source

Mark latest message as read if latest event is a reaction (#44)

Scott Weber 3 years ago
parent
commit
6a6c108b6e

+ 18 - 4
mautrix_instagram/db/message.py

@@ -35,11 +35,12 @@ class Message:
     client_context: str | None
     receiver: int
     sender: int
+    ig_timestamp: int
 
     async def insert(self) -> None:
         q = (
-            "INSERT INTO message (mxid, mx_room, item_id, client_context, receiver, sender) "
-            "VALUES ($1, $2, $3, $4, $5, $6)"
+            "INSERT INTO message (mxid, mx_room, item_id, client_context, receiver, sender, ig_timestamp) "
+            "VALUES ($1, $2, $3, $4, $5, $6, $7)"
         )
         await self.db.execute(
             q,
@@ -49,6 +50,7 @@ class Message:
             self.client_context,
             self.receiver,
             self.sender,
+            self.ig_timestamp,
         )
 
     async def delete(self) -> None:
@@ -62,7 +64,7 @@ class Message:
     @classmethod
     async def get_by_mxid(cls, mxid: EventID, mx_room: RoomID) -> Message | None:
         q = (
-            "SELECT mxid, mx_room, item_id, client_context, receiver, sender "
+            "SELECT mxid, mx_room, item_id, client_context, receiver, sender, ig_timestamp "
             "FROM message WHERE mxid=$1 AND mx_room=$2"
         )
         row = await cls.db.fetchrow(q, mxid, mx_room)
@@ -70,10 +72,22 @@ class Message:
             return None
         return cls(**row)
 
+    @classmethod
+    async def get_last(cls, mx_room: RoomID) -> Message | None:
+        q = (
+            "SELECT mxid, mx_room, item_id, client_context, receiver, sender, ig_timestamp "
+            "FROM message WHERE mx_room=$1 AND item_id NOT LIKE 'fi.mau.instagram.%' "
+            "AND ig_timestamp IS NOT NULL ORDER BY ig_timestamp DESC LIMIT 1"
+        )
+        row = await cls.db.fetchrow(q, mx_room)
+        if not row:
+            return None
+        return cls(**row)
+
     @classmethod
     async def get_by_item_id(cls, item_id: str, receiver: int) -> Message | None:
         q = (
-            "SELECT mxid, mx_room, item_id, client_context, receiver, sender "
+            "SELECT mxid, mx_room, item_id, client_context, receiver, sender, ig_timestamp "
             "FROM message WHERE item_id=$1 AND receiver=$2"
         )
         row = await cls.db.fetchrow(q, item_id, receiver)

+ 5 - 0
mautrix_instagram/db/upgrade.py

@@ -110,3 +110,8 @@ async def upgrade_v3(conn: Connection) -> None:
 @upgrade_table.register(description="Add client context field to message table")
 async def upgrade_v4(conn: Connection) -> None:
     await conn.execute("ALTER TABLE message ADD COLUMN client_context TEXT")
+
+
+@upgrade_table.register(description="Add ig_timestamp field to message table")
+async def upgrade_v5(conn: Connection) -> None:
+    await conn.execute("ALTER TABLE message ADD COLUMN ig_timestamp BIGINT")

+ 3 - 0
mautrix_instagram/matrix.py

@@ -123,6 +123,9 @@ class MatrixHandler(BaseMatrixHandler):
     ) -> None:
         message = await DBMessage.get_by_mxid(event_id, portal.mxid)
         if not message or message.is_internal:
+            # Message might actually be reaction - mark all as read
+            message = await DBMessage.get_last(portal.mxid)
+        if not message:
             return
         user.log.debug(f"Marking {message.item_id} in {portal.thread_id} as read")
         await user.mqtt.mark_seen(portal.thread_id, message.item_id)

+ 3 - 0
mautrix_instagram/portal.py

@@ -483,6 +483,7 @@ class Portal(DBPortal, BasePortal):
                     client_context=resp.payload.client_context,
                     receiver=self.receiver,
                     sender=sender.igpk,
+                    ig_timestamp=int(resp.payload.timestamp),
                 ).insert()
             except asyncpg.UniqueViolationError as e:
                 self.log.warning(
@@ -976,6 +977,7 @@ class Portal(DBPortal, BasePortal):
                     client_context=None,
                     receiver=self.receiver,
                     sender=media.user.pk,
+                    ig_timestamp=None,
                 ).insert()
         return await self._send_message(intent, content, timestamp=item.timestamp // 1000)
 
@@ -1170,6 +1172,7 @@ class Portal(DBPortal, BasePortal):
             client_context=item.client_context,
             receiver=self.receiver,
             sender=sender.pk,
+            ig_timestamp=item.timestamp,
         )
         await msg.insert()
         await self._send_delivery_receipt(event_id)