fix(boosters): address final-review findings

- daily claim: record the claim before granting boosters, so a crash
  mid-claim forfeits at most one reward instead of allowing a re-claim
  (booster farming) on next launch.
- game screen: disarm the booster target synchronously before awaiting,
  so a rapid second board tap can't double-fire a use or stack a dialog.
- new players: seed one of each booster once (idempotent persisted flag),
  fulfilling the spec's starting inventory. Wired in main().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-18 19:36:24 +09:00
parent 412cc08167
commit fa2784519b
5 changed files with 44 additions and 4 deletions
+17
View File
@@ -52,6 +52,9 @@ class SaveRepository {
_reviewRequested = (json['flags']
as Map<String, dynamic>?)?['reviewRequested'] as bool? ??
false;
_boostersSeeded = (json['flags']
as Map<String, dynamic>?)?['boostersSeeded'] as bool? ??
false;
final boosters = json['boosters'] as Map<String, dynamic>? ?? {};
for (final t in BoosterType.values) {
_boosters[t] = boosters[t.name] as int? ?? 0;
@@ -76,6 +79,7 @@ class SaveRepository {
bool _soundEnabled = true;
bool _musicEnabled = true;
bool _reviewRequested = false;
bool _boostersSeeded = false;
final Map<BoosterType, int> _boosters = {
for (final t in BoosterType.values) t: 0,
};
@@ -138,6 +142,18 @@ class SaveRepository {
return true;
}
/// Grants one of each booster the first time it ever runs, so a new player
/// can try every booster. Idempotent for the app's lifetime via a persisted
/// flag — safe to call on every launch.
Future<void> seedInitialBoostersIfNeeded() async {
if (_boostersSeeded) return;
_boostersSeeded = true;
for (final t in BoosterType.values) {
_boosters[t] = (_boosters[t] ?? 0) + 1;
}
await _flush();
}
String? get dailyLastClaimedYmd => _dailyLastClaimedYmd;
int get dailyCalendarDay => _dailyCalendarDay;
@@ -221,6 +237,7 @@ class SaveRepository {
'soundEnabled': _soundEnabled,
'musicEnabled': _musicEnabled,
'reviewRequested': _reviewRequested,
'boostersSeeded': _boostersSeeded,
},
'endless': {'best': _endlessBest},
'boosters': {for (final t in BoosterType.values) t.name: _boosters[t]},