waitForLogin function

Future<void> waitForLogin(
  1. WpClientInterface wpClient, {
  2. required dynamic onQrCode(
    1. String qrCodeUrl,
    2. Uint8List? qrCodeImage
    )?,
  3. int waitDurationSeconds = 60,
  4. dynamic onConnectionEvent(
    1. ConnectionEvent
    )?,
  5. bool skipQrScan = false,
})

waitForLogin will either complete with successful login or failed with timeout exception this method will automatically try to get the qrCode also it will make sure that we get the latest qrCode

Implementation

Future<void> waitForLogin(
  WpClientInterface wpClient, {
  required Function(String qrCodeUrl, Uint8List? qrCodeImage)? onQrCode,
  int waitDurationSeconds = 60,
  Function(ConnectionEvent)? onConnectionEvent,
  bool skipQrScan = false,
}) async {
  WhatsappLogger.log('Checking authentication status...');
  final wppAuth = WppAuth(wpClient);

  bool authenticated = await wppAuth.isAuthenticated();

  if (!authenticated && skipQrScan) {
    WhatsappLogger.log('Authentication required but skipQrScan is true. Redirecting to google.com...');
    await wpClient.loadUrl('https://www.google.com');
    return;
  }

  if (!authenticated) {
    onConnectionEvent?.call(ConnectionEvent.waitingForQrScan);
    WhatsappLogger.log('Waiting for QRCode Scan...');

    final authCompleter = Completer<void>();
    wpClient.on(WhatsappEvent.connauthenticated, (_) {
      if (!authCompleter.isCompleted) authCompleter.complete();
    });

    try {
      await Future.any([
        waitForQrCodeScan(
          wpClient: wpClient,
          onCatchQR: (QrCodeImage qrCodeImage, int attempt) {
            if (qrCodeImage.base64Image != null && qrCodeImage.urlCode != null) {
              Uint8List? imageBytes;
              try {
                final base64String = qrCodeImage.base64Image!.replaceFirst(
                    RegExp(r'data:image\/[a-zA-Z]+;base64,'), "");
                imageBytes = base64Decode(base64String);
              } catch (e) {
                WhatsappLogger.log("Error decoding QR image: $e");
              }
              onQrCode?.call(qrCodeImage.urlCode!, imageBytes);
            }
          },
          waitDurationSeconds: waitDurationSeconds,
        ),
        authCompleter.future,
      ]);
    } catch (e) {
      if (e is WhatsappException) rethrow;
      throw WhatsappException(
        message: "Error during QR scan: $e",
        exceptionType: WhatsappExceptionType.unknown,
      );
    } finally {
      wpClient.off(WhatsappEvent.connauthenticated);
    }

    WhatsappLogger.log('Checking login status after scan...');
    // Small delay to let internal state settle
    await Future.delayed(const Duration(milliseconds: 200));
    authenticated = await wppAuth.isAuthenticated();

    if (!authenticated) {
      throw const WhatsappException(
        message: 'Login Failed: Not authenticated after scan',
        exceptionType: WhatsappExceptionType.loginFailed,
      );
    }
  }

  onConnectionEvent?.call(ConnectionEvent.authenticated);
  await Future.delayed(const Duration(milliseconds: 200));

  WhatsappLogger.log('Waiting for connection to be ready...');
  onConnectionEvent?.call(ConnectionEvent.connecting);

  // Wait for main interface to be ready
  final isReady = await waitForInChat(wpClient);
  if (!isReady) {
    throw const WhatsappException(
      message: 'Connection failed: Main interface not ready',
      exceptionType: WhatsappExceptionType.connectionFailed,
    );
  }

  WhatsappLogger.log('Connected successfully');
  onConnectionEvent?.call(ConnectionEvent.connected);
}