requestUser method

Future<User?> requestUser(
  1. String mxID, {
  2. bool ignoreErrors = false,
  3. bool requestProfile = true,
})

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;
}