next method

Future<void> next()

Fetches a next page of the items.

Implementation

Future<void> next() async {
  if (_disposed) {
    return Future.value();
  }

  final bool locked = _nextGuard.isLocked;

  return _nextGuard.protect(() async {
    if (locked || _disposed) {
      return;
    }

    await _repeatUntilFulfilled(() async {
      Log.debug('next()...', '$runtimeType');

      if (hasNext.isTrue && nextLoading.isFalse) {
        nextLoading.value = true;

        try {
          if (items.isNotEmpty) {
            try {
              final Page<T, C>? page = await Backoff.run(
                () => provider.after(onKey(items.last), endCursor, perPage),
                _cancelToken,
              );
              Log.debug(
                'next()... fetched ${page?.edges.length} items',
                '$runtimeType',
              );

              final int before = items.length;
              for (var e in page?.edges ?? []) {
                items[onKey(e)] = e;
              }

              endCursor = page?.info.endCursor ?? endCursor;
              hasNext.value = page?.info.hasNext ?? hasNext.value;
              Log.debug('next()... done', '$runtimeType');

              return page?.edges
                  .skip(before)
                  .take(max(0, items.length - before));
            } catch (e) {
              if (e is! OperationCanceledException) {
                rethrow;
              }
            }
          } else {
            await around();
          }
        } finally {
          nextLoading.value = false;
        }
      }

      return null;
    });
  });
}