From a9f5c99755f3046d5d81a7d0ff24dc2cc0930637 Mon Sep 17 00:00:00 2001 From: Zeeshan Date: Thu, 27 May 2021 00:49:26 +0530 Subject: [PATCH] model: Add support for handling delete_message events. This adds a new event action in model that looks for delete_message events, potentially handling it by removing the message completely from the index, and then updates the rendered_view to handle the event dynamically without needing to switch narrows. It also looks out for messages being unread before being deleted and updates the count appropriately. The tests are still missing which will be added in the next iteration of this commit. Fixes one check-box of #993. --- zulipterminal/model.py | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/zulipterminal/model.py b/zulipterminal/model.py index ed7d6b2d397..b2cc913c8b7 100644 --- a/zulipterminal/model.py +++ b/zulipterminal/model.py @@ -121,6 +121,7 @@ def __init__(self, controller: Any) -> None: [ ("message", self._handle_message_event), ("update_message", self._handle_update_message_event), + ('delete_message', self._handle_delete_message_event), ("reaction", self._handle_reaction_event), ("subscription", self._handle_subscription_event), ("typing", self._handle_typing_event), @@ -1160,6 +1161,52 @@ def _update_topic_index(self, stream_id: int, topic_name: str) -> None: # Update the index. self.index["topics"][stream_id] = topic_list + def _handle_delete_message_event(self, event: Event) -> None: + """ + Handles message delete event. + TODO: Handle bulk_message_deletion when we support that + """ + assert event['type'] == 'delete_message' + + message_id = event['message_id'] + indexed_message = self.index["messages"].get(message_id, None) + + # deleted_message = self.index['messages'].pop(message_id, None) + if indexed_message: + # Update unread_count if message was unread before being deleted + # We need to do this before removing the message from index. + # FIXME: Does it feel hacky to mark the message as read instead + # of using something like unset_count? + set_count([message_id], self.controller, -1) + + # Remove all traces of the message from index if present and + # update the rendered view. + # FIXME?: Do we need to archive the message instead of completely + # erasing from index? + self.index["messages"].pop(message_id, None) + self.index["all_msg_ids"].discard(message_id) + self.index["mentioned_msg_ids"].discard(message_id) + self.index["edited_messages"].discard(message_id) + + if event["message_type"] == "private": + self.index["private_msg_ids"].discard(message_id) + sender_id = event["sender_id"] + private_msg_set = self.index["private_msg_ids_by_user_ids"] + for user_id_set, msg_id in private_msg_set.items(): + if sender_id in user_id_set: + private_msg_set[user_id_set].discard(msg_id) + else: + stream_id, topic = event["stream_id"], event["topic"] + stream_msg_ids = self.index["stream_msg_ids_by_stream_id"].get( + stream_id, None) + if stream_msg_ids: + stream_msg_ids.discard(message_id) + topic_msg_ids = self.index["topic_msg_ids"][stream_id].get(topic, None) + if topic_msg_ids: + topic_msg_ids.discard(message_id) + + self._update_rendered_view(message_id) + def _handle_update_message_event(self, event: Event) -> None: """ Handle updated (edited) messages (changed content/subject) @@ -1327,6 +1374,11 @@ def _update_rendered_view(self, msg_id: int) -> None: for msg_w in view.message_view.log: msg_box = msg_w.original_widget if msg_box.message["id"] == msg_id: + # Remove message if deleted + if (msg_id not in self.index["messages"]): + view.message_view.log.remove(msg_w) + self.controller.update_screen() + return # Remove the message if it no longer belongs in the current # narrow. if (