From 4394196ba1f1f650dfd8be717c1f95eb68d43b46 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Tue, 14 Jul 2020 11:30:13 +0200 Subject: [PATCH 1/2] try to load members from database first and cache them in-memory --- lib/src/database/database.dart | 9 +++++++++ lib/src/database/database.g.dart | 18 ++++-------------- lib/src/database/database.moor | 1 + lib/src/room.dart | 10 ++++++++++ 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lib/src/database/database.dart b/lib/src/database/database.dart index c329d0b..5e26e23 100644 --- a/lib/src/database/database.dart +++ b/lib/src/database/database.dart @@ -528,6 +528,15 @@ class Database extends _$Database { return sdk.Event.fromDb(res.first, room).asUser; } + Future> getUsers(int clientId, sdk.Room room) async { + final res = await dbGetUsers(clientId, room.id).get(); + final ret = []; + for (final r in res) { + ret.add(sdk.Event.fromDb(r, room).asUser); + } + return ret; + } + Future> getEventList(int clientId, sdk.Room room) async { final res = await dbGetEventList(clientId, room.id).get(); final eventList = []; diff --git a/lib/src/database/database.g.dart b/lib/src/database/database.g.dart index e17101d..79e524a 100644 --- a/lib/src/database/database.g.dart +++ b/lib/src/database/database.g.dart @@ -6196,21 +6196,11 @@ abstract class _$Database extends GeneratedDatabase { }).map(_rowToDbRoomState); } - Selectable dbGetUsers( - int client_id, List mxids, String room_id) { - var $arrayStartIndex = 2; - final expandedmxids = $expandVar($arrayStartIndex, mxids.length); - $arrayStartIndex += mxids.length; + Selectable dbGetUsers(int client_id, String room_id) { return customSelect( - 'SELECT * FROM room_states WHERE client_id = :client_id AND type = \'m.room.member\' AND state_key IN ($expandedmxids) AND room_id = :room_id', - variables: [ - Variable.withInt(client_id), - for (var $ in mxids) Variable.withString($), - Variable.withString(room_id) - ], - readsFrom: { - roomStates - }).map(_rowToDbRoomState); + 'SELECT * FROM room_states WHERE client_id = :client_id AND type = \'m.room.member\' AND room_id = :room_id', + variables: [Variable.withInt(client_id), Variable.withString(room_id)], + readsFrom: {roomStates}).map(_rowToDbRoomState); } DbEvent _rowToDbEvent(QueryRow row) { diff --git a/lib/src/database/database.moor b/lib/src/database/database.moor index 716bdc6..cade18c 100644 --- a/lib/src/database/database.moor +++ b/lib/src/database/database.moor @@ -216,6 +216,7 @@ storeRoomState: INSERT OR REPLACE INTO room_states (client_id, event_id, room_id getAllRoomAccountData: SELECT * FROM room_account_data WHERE client_id = :client_id; storeRoomAccountData: INSERT OR REPLACE INTO room_account_data (client_id, type, room_id, content) VALUES (:client_id, :type, :room_id, :content); dbGetUser: SELECT * FROM room_states WHERE client_id = :client_id AND type = 'm.room.member' AND state_key = :state_key AND room_id = :room_id; +dbGetUsers: SELECT * FROM room_states WHERE client_id = :client_id AND type = 'm.room.member' AND room_id = :room_id; dbGetEventList: SELECT * FROM events WHERE client_id = :client_id AND room_id = :room_id GROUP BY event_id ORDER BY sort_order DESC; getStates: SELECT * FROM room_states WHERE client_id = :client_id AND room_id = :room_id; resetNotificationCount: UPDATE rooms SET notification_count = 0, highlight_count = 0 WHERE client_id = :client_id AND room_id = :room_id; diff --git a/lib/src/room.dart b/lib/src/room.dart index 40aa431..3ae81cc 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1004,10 +1004,20 @@ class Room { /// Request the full list of participants from the server. The local list /// from the store is not complete if the client uses lazy loading. Future> requestParticipants() async { + if (!participantListComplete && partial && client.database != null) { + // we aren't fully loaded, maybe the users are in the database + final users = await client.database.getUsers(client.id, this); + for (final user in users) { + setState(user); + } + } if (participantListComplete) return getParticipants(); final matrixEvents = await client.api.requestMembers(id); final users = matrixEvents.map((e) => Event.fromMatrixEvent(e, this).asUser).toList(); + for (final user in users) { + setState(user); // at *least* cache this in-memory + } users.removeWhere( (u) => [Membership.leave, Membership.ban].contains(u.membership)); return users; From 8b3e2e6c865badf3b976018578fffc8bc4273672 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Tue, 14 Jul 2020 11:46:37 +0200 Subject: [PATCH 2/2] fix tests --- test/room_test.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/room_test.dart b/test/room_test.dart index 590f0ec..b459db5 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -300,6 +300,9 @@ void main() { }); test('getParticipants', () async { + var userList = room.getParticipants(); + expect(userList.length, 4); + // add new user room.setState(Event( senderId: '@alice:test.abc', type: 'm.room.member', @@ -309,9 +312,9 @@ void main() { originServerTs: DateTime.now(), content: {'displayname': 'alice'}, stateKey: '@alice:test.abc')); - final userList = room.getParticipants(); - expect(userList.length, 4); - expect(userList[3].displayName, 'alice'); + userList = room.getParticipants(); + expect(userList.length, 5); + expect(userList[4].displayName, 'alice'); }); test('addToDirectChat', () async {