consumeWith method

double consumeWith(
  1. double available,
  2. NestedScrollPosition position,
  3. NestedScrollConsumer selfConsumer,
  4. NestedScrollConsumer ancestorConsumer,
)

Implementation

double consumeWith(
  double available,
  NestedScrollPosition position,
  NestedScrollConsumer selfConsumer,
  NestedScrollConsumer ancestorConsumer,
) {
  final List<NestedScrollConnection> delegators =
      findSelfAndAncestorWidgets();

  // Current consumed amount from available.
  double consumed = 0;

  // Returns the remaining offset after consumption.
  double remained() => available - consumed;

  for (final delegator in delegators) {
    if (delegator.predicate?.call(available, position) ?? false) {
      consumed += selfConsumer(delegator)?.call(remained(), position) ?? 0.0;

      // When the available offset has been fully consumed.
      if ((consumed - available).abs() < precisionErrorTolerance) {
        return consumed;
      }
    }
  }

  if (widget.propagation == NestedScrollConnectionPropagation.selfFirst) {
    consumed += selfConsumer(widget)?.call(remained(), position) ?? 0.0;

    // When the available offset is not fully consumed,
    // delegate the remainder to the ancestor.
    if ((consumed - available).abs() > precisionErrorTolerance) {
      return ancestorConsumer(widget)?.call(remained(), position) ?? consumed;
    }
  } else if (widget.propagation ==
      NestedScrollConnectionPropagation.deferToAncestor) {
    consumed += ancestorConsumer(widget)?.call(remained(), position) ?? 0.0;

    // When the available offset is not fully consumed,
    // delegate the remainder to the ancestor.
    if ((consumed - available).abs() > precisionErrorTolerance) {
      return selfConsumer(widget)?.call(remained(), position) ?? consumed;
    }
  } else {
    final prioritized = List<NestedScrollConnection>.from(delegators)
      ..sort((a, b) {
        int priority(NestedScrollConnection c) {
          return switch (c.propagation) {
            NestedScrollConnectionPropagation.selfFirst => 0,
            NestedScrollConnectionPropagation.directional => 1,
            NestedScrollConnectionPropagation.deferToAncestor => 2,
          };
        }

        return priority(a).compareTo(priority(b));
      });

    final targets = available > 0 ? prioritized : prioritized.reversed;

    for (final it in targets) {
      consumed += selfConsumer(it)?.call(remained(), position) ?? 0;

      // If when all consumed, stops the travel.
      if ((consumed - available).abs() < precisionErrorTolerance) {
        break;
      }
    }
  }

  return consumed;
}