feat(ads): home/map banner slot (hidden when removed or unloaded)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
// lib/ui/widgets/banner_ad_slot.dart
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:google_mobile_ads/google_mobile_ads.dart';
|
||||
|
||||
import '../../state/providers.dart';
|
||||
|
||||
/// A self-loading 320x50 banner for the home/map screens. Renders nothing
|
||||
/// when ads are removed or the banner has not loaded — never reserves blank
|
||||
/// space and never appears on the game screen.
|
||||
class BannerAdSlot extends ConsumerStatefulWidget {
|
||||
const BannerAdSlot({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<BannerAdSlot> createState() => _BannerAdSlotState();
|
||||
}
|
||||
|
||||
class _BannerAdSlotState extends ConsumerState<BannerAdSlot> {
|
||||
BannerAd? _ad;
|
||||
bool _loaded = false;
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
if (_ad != null) return;
|
||||
if (ref.read(adsRemovedProvider)) return;
|
||||
final ad = ref.read(adServiceProvider).createBanner(
|
||||
listener: BannerAdListener(
|
||||
onAdLoaded: (_) {
|
||||
if (mounted) setState(() => _loaded = true);
|
||||
},
|
||||
onAdFailedToLoad: (ad, _) => ad.dispose(),
|
||||
),
|
||||
);
|
||||
if (ad == null) return;
|
||||
_ad = ad;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_ad?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ad = _ad;
|
||||
if (ad == null || !_loaded || ref.watch(adsRemovedProvider)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return SizedBox(
|
||||
width: ad.size.width.toDouble(),
|
||||
height: ad.size.height.toDouble(),
|
||||
child: AdWidget(ad: ad),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user