From ef9b8801527cc91cbfb365173a2db508bd886e62 Mon Sep 17 00:00:00 2001 From: miruka Date: Sun, 17 May 2020 15:29:23 -0400 Subject: [PATCH] Register room members only when needed --- TODO.md | 2 ++ src/backend/matrix_client.py | 68 +++++++++++++++++++----------------- src/backend/nio_callbacks.py | 5 +++ 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/TODO.md b/TODO.md index 19dacf19..5e7019cb 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,7 @@ # TODO +- shorten indicator numbers with hundreds + - fix python getting stuck when loading large room - fix lag when clicking accounts in the AccountBar with a very long room list diff --git a/src/backend/matrix_client.py b/src/backend/matrix_client.py index abd10b78..e2e44bde 100644 --- a/src/backend/matrix_client.py +++ b/src/backend/matrix_client.py @@ -752,7 +752,7 @@ class MatrixClient(nio.AsyncClient): if not room.members_synced: await super().joined_members(room_id) - await self.register_nio_room(self.all_rooms[room_id]) + await self.register_nio_room(room, force_register_members=True) async def load_past_events(self, room_id: str) -> bool: @@ -1188,7 +1188,10 @@ class MatrixClient(nio.AsyncClient): async def register_nio_room( - self, room: nio.MatrixRoom, left: bool = False, + self, + room: nio.MatrixRoom, + left: bool = False, + force_register_members: bool = False, ) -> None: """Register a `nio.MatrixRoom` as a `Room` object in our model.""" @@ -1199,16 +1202,18 @@ class MatrixClient(nio.AsyncClient): can_send_msg = partial(levels.can_user_send_message, self.user_id) try: - registered = self.models[self.user_id, "rooms"][room.room_id] - last_event_date = registered.last_event_date - typing_members = registered.typing_members - mentions = registered.mentions - unreads = registered.unreads + registered = self.models[self.user_id, "rooms"][room.room_id] except KeyError: + registered = None last_event_date = datetime.fromtimestamp(0) typing_members = [] mentions = 0 unreads = 0 + else: + last_event_date = registered.last_event_date + typing_members = registered.typing_members + mentions = registered.mentions + unreads = registered.unreads room_item = Room( id = room.room_id, @@ -1250,35 +1255,32 @@ class MatrixClient(nio.AsyncClient): self.models[self.user_id, "rooms"][room.room_id] = room_item - # List members that left the room, then remove them from our model - left_the_room = [ - user_id - for user_id in self.models[self.user_id, room.room_id, "members"] - if user_id not in room.users - ] + if not registered or force_register_members: + for user_id in room.users: + await self.add_member(room, user_id) - for user_id in left_the_room: - del self.models[self.user_id, room.room_id, "members"][user_id] - HTML.rooms_user_id_names[room.room_id].pop(user_id, None) - # Add the room members to the added room - new_dict = { - user_id: Member( - id = user_id, - display_name = room.user_name(user_id) # disambiguated - if member.display_name else "", - avatar_url = member.avatar_url or "", - typing = user_id in room.typing_users, - power_level = member.power_level, - invited = member.invited, - ) for user_id, member in room.users.items() - } - self.models[self.user_id, room.room_id, "members"].update(new_dict) + async def add_member(self, room: nio.MatrixRoom, user_id: str) -> None: + member = room.users[user_id] - for user_id, member in room.users.items(): - if member.display_name: - HTML.rooms_user_id_names[room.room_id][user_id] = \ - member.display_name + self.models[self.user_id, room.room_id, "members"][user_id] = Member( + id = user_id, + display_name = room.user_name(user_id) # disambiguated + if member.display_name else "", + avatar_url = member.avatar_url or "", + typing = user_id in room.typing_users, + power_level = member.power_level, + invited = member.invited, + ) + + if member.display_name: + HTML.rooms_user_id_names[room.room_id][user_id] = \ + member.display_name + + + async def remove_member(self, room: nio.MatrixRoom, user_id: str) -> None: + self.models[self.user_id, room.room_id, "members"].pop(user_id, None) + HTML.rooms_user_id_names[room.room_id].pop(user_id, None) async def get_member_name_avatar( diff --git a/src/backend/nio_callbacks.py b/src/backend/nio_callbacks.py index 6447fb9b..0bb838a9 100644 --- a/src/backend/nio_callbacks.py +++ b/src/backend/nio_callbacks.py @@ -353,6 +353,11 @@ class NioCallbacks: async def onRoomMemberEvent(self, room, ev) -> None: + if ev.membership in ("invite", "join") and ev.state_key in room.users: + await self.client.add_member(room, user_id=ev.state_key) + elif ev.membership in ("left", "ban"): + await self.client.remove_member(room, user_id=ev.state_key) + type_and_content = await self.process_room_member_event(room, ev) if type_and_content is not None: