From 91ed60099776897e77509b3da42e96757bc4f5df Mon Sep 17 00:00:00 2001 From: vslg Date: Thu, 2 Jul 2020 21:25:24 -0300 Subject: [PATCH] Check server presence support and comment code --- src/backend/backend.py | 2 ++ src/backend/matrix_client.py | 7 ++++++- src/backend/models/items.py | 7 +++++++ src/backend/nio_callbacks.py | 8 +++++++- src/gui/MainPane/AccountContextMenu.qml | 2 ++ src/gui/MainPane/AccountDelegate.qml | 4 +++- 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/backend/backend.py b/src/backend/backend.py index 28d46ee4..a89edd0e 100644 --- a/src/backend/backend.py +++ b/src/backend/backend.py @@ -155,6 +155,7 @@ class Backend: self.clients[client.user_id] = client self.models["accounts"][client.user_id] = account + # Get or create presence for account presence = self.presences.setdefault(client.user_id, Presence()) presence.members["account", client.user_id] = account @@ -182,6 +183,7 @@ class Backend: self.clients[user_id] = client self.models["accounts"][user_id] = account + # Get or create presence for account presence = self.presences.setdefault(user_id, Presence()) presence.members["account", user_id] = account diff --git a/src/backend/matrix_client.py b/src/backend/matrix_client.py index 9308f883..64435288 100644 --- a/src/backend/matrix_client.py +++ b/src/backend/matrix_client.py @@ -253,6 +253,7 @@ class MatrixClient(nio.AsyncClient): response = nio.LoginResponse(user_id, device_id, token) await self.receive_response(response) + # Need to await, else presence will flash on other clients await self.set_presence(state) self.start_task = asyncio.ensure_future(self._start()) @@ -1223,6 +1224,8 @@ class MatrixClient(nio.AsyncClient): await super().set_presence("offline" if presence == "invisible" else presence) + # Assign invisible on model in here, because server will tell us we are + # offline if presence == "invisible": self.models["accounts"][self.user_id].presence = \ Presence.State.invisible @@ -1594,10 +1597,12 @@ class MatrixClient(nio.AsyncClient): invited = member.invited, ) + # Associate presence with member, if it exists if user_id in self.backend.presences: presence.members[room.room_id, user_id] = member_item - presence.update_members() + # And then update presence fields + presence.update_members() self.models[self.user_id, room.room_id, "members"][user_id] = \ member_item diff --git a/src/backend/models/items.py b/src/backend/models/items.py index 41f231f1..12b3554f 100644 --- a/src/backend/models/items.py +++ b/src/backend/models/items.py @@ -61,6 +61,10 @@ class Presence(): def update_members(self): for member in self.members.values(): + # Do not update if member is changing to invisible + # Because when setting invisible presence will give us presence + # event telling us we are offline, we do not want to set member + # presence to offline. if ( member.presence == self.State.invisible ) and ( @@ -90,6 +94,9 @@ class Account(ModelItem): local_unreads: bool = False local_highlights: bool = False + # For some reason, Account cannot inherit Presence, because QML keeps + # complaining type error on unknown file + presence_support: bool = False presence: Presence.State = Presence.State.offline currently_active: bool = False last_active_ago: int = -1 diff --git a/src/backend/nio_callbacks.py b/src/backend/nio_callbacks.py index 840dd2a0..2b8dd110 100644 --- a/src/backend/nio_callbacks.py +++ b/src/backend/nio_callbacks.py @@ -133,7 +133,6 @@ class NioCallbacks: DevicesUpdated(self.user_id) - # Room events, invite events and misc events callbacks async def onRoomMessageText( @@ -600,6 +599,7 @@ class NioCallbacks: presence.last_active_ago = ev.last_active_ago or -1 presence.currently_active = ev.currently_active or False + # Add all existing members related to this presence for room_id in self.models[self.user_id, "rooms"]: member = self.models[self.user_id, room_id, "members"].get( ev.user_id, @@ -608,9 +608,15 @@ class NioCallbacks: if member: presence.members[room_id, ev.user_id] = member + # Update members and accounts presence.update_members() + # Check if presence event is ours if ev.user_id in self.models["accounts"]: + # Servers that send presence events support presence + self.models["accounts"][ev.user_id].presence_support = True + + # Save the presence for the next resume await self.client.backend.saved_accounts.add(ev.user_id) self.client.backend.presences[ev.user_id] = presence diff --git a/src/gui/MainPane/AccountContextMenu.qml b/src/gui/MainPane/AccountContextMenu.qml index f58cc29b..b4f08dbd 100644 --- a/src/gui/MainPane/AccountContextMenu.qml +++ b/src/gui/MainPane/AccountContextMenu.qml @@ -56,6 +56,7 @@ HMenu { } HMenuItem { + visible: presence enabled: presence !== "unavailable" && firstSyncDone icon.name: "user-presence" icon.color: theme.controls.presence.unavailable @@ -64,6 +65,7 @@ HMenu { } HMenuItem { + visible: presence enabled: presence !== "invisible" && firstSyncDone icon.name: "user-presence" icon.color: theme.controls.presence.offline diff --git a/src/gui/MainPane/AccountDelegate.qml b/src/gui/MainPane/AccountDelegate.qml index ff8d1991..fc9d35be 100644 --- a/src/gui/MainPane/AccountDelegate.qml +++ b/src/gui/MainPane/AccountDelegate.qml @@ -137,7 +137,9 @@ HTile { contextMenu: AccountContextMenu { userId: model.id - presence: model.presence + presence: model.presence_support ? model.presence : null + + // Gray out buttons before first sync firstSyncDone: model.first_sync_done }