From 539afd1dad688b9d9b01638f523f702e62de1fb8 Mon Sep 17 00:00:00 2001 From: airkjw Date: Sat, 13 Jun 2026 13:57:30 +0900 Subject: [PATCH] feat(ads): ref-constructed ad/consent/iap providers, single ownership source --- lib/state/providers.dart | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/state/providers.dart b/lib/state/providers.dart index 49cd009..02e35d2 100644 --- a/lib/state/providers.dart +++ b/lib/state/providers.dart @@ -4,8 +4,11 @@ import '../data/content_repository.dart'; import '../data/save_repository.dart'; import '../data/streak.dart'; import '../game/models/season.dart'; +import '../services/ad_service.dart'; import '../services/analytics_service.dart'; import '../services/audio_service.dart'; +import '../services/consent_service.dart'; +import '../services/iap_service.dart'; import 'ads_notifier.dart'; import 'endless_best_notifier.dart'; import 'game_session_notifier.dart'; @@ -75,6 +78,30 @@ final endlessBestProvider = NotifierProvider( final adsRemovedProvider = NotifierProvider(AdsRemovedNotifier.new); +/// Reads ownership live from [adsRemovedProvider]; a mid-session purchase +/// takes effect on the next ad decision without re-wiring. +final adServiceProvider = Provider((ref) { + final service = AdService(adsRemoved: () => ref.read(adsRemovedProvider)); + ref.onDispose(service.dispose); + return service; +}); + +final consentServiceProvider = Provider( + (ref) => ConsentService(ref.read(adServiceProvider)), +); + +/// A verified remove_ads purchase/restore grants the entitlement through the +/// notifier (persists + flips state), which AdService and the banner observe. +final iapServiceProvider = Provider((ref) { + final service = IapService( + onEntitlementGranted: () => + ref.read(adsRemovedProvider.notifier).grant(), + ); + ref.onDispose(service.dispose); + service.initialize(); + return service; +}); + final analyticsProvider = Provider( (ref) => AnalyticsService(DebugAnalyticsBackend()), );