applyReveal function

List<InlineSpan> applyReveal({
  1. required List<InlineSpan> spans,
  2. required int revealed,
  3. required GptMarkdownAnimation effect,
  4. required double progressFor(
    1. int index
    ),
  5. required Color defaultColor,
  6. int window = 64,
})

Rebuilds spans showing only the first revealed characters, with the ones still arriving styled by effect.

progressFor reports how far through its entrance the character at a given index is — RevealEngine.progressFor in practice, but any function will do.

Three regions come out of this, and only the middle one costs anything per frame:

  • Settled — characters whose entrance is over, emitted as whole spans and never split, so a long reply stays a handful of spans.
  • Arriving — at most window characters, grouped by word (or split per character for an effect that styles letters individually), each group carrying the effect's style delta.
  • Unrevealed — dropped. The document ends where the reveal is, so nothing below the reading position is laid out before it is meant to be seen, and nothing pops in there later.

Implementation

List<InlineSpan> applyReveal({
  required List<InlineSpan> spans,
  required int revealed,
  required GptMarkdownAnimation effect,
  required double Function(int index) progressFor,
  required Color defaultColor,
  int window = 64,
}) {
  final from = effect.animatesCharacters ? revealed - window : revealed;
  final out = <InlineSpan>[];
  _walk(
    spans: spans,
    out: out,
    cursor: _Cursor(),
    revealed: revealed,
    settledBelow: from < 0 ? 0 : from,
    effect: effect,
    progressFor: progressFor,
    inheritedColor: defaultColor,
  );
  return out;
}