@@ -2,6 +2,7 @@ import 'dart:math';
22
33import 'package:core/core.dart' ;
44import 'package:data_repository/data_repository.dart' ;
5+ import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_service.dart' ;
56import 'package:flutter_news_app_mobile_client_full_source_code/router/routes.dart' ;
67import 'package:uuid/uuid.dart' ;
78
@@ -56,16 +57,19 @@ class FeedDecoratorService {
5657 /// Creates a [FeedDecoratorService] .
5758 ///
5859 /// Requires [DataRepository] instances for [Topic] and [Source] to fetch
59- /// content for collection decorators.
60+ /// content for collection decorators, and an [AdService] to inject ads .
6061 FeedDecoratorService ({
6162 required DataRepository <Topic > topicsRepository,
6263 required DataRepository <Source > sourcesRepository,
63- }) : _topicsRepository = topicsRepository,
64- _sourcesRepository = sourcesRepository;
64+ required AdService adService,
65+ }) : _topicsRepository = topicsRepository,
66+ _sourcesRepository = sourcesRepository,
67+ _adService = adService;
6568
6669 final Uuid _uuid = const Uuid ();
6770 final DataRepository <Topic > _topicsRepository;
6871 final DataRepository <Source > _sourcesRepository;
72+ final AdService _adService;
6973
7074 // The zero-based index in the feed where the decorator will be inserted.
7175 // A value of 3 places it after the third headline, which is a common
@@ -142,7 +146,7 @@ class FeedDecoratorService {
142146
143147 // --- Step 2: Ad Injection ---
144148 // Inject ads into the list that may or may not already contain a decorator.
145- final finalFeed = _injectAds (
149+ final finalFeed = await _injectAds (
146150 feedItems: feedWithDecorators,
147151 user: user,
148152 adConfig: remoteConfig.adConfig,
@@ -161,12 +165,12 @@ class FeedDecoratorService {
161165 /// existing feed without re-evaluating or injecting new decorators.
162166 ///
163167 /// Returns a new list of [FeedItem] objects, interspersed with ads.
164- List <FeedItem > injectAds ({
168+ Future < List <FeedItem > > injectAds ({
165169 required List <FeedItem > feedItems,
166170 required User ? user,
167171 required AdConfig adConfig,
168172 int processedContentItemCount = 0 ,
169- }) {
173+ }) async {
170174 return _injectAds (
171175 feedItems: feedItems,
172176 user: user,
@@ -358,12 +362,12 @@ class FeedDecoratorService {
358362 /// crucial for maintaining correct ad placement across pagination.
359363 ///
360364 /// Returns a new list of [FeedItem] objects, interspersed with ads.
361- List <FeedItem > _injectAds ({
365+ Future < List <FeedItem > > _injectAds ({
362366 required List <FeedItem > feedItems,
363367 required User ? user,
364368 required AdConfig adConfig,
365369 int processedContentItemCount = 0 ,
366- }) {
370+ }) async {
367371 final userRole = user? .appRole ?? AppUserRole .guestUser;
368372
369373 // Determine ad frequency rules based on user role.
@@ -413,48 +417,13 @@ class FeedDecoratorService {
413417 // multiple of the ad frequency.
414418 if (currentContentItemCount >= adPlacementInterval &&
415419 (currentContentItemCount - adPlacementInterval) % adFrequency == 0 ) {
416- final adToInject = _getAdToInject ();
420+ // Request an ad from the AdService.
421+ final adToInject = await _adService.getAd ();
417422 if (adToInject != null ) {
418423 result.add (adToInject);
419424 }
420425 }
421426 }
422427 return result;
423428 }
424-
425- /// Constructs a placeholder [Ad] object.
426- ///
427- /// TODO(fulleni): fetch from an ad network SDK.
428- Ad ? _getAdToInject () {
429- // A small, predefined list of mock ads to simulate variety.
430- final mockAds = < Ad > [
431- Ad (
432- id: _uuid.v4 (),
433- imageUrl:
434- 'https://via.placeholder.com/300x100.png/0000FF/FFFFFF?Text=Tech+Gadget+Ad' ,
435- targetUrl: 'https://example.com/ad-tech' ,
436- adType: AdType .native ,
437- placement: AdPlacement .feedInlineNativeBanner,
438- ),
439- Ad (
440- id: _uuid.v4 (),
441- imageUrl:
442- 'https://via.placeholder.com/300x100.png/FF0000/FFFFFF?Text=Fashion+Sale+Ad' ,
443- targetUrl: 'https://example.com/ad-fashion' ,
444- adType: AdType .banner,
445- placement: AdPlacement .feedInlineStandardBanner,
446- ),
447- Ad (
448- id: _uuid.v4 (),
449- imageUrl:
450- 'https://via.placeholder.com/300x100.png/008000/FFFFFF?Text=Travel+Deals+Ad' ,
451- targetUrl: 'https://example.com/ad-travel' ,
452- adType: AdType .native ,
453- placement: AdPlacement .feedInlineNativeBanner,
454- ),
455- ];
456-
457- // Return a random ad from the list.
458- return mockAds[Random ().nextInt (mockAds.length)];
459- }
460429}
0 commit comments