diff --git a/tests/model/test_model.py b/tests/model/test_model.py index bf0f88774a..7aab54f5f5 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -1624,6 +1624,7 @@ def test_notify_users_enabled( case( { # Only subject of 1 message is updated. "message_id": 1, + "orig_subject": "old subject", "subject": "new subject", "stream_id": 10, "message_ids": [1], @@ -1644,6 +1645,9 @@ def test_notify_users_enabled( "subject": "old subject", }, }, + "topic_msg_ids": { + 10: {"new subject": {1}, "old subject": {2}}, + }, "edited_messages": {1}, "topics": {10: []}, }, @@ -1653,6 +1657,7 @@ def test_notify_users_enabled( case( { # Subject of 2 messages is updated "message_id": 1, + "orig_subject": "old subject", "subject": "new subject", "stream_id": 10, "message_ids": [1, 2], @@ -1673,6 +1678,9 @@ def test_notify_users_enabled( "subject": "new subject", }, }, + "topic_msg_ids": { + 10: {"new subject": {1, 2}, "old subject": set()}, + }, "edited_messages": {1}, "topics": {10: []}, }, @@ -1701,8 +1709,11 @@ def test_notify_users_enabled( "subject": "old subject", }, }, + "topic_msg_ids": { + 10: {"new subject": set(), "old subject": {1, 2}}, + }, "edited_messages": {1}, - "topics": {10: ["old subject"]}, + "topics": {10: ["new subject", "old subject"]}, }, False, id="Message content is updated", @@ -1711,6 +1722,7 @@ def test_notify_users_enabled( { # Both message content and subject is updated. "message_id": 1, "rendered_content": "
new content
", + "orig_subject": "old subject", "subject": "new subject", "stream_id": 10, "message_ids": [1], @@ -1731,6 +1743,9 @@ def test_notify_users_enabled( "subject": "old subject", }, }, + "topic_msg_ids": { + 10: {"new subject": {1}, "old subject": {2}}, + }, "edited_messages": {1}, "topics": {10: []}, }, @@ -1758,8 +1773,11 @@ def test_notify_users_enabled( "subject": "old subject", }, }, + "topic_msg_ids": { + 10: {"new subject": set(), "old subject": {1, 2}}, + }, "edited_messages": {1}, - "topics": {10: ["old subject"]}, + "topics": {10: ["new subject", "old subject"]}, }, False, id="Some new type of update which we don't handle yet", @@ -1768,6 +1786,7 @@ def test_notify_users_enabled( { # message_id not present in index, topic view closed. "message_id": 3, "rendered_content": "new content
", + "orig_subject": "old subject", "subject": "new subject", "stream_id": 10, "message_ids": [3], @@ -1788,6 +1807,9 @@ def test_notify_users_enabled( "subject": "old subject", }, }, + "topic_msg_ids": { + 10: {"new subject": {3}, "old subject": {1, 2}}, + }, "edited_messages": set(), "topics": {10: []}, # This resets the cache }, @@ -1798,6 +1820,7 @@ def test_notify_users_enabled( { # message_id not present in index, topic view is enabled. "message_id": 3, "rendered_content": "new content
", + "orig_subject": "old subject", "subject": "new subject", "stream_id": 10, "message_ids": [3], @@ -1818,6 +1841,9 @@ def test_notify_users_enabled( "subject": "old subject", }, }, + "topic_msg_ids": { + 10: {"new subject": {3}, "old subject": {1, 2}}, + }, "edited_messages": set(), "topics": {10: ["new subject", "old subject"]}, }, @@ -1828,6 +1854,7 @@ def test_notify_users_enabled( { # Message content is updated and topic view is enabled. "message_id": 1, "rendered_content": "new content
", + "orig_subject": "old subject", "subject": "new subject", "stream_id": 10, "message_ids": [1], @@ -1848,6 +1875,9 @@ def test_notify_users_enabled( "subject": "old subject", }, }, + "topic_msg_ids": { + 10: {"new subject": {1}, "old subject": {2}}, + }, "edited_messages": {1}, "topics": {10: ["new subject", "old subject"]}, }, @@ -1877,8 +1907,11 @@ def test__handle_update_message_event( } for message_id in [1, 2] }, + "topic_msg_ids": { # FIXME? consider test for eg. absence of empty set + 10: {"new subject": set(), "old subject": {1, 2}}, + }, "edited_messages": set(), - "topics": {10: ["old subject"]}, + "topics": {10: ["new subject", "old subject"]}, } mocker.patch(MODEL + "._update_rendered_view") diff --git a/zulipterminal/api_types.py b/zulipterminal/api_types.py index a47d5edd97..55237c4342 100644 --- a/zulipterminal/api_types.py +++ b/zulipterminal/api_types.py @@ -151,7 +151,9 @@ class UpdateMessageEvent(TypedDict): rendered_content: str # B: Subject of these message ids needs updating? message_ids: List[int] + orig_subject: str subject: str + propagate_mode: EditPropagateMode stream_id: int diff --git a/zulipterminal/model.py b/zulipterminal/model.py index 142a41a2d6..a53d2a677d 100644 --- a/zulipterminal/model.py +++ b/zulipterminal/model.py @@ -1384,9 +1384,26 @@ def _handle_update_message_event(self, event: Event) -> None: if "subject" in event: new_subject = event["subject"] stream_id = event["stream_id"] + old_subject = event["orig_subject"] + msg_ids_by_topic = self.index["topic_msg_ids"][stream_id] - # Update any indexed messages & re-render them + # Remove each message_id from the old topic's `topic_msg_ids` set + # if it exists, and update & re-render the message if it is indexed. for msg_id in event["message_ids"]: + # Ensure that the new topic is not the same as the old one + # (no-op topic edit). + if new_subject != old_subject: + # Remove the msg_id from the relevant `topic_msg_ids` set, + # if that topic's set has already been initiated. + if old_subject in msg_ids_by_topic: + msg_ids_by_topic[old_subject].discard(msg_id) + + # Add the msg_id to the new topic's set, if the set has + # already been initiated. + if new_subject in msg_ids_by_topic: + msg_ids_by_topic[new_subject].add(msg_id) + + # Update and re-render indexed messages. indexed_msg = self.index["messages"].get(msg_id) if indexed_msg: indexed_msg["subject"] = new_subject