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 sys
import traceback import traceback
from pathlib import Path 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 from appdirs import AppDirs
@ -23,6 +23,9 @@ from .models.model import Model
from .models.model_store import ModelStore from .models.model_store import ModelStore
from .user_files import Accounts, History, Theme, UISettings, UIState from .user_files import Accounts, History, Theme, UISettings, UIState
if TYPE_CHECKING:
from .models.items import Presence
# Logging configuration # Logging configuration
log.getLogger().setLevel(log.INFO) log.getLogger().setLevel(log.INFO)
nio.logger_group.level = nio.log.logbook.ERROR nio.logger_group.level = nio.log.logbook.ERROR
@ -109,6 +112,8 @@ class Backend:
self.media_cache: MediaCache = MediaCache(self, cache_dir) self.media_cache: MediaCache = MediaCache(self, cache_dir)
self.presences: Dict[str, "Presence"] = {}
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

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

View File

@ -29,10 +29,26 @@ class TypeSpecifier(AutoStrEnum):
MembershipChange = auto() MembershipChange = auto()
class Presence(AutoStrEnum): @dataclass
Offline = auto() # can mean offline, invisible or unknwon class Presence():
Unavailable = auto() class State(AutoStrEnum):
Online = auto() 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 @dataclass
@ -169,7 +185,7 @@ class AccountOrRoom(Account, Room):
@dataclass @dataclass
class Member(ModelItem): class Member(Presence, ModelItem):
"""A member in a matrix room.""" """A member in a matrix room."""
id: str = field() id: str = field()
@ -183,22 +199,22 @@ class Member(ModelItem):
last_read_event: str = "" last_read_event: str = ""
last_read_at: datetime = ZeroDate 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: 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:] name = self.display_name or self.id[1:]
other_name = other.display_name or other.id[1:] other_name = other.display_name or other.id[1:]
return ( 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 # Presence event callbacks
async def onPresenceEvent(self, ev: nio.PresenceEvent) -> None: async def onPresenceEvent(self, ev: nio.PresenceEvent) -> None:
for room_id in self.models[self.user_id, "rooms"]: self.client.backend.presences[ev.user_id] = Presence(
member = \ status_msg = ev.status_msg or "",
self.models[self.user_id, room_id, "members"].get(ev.user_id) presence = Presence.State(ev.presence) if ev.presence
else Presence.State.offline,
if member: last_active_ago = ev.last_active_ago or -1,
member.last_active_ago = \ currently_active = ev.currently_active,
-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 ""

View File

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

View File

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