showLoadingAlertDialog<T> static method

Future<T?> showLoadingAlertDialog<T>({
  1. required BuildContext context,
  2. required Future<T> computation,
  3. WidgetBuilder? builder,
})

Wrapper for a call to showDialog on Android or showCupertinoDialog on iOS, controlled by the computation argument, which is a Future.

This method's workflow are described below:

  1. Shows the Dialog
  2. Runs the computation
  3. When the computation finishes, close the Dialog

This method returns a distinct Future instance which completes with the result/error from the original provided Future from the computation argument.

If builder argument is null, the Dialog defaults to result from _defaultWidgetBuilder return value, or an empty Container if both are not provided.

Implementation

static Future<T?> showLoadingAlertDialog<T>({
  required BuildContext context,
  required Future<T> computation,
  WidgetBuilder? builder,
}) {
  final Completer<T?> completer = Completer<T?>();

  final WidgetBuilder builderWrapper = (context) {
    computation.then((value) {
      final overlayContext = Navigator.of(context,).overlay?.context;
      if (overlayContext == null) {
        if (!completer.isCompleted) {
          completer.complete(value,);
        }
        return;
      }
      final navigator = Navigator.of(overlayContext,);
      if (!completer.isCompleted && navigator.canPop()) {
        navigator.pop();
      }
      if (!completer.isCompleted) {
        completer.complete(value,);
      }
    },).catchError((e,) {
      final overlayContext = Navigator.of(context,).overlay?.context;
      if (overlayContext == null) {
        if (!completer.isCompleted) {
          completer.completeError(e,);
        }
        return;
      }
      final navigator = Navigator.of(context,);
      if (!completer.isCompleted && navigator.canPop()) {
        navigator.pop();
      }
      if (!completer.isCompleted) {
        completer.completeError(e,);
      }
    },);
    return WillPopScope(
      onWillPop: () async => false,
      child: Builder(
        builder: (context) => builder?.call(context,) ?? _defaultWidgetBuilder?.call(context,) ?? Container(),
      ),
    );
  };

  if (Platform.isIOS) {
    showCupertinoDialog(
      context: context,
      builder: (context) {
        return Builder(
          builder: builderWrapper,
        );
      },
    );
  } else if (Platform.isAndroid) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: builderWrapper,
    );
  } else {
    completer.completeError(UnsupportedError(UNSUPPORTED_PLATFORM,),);
  }

  return completer.future;
}