cec4c3e427
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>
39 lines
1.4 KiB
Dart
39 lines
1.4 KiB
Dart
// lib/services/review_prompt_policy.dart
|
|
|
|
/// Decides — as pure logic, with no plugin or storage dependency — whether the
|
|
/// app should ask the player for a store review right now.
|
|
///
|
|
/// Store review prompts only land when they catch the player at a genuine high
|
|
/// point, and both OSes hard-throttle how often the native sheet can appear.
|
|
/// So we ask at most once (the caller persists [alreadyRequested]), and only
|
|
/// after a clean, high-scoring win once the player is clearly invested.
|
|
class ReviewPromptPolicy {
|
|
const ReviewPromptPolicy({
|
|
this.minStagesWon = 5,
|
|
this.requiredStars = 3,
|
|
});
|
|
|
|
/// How many stages the player must have cleared before we'll ask, so the
|
|
/// prompt never interrupts a newcomer still deciding if they like the game.
|
|
final int minStagesWon;
|
|
|
|
/// The star count the triggering win must reach — a top-marks finish is the
|
|
/// emotional peak we want to ride.
|
|
final int requiredStars;
|
|
|
|
/// True when a just-finished stage result should trigger the review prompt.
|
|
/// [alreadyRequested] is the persisted one-time guard owned by the caller.
|
|
bool shouldRequest({
|
|
required bool alreadyRequested,
|
|
required bool won,
|
|
required int stars,
|
|
required int totalStagesWon,
|
|
}) {
|
|
if (alreadyRequested) return false;
|
|
if (!won) return false;
|
|
if (stars < requiredStars) return false;
|
|
if (totalStagesWon < minStagesWon) return false;
|
|
return true;
|
|
}
|
|
}
|