Retrieve last seen time for offline room members
This commit is contained in:
parent
a17daf61c8
commit
6c4ee17e40
1
TODO.md
1
TODO.md
@ -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)
|
||||||
|
@ -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})"
|
||||||
|
@ -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,
|
||||||
|
@ -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 {} }
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user