replayFrames function

  1. @riverpod
Future<List<Frame>> replayFrames(
  1. Ref ref, {
  2. required String gameId,
})

The full ordered frame history of a finished game.

Read from the replica when it holds all of it, which it always does for a game played on this device and does for an online game opened before (up to the replica's replay budget), so a replay opens offline. Otherwise fetched once and stored, since a finished game's history never changes.

A participant receives their own seat's projection; a non-participant replaying a public game receives the observer projection - the shape is identical either way, so the replay UI does not branch on it. The same range endpoint backs live gap recovery; replay is just the whole range rather than a missing slice of it.

Implementation

@riverpod
Future<List<Frame>> replayFrames(Ref ref, {required String gameId}) async {
  final replica = await ref.watch(accountReplicaProvider.future);
  final held = await replica?.replayFrames(gameId);
  if (held != null) return held;
  final frames = await ref.watch(gameRepositoryProvider).getFrames(gameId);
  await replica?.applyReplay(gameId, frames);
  return frames;
}