popUntil<T extends Object?> method

void popUntil<T extends Object?>(
  1. SheetPredicate predicate, [
  2. T? result
])

Clears the sheets from the navigation stack until 'predicate' function returns true. The top-most widget is closed with animation and its result is returned.

Implementation

void popUntil<T extends Object?>(
  SheetPredicate predicate, [
  T? result,
]) async {
  if (_blockGestures) return;

  if (_sheetEntries.isEmpty) {
    throw StateError('No active sheets to pop.');
  }

  final lastEntry = _sheetEntries.last;
  final candidate = _sheetEntries.cast<SideSheetEntry?>().firstWhere(
        (entry) => entry == null ? false : predicate(entry),
        orElse: () => null,
      );

  // Nothing found, just close all the sheets.
  if (candidate == null) {
    close();
    return;
  }

  // Otherwise, pop until candidate sheet.
  Completer? completer;
  try {
    // Find the candidate index.
    final candidateIndex = _sheetEntries.indexOf(candidate);
    // Find the completer, that was created by the candidate sheet.
    final preCandidate = _sheetEntries[candidateIndex + 1];
    completer = preCandidate.completer;
  } catch (_) {
    /*ignore*/
  }

  for (final entry in _sheetEntries.reversed.toList()) {
    if (entry != candidate && entry != lastEntry) {
      _removeSheetSilently(entry);
    } else if (predicate(entry)) {
      break;
    }
  }
  _notifyStateChange();
  await Future.delayed(const Duration(milliseconds: 17));
  _pop(result, completer);
}