Correctly handle initial sync member events

Previously, member events in initial syncs (unless user had "hide member
events" and "hide profile events" set to false in their config) were
completely discarded with the help of a sync filter, instead of simply
being hidden like events loaded from room backfilling.

This was done due to the common case of rooms getting only
userconfig-ignored/hidden events on startup (especially with the
low number of initial events requested for lazy initial sync),
and thus having nothing to show as "last message" in
the room list (room delegate subtitles).

Other problems resulted from this, like missing join/leave events
when the config was set to hide profile events but not other
member events, and the "Members not synced" (#54) in encrypted room
with recent discarded member events.

The discarding filter is no longer used. Instead, if a room in the room
list has no visible "last message" and is currently visible to the user,
messages will be lazily fetched until we find something adequate or the
room goes out of view.
This commit is contained in:
miruka 2020-07-27 03:59:41 -04:00
parent f1f24f5121
commit d127ad978c
2 changed files with 35 additions and 10 deletions

View File

@ -130,12 +130,6 @@ class MatrixClient(nio.AsyncClient):
}, },
} }
no_profile_events_filter: ClassVar[Dict[str, Any]] = {
"room": {
"timeline": {"not_types": ["m.room.member"]},
},
}
no_unknown_events_filter: ClassVar[Dict[str, Any]] = { no_unknown_events_filter: ClassVar[Dict[str, Any]] = {
"room": { "room": {
"timeline": { "timeline": {
@ -380,8 +374,6 @@ class MatrixClient(nio.AsyncClient):
utils.dict_update_recursive(filter1, self.low_limit_filter) utils.dict_update_recursive(filter1, self.low_limit_filter)
cfg = self.backend.ui_settings cfg = self.backend.ui_settings
if cfg["hideProfileChangeEvents"] or cfg["hideMembershipEvents"]:
utils.dict_update_recursive(filter1, self.no_profile_events_filter)
if cfg["hideUnknownEvents"]: if cfg["hideUnknownEvents"]:
filter1["room"]["timeline"]["not_types"].extend( filter1["room"]["timeline"]["not_types"].extend(
@ -952,7 +944,11 @@ class MatrixClient(nio.AsyncClient):
async def load_past_events(self, room_id: str) -> bool: async def load_past_events(self, room_id: str) -> bool:
"""Ask the server for 100 previous events of the room. """Ask the server for previous events of the room.
If it's the first time that the room is being loaded, 10 events
will be requested (to give the user something to read quickly), else
100 events will be requested.
Events from before the client was started will be requested and Events from before the client was started will be requested and
registered into our models. registered into our models.
@ -975,7 +971,7 @@ class MatrixClient(nio.AsyncClient):
response = await self.room_messages( response = await self.room_messages(
room_id = room_id, room_id = room_id,
start = self.past_tokens[room_id], start = self.past_tokens[room_id],
limit = 100 if room_id in self.loaded_once_rooms else 20, limit = 100 if room_id in self.loaded_once_rooms else 10,
message_filter = self.lazy_load_filter, message_filter = self.lazy_load_filter,
) )

View File

@ -6,10 +6,14 @@ import Clipboard 0.1
import ".." import ".."
import "../Base" import "../Base"
import "../Base/HTile" import "../Base/HTile"
import "../PythonBridge"
HTile { HTile {
id: room id: room
property Future loadEventsFuture: null
property bool moreToLoad: true
readonly property bool joined: ! invited && ! parted readonly property bool joined: ! invited && ! parted
readonly property bool invited: model.inviter_id && ! parted readonly property bool invited: model.inviter_id && ! parted
readonly property bool parted: model.left readonly property bool parted: model.left
@ -195,4 +199,29 @@ HTile {
}) })
} }
} }
Component.onDestruction: if (loadEventsFuture) loadEventsFuture.cancel()
Timer {
running:
! accountModel.connecting &&
accountModel.presence !== "offline" &&
! lastEvent &&
moreToLoad
interval: 1000
triggeredOnStart: true
onTriggered: if (! loadEventsFuture) {
loadEventsFuture = py.callClientCoro(
model.for_account,
"load_past_events",
[model.id],
more => {
if (! room) return // delegate was destroyed
loadEventsFuture = null
moreToLoad = more
}
)
}
}
} }