feat(review): request a store review after a 3-star win, once
Adds an in-app review prompt gated by ReviewPromptPolicy: only after a 3-star stage win, once the player has cleared >=5 stages, at most once ever (persisted reviewRequested flag). ReviewService swallows all failures and only burns the one-shot when the store actually shows the sheet, so an unavailable store retries on a later win. StoreReviewer wraps in_app_review behind a Reviewer seam so unit tests skip platform channels. 13 new tests; full suite 194 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,8 @@ import '../services/audio_service.dart';
|
||||
import '../services/consent_service.dart';
|
||||
import '../services/iap_service.dart';
|
||||
import '../services/music_service.dart';
|
||||
import '../services/review_service.dart';
|
||||
import '../services/store_reviewer.dart';
|
||||
import 'ads_notifier.dart';
|
||||
import 'endless_best_notifier.dart';
|
||||
import 'music_notifier.dart';
|
||||
@@ -126,6 +128,15 @@ final analyticsProvider = Provider<AnalyticsService>(
|
||||
(ref) => AnalyticsService(DebugAnalyticsBackend()),
|
||||
);
|
||||
|
||||
/// Asks for a store review at most once, after a genuine high point. Reads the
|
||||
/// one-time flag and cleared-stage count live from [saveRepositoryProvider].
|
||||
final reviewServiceProvider = Provider<ReviewService>(
|
||||
(ref) => ReviewService(
|
||||
save: ref.read(saveRepositoryProvider),
|
||||
reviewer: StoreReviewer(),
|
||||
),
|
||||
);
|
||||
|
||||
/// The visual theme of whatever season is in play; fallback outside seasons
|
||||
/// (home, endless). Pure model — UI converts via ThemeColors.
|
||||
final activeThemeProvider = Provider<SeasonTheme>((ref) {
|
||||
|
||||
Reference in New Issue
Block a user