074a21ea2b
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
53 lines
1.5 KiB
Dart
53 lines
1.5 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../game/models/season.dart';
|
|
import '../game/models/stage.dart';
|
|
import 'providers.dart';
|
|
|
|
class SeasonFlow {
|
|
const SeasonFlow({required this.pack, required this.index});
|
|
|
|
final SeasonPack pack;
|
|
final int index;
|
|
|
|
StageConfig get stage => pack.stages[index];
|
|
bool get hasNext => index + 1 < pack.stages.length;
|
|
}
|
|
|
|
/// Orchestrates which season stage is being played: starting stages,
|
|
/// recording wins, advancing to the next stage.
|
|
class SeasonFlowNotifier extends Notifier<SeasonFlow?> {
|
|
@override
|
|
SeasonFlow? build() => null;
|
|
|
|
void startSeasonStage(SeasonPack pack, int index) {
|
|
state = SeasonFlow(pack: pack, index: index);
|
|
ref.read(gameSessionProvider.notifier).startStage(pack.stages[index]);
|
|
ref.read(analyticsProvider).stageStart(
|
|
seasonId: pack.seasonId,
|
|
stageId: pack.stages[index].id,
|
|
);
|
|
}
|
|
|
|
Future<void> recordWin({required int stars, required int score}) async {
|
|
final flow = state;
|
|
if (flow == null) return;
|
|
await ref.read(progressProvider.notifier).record(
|
|
seasonId: flow.pack.seasonId,
|
|
stageId: flow.stage.id,
|
|
stars: stars,
|
|
score: score,
|
|
);
|
|
}
|
|
|
|
void nextStage() {
|
|
final flow = state;
|
|
if (flow == null || !flow.hasNext) return;
|
|
startSeasonStage(flow.pack, flow.index + 1);
|
|
}
|
|
|
|
/// Leaving season play (e.g. starting a Classic run) clears the flow so
|
|
/// stale stage context can't leak into other modes.
|
|
void clear() => state = null;
|
|
}
|