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;