Skip to content

Commit e718c95

Browse files
committed
refactor(ads): expand ad loading functionality and improve rendering logic
- Update AdLoaderWidget to support new ad types and loading logic - Modify ad loading method from getInlineAd to getFeedAd - Add support for BannerAd and NativeAd in addition to InlineAd - Implement provider-specific ad rendering widgets - Improve error handling and ad type checking
1 parent 1467b26 commit e718c95

File tree

1 file changed

+34
-22
lines changed

1 file changed

+34
-22
lines changed

lib/ads/widgets/ad_loader_widget.dart

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import 'package:core/core.dart';
44
import 'package:flutter/material.dart';
55
import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_cache_service.dart';
66
import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_service.dart';
7-
import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/ad_feed_item.dart';
87
import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/ad_placeholder.dart';
98
import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/ad_theme_style.dart';
10-
import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/inline_ad.dart'; // Import InlineAd
11-
import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/ad_feed_item_widget.dart';
9+
import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/banner_ad.dart';
10+
import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/inline_ad.dart';
11+
import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/native_ad.dart';
12+
import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/admob_inline_ad_widget.dart';
13+
import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/local_banner_ad_widget.dart';
14+
import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/local_native_ad_widget.dart';
1215
import 'package:flutter_news_app_mobile_client_full_source_code/ads/widgets/placeholder_ad_widget.dart';
1316
import 'package:logging/logging.dart';
1417
import 'package:ui_kit/ui_kit.dart';
@@ -18,7 +21,7 @@ import 'package:ui_kit/ui_kit.dart';
1821
///
1922
/// This widget handles the entire lifecycle of a single ad slot in the feed.
2023
/// It attempts to retrieve a cached [InlineAd] first. If no ad is cached,
21-
/// it requests a new one from the [AdService] using `getInlineAd` and stores
24+
/// it requests a new one from the [AdService] using `getFeedAd` and stores
2225
/// it in the cache upon success. It manages its own loading and error states.
2326
///
2427
/// This approach decouples ad loading from the BLoC and ensures that native
@@ -53,7 +56,7 @@ class AdLoaderWidget extends StatefulWidget {
5356
}
5457

5558
class _AdLoaderWidgetState extends State<AdLoaderWidget> {
56-
InlineAd? _loadedAd; // Changed to InlineAd
59+
InlineAd? _loadedAd;
5760
bool _isLoading = true;
5861
bool _hasError = false;
5962
final Logger _logger = Logger('AdLoaderWidget');
@@ -89,7 +92,9 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
8992
// while an old one is still in progress.
9093
if (_loadAdCompleter != null && !_loadAdCompleter!.isCompleted) {
9194
_loadAdCompleter?.completeError(
92-
StateError('Ad loading cancelled: Widget updated with new ID or config.'),
95+
StateError(
96+
'Ad loading cancelled: Widget updated with new ID or config.',
97+
),
9398
);
9499
}
95100
_loadAdCompleter = null; // Clear the old completer for the new load
@@ -124,7 +129,7 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
124129
///
125130
/// This method first checks the [AdCacheService] for a pre-loaded [InlineAd].
126131
/// If found, it uses the cached ad. Otherwise, it requests a new inline ad
127-
/// from the [AdService] using `getInlineAd` and stores it in the cache
132+
/// from the [AdService] using `getFeedAd` and stores it in the cache
128133
/// upon success.
129134
Future<void> _loadAd() async {
130135
// Initialize a new completer for this loading operation.
@@ -182,23 +187,26 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
182187
return;
183188
}
184189

185-
// Call AdService.getInlineAd with the full AdConfig and adType from the placeholder.
186-
final adFeedItem = await widget.adService.getInlineAd(
190+
// Call AdService.getFeedAd with the full AdConfig and adType from the placeholder.
191+
final loadedAd = await widget.adService.getFeedAd(
187192
adConfig: widget.adConfig, // Pass the full AdConfig
188193
adType: widget.adPlaceholder.adType,
189194
adThemeStyle: widget.adThemeStyle,
190195
);
191196

192-
if (adFeedItem != null) {
197+
if (loadedAd != null) {
193198
_logger.info(
194199
'New ad loaded for placeholder ID: ${widget.adPlaceholder.id}',
195200
);
196201
// Store the newly loaded ad in the cache.
197-
_adCacheService.setAd(widget.adPlaceholder.id, adFeedItem.inlineAd); // Use inlineAd
202+
_adCacheService.setAd(
203+
widget.adPlaceholder.id,
204+
loadedAd,
205+
);
198206
// Ensure the widget is still mounted before calling setState.
199207
if (!mounted) return;
200208
setState(() {
201-
_loadedAd = adFeedItem.inlineAd; // Use inlineAd
209+
_loadedAd = loadedAd;
202210
_isLoading = false;
203211
});
204212
// Complete the completer only if it hasn't been completed already.
@@ -262,16 +270,20 @@ class _AdLoaderWidgetState extends State<AdLoaderWidget> {
262270
// Show a placeholder or error message if ad loading failed.
263271
return const PlaceholderAdWidget();
264272
} else {
265-
// If an ad is successfully loaded, wrap it in an AdFeedItem
266-
// and pass it to the AdFeedItemWidget for rendering.
267-
// This improves separation of concerns, as AdLoaderWidget is now
268-
// only responsible for loading, not rendering logic.
269-
return AdFeedItemWidget(
270-
adFeedItem: AdFeedItem(
271-
id: widget.adPlaceholder.id,
272-
inlineAd: _loadedAd!, // Use inlineAd
273-
),
274-
);
273+
// If an ad is successfully loaded, dispatch to the appropriate
274+
// provider-specific widget for rendering.
275+
switch (_loadedAd!.provider) {
276+
case AdPlatformType.admob:
277+
return AdmobInlineAdWidget(inlineAd: _loadedAd!);
278+
case AdPlatformType.local:
279+
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);
283+
}
284+
// Fallback for unsupported local ad types or errors
285+
return const PlaceholderAdWidget();
286+
}
275287
}
276288
}
277289
}

0 commit comments

Comments
 (0)