@@ -121,6 +121,7 @@ def __init__(self, controller: Any) -> None:
121
121
[
122
122
("message" , self ._handle_message_event ),
123
123
("update_message" , self ._handle_update_message_event ),
124
+ ("delete_message" , self ._handle_delete_message_event ),
124
125
("reaction" , self ._handle_reaction_event ),
125
126
("subscription" , self ._handle_subscription_event ),
126
127
("typing" , self ._handle_typing_event ),
@@ -1160,6 +1161,58 @@ def _update_topic_index(self, stream_id: int, topic_name: str) -> None:
1160
1161
# Update the index.
1161
1162
self .index ["topics" ][stream_id ] = topic_list
1162
1163
1164
+ def _handle_delete_message_event (self , event : Event ) -> None :
1165
+ """
1166
+ Handles message delete event.
1167
+ TODO: Handle bulk_message_deletion when we support that
1168
+ """
1169
+ assert event ["type" ] == "delete_message"
1170
+
1171
+ message_id = event ["message_id" ]
1172
+ indexed_message = self .index ["messages" ].get (message_id , None )
1173
+
1174
+ if indexed_message :
1175
+ # Update unread_count if message was unread before being deleted
1176
+ # We need to do this before removing the message from index.
1177
+ # FIXME: Does it feel hacky to mark the message as read instead
1178
+ # of using something like unset_count?
1179
+ if "read" not in indexed_message ["flags" ]:
1180
+ set_count ([message_id ], self .controller , - 1 )
1181
+ if "starred" in indexed_message ["flags" ]:
1182
+ self .index ["starred_msg_ids" ].discard (message_id )
1183
+ self .controller .view .starred_button .update_count (
1184
+ self .controller .view .starred_button .count - 1
1185
+ )
1186
+
1187
+ # Remove all traces of the message from index if present and
1188
+ # update the rendered view.
1189
+ # FIXME?: Do we need to archive the message instead of completely
1190
+ # erasing from index?
1191
+ self .index ["messages" ].pop (message_id , None )
1192
+ self .index ["all_msg_ids" ].discard (message_id )
1193
+ self .index ["mentioned_msg_ids" ].discard (message_id )
1194
+ self .index ["edited_messages" ].discard (message_id )
1195
+
1196
+ if event ["message_type" ] == "private" :
1197
+ self .index ["private_msg_ids" ].discard (message_id )
1198
+ sender_id = event ["sender_id" ]
1199
+ private_msg_set = self .index ["private_msg_ids_by_user_ids" ]
1200
+ for user_id_set , msg_id in private_msg_set .items ():
1201
+ if sender_id in user_id_set :
1202
+ private_msg_set [user_id_set ].discard (msg_id )
1203
+ else :
1204
+ stream_id , topic = event ["stream_id" ], event ["topic" ]
1205
+ stream_msg_ids = self .index ["stream_msg_ids_by_stream_id" ].get (
1206
+ stream_id , None
1207
+ )
1208
+ if stream_msg_ids :
1209
+ stream_msg_ids .discard (message_id )
1210
+ topic_msg_ids = self .index ["topic_msg_ids" ][stream_id ].get (topic , None )
1211
+ if topic_msg_ids :
1212
+ topic_msg_ids .discard (message_id )
1213
+
1214
+ self ._update_rendered_view (message_id )
1215
+
1163
1216
def _handle_update_message_event (self , event : Event ) -> None :
1164
1217
"""
1165
1218
Handle updated (edited) messages (changed content/subject)
@@ -1327,6 +1380,11 @@ def _update_rendered_view(self, msg_id: int) -> None:
1327
1380
for msg_w in view .message_view .log :
1328
1381
msg_box = msg_w .original_widget
1329
1382
if msg_box .message ["id" ] == msg_id :
1383
+ # Remove the message if deleted
1384
+ if msg_id not in self .index ["messages" ]:
1385
+ view .message_view .log .remove (msg_w )
1386
+ self .controller .update_screen ()
1387
+ return
1330
1388
# Remove the message if it no longer belongs in the current
1331
1389
# narrow.
1332
1390
if (
0 commit comments