@@ -7,13 +7,12 @@ import 'package:data_repository/data_repository.dart';
77import 'package:equatable/equatable.dart' ;
88import 'package:flex_color_scheme/flex_color_scheme.dart' ;
99import 'package:flutter/material.dart' ;
10- import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_service.dart' ; // Import AdService
11- import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/ad_theme_style.dart' ; // Import AdThemeStyle
10+ import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_service.dart' ;
1211import 'package:flutter_news_app_mobile_client_full_source_code/app/config/config.dart'
1312 as local_config;
1413import 'package:flutter_news_app_mobile_client_full_source_code/app/services/demo_data_initializer_service.dart' ;
1514import 'package:flutter_news_app_mobile_client_full_source_code/app/services/demo_data_migration_service.dart' ;
16- import 'package:logging/logging.dart' ; // Import Logger
15+ import 'package:logging/logging.dart' ;
1716
1817part 'app_event.dart' ;
1918part 'app_state.dart' ;
@@ -25,7 +24,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
2524 required DataRepository <RemoteConfig > appConfigRepository,
2625 required DataRepository <User > userRepository,
2726 required local_config.AppEnvironment environment,
28- required AdService adService, // Inject AdService
27+ required AdService adService,
2928 this .demoDataMigrationService,
3029 this .demoDataInitializerService,
3130 this .initialUser,
@@ -34,16 +33,10 @@ class AppBloc extends Bloc<AppEvent, AppState> {
3433 _appConfigRepository = appConfigRepository,
3534 _userRepository = userRepository,
3635 _environment = environment,
37- _adService = adService, // Initialize AdService
38- _logger = Logger ('AppBloc' ), // Initialize Logger
39- _showInterstitialAdController = StreamController <void >.broadcast (), // Initialize the stream controller
36+ _adService = adService,
37+ _logger = Logger ('AppBloc' ),
4038 super (
4139 AppState (
42- // Initialize with default settings and preferences.
43- // This is crucial for immediate UI rendering and provides a safe
44- // fallback before user-specific settings are loaded.
45- // The `AppSettingsRefreshed` event will later replace these
46- // with actual user data.
4740 settings: UserAppSettings (
4841 id: 'default' ,
4942 displaySettings: const DisplaySettings (
@@ -69,15 +62,12 @@ class AppBloc extends Bloc<AppEvent, AppState> {
6962 selectedBottomNavigationIndex: 0 ,
7063 remoteConfig: null ,
7164 environment: environment,
72- // Initialize status and user based on initialUser
7365 status: initialUser != null
7466 ? (initialUser.appRole == AppUserRole .standardUser
7567 ? AppStatus .authenticated
7668 : AppStatus .anonymous)
7769 : AppStatus .unauthenticated,
7870 user: initialUser,
79- pageTransitionCount: 0 , // Initialize page transition count
80- showInterstitialAdStream: _showInterstitialAdController.stream, // Provide the stream
8171 ),
8272 ) {
8373 on < AppUserChanged > (_onAppUserChanged);
@@ -90,9 +80,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
9080 on < AppFontFamilyChanged > (_onFontFamilyChanged);
9181 on < AppTextScaleFactorChanged > (_onAppTextScaleFactorChanged);
9282 on < AppFontWeightChanged > (_onAppFontWeightChanged);
93- on < AppPageTransitioned > (_onAppPageTransitioned); // New event handler
9483
95- // Listen directly to the auth state changes stream
9684 _userSubscription = _authenticationRepository.authStateChanges.listen (
9785 (User ? user) => add (AppUserChanged (user)),
9886 );
@@ -103,9 +91,8 @@ class AppBloc extends Bloc<AppEvent, AppState> {
10391 final DataRepository <RemoteConfig > _appConfigRepository;
10492 final DataRepository <User > _userRepository;
10593 final local_config.AppEnvironment _environment;
106- final AdService _adService; // AdService instance
107- final Logger _logger; // Logger instance
108- final StreamController <void > _showInterstitialAdController; // Stream controller for interstitial ads
94+ final AdService _adService;
95+ final Logger _logger;
10996 final DemoDataMigrationService ? demoDataMigrationService;
11097 final DemoDataInitializerService ? demoDataInitializerService;
11198 final User ? initialUser;
@@ -204,7 +191,6 @@ class AppBloc extends Bloc<AppEvent, AppState> {
204191 remoteConfig: null ,
205192 clearAppConfig: true ,
206193 status: AppStatus .unauthenticated,
207- pageTransitionCount: 0 , // Reset page transition count on logout
208194 ),
209195 );
210196 }
@@ -285,8 +271,8 @@ class AppBloc extends Bloc<AppEvent, AppState> {
285271 baseTheme: event.themeMode == ThemeMode .light
286272 ? AppBaseTheme .light
287273 : (event.themeMode == ThemeMode .dark
288- ? AppBaseTheme .dark
289- : AppBaseTheme .system),
274+ ? AppBaseTheme .dark
275+ : AppBaseTheme .system),
290276 ),
291277 );
292278 emit (state.copyWith (settings: updatedSettings, themeMode: event.themeMode));
@@ -304,8 +290,8 @@ class AppBloc extends Bloc<AppEvent, AppState> {
304290 accentTheme: event.flexScheme == FlexScheme .blue
305291 ? AppAccentTheme .defaultBlue
306292 : (event.flexScheme == FlexScheme .red
307- ? AppAccentTheme .newsRed
308- : AppAccentTheme .graphiteGray),
293+ ? AppAccentTheme .newsRed
294+ : AppAccentTheme .graphiteGray),
309295 ),
310296 );
311297 emit (
@@ -336,7 +322,6 @@ class AppBloc extends Bloc<AppEvent, AppState> {
336322 AppTextScaleFactorChanged event,
337323 Emitter <AppState > emit,
338324 ) {
339- // Update settings and emit new state
340325 final updatedSettings = state.settings.copyWith (
341326 displaySettings: state.settings.displaySettings.copyWith (
342327 textScaleFactor: event.appTextScaleFactor,
@@ -356,76 +341,14 @@ class AppBloc extends Bloc<AppEvent, AppState> {
356341 AppFontWeightChanged event,
357342 Emitter <AppState > emit,
358343 ) {
359- // Update settings and emit new state
360344 final updatedSettings = state.settings.copyWith (
361345 displaySettings: state.settings.displaySettings.copyWith (
362346 fontWeight: event.fontWeight,
363347 ),
364348 );
365349 emit (state.copyWith (settings: updatedSettings));
366- // Optionally save settings to repository here
367- // unawaited(_userAppSettingsRepository.update(id: updatedSettings.id, item: updatedSettings));
368350 }
369351
370- /// Handles page transition events to track interstitial ad frequency.
371- Future <void > _onAppPageTransitioned (
372- AppPageTransitioned event,
373- Emitter <AppState > emit,
374- ) async {
375- // Increment the page transition count.
376- final newCount = state.pageTransitionCount + 1 ;
377- emit (state.copyWith (pageTransitionCount: newCount));
378-
379- _logger.info ('Page transitioned. Current count: $newCount ' );
380-
381- final remoteConfig = state.remoteConfig;
382- final user = state.user;
383-
384- // Only proceed if remote config is available, ads are globally enabled,
385- // and interstitial ads are enabled in the config.
386- if (remoteConfig == null ||
387- ! remoteConfig.adConfig.enabled ||
388- ! remoteConfig.adConfig.interstitialAdConfiguration.enabled) {
389- _logger.info ('Interstitial ads are not enabled or config not ready.' );
390- return ;
391- }
392-
393- final interstitialConfig = remoteConfig.adConfig.interstitialAdConfiguration;
394- final frequencyConfig = interstitialConfig.feedInterstitialAdFrequencyConfig;
395-
396- // Determine the required transitions based on user role.
397- final int requiredTransitions;
398- switch (user? .appRole) {
399- case AppUserRole .guestUser:
400- requiredTransitions =
401- frequencyConfig.guestTransitionsBeforeShowingInterstitialAds;
402- case AppUserRole .standardUser:
403- requiredTransitions =
404- frequencyConfig.standardUserTransitionsBeforeShowingInterstitialAds;
405- case AppUserRole .premiumUser:
406- requiredTransitions =
407- frequencyConfig.premiumUserTransitionsBeforeShowingInterstitialAds;
408- case null :
409- // If user is null, default to guest user settings.
410- requiredTransitions =
411- frequencyConfig.guestTransitionsBeforeShowingInterstitialAds;
412- }
413-
414- _logger.info (
415- 'Required transitions for user role ${user ?.appRole }: $requiredTransitions ' ,
416- );
417-
418- // Check if it's time to show an interstitial ad.
419- if (requiredTransitions > 0 && newCount >= requiredTransitions) {
420- _logger.info ('Interstitial ad due. Signaling AdNavigatorObserver.' );
421- // Signal the AdNavigatorObserver to show the ad.
422- _showInterstitialAdController.add (null ); // Add a signal to the stream
423- emit (state.copyWith (pageTransitionCount: 0 )); // Reset count after signaling
424- }
425- }
426-
427- // --- Settings Mapping Helpers ---
428-
429352 ThemeMode _mapAppBaseTheme (AppBaseTheme mode) {
430353 switch (mode) {
431354 case AppBaseTheme .light:
@@ -451,9 +374,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
451374 String ? _mapFontFamily (String fontFamilyString) {
452375 // If the input is 'SystemDefault', return null so FlexColorScheme uses its default.
453376 if (fontFamilyString == 'SystemDefault' ) {
454- _logger.info (
455- '_mapFontFamily: Input is SystemDefault, returning null.' ,
456- );
377+ _logger.info ('_mapFontFamily: Input is SystemDefault, returning null.' );
457378 return null ;
458379 }
459380 // Otherwise, return the font family string directly.
@@ -473,7 +394,6 @@ class AppBloc extends Bloc<AppEvent, AppState> {
473394 @override
474395 Future <void > close () {
475396 _userSubscription.cancel ();
476- _showInterstitialAdController.close (); // Close the stream controller
477397 return super .close ();
478398 }
479399
@@ -589,7 +509,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
589509 // Get the current status for the decorator, or create a default if not present.
590510 final currentStatus =
591511 originalUser.feedDecoratorStatus[event.feedDecoratorType] ??
592- const UserFeedDecoratorStatus (isCompleted: false );
512+ const UserFeedDecoratorStatus (isCompleted: false );
593513
594514 // Create an updated status.
595515 // It always updates the `lastShownAt` timestamp.
@@ -603,12 +523,12 @@ class AppBloc extends Bloc<AppEvent, AppState> {
603523 // Create a new map with the updated status for the specific decorator type.
604524 final newFeedDecoratorStatus =
605525 Map <FeedDecoratorType , UserFeedDecoratorStatus >.from (
606- originalUser.feedDecoratorStatus,
607- )..update (
608- event.feedDecoratorType,
609- (_) => updatedDecoratorStatus,
610- ifAbsent: () => updatedDecoratorStatus,
611- );
526+ originalUser.feedDecoratorStatus,
527+ )..update (
528+ event.feedDecoratorType,
529+ (_) => updatedDecoratorStatus,
530+ ifAbsent: () => updatedDecoratorStatus,
531+ );
612532
613533 // Update the user with the new feedDecoratorStatus map.
614534 final updatedUser = originalUser.copyWith (
0 commit comments