@@ -27,22 +27,22 @@ part 'headlines_feed_state.dart';
2727/// - Fetching, filtering, and displaying headlines from a `DataRepository` .
2828/// - Injecting dynamic content placeholders for ads and non-ad decorators
2929/// using the `AdService` and the new `FeedDecoratorService` .
30- /// - Implementing a robust, session-based in-memory caching strategy via
31- /// [FeedCacheService] to provide a highly responsive user experience.
30+ /// - Implementing a session-based in-memory caching strategy via
31+ /// [FeedCacheService] to provide a responsive user experience.
3232///
3333/// ### Feed Decoration and Ad Injection:
34- /// On major feed loads (initial load, refresh, or new filter), this BLoC now
34+ /// On major feed loads (initial load, refresh, or new filter), this BLoC
3535/// uses a two-step process:
3636/// 1. The new `FeedDecoratorService` injects a single `DecoratorPlaceholder` .
37- /// 2. The `AdService` injects multiple `AdPlaceholder` items.
37+ /// 2. The `AdService` then injects multiple `AdPlaceholder` items.
3838/// The UI is then responsible for rendering loader widgets for these placeholders.
3939///
4040/// ### Caching and Data Flow Scenarios:
4141///
4242/// 1. **Cache Miss (Initial Load / New Filter):** When a filter is applied for
4343/// the first time, the BLoC fetches data from the [DataRepository],
4444/// decorates it using [FeedDecoratorService], and stores the result in the
45- /// cache before emitting the `success` state.
45+ /// cache before emitting the `success` state with the decorated feed .
4646///
4747/// 2. **Cache Hit (Switching Filters):** When switching to a previously viewed
4848/// filter, the BLoC instantly emits the cached data. If the cached data is
@@ -53,7 +53,7 @@ part 'headlines_feed_state.dart';
5353/// feed, the BLoC fetches the next page of headlines and **appends** them
5454/// to the existing cached list, ensuring a seamless infinite scroll.
5555///
56- /// 4. **Pull-to-Refresh (Prepending) :** On a pull-to-refresh action, the BLoC
56+ /// 4. **Pull-to-Refresh:** On a pull-to-refresh action, the BLoC
5757/// fetches the latest headlines and intelligently **prepends** only the new
5858/// items to the top of the cached list, avoiding full reloads.
5959/// {@endtemplate}
@@ -404,30 +404,28 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
404404 }
405405 }
406406
407- // Use user content preferences from AppBloc for followed items.
408407 _logger.info (
409408 'Refresh: Performing full decoration for filter "$filterKey ".' ,
410409 );
411- final userPreferences = _appBloc.state.userContentPreferences;
412410 final settings = _appBloc.state.settings;
413411
414412 // Step 1: Inject the non-ad decorator placeholder.
415- final feedWithDecorator = _feedDecoratorService.decorateFeed (
413+ final feedWithDecorator = await _feedDecoratorService.decorateFeed (
416414 feedItems: headlineResponse.items,
417415 remoteConfig: appConfig,
418416 );
419417
420418 // Step 2: Inject ad placeholders into the resulting list.
421419 final fullyDecoratedFeed = await _adService.injectAdPlaceholders (
422- feedItems: feedWithDecorator,
420+ feedItems: feedWithDecorator.decoratedItems ,
423421 user: currentUser,
424422 adConfig: appConfig.adConfig,
425423 imageStyle: settings! .feedPreferences.headlineImageStyle,
426424 adThemeStyle: event.adThemeStyle,
427425 );
428426
429427 final newCachedFeed = CachedFeed (
430- feedItems: fullyDecoratedFeed,
428+ feedItems: fullyDecoratedFeed.decoratedItems ,
431429 hasMore: headlineResponse.hasMore,
432430 cursor: headlineResponse.cursor,
433431 lastRefreshedAt: DateTime .now (),
@@ -534,26 +532,25 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
534532 sort: [const SortOption ('updatedAt' , SortOrder .desc)],
535533 );
536534
537- final userPreferences = _appBloc.state.userContentPreferences;
538535 final settings = _appBloc.state.settings;
539536
540537 // Step 1: Inject the non-ad decorator placeholder.
541- final feedWithDecorator = _feedDecoratorService.decorateFeed (
538+ final feedWithDecorator = await _feedDecoratorService.decorateFeed (
542539 feedItems: headlineResponse.items,
543540 remoteConfig: appConfig,
544541 );
545542
546543 // Step 2: Inject ad placeholders into the resulting list.
547544 final fullyDecoratedFeed = await _adService.injectAdPlaceholders (
548- feedItems: feedWithDecorator,
545+ feedItems: feedWithDecorator.decoratedItems ,
549546 user: currentUser,
550547 adConfig: appConfig.adConfig,
551548 imageStyle: settings! .feedPreferences.headlineImageStyle,
552549 adThemeStyle: event.adThemeStyle,
553550 );
554551
555552 final newCachedFeed = CachedFeed (
556- feedItems: fullyDecoratedFeed,
553+ feedItems: fullyDecoratedFeed.decoratedItems ,
557554 hasMore: headlineResponse.hasMore,
558555 cursor: headlineResponse.cursor,
559556 lastRefreshedAt: DateTime .now (),
@@ -631,26 +628,25 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
631628 sort: [const SortOption ('updatedAt' , SortOrder .desc)],
632629 );
633630
634- final userPreferences = _appBloc.state.userContentPreferences;
635631 final settings = _appBloc.state.settings;
636632
637633 // Step 1: Inject the non-ad decorator placeholder.
638- final feedWithDecorator = _feedDecoratorService.decorateFeed (
634+ final feedWithDecorator = await _feedDecoratorService.decorateFeed (
639635 feedItems: headlineResponse.items,
640636 remoteConfig: appConfig,
641637 );
642638
643639 // Step 2: Inject ad placeholders into the resulting list.
644640 final fullyDecoratedFeed = await _adService.injectAdPlaceholders (
645- feedItems: feedWithDecorator,
641+ feedItems: feedWithDecorator.decoratedItems ,
646642 user: currentUser,
647643 adConfig: appConfig.adConfig,
648644 imageStyle: settings! .feedPreferences.headlineImageStyle,
649645 adThemeStyle: event.adThemeStyle,
650646 );
651647
652648 final newCachedFeed = CachedFeed (
653- feedItems: fullyDecoratedFeed,
649+ feedItems: fullyDecoratedFeed.decoratedItems ,
654650 hasMore: headlineResponse.hasMore,
655651 cursor: headlineResponse.cursor,
656652 lastRefreshedAt: DateTime .now (),
0 commit comments