From 55bfc92ee03e9403648b34274f17cb670486a1b9 Mon Sep 17 00:00:00 2001 From: Krille Date: Fri, 8 Dec 2023 10:46:16 +0100 Subject: [PATCH 1/2] refactor: Make possible to wait for first sync and await first sync before create megolm session --- lib/encryption/key_manager.dart | 1 + lib/src/client.dart | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/encryption/key_manager.dart b/lib/encryption/key_manager.dart index c74539cb..f01ac1b8 100644 --- a/lib/encryption/key_manager.dart +++ b/lib/encryption/key_manager.dart @@ -502,6 +502,7 @@ class KeyManager { Future _createOutboundGroupSession( String roomId) async { await clearOrUseOutboundGroupSession(roomId, wipe: true); + await client.firstSyncReceived; final room = client.getRoomById(roomId); if (room == null) { throw Exception( diff --git a/lib/src/client.dart b/lib/src/client.dart index 770a4be2..7a91f892 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1586,9 +1586,9 @@ class Client extends MatrixApi { ); /// Timeout of 0, so that we don't see a spinner for 30 seconds. - final syncFuture = _sync(timeout: Duration.zero); + firstSyncReceived = _sync(timeout: Duration.zero); if (waitForFirstSync) { - await syncFuture; + await firstSyncReceived; } return; } catch (e, s) { @@ -2341,6 +2341,7 @@ class Client extends MatrixApi { Future? userDeviceKeysLoading; Future? roomsLoading; Future? _accountDataLoading; + Future? firstSyncReceived; Future? get accountDataLoading => _accountDataLoading; From 9dc2f825a388c92fe3d124b7fe88b084a2f2cc39 Mon Sep 17 00:00:00 2001 From: Krille Date: Wed, 13 Dec 2023 14:28:08 +0100 Subject: [PATCH 2/2] refactor: Add loadHeroUsers method This makes it possible to await loading the hero users to correctly calculate displayname and avatar. --- lib/src/room.dart | 23 +++++++++++++++++++++++ test/room_test.dart | 3 +++ 2 files changed, 26 insertions(+) diff --git a/lib/src/room.dart b/lib/src/room.dart index 1ff131ea..a2714710 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -223,6 +223,29 @@ class Room { return pinned is Iterable ? pinned.map((e) => e.toString()).toList() : []; } + /// Returns the heroes as `User` objects. + /// This is very useful if you want to make sure that all users are loaded + /// from the database, that you need to correctly calculate the displayname + /// and the avatar of the room. + Future> loadHeroUsers() async { + var heroes = summary.mHeroes; + if (heroes == null) { + final directChatMatrixID = this.directChatMatrixID; + if (directChatMatrixID != null) { + heroes = [directChatMatrixID]; + } + } + + if (heroes == null) return []; + + return await Future.wait(heroes.map((hero) async => + (await requestUser( + hero, + ignoreErrors: true, + )) ?? + User(hero, room: this))); + } + /// Returns a localized displayname for this server. If the room is a groupchat /// without a name, then it will return the localized version of 'Group with Alice' instead /// of just 'Alice' to make it different to a direct chat. diff --git a/test/room_test.dart b/test/room_test.dart index 00df688f..1d204c6f 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -81,6 +81,9 @@ void main() { stateKey: '', )); + final heroUsers = await room.loadHeroUsers(); + expect(heroUsers.length, 3); + expect(room.id, id); expect(room.membership, membership); expect(room.notificationCount, notificationCount);