init method

Future<void> init({
  1. FutureOr<RxChat?> getChat(
    1. ChatId
    )?,
})

Initializes the media client resources.

No-op if already initialized.

Implementation

Future<void> init({FutureOr<RxChat?> Function(ChatId)? getChat}) async {
  Log.debug('init()', '$runtimeType');

  if (_background) {
    _background = false;

    _devicesSubscription = MediaUtils.onDeviceChange.listen((e) async {
      Log.debug('onDeviceChange(${e.map((e) => e.label())})', '$runtimeType');

      final List<DeviceDetails> previous = List.from(
        devices,
        growable: false,
      );

      devices.value = e;

      final List<DeviceDetails> removed = [];

      for (DeviceDetails d in previous) {
        if (devices.none((p) => p.deviceId() == d.deviceId())) {
          removed.add(d);
        }
      }

      final bool audioChanged =
          !previous
              .audio()
              .map((e) => e.deviceId())
              .sameAs(devices.audio().map((e) => e.deviceId()));

      final bool outputChanged =
          !previous
              .output()
              .map((e) => e.deviceId())
              .sameAs(devices.output().map((e) => e.deviceId()));

      final bool videoChanged =
          !previous
              .video()
              .map((e) => e.deviceId())
              .sameAs(devices.video().map((e) => e.deviceId()));

      if (audioChanged) {
        _pickAudioDevice();
      }

      if (outputChanged) {
        _pickOutputDevice();
      }

      if (videoChanged) {
        _pickVideoDevice(previous, removed);
      }
    });

    _displaysSubscription = MediaUtils.onDisplayChange.listen((e) async {
      final List<MediaDisplayDetails> previous = List.from(
        displays,
        growable: false,
      );

      displays.value = e;

      final List<MediaDisplayDetails> removed = [];

      for (MediaDisplayDetails d in previous) {
        if (displays.none((p) => p.deviceId() == d.deviceId())) {
          removed.add(d);
        }
      }

      _pickScreenDevice(removed);
    });

    // Puts the members of the provided [chat] to the [members] through
    // [_addDialing].
    Future<void> addDialingsFrom(RxChat? chat) async {
      if (chat == null) {
        return;
      }

      final int membersCount = chat.chat.value.membersCount;
      final bool shouldAddDialed =
          (outgoing && conversationStartedAt == null) ||
          chat.chat.value.isDialog;

      // Dialed [User]s should be added, if [membersCount] is less than a page
      // of [Chat.members].
      if (membersCount <= chat.members.perPage && shouldAddDialed) {
        if (chat.members.length < membersCount) {
          await chat.members.around();
        }

        // If [connected], then the dialed [User] will be added in [connect],
        // when handling [ChatMembersDialedAll].
        if (!connected) {
          for (UserId e in chat.members.items.keys.where(
            (e) => e != me.id.userId,
          )) {
            _addDialing(e);
          }
        }
      }
    }

    // Retrieve the [RxChat] this [OngoingCall] is happening in to add its
    // members to the [members] in redialing mode as fast as possible.
    final FutureOr<RxChat?>? chatOrFuture = getChat?.call(chatId.value);
    if (chatOrFuture is RxChat?) {
      addDialingsFrom(chatOrFuture);
    } else {
      chatOrFuture.then(addDialingsFrom);
    }

    await _initRoom();
    await _setInitialMediaSettings();
    await _initLocalMedia();
  }
}