buildQuilts method

Future<void> buildQuilts(
  1. QuiltDirection direction, {
  2. bool allowPull = true,
})

Builds quilts in the specified direction, handling pulls and insertions.

Manages buffer updates, edge tracking, and quilt insertion/removal for seamless infinite scrolling. Integrates with buildQuilt for tile placement and tileFaucet for data fetching, logging pulls in debug mode.

Implementation

Future<void> buildQuilts(QuiltDirection direction,
    {bool allowPull = true}) async {
  bool isFuture = direction == QuiltDirection.future;
  DateTime? edge = isFuture ? futureEdge : pastEdge;
  int bufferLength = tileFaucet.buffer.length;
  Iterable<T> unseen = isFuture ? unseenFuture : unseenPast;
  int unseenCount = unseen.length;
  int threshold = style.carpetWidth * style.maxQuiltHeight;
  bool shouldPull = allowPull && (edge == null || unseenCount < threshold);
  int oldLength = bufferLength;
  if (shouldPull) {
    PrecisionStopwatch? p = kDebugMode ? PrecisionStopwatch.start() : null;
    int tl = tileFaucet.buffer.length;
    if (isFuture) {
      await tileFaucet.pullFuture(threshold);
    } else {
      await tileFaucet.pullPast(threshold);
    }
    int gl = tileFaucet.buffer.length - tl;

    if (kDebugMode && gl > 0) {
      info(
          "[CARPET] Pulled <$tl>+$gl ${isFuture ? "future" : "past"} posts in ${p!.getMilliseconds()}ms");
    }
  }

  bufferLength = tileFaucet.buffer.length;
  int added = bufferLength - oldLength;
  bool didPull = added > 0;
  int rebuildCount = 0;
  if (didPull && unseenCount == 0 && quiltBuffer.isNotEmpty) {
    rebuildCount =
        isFuture ? quiltPostCounts.removeAt(0) : quiltPostCounts.removeLast();
    isFuture ? quiltBuffer.removeAt(0) : quiltBuffer.removeLast();
    isFuture ? quiltHeights.removeAt(0) : quiltHeights.removeLast();
  }
  int buildStart =
      isFuture ? 0 : bufferLength - (added + unseenCount + rebuildCount);
  int buildMax = isFuture
      ? (added + unseenCount + rebuildCount)
      : (bufferLength - buildStart);
  if (buildMax <= 0) return;
  List<Widget> newQuilts = [];
  List<int> newCounts = [];
  int current = buildStart;
  int end = buildStart + buildMax;
  if (current < end) {
    QuiltResult res = buildQuilt(current);
    int used = res.used;
    if (used > 0) {
      newQuilts.add(res.widget);
      newCounts.add(used);
      current += used;
    }
  }
  if (isFuture && current < end) {
    int remaining = end - current;
    QuiltResult res = buildQuilt(current, maxPosts: remaining);
    if (res.used > 0) {
      newQuilts.add(res.widget);
      newCounts.add(res.used);
      current += res.used;
    }
  }
  if (isFuture) {
    quiltBuffer.insertAll(0, newQuilts);
    quiltHeights.insertAll(0, List.generate(newQuilts.length, (_) => 0));
    quiltPostCounts.insertAll(0, newCounts);
  } else {
    quiltBuffer.addAll(newQuilts);
    quiltHeights.addAll(List.generate(newQuilts.length, (_) => 0));
    quiltPostCounts.addAll(newCounts);
  }
  if (current > buildStart) {
    if (isFuture) {
      futureEdge = tileFaucet.getTime(tileFaucet.buffer[0]);
    } else {
      pastEdge = tileFaucet.getTime(tileFaucet.buffer[current - 1]);
    }
  }
}