Spaces:
Running
Running
Commit ·
2043cb2
1
Parent(s): 495207e
fyp
Browse files- app/models/message.py +27 -2
- app/services/conversation_service.py +10 -5
app/models/message.py
CHANGED
|
@@ -43,6 +43,7 @@ class Message:
|
|
| 43 |
"replied_to_sender": replied_to_sender, # Name of original sender
|
| 44 |
"is_read": False,
|
| 45 |
"read_at": None,
|
|
|
|
| 46 |
# Edit tracking
|
| 47 |
"is_edited": False,
|
| 48 |
"edited_at": None,
|
|
@@ -163,13 +164,37 @@ class Message:
|
|
| 163 |
# Reactions
|
| 164 |
"reactions": message_doc.get("reactions", {}),
|
| 165 |
"created_at": Message._serialize_datetime(message_doc.get("created_at")),
|
| 166 |
-
# Status field for read receipts
|
| 167 |
-
"status":
|
| 168 |
# Action availability flags for frontend UI
|
| 169 |
"can_edit": action_availability["can_edit"],
|
| 170 |
"can_delete_for_everyone": action_availability["can_delete_for_everyone"],
|
| 171 |
}
|
| 172 |
|
| 173 |
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
|
| 175 |
|
|
|
|
| 43 |
"replied_to_sender": replied_to_sender, # Name of original sender
|
| 44 |
"is_read": False,
|
| 45 |
"read_at": None,
|
| 46 |
+
"read_by": [], # List of user IDs who have read this message
|
| 47 |
# Edit tracking
|
| 48 |
"is_edited": False,
|
| 49 |
"edited_at": None,
|
|
|
|
| 164 |
# Reactions
|
| 165 |
"reactions": message_doc.get("reactions", {}),
|
| 166 |
"created_at": Message._serialize_datetime(message_doc.get("created_at")),
|
| 167 |
+
# Status field for read receipts - calculated from sender's perspective
|
| 168 |
+
"status": Message._calculate_status(message_doc, for_user_id),
|
| 169 |
# Action availability flags for frontend UI
|
| 170 |
"can_edit": action_availability["can_edit"],
|
| 171 |
"can_delete_for_everyone": action_availability["can_delete_for_everyone"],
|
| 172 |
}
|
| 173 |
|
| 174 |
return response
|
| 175 |
+
|
| 176 |
+
@staticmethod
|
| 177 |
+
def _calculate_status(message_doc: dict, for_user_id: Optional[str] = None) -> str:
|
| 178 |
+
"""
|
| 179 |
+
Calculate message status from user's perspective.
|
| 180 |
+
|
| 181 |
+
For sender: Check if recipient has read it
|
| 182 |
+
For recipient: Always show as delivered (they have it)
|
| 183 |
+
"""
|
| 184 |
+
sender_id = message_doc.get("sender_id")
|
| 185 |
+
read_by = message_doc.get("read_by", [])
|
| 186 |
+
|
| 187 |
+
# If viewing as sender
|
| 188 |
+
if for_user_id and for_user_id == sender_id:
|
| 189 |
+
# Check if anyone else has read it
|
| 190 |
+
other_readers = [uid for uid in read_by if uid != sender_id]
|
| 191 |
+
if other_readers:
|
| 192 |
+
return "read"
|
| 193 |
+
else:
|
| 194 |
+
return "delivered" # Sent and delivered but not read yet
|
| 195 |
+
else:
|
| 196 |
+
# Viewing as recipient - they have the message
|
| 197 |
+
return "delivered"
|
| 198 |
+
|
| 199 |
|
| 200 |
|
app/services/conversation_service.py
CHANGED
|
@@ -1001,22 +1001,27 @@ If user says they found what they wanted or wants to stop notifications, use del
|
|
| 1001 |
detail="You are not a participant in this conversation"
|
| 1002 |
)
|
| 1003 |
|
| 1004 |
-
# Mark messages as read
|
| 1005 |
now = datetime.utcnow()
|
| 1006 |
-
await db.messages.update_many(
|
| 1007 |
{
|
| 1008 |
"conversation_id": conversation_id,
|
| 1009 |
-
"sender_id": {"$ne": current_user_id},
|
| 1010 |
-
"
|
| 1011 |
},
|
| 1012 |
{
|
| 1013 |
"$set": {
|
| 1014 |
-
"is_read": True,
|
| 1015 |
"read_at": now,
|
|
|
|
|
|
|
|
|
|
| 1016 |
}
|
| 1017 |
}
|
| 1018 |
)
|
| 1019 |
|
|
|
|
|
|
|
| 1020 |
# Reset unread count for current user
|
| 1021 |
await db.conversations.update_one(
|
| 1022 |
{"_id": ObjectId(conversation_id)},
|
|
|
|
| 1001 |
detail="You are not a participant in this conversation"
|
| 1002 |
)
|
| 1003 |
|
| 1004 |
+
# Mark messages as read and add user to read_by array
|
| 1005 |
now = datetime.utcnow()
|
| 1006 |
+
result = await db.messages.update_many(
|
| 1007 |
{
|
| 1008 |
"conversation_id": conversation_id,
|
| 1009 |
+
"sender_id": {"$ne": current_user_id}, # Not sent by this user
|
| 1010 |
+
"read_by": {"$ne": current_user_id}, # Not already read by this user
|
| 1011 |
},
|
| 1012 |
{
|
| 1013 |
"$set": {
|
| 1014 |
+
"is_read": True, # Keep for backwards compatibility
|
| 1015 |
"read_at": now,
|
| 1016 |
+
},
|
| 1017 |
+
"$addToSet": {
|
| 1018 |
+
"read_by": current_user_id # Add user to read_by array (no duplicates)
|
| 1019 |
}
|
| 1020 |
}
|
| 1021 |
)
|
| 1022 |
|
| 1023 |
+
logger.info(f"Marked {result.modified_count} messages as read, added {current_user_id} to read_by")
|
| 1024 |
+
|
| 1025 |
# Reset unread count for current user
|
| 1026 |
await db.conversations.update_one(
|
| 1027 |
{"_id": ObjectId(conversation_id)},
|