11import 'package:core/core.dart' ;
22import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_provider.dart' ;
3- import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/ad_feed_item.dart' ;
3+ import 'package:core/core.dart' ;
4+ import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_provider.dart' ;
45import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/ad_theme_style.dart' ;
5- // Import BannerAd
66import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/inline_ad.dart' ; // Import InlineAd
77import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/interstitial_ad.dart' ;
8- // Import NativeAd
98import 'package:logging/logging.dart' ;
109import 'package:uuid/uuid.dart' ;
1110
@@ -44,105 +43,27 @@ class AdService {
4443 _logger.info ('AdService initialized.' );
4544 }
4645
47- /// Retrieves a loaded inline ad (native or banner) wrapped as an [AdFeedItem] .
46+ /// Retrieves a loaded inline ad (native or banner) for display in a feed .
4847 ///
4948 /// This method delegates the ad loading to the appropriate [AdProvider]
5049 /// based on the [adConfig] 's `primaryAdPlatform` and the requested [adType] .
51- /// If an ad is successfully loaded, it's wrapped in an [AdFeedItem]
52- /// with a unique ID for display in content feeds.
5350 ///
54- /// Returns an [AdFeedItem ] if an inline ad is available, otherwise `null` .
51+ /// Returns an [InlineAd ] if an inline ad is available, otherwise `null` .
5552 ///
5653 /// - [adConfig] : The remote configuration for ad display rules.
5754 /// - [adType] : The specific type of inline ad to load ([AdType.native] or [AdType.banner] ).
5855 /// - [adThemeStyle] : UI-agnostic theme properties for ad styling.
59- Future <AdFeedItem ?> getInlineAd ({
56+ Future <InlineAd ?> getFeedAd ({
6057 required AdConfig adConfig,
6158 required AdType adType,
6259 required AdThemeStyle adThemeStyle,
6360 }) async {
64- if (! adConfig.enabled) {
65- _logger.info ('Ads are globally disabled in RemoteConfig.' );
66- return null ;
67- }
68-
69- // Ensure the requested adType is valid for inline ads.
70- if (adType != AdType .native && adType != AdType .banner) {
71- _logger.warning (
72- 'getInlineAd called with unsupported AdType: $adType . '
73- 'Expected AdType.native or AdType.banner.' ,
74- );
75- return null ;
76- }
77-
78- final primaryAdPlatform = adConfig.primaryAdPlatform;
79- final adProvider = _adProviders[primaryAdPlatform];
80-
81- if (adProvider == null ) {
82- _logger.warning ('No AdProvider found for platform: $primaryAdPlatform ' );
83- return null ;
84- }
85-
86- final platformAdIdentifiers =
87- adConfig.platformAdIdentifiers[primaryAdPlatform];
88- if (platformAdIdentifiers == null ) {
89- _logger.warning (
90- 'No AdPlatformIdentifiers found for platform: $primaryAdPlatform ' ,
91- );
92- return null ;
93- }
94-
95- final adId = switch (adType) {
96- AdType .native => platformAdIdentifiers.feedNativeAdId,
97- AdType .banner => platformAdIdentifiers.feedBannerAdId,
98- _ => null , // Handled by the initial adType check
99- };
100-
101- if (adId == null || adId.isEmpty) {
102- _logger.warning (
103- 'No ad ID configured for platform $primaryAdPlatform and ad type $adType ' ,
104- );
105- return null ;
106- }
107-
108- _logger.info (
109- 'Requesting $adType ad from $primaryAdPlatform AdProvider with ID: $adId ' ,
61+ return _loadInlineAd (
62+ adConfig: adConfig,
63+ adType: adType,
64+ adThemeStyle: adThemeStyle,
65+ feedAd: true ,
11066 );
111- try {
112- InlineAd ? loadedAd; // Use the new InlineAd abstract type
113- switch (adType) {
114- case AdType .native :
115- loadedAd = await adProvider.loadNativeAd (
116- adPlatformIdentifiers: platformAdIdentifiers,
117- adId: adId,
118- adThemeStyle: adThemeStyle,
119- );
120- case AdType .banner:
121- loadedAd = await adProvider.loadBannerAd (
122- adPlatformIdentifiers: platformAdIdentifiers,
123- adId: adId,
124- adThemeStyle: adThemeStyle,
125- );
126- case AdType .interstitial:
127- case AdType .video:
128- // These types are not handled by getInlineAd.
129- _logger.warning (
130- 'Attempted to load $adType ad using getInlineAd. This is not supported.' ,
131- );
132- return null ;
133- }
134-
135- if (loadedAd != null ) {
136- _logger.info ('$adType ad successfully loaded and wrapped.' );
137- return AdFeedItem (id: _uuid.v4 (), inlineAd: loadedAd); // Use inlineAd
138- } else {
139- _logger.info ('No $adType ad loaded by AdProvider.' );
140- return null ;
141- }
142- } catch (e) {
143- _logger.severe ('Error getting $adType ad from AdProvider: $e ' );
144- return null ;
145- }
14667 }
14768
14869 /// Retrieves a loaded full-screen interstitial ad.
@@ -235,10 +156,47 @@ class AdService {
235156 required AdConfig adConfig,
236157 required AdThemeStyle adThemeStyle,
237158 }) async {
238- // Check if ads are globally enabled and specifically for articles.
239- if (! adConfig.enabled || ! adConfig.articleAdConfiguration.enabled) {
159+ return _loadInlineAd (
160+ adConfig: adConfig,
161+ adType: adConfig.articleAdConfiguration.defaultInArticleAdType,
162+ adThemeStyle: adThemeStyle,
163+ feedAd: false ,
164+ );
165+ }
166+
167+ /// Private helper method to consolidate logic for loading inline ads (native/banner).
168+ ///
169+ /// This method handles the common steps of checking ad enablement, selecting
170+ /// the ad provider, retrieving platform-specific ad identifiers, and calling
171+ /// the appropriate `loadNativeAd` or `loadBannerAd` method on the provider.
172+ ///
173+ /// - [adConfig] : The remote configuration for ad display rules.
174+ /// - [adType] : The specific type of inline ad to load ([AdType.native] or [AdType.banner] ).
175+ /// - [adThemeStyle] : UI-agnostic theme properties for ad styling.
176+ /// - [feedAd] : A boolean indicating if this is for a feed ad (true) or in-article ad (false).
177+ ///
178+ /// Returns an [InlineAd] if an ad is successfully loaded, otherwise `null` .
179+ Future <InlineAd ?> _loadInlineAd ({
180+ required AdConfig adConfig,
181+ required AdType adType,
182+ required AdThemeStyle adThemeStyle,
183+ required bool feedAd,
184+ }) async {
185+ // Check if ads are globally enabled and specifically for the context (feed or article).
186+ if (! adConfig.enabled ||
187+ (feedAd && ! adConfig.feedAdConfiguration.enabled) ||
188+ (! feedAd && ! adConfig.articleAdConfiguration.enabled)) {
240189 _logger.info (
241- 'In-article ads are disabled in RemoteConfig, either globally or for articles.' ,
190+ 'Inline ads are disabled in RemoteConfig, either globally or for this context.' ,
191+ );
192+ return null ;
193+ }
194+
195+ // Ensure the requested adType is valid for inline ads.
196+ if (adType != AdType .native && adType != AdType .banner) {
197+ _logger.warning (
198+ '_loadInlineAd called with unsupported AdType: $adType . '
199+ 'Expected AdType.native or AdType.banner.' ,
242200 );
243201 return null ;
244202 }
@@ -260,24 +218,25 @@ class AdService {
260218 return null ;
261219 }
262220
263- // Determine the ad type and ID from the article-specific configuration.
264- final articleAdConfig = adConfig.articleAdConfiguration;
265- final adType = articleAdConfig.defaultInArticleAdType;
266- final adId = switch (adType) {
267- AdType .native => platformAdIdentifiers.inArticleNativeAdId,
268- AdType .banner => platformAdIdentifiers.inArticleBannerAdId,
269- _ => null , // Should not happen due to AdConfig assertion
270- };
221+ final adId = feedAd
222+ ? (adType == AdType .native
223+ ? platformAdIdentifiers.feedNativeAdId
224+ : platformAdIdentifiers.feedBannerAdId)
225+ : (adType == AdType .native
226+ ? platformAdIdentifiers.inArticleNativeAdId
227+ : platformAdIdentifiers.inArticleBannerAdId);
271228
272229 if (adId == null || adId.isEmpty) {
273230 _logger.warning (
274- 'No in-article ad ID configured for platform $primaryAdPlatform and ad type $adType ' ,
231+ 'No ad ID configured for platform $primaryAdPlatform and ad type $adType '
232+ 'for ${feedAd ? 'feed' : 'in-article' } placement.' ,
275233 );
276234 return null ;
277235 }
278236
279237 _logger.info (
280- 'Requesting in-article $adType ad from $primaryAdPlatform AdProvider with ID: $adId ' ,
238+ 'Requesting $adType ad from $primaryAdPlatform AdProvider with ID: $adId '
239+ 'for ${feedAd ? 'feed' : 'in-article' } placement.' ,
281240 );
282241 try {
283242 InlineAd ? loadedAd;
@@ -297,20 +256,20 @@ class AdService {
297256 case AdType .interstitial:
298257 case AdType .video:
299258 _logger.warning (
300- 'Attempted to load $adType ad using getInArticleAd . This is not supported.' ,
259+ 'Attempted to load $adType ad using _loadInlineAd . This is not supported.' ,
301260 );
302261 return null ;
303262 }
304263
305264 if (loadedAd != null ) {
306- _logger.info ('In-article $adType ad successfully loaded.' );
265+ _logger.info ('$adType ad successfully loaded.' );
307266 return loadedAd;
308267 } else {
309- _logger.info ('No in-article $adType ad loaded by AdProvider.' );
268+ _logger.info ('No $adType ad loaded by AdProvider.' );
310269 return null ;
311270 }
312271 } catch (e) {
313- _logger.severe ('Error getting in-article $adType ad from AdProvider: $e ' );
272+ _logger.severe ('Error getting $adType ad from AdProvider: $e ' );
314273 return null ;
315274 }
316275 }
0 commit comments