waitForAppReady method

Future<void> waitForAppReady()

Wait until the splash screen is gone and the real app is loaded.

Implementation

Future<void> waitForAppReady() async {
  print('\n⏳ Waiting for app to finish loading...');
  const splashWidgets = [
    'SplashScreen',
    'splashScreenPage',
    'LinearProgressIndicator',
    'AnimatedContainer',
  ];
  final deadline = DateTime.now().add(const Duration(seconds: 60));
  bool wasSplash = false;
  int failCount = 0;

  while (DateTime.now().isBefore(deadline)) {
    try {
      final tree = await captureWidgetTree(silent: true);
      failCount = 0; // reset on success

      final isSplash = splashWidgets.any((s) => _treeContains(tree, s));

      if (isSplash) {
        wasSplash = true;
        stdout.write('  ⏳ Splash screen loading...\r');
      } else if (wasSplash) {
        print('  ✅ App loaded — splash screen dismissed');
        await Future.delayed(const Duration(milliseconds: 800));
        return;
      } else {
        // Never saw splash — app already loaded
        print('  ✅ App ready');
        return;
      }
    } catch (_) {
      failCount++;
      stdout.write('  ⏳ Connecting... (attempt $failCount)\r');
      if (failCount > 10) {
        // Connection repeatedly failing — likely port not forwarded
        print('\n  ⚠️  Cannot read widget tree.');
        print('  Run this in another terminal:');
        print('  adb -s <device_id> forward tcp:8181 tcp:8181');
        print('  Then press Enter to retry...');
        stdin.readLineSync();
        failCount = 0;
      }
    }

    await Future.delayed(const Duration(milliseconds: 500));
  }

  print('  ⚠️  Timed out — proceeding anyway');
}