diff --git a/matrix/buffer.py b/matrix/buffer.py index 9fe4506..c5564ac 100644 --- a/matrix/buffer.py +++ b/matrix/buffer.py @@ -21,6 +21,7 @@ import time from builtins import super from functools import partial from typing import Dict, List, NamedTuple, Optional, Set +from uuid import UUID from nio import ( Api, @@ -810,6 +811,9 @@ class RoomBuffer(object): self.unhandled_users = [] # type: List[str] self.inactive_users = [] + self.sent_messages_queue = dict() # type: Dict[UUID, OwnMessage] + self.printed_before_ack_queue = list() # type: List[UUID] + buffer_name = "{}.{}".format(server_name, room.room_id) # This dict remembers the connection from a user_id to the name we @@ -1081,6 +1085,36 @@ class RoomBuffer(object): elif isinstance(event, RoomEncryptionEvent): pass + def handle_own_message_in_timeline(self, event): + """Check if our own message is already printed if not print it. + This function is called for messages that contain a transaction id + indicating that they were sent out using our own client. If we sent out + a message but never got a valid server response (e.g. due to + disconnects) this function prints them out using data from the next + sync response""" + uuid = UUID(event.transaction_id) + message = self.sent_messages_queue.pop(uuid, None) + + # We already got a response to the room_send_message() API call and + # handled the message, no need to print it out again + if not message: + return + + message = message._replace(event_id=event.event_id) + if uuid in self.printed_before_ack_queue: + self.replace_printed_line_by_uuid( + event.transaction_id, + message + ) + self.printed_before_ack_queue.remove(uuid) + return + + if isinstance(message, OwnAction): + self.self_action(message) + elif isinstance(message, OwnMessage): + self.self_message(message) + return + def handle_timeline_event(self, event): # TODO this should be done for every messagetype that gets printed in # the buffer @@ -1095,6 +1129,10 @@ class RoomBuffer(object): self.add_user(event.sender, 0, True, True) + if event.transaction_id: + self.handle_own_message_in_timeline(event) + return + if isinstance(event, RoomMemberEvent): self.handle_membership_events(event, False) diff --git a/matrix/server.py b/matrix/server.py index 18b7943..178da3a 100644 --- a/matrix/server.py +++ b/matrix/server.py @@ -247,8 +247,6 @@ class MatrixServer(object): self.device_deletion_queue = dict() - self.own_message_queue = dict() # type: Dict[str, OwnMessage] - self.print_before_ack_queue = [] # type: List[UUID] self.encryption_queue = defaultdict(deque) \ # type: DefaultDict[str, Deque[EncrytpionQueueItem]] self.backlog_queue = dict() # type: Dict[str, str] @@ -723,11 +721,11 @@ class MatrixServer(object): self.user_id, 0, "", uuid, room.room_id, formatted ) - self.own_message_queue[uuid] = own_message + room_buffer.sent_messages_queue[uuid] = own_message self.send_or_queue(request) if G.CONFIG.network.print_unconfirmed_messages: - self.print_before_ack_queue.append(uuid) + room_buffer.printed_before_ack_queue.append(uuid) plain_message = formatted.to_weechat() plain_message = W.string_remove_color(plain_message, "") attributes = DEFAULT_ATRIBUTES.copy() @@ -781,22 +779,24 @@ class MatrixServer(object): server_buffer_prnt(self, pprint.pformat(message.response.body)) def handle_own_messages_error(self, response): - message = self.own_message_queue.pop(response.uuid) - if response.uuid not in self.print_before_ack_queue: + room_buffer = self.room_buffers[response.room_id] + + if response.uuid not in room_buffer.printed_before_ack_queue: return - room_buffer = self.room_buffers[message.room_id] + message = room_buffer.sent_messages_queue.pop(response.uuid) room_buffer.mark_message_as_unsent(response.uuid, message) + room_buffer.printed_before_ack_queue.remove(response.uuid) def handle_own_messages(self, response): - message = self.own_message_queue.pop(response.uuid) - room_buffer = self.room_buffers[message.room_id] + room_buffer = self.room_buffers[response.room_id] + message = room_buffer.sent_messages_queue.pop(response.uuid) message = message._replace(event_id=response.event_id) - # We already printed the message, just modify it to contain the proper # colors and formatting. - if response.uuid in self.print_before_ack_queue: + if response.uuid in room_buffer.printed_before_ack_queue: room_buffer.replace_printed_line_by_uuid(response.uuid, message) + room_buffer.printed_before_ack_queue.remove(response.uuid) return if isinstance(message, OwnAction):