Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
// lib/widgets/ad_banner.dart | |
import 'dart:math'; | |
import 'dart:async'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/foundation.dart'; | |
import 'package:tikslop/config/config.dart'; | |
import 'package:tikslop/theme/colors.dart'; | |
import 'package:url_launcher/url_launcher.dart'; | |
import 'package:universal_html/html.dart' if (dart.library.io) 'package:tikslop/services/html_stub.dart' as html; | |
class AdBanner extends StatefulWidget { | |
final bool showAd; | |
const AdBanner({ | |
super.key, | |
this.showAd = true, | |
}); | |
State<AdBanner> createState() => _AdBannerState(); | |
} | |
class _AdBannerState extends State<AdBanner> { | |
Map<String, String>? _currentAd; | |
Timer? _rotationTimer; | |
void initState() { | |
super.initState(); | |
// Initialize with a random ad | |
_selectRandomAd(); | |
// Start the rotation timer | |
_startRotationTimer(); | |
} | |
void dispose() { | |
// Cancel the timer when the widget is disposed | |
_rotationTimer?.cancel(); | |
super.dispose(); | |
} | |
/// Starts the ad rotation timer | |
void _startRotationTimer() { | |
// Rotate every 30 seconds | |
_rotationTimer = Timer.periodic(const Duration(seconds: 30), (timer) { | |
_selectRandomAd(); | |
}); | |
} | |
/// Selects a new random ad and updates the state | |
void _selectRandomAd() { | |
if (!mounted) return; | |
final ads = Configuration.instance.adBanners; | |
if (ads.isEmpty) { | |
setState(() => _currentAd = null); | |
return; | |
} | |
final random = Random(); | |
setState(() => _currentAd = ads[random.nextInt(ads.length)]); | |
} | |
/// Opens a URL in a new tab or browser | |
Future<void> _launchURL(String url) async { | |
final Uri uri = Uri.parse(url); | |
if (kIsWeb) { | |
// Use HTML for web platform | |
html.window.open(url, '_blank'); | |
} else { | |
// Use url_launcher for other platforms | |
if (!await launchUrl(uri, mode: LaunchMode.externalApplication)) { | |
throw Exception('Could not launch $url'); | |
} | |
} | |
} | |
Widget build(BuildContext context) { | |
// Only show ads if enabled in config and showAd is true | |
if (!Configuration.instance.enableAds || !widget.showAd) { | |
return const SizedBox.shrink(); | |
} | |
if (_currentAd == null || _currentAd!.isEmpty) { | |
return const SizedBox.shrink(); | |
} | |
return Column( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
// Divider above ad | |
const Divider(color: TikSlopColors.surfaceVariant), | |
// Ad banner | |
Padding( | |
padding: const EdgeInsets.symmetric(vertical: 4.0), | |
child: InkWell( | |
onTap: () => _launchURL(_currentAd!['link'] ?? ''), | |
child: Image.asset( | |
_currentAd!['image'] ?? '', | |
height: 64, | |
fit: BoxFit.contain, | |
errorBuilder: (context, error, stackTrace) { | |
// If image fails to load, show a placeholder | |
print('Error loading ad image: $error'); | |
return Container( | |
height: 64, | |
color: Colors.grey.withOpacity(0.1), | |
child: const Center(child: Text('Ad')), | |
); | |
}, | |
), | |
), | |
), | |
], | |
); | |
} | |
} |