Fix outdated presence for lazy loaded members

This commit is contained in:
vslg 2020-07-01 17:55:03 -03:00 committed by miruka
parent 59198da3b0
commit 6e202c3e27
6 changed files with 55 additions and 39 deletions

View File

@ -6,7 +6,7 @@ import os
import sys
import traceback
from pathlib import Path
from typing import Any, DefaultDict, Dict, List, Optional
from typing import TYPE_CHECKING, Any, DefaultDict, Dict, List, Optional
from appdirs import AppDirs
@ -23,6 +23,9 @@ from .models.model import Model
from .models.model_store import ModelStore
from .user_files import Accounts, History, Theme, UISettings, UIState
if TYPE_CHECKING:
from .models.items import Presence
# Logging configuration
log.getLogger().setLevel(log.INFO)
nio.logger_group.level = nio.log.logbook.ERROR
@ -109,6 +112,8 @@ class Backend:
self.media_cache: MediaCache = MediaCache(self, cache_dir)
self.presences: Dict[str, "Presence"] = {}
def __repr__(self) -> str:
return f"{type(self).__name__}(clients={self.clients!r})"

View File

@ -113,8 +113,6 @@ class MatrixClient(nio.AsyncClient):
}
low_limit_filter: ClassVar[Dict[str, Any]] = {
"presence": {"limit": 1},
"room": {
"ephemeral": {"limit": 1},
"timeline": {
@ -1566,6 +1564,7 @@ class MatrixClient(nio.AsyncClient):
async def add_member(self, room: nio.MatrixRoom, user_id: str) -> None:
"""Register/update a room member into our models."""
member = room.users[user_id]
presence = self.backend.presences.get(user_id, Presence())
self.models[self.user_id, room.room_id, "members"][user_id] = Member(
id = user_id,
@ -1576,12 +1575,10 @@ class MatrixClient(nio.AsyncClient):
power_level = member.power_level,
invited = member.invited,
last_active_ago = -1 if member.last_active_ago is None else
member.last_active_ago,
currently_active = member.currently_active or False,
presence = member.presence or Presence.Offline,
status_message = member.status_msg or "",
presence = presence.presence,
last_active_ago = presence.last_active_ago,
status_msg = presence.status_msg,
currently_active = presence.currently_active,
)
if member.display_name:

View File

@ -29,10 +29,26 @@ class TypeSpecifier(AutoStrEnum):
MembershipChange = auto()
class Presence(AutoStrEnum):
Offline = auto() # can mean offline, invisible or unknwon
Unavailable = auto()
Online = auto()
@dataclass
class Presence():
class State(AutoStrEnum):
offline = auto() # can mean offline, invisible or unknwon
unavailable = auto()
online = auto()
def __lt__(self, other: "Presence.State") -> bool:
order = [self.online, self.unavailable, self.offline]
return (
order.index(self) # type: ignore
) < (
order.index(other) # type: ignore
)
status_msg: str = ""
presence: State = State.offline
last_active_ago: int = -1
currently_active: bool = False
@dataclass
@ -169,7 +185,7 @@ class AccountOrRoom(Account, Room):
@dataclass
class Member(ModelItem):
class Member(Presence, ModelItem):
"""A member in a matrix room."""
id: str = field()
@ -183,22 +199,22 @@ class Member(ModelItem):
last_read_event: str = ""
last_read_at: datetime = ZeroDate
last_active_ago: int = -1
currently_active: bool = False
presence: Presence = Presence.Offline
status_message: str = ""
def __lt__(self, other: "Member") -> bool:
"""Sort by power level, then by display name/user ID."""
"""Sort by presence, power level, then by display name/user ID."""
name = self.display_name or self.id[1:]
other_name = other.display_name or other.id[1:]
return (
self.invited, other.power_level, name.lower(),
self.presence,
self.invited,
other.power_level,
name.lower(),
) < (
other.invited, self.power_level, other_name.lower(),
other.presence,
other.invited,
self.power_level,
other_name.lower(),
)

View File

@ -592,14 +592,10 @@ class NioCallbacks:
# Presence event callbacks
async def onPresenceEvent(self, ev: nio.PresenceEvent) -> None:
for room_id in self.models[self.user_id, "rooms"]:
member = \
self.models[self.user_id, room_id, "members"].get(ev.user_id)
if member:
member.last_active_ago = \
-1 if ev.last_active_ago is None else ev.last_active_ago
member.currently_active = ev.currently_active or False
member.presence = ev.presence or Presence.Offline
member.status_message = ev.status_msg or ""
self.client.backend.presences[ev.user_id] = Presence(
status_msg = ev.status_msg or "",
presence = Presence.State(ev.presence) if ev.presence
else Presence.State.offline,
last_active_ago = ev.last_active_ago or -1,
currently_active = ev.currently_active,
)

View File

@ -54,7 +54,7 @@ HAvatar {
}
HLoader {
active: presence
active: presence && presence !== "offline"
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.bottomMargin: -diameter / 2

View File

@ -46,8 +46,10 @@ HTile {
text:
model.presence === "offline" &&
model.last_active_ago !== -1 ?
"offline for " +
utils.formatRelativeTime(model.last_active_ago) :
"for " +
utils.formatRelativeTime(
model.last_active_ago
) :
""
}
}
@ -55,7 +57,7 @@ HTile {
SubtitleLabel {
tile: member
color: theme.chat.roomPane.listView.member.subtitle
text: model.status_message.trim() || model.id
text: model.status_msg.trim() || model.id
}
}
}