@@ -2,7 +2,8 @@ import 'dart:async';
22
33import 'package:core/core.dart' ;
44import 'package:flutter/material.dart' ;
5- import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_cache_service.dart' ;
5+ import 'package:flutter_bloc/flutter_bloc.dart' ;
6+ import 'package:flutter_news_app_mobile_client_full_source_code/ads/inline_ad_cache_service.dart' ;
67import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_service.dart' ;
78import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/ad_placeholder.dart' ;
89import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/ad_theme_style.dart' ;
@@ -13,11 +14,13 @@ import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/admo
1314import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/local_banner_ad_widget.dart' ;
1415import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/local_native_ad_widget.dart' ;
1516import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/placeholder_ad_widget.dart' ;
17+ import 'package:flutter_news_app_mobile_client_full_source_code/app/bloc/app_bloc.dart' ;
1618import 'package:logging/logging.dart' ;
1719import 'package:ui_kit/ui_kit.dart' ;
1820
19- /// {@template ad_loader_widget}
20- /// A self-contained widget responsible for loading and displaying an inline ad.
21+ /// {@template feed_ad_loader_widget}
22+ /// A self-contained widget responsible for loading and displaying an inline ad
23+ /// specifically within content feeds (e.g., main feed, search results).
2124///
2225/// This widget handles the entire lifecycle of a single ad slot in the feed.
2326/// It attempts to retrieve a cached [InlineAd] first. If no ad is cached,
@@ -29,9 +32,9 @@ import 'package:ui_kit/ui_kit.dart';
2932/// scrolling performance in lists. It specifically handles inline ads (native
3033/// and banner), while interstitial ads are managed separately.
3134/// {@endtemplate}
32- class AdLoaderWidget extends StatefulWidget {
33- /// {@macro ad_loader_widget }
34- const AdLoaderWidget ({
35+ class FeedAdLoaderWidget extends StatefulWidget {
36+ /// {@macro feed_ad_loader_widget }
37+ const FeedAdLoaderWidget ({
3538 required this .adPlaceholder,
3639 required this .adService,
3740 required this .adThemeStyle,
@@ -52,15 +55,15 @@ class AdLoaderWidget extends StatefulWidget {
5255 final AdConfig adConfig;
5356
5457 @override
55- State <AdLoaderWidget > createState () => _AdLoaderWidgetState ();
58+ State <FeedAdLoaderWidget > createState () => _FeedAdLoaderWidgetState ();
5659}
5760
58- class _AdLoaderWidgetState extends State <AdLoaderWidget > {
61+ class _FeedAdLoaderWidgetState extends State <FeedAdLoaderWidget > {
5962 InlineAd ? _loadedAd;
6063 bool _isLoading = true ;
6164 bool _hasError = false ;
62- final Logger _logger = Logger ('AdLoaderWidget ' );
63- final AdCacheService _adCacheService = AdCacheService ();
65+ final Logger _logger = Logger ('FeedAdLoaderWidget ' ); // Renamed logger
66+ final InlineAdCacheService _adCacheService = InlineAdCacheService ();
6467
6568 /// Completer to manage the lifecycle of the ad loading future.
6669 /// This helps in cancelling pending operations if the widget is disposed
@@ -75,7 +78,7 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
7578 }
7679
7780 @override
78- void didUpdateWidget (covariant AdLoaderWidget oldWidget) {
81+ void didUpdateWidget (covariant FeedAdLoaderWidget oldWidget) {
7982 super .didUpdateWidget (oldWidget);
8083 // If the adPlaceholder ID changes, it means this widget is being reused
8184 // for a different ad slot. We need to cancel any ongoing load for the old
@@ -84,7 +87,7 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
8487 if (widget.adPlaceholder.id != oldWidget.adPlaceholder.id ||
8588 widget.adConfig != oldWidget.adConfig) {
8689 _logger.info (
87- 'AdLoaderWidget updated for new placeholder ID: '
90+ 'FeedAdLoaderWidget updated for new placeholder ID: ' // Renamed log
8891 '${widget .adPlaceholder .id } or AdConfig changed. Re-loading ad.' ,
8992 );
9093 // Cancel the previous loading operation if it's still active and not yet
@@ -125,9 +128,9 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
125128 super .dispose ();
126129 }
127130
128- /// Loads the inline ad for this slot.
131+ /// Loads the inline ad for this feed slot.
129132 ///
130- /// This method first checks the [AdCacheService ] for a pre-loaded [InlineAd] .
133+ /// This method first checks the [InlineAdCacheService ] for a pre-loaded [InlineAd] .
131134 /// If found, it uses the cached ad. Otherwise, it requests a new inline ad
132135 /// from the [AdService] using `getFeedAd` and stores it in the cache
133136 /// upon success.
@@ -146,7 +149,7 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
146149
147150 if (cachedAd != null ) {
148151 _logger.info (
149- 'Using cached ad for placeholder ID: ${widget .adPlaceholder .id }' ,
152+ 'Using cached ad for feed placeholder ID: ${widget .adPlaceholder .id }' , // Renamed log
150153 );
151154 // Ensure the widget is still mounted before calling setState.
152155 if (! mounted) return ;
@@ -163,7 +166,7 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
163166 }
164167
165168 _logger.info (
166- 'Loading new ad for placeholder ID: ${widget .adPlaceholder .id }' ,
169+ 'Loading new ad for feed placeholder ID: ${widget .adPlaceholder .id }' , // Renamed log
167170 );
168171 try {
169172 // The adId is now directly available from the placeholder.
@@ -187,22 +190,28 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
187190 return ;
188191 }
189192
193+ // Get the current HeadlineImageStyle from AppBloc
194+ final headlineImageStyle = context
195+ .read <AppBloc >()
196+ .state
197+ .settings
198+ .feedPreferences
199+ .headlineImageStyle;
200+
190201 // Call AdService.getFeedAd with the full AdConfig and adType from the placeholder.
191202 final loadedAd = await widget.adService.getFeedAd (
192203 adConfig: widget.adConfig, // Pass the full AdConfig
193204 adType: widget.adPlaceholder.adType,
194205 adThemeStyle: widget.adThemeStyle,
206+ headlineImageStyle: headlineImageStyle, // Pass the headlineImageStyle
195207 );
196208
197209 if (loadedAd != null ) {
198210 _logger.info (
199- 'New ad loaded for placeholder ID: ${widget .adPlaceholder .id }' ,
211+ 'New ad loaded for feed placeholder ID: ${widget .adPlaceholder .id }' , // Renamed log
200212 );
201213 // Store the newly loaded ad in the cache.
202- _adCacheService.setAd (
203- widget.adPlaceholder.id,
204- loadedAd,
205- );
214+ _adCacheService.setAd (widget.adPlaceholder.id, loadedAd);
206215 // Ensure the widget is still mounted before calling setState.
207216 if (! mounted) return ;
208217 setState (() {
@@ -215,7 +224,7 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
215224 }
216225 } else {
217226 _logger.warning (
218- 'Failed to load ad for placeholder ID: ${widget .adPlaceholder .id }. '
227+ 'Failed to load ad for feed placeholder ID: ${widget .adPlaceholder .id }. ' // Renamed log
219228 'No ad returned.' ,
220229 );
221230 // Ensure the widget is still mounted before calling setState.
@@ -233,7 +242,7 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
233242 }
234243 } catch (e, s) {
235244 _logger.severe (
236- 'Error loading ad for placeholder ID: ${widget .adPlaceholder .id }: $e ' ,
245+ 'Error loading ad for feed placeholder ID: ${widget .adPlaceholder .id }: $e ' , // Renamed log
237246 e,
238247 s,
239248 );
@@ -274,12 +283,37 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
274283 // provider-specific widget for rendering.
275284 switch (_loadedAd! .provider) {
276285 case AdPlatformType .admob:
277- return AdmobInlineAdWidget (inlineAd: _loadedAd! );
286+ return AdmobInlineAdWidget (
287+ inlineAd: _loadedAd! ,
288+ headlineImageStyle: context
289+ .read <AppBloc >()
290+ .state
291+ .settings
292+ .feedPreferences
293+ .headlineImageStyle,
294+ );
278295 case AdPlatformType .local:
279296 if (_loadedAd is NativeAd && _loadedAd! .adObject is LocalNativeAd ) {
280- return LocalNativeAdWidget (localNativeAd: _loadedAd! .adObject as LocalNativeAd );
281- } else if (_loadedAd is BannerAd && _loadedAd! .adObject is LocalBannerAd ) {
282- return LocalBannerAdWidget (localBannerAd: _loadedAd! .adObject as LocalBannerAd );
297+ return LocalNativeAdWidget (
298+ localNativeAd: _loadedAd! .adObject as LocalNativeAd ,
299+ headlineImageStyle: context
300+ .read <AppBloc >()
301+ .state
302+ .settings
303+ .feedPreferences
304+ .headlineImageStyle,
305+ );
306+ } else if (_loadedAd is BannerAd &&
307+ _loadedAd! .adObject is LocalBannerAd ) {
308+ return LocalBannerAdWidget (
309+ localBannerAd: _loadedAd! .adObject as LocalBannerAd ,
310+ headlineImageStyle: context
311+ .read <AppBloc >()
312+ .state
313+ .settings
314+ .feedPreferences
315+ .headlineImageStyle,
316+ );
283317 }
284318 // Fallback for unsupported local ad types or errors
285319 return const PlaceholderAdWidget ();
0 commit comments