Retrieve last seen time for offline room members

This commit is contained in:
miruka 2020-07-17 00:46:46 -04:00
parent a17daf61c8
commit 6c4ee17e40
5 changed files with 56 additions and 3 deletions

View File

@ -1,7 +1,6 @@
# TODO # TODO
- global presence control - global presence control
- retrieve last seen time for offline members on hover/in profile/automatically
- fix HLabeledItem disabled opacity - fix HLabeledItem disabled opacity
(visible for the topic area in room settings) (visible for the topic area in room settings)

View File

@ -114,6 +114,8 @@ class Backend:
self.presences: Dict[str, Presence] = {} self.presences: Dict[str, Presence] = {}
self.concurrent_get_presence_limit = asyncio.BoundedSemaphore(8)
def __repr__(self) -> str: def __repr__(self) -> str:
return f"{type(self).__name__}(clients={self.clients!r})" return f"{type(self).__name__}(clients={self.clients!r})"

View File

@ -1353,6 +1353,33 @@ class MatrixClient(nio.AsyncClient):
await self.set_avatar(mxc) await self.set_avatar(mxc)
async def get_offline_presence(self, user_id: str) -> None:
"""Get a offline room member's presence and set it on model item.
This is called by QML when a member list delegate or profile that
is offline is displayed.
Since we don't get last seen times for offline in users in syncs,
we have to fetch those manually.
"""
if self.backend.presences.get(user_id):
return
if not self.models["accounts"][self.user_id].presence_support:
return
async with self.backend.concurrent_get_presence_limit:
resp = await self.get_presence(user_id)
await self.nio_callbacks.onPresenceEvent(nio.PresenceEvent(
user_id = resp.user_id,
presence = resp.presence,
last_active_ago = resp.last_active_ago,
currently_active = resp.currently_active,
status_msg = resp.status_msg,
))
async def set_presence( async def set_presence(
self, self,
presence: str, presence: str,

View File

@ -6,10 +6,13 @@ import "../../../.."
import "../../../../Base" import "../../../../Base"
import "../../../../Base/HTile" import "../../../../Base/HTile"
import "../../../../Popups" import "../../../../Popups"
import "../../../../PythonBridge"
HTile { HTile {
id: member id: member
property Future getPresenceFuture: null
backgroundColor: theme.chat.roomPane.listView.member.background backgroundColor: theme.chat.roomPane.listView.member.background
contentOpacity: contentOpacity:
model.invited ? theme.chat.roomPane.listView.member.invitedOpacity : 1 model.invited ? theme.chat.roomPane.listView.member.invitedOpacity : 1
@ -145,6 +148,14 @@ HTile {
} }
} }
Component.onCompleted:
if (model.presence === "offline" && model.last_active_at < new Date(1))
getPresenceFuture = py.callClientCoro(
chat.userId, "get_offline_presence", [model.id],
)
Component.onDestruction: if (getPresenceFuture) getPresenceFuture.cancel()
Behavior on contentOpacity { HNumberAnimation {} } Behavior on contentOpacity { HNumberAnimation {} }
Behavior on spacing { HNumberAnimation {} } Behavior on spacing { HNumberAnimation {} }

View File

@ -20,6 +20,7 @@ HListView {
property bool powerLevelFieldFocused: false property bool powerLevelFieldFocused: false
property Future setPowerFuture: null property Future setPowerFuture: null
property Future getPresenceFuture: null
function loadDevices() { function loadDevices() {
py.callClientCoro(userId, "member_devices", [member.id], devices => { py.callClientCoro(userId, "member_devices", [member.id], devices => {
@ -269,8 +270,21 @@ HListView {
} }
} }
Component.onCompleted: loadDevices() Component.onCompleted: {
Component.onDestruction: if (setPowerFuture) setPowerFuture.cancel() loadDevices()
if (member.presence === "offline" &&
member.last_active_at < new Date(1))
{
getPresenceFuture =
py.callClientCoro(userId, "get_offline_presence", [member.id])
}
}
Component.onDestruction: {
if (setPowerFuture) setPowerFuture.cancel()
if (getPresenceFuture) getPresenceFuture.cancel()
}
Keys.onEnterPressed: Keys.onReturnPressed(event) Keys.onEnterPressed: Keys.onReturnPressed(event)
Keys.onReturnPressed: if (! root.powerLevelFieldFocused && currentItem) { Keys.onReturnPressed: if (! root.powerLevelFieldFocused && currentItem) {