requestUser method
Requests a missing User for this room. Important for clients using
lazy loading. If the user can't be found this method tries to fetch
the displayname and avatar from the profile if requestProfile
is true.
Implementation
Future<User?> requestUser(
String mxID, {
bool ignoreErrors = false,
bool requestProfile = true,
}) async {
assert(mxID.isValidSDNId);
// Checks if the user is really missing
final stateUser = getState(EventTypes.RoomMember, mxID);
if (stateUser != null) {
return stateUser.asUser;
}
// it may be in the database
final dbuser = await client.database?.getUser(mxID, this);
if (dbuser != null) {
setState(dbuser);
onUpdate.add(id);
return dbuser;
}
if (!_requestingSDNIds.add(mxID)) return null;
Map<String, dynamic>? resp;
try {
Logs().v(
'Request missing user $mxID in room ${getLocalizedDisplayname()} from the server...');
resp = await client.getRoomStateWithKey(
id,
EventTypes.RoomMember,
mxID,
);
} on SDNException catch (_) {
// Ignore if we have no permission
} catch (e, s) {
if (!ignoreErrors) {
_requestingSDNIds.remove(mxID);
rethrow;
} else {
Logs().w('Unable to request the user $mxID from the server', e, s);
}
}
if (resp == null && requestProfile) {
try {
final profile = await client.getUserProfile(mxID);
_requestingSDNIds.remove(mxID);
return User(
mxID,
displayName: profile.displayname,
avatarUrl: profile.avatarUrl?.toString(),
membership: Membership.leave.name,
room: this,
);
} catch (e, s) {
_requestingSDNIds.remove(mxID);
if (!ignoreErrors) {
rethrow;
} else {
Logs().w('Unable to request the profile $mxID from the server', e, s);
}
}
}
if (resp == null) {
return null;
}
final user = User(mxID,
displayName: resp['displayname'],
avatarUrl: resp['avatar_url'],
room: this);
setState(user);
await client.database?.transaction(() async {
final fakeEventId = String.fromCharCodes(
await sha256(
Uint8List.fromList(
(id + mxID + client.generateUniqueTransactionId()).codeUnits),
),
);
await client.database?.storeEventUpdate(
EventUpdate(
content: SDNEvent(
type: EventTypes.RoomMember,
content: resp!,
stateKey: mxID,
originServerTs: DateTime.now(),
senderId: mxID,
eventId: fakeEventId,
).toJson(),
roomID: id,
type: EventUpdateType.state,
),
client,
);
});
onUpdate.add(id);
_requestingSDNIds.remove(mxID);
return user;
}