From cf04f8ad2f64ab8d49cc92f37328525bfee4ec40 Mon Sep 17 00:00:00 2001 From: miruka Date: Sat, 6 Jul 2019 22:35:42 -0400 Subject: [PATCH] Display Left rooms, shorter onSyncResponse func --- src/python/events/rooms.py | 44 ++++++++++++++++++++++--- src/python/matrix_client.py | 60 ++++++++-------------------------- src/qml/Chat/Chat.qml | 8 ++--- src/qml/EventHandlers/rooms.js | 32 +++++------------- 4 files changed, 66 insertions(+), 78 deletions(-) diff --git a/src/python/events/rooms.py b/src/python/events/rooms.py index b78d3c42..c1e8ac8c 100644 --- a/src/python/events/rooms.py +++ b/src/python/events/rooms.py @@ -1,10 +1,11 @@ from datetime import datetime from enum import auto -from typing import Dict, Sequence, Type, Union +from typing import Dict, List, Optional, Sequence, Type, Union from dataclasses import dataclass, field import nio +from nio.rooms import MatrixRoom from .event import AutoStrEnum, Event @@ -19,8 +20,42 @@ class RoomUpdated(Event): topic: str = "" typing_members: Sequence[str] = () - inviter_id: str = "" - left_event: Dict[str, str] = field(default_factory=dict) + inviter_id: str = "" + left_event: Optional[nio.RoomMemberEvent] = None + + + @classmethod + def from_nio(cls, + user_id: str, + category: str, + room: MatrixRoom, + info: nio.RoomInfo, + **fields) -> "RoomUpdated": + + typing: List[str] = [] + + if hasattr(info, "ephemeral"): + for ev in info.ephemeral: + if isinstance(ev, nio.TypingNoticeEvent): + typing = ev.users + + name = room.name or room.canonical_alias + + if not name: + name = room.group_name() + name = "" if name == "Empty room?" else name + + return cls( + user_id = user_id, + category = category, + room_id = room.room_id, + display_name = name, + avatar_url = room.gen_avatar_url or "", + topic = room.topic or "", + inviter_id = getattr(room, "inviter", "") or "", + typing_members = typing, + **fields + ) @dataclass @@ -71,7 +106,8 @@ class TimelineEventReceived(Event): target_user_id: str = "" @classmethod - def from_nio(cls, room, ev, **fields) -> "TimelineEventReceived": + def from_nio(cls, room: MatrixRoom, ev: nio.Event, **fields + ) -> "TimelineEventReceived": return cls( event_type = type(ev), room_id = room.room_id, diff --git a/src/python/matrix_client.py b/src/python/matrix_client.py index a8e50650..9daa2b62 100644 --- a/src/python/matrix_client.py +++ b/src/python/matrix_client.py @@ -7,7 +7,7 @@ import platform from contextlib import suppress from datetime import datetime from types import ModuleType -from typing import DefaultDict, Dict, List, Optional, Type +from typing import DefaultDict, Dict, Optional, Type from uuid import uuid4 import nio @@ -185,59 +185,28 @@ class MatrixClient(nio.AsyncClient): # Callbacks for nio responses - @staticmethod - def _get_room_name(room: MatrixRoom) -> Optional[str]: - # FIXME: reimplanted because of nio's non-standard room.display_name - name = room.name or room.canonical_alias - if name: - return name - - name = room.group_name() - return None if name == "Empty room?" else name - - async def onSyncResponse(self, resp: nio.SyncResponse) -> None: - for room_id, _ in resp.rooms.invite.items(): - room: MatrixRoom = self.invited_rooms[room_id] + up = rooms.RoomUpdated.from_nio - rooms.RoomUpdated( - user_id = self.user_id, - category = "Invites", - room_id = room_id, - display_name = self._get_room_name(room) or "", - avatar_url = room.gen_avatar_url or "", - topic = room.topic or "", - inviter_id = room.inviter or "", - ) + for room_id, info in resp.rooms.invite.items(): + up(self.user_id, "Invites", self.invited_rooms[room_id], info) for room_id, info in resp.rooms.join.items(): - room = self.rooms[room_id] - if room_id not in self.backend.past_tokens: self.backend.past_tokens[room_id] = info.timeline.prev_batch - typing: List[str] = [] - for ev in info.ephemeral: - if isinstance(ev, nio.TypingNoticeEvent): - typing = ev.users + up(self.user_id, "Rooms", self.rooms[room_id], info) - rooms.RoomUpdated( - user_id = self.user_id, - category = "Rooms", - room_id = room_id, - display_name = self._get_room_name(room) or "", - avatar_url = room.gen_avatar_url or "", - topic = room.topic or "", - typing_members = typing, - ) + for room_id, info in resp.rooms.leave.items(): + lev = None - for room_id, _ in resp.rooms.leave.items(): - rooms.RoomUpdated( - user_id = self.user_id, - category = "Left", - room_id = room_id, - # left_event TODO - ) + for ev in info.timeline.events: + is_member_ev = isinstance(ev, nio.RoomMemberEvent) + + if is_member_ev and ev.membership in ("leave", "ban"): + lev = ev + + up(self.user_id, "Left", self.rooms[room_id], info, left_event=lev) async def onErrorResponse(self, resp: nio.ErrorResponse) -> None: @@ -250,7 +219,6 @@ class MatrixClient(nio.AsyncClient): # Special %tokens for event contents: # %S = sender's displayname # %T = target (ev.state_key)'s displayname - # pylint: disable=unused-argument async def onRoomMessageText(self, room, ev, from_past=False) -> None: diff --git a/src/qml/Chat/Chat.qml b/src/qml/Chat/Chat.qml index 7776f421..1b694582 100644 --- a/src/qml/Chat/Chat.qml +++ b/src/qml/Chat/Chat.qml @@ -57,11 +57,10 @@ HColumnLayout { TypingMembersBar { Layout.fillWidth: true - //Layout.preferredHeight: text ? implicitHeight : 0 } InviteBanner { - visible: category === "Invites" + visible: category == "Invites" inviterId: roomInfo.inviterId } @@ -75,10 +74,10 @@ HColumnLayout { } //LeftBanner { - //visible: category === "Left" + //visible: category == "Left" //leftEvent: roomInfo.leftEvent //} - //} + } // RoomSidePane { //id: roomSidePane @@ -145,6 +144,5 @@ HColumnLayout { //Layout.minimumWidth: theme.avatar.size //Layout.maximumWidth: parent.width //} - } } } diff --git a/src/qml/EventHandlers/rooms.js b/src/qml/EventHandlers/rooms.js index feb229b9..82634560 100644 --- a/src/qml/EventHandlers/rooms.js +++ b/src/qml/EventHandlers/rooms.js @@ -32,31 +32,17 @@ function onRoomUpdated( "name": category }) - function roles(for_category) { - return {"userId": user_id, "roomId": room_id, "category": for_category} + function pop(for_category) { + rooms.popWhere( + {"userId": user_id, "roomId": room_id, "category": for_category}, 1 + ) } - if (category == "Invites") { - rooms.popWhere(roles("Rooms"), 1) - rooms.popWhere(roles("Left"), 1) - } - else if (category == "Rooms") { - rooms.popWhere(roles("Invites"), 1) - rooms.popWhere(roles("Left"), 1) - } - else if (category == "Left") { - var old_room = rooms.popWhere(roles("Invites"), 1)[0] || - rooms.popWhere(roles("Rooms"), 1)[0] + if (category == "Invites") { pop("Rooms"); pop("Left") } + else if (category == "Rooms") { pop("Invites"); pop("Left") } + else if (category == "Left") { pop("Invites"); pop("Rooms") } - if (old_room) { - display_name = old_room.displayName - avatar_url = old_room.avatarUrl - topic = old_room.topic - inviter_id = old_room.inviterId - } - } - - rooms.upsert(roles(category), { + rooms.upsert({"userId": user_id, "roomId": room_id, "category": category},{ "userId": user_id, "category": category, "roomId": room_id, @@ -65,7 +51,7 @@ function onRoomUpdated( "topic": topic, "typingText": typingTextFor(typing_members, user_id), "inviterId": inviter_id, - "leftEvent": left_event, + "leftEvent": left_event ? py.getattr(left_event, "__dict__") : {}, }) }