Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 3,279 Bytes
cc8c83c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
// 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,
});
@override
State<AdBanner> createState() => _AdBannerState();
}
class _AdBannerState extends State<AdBanner> {
Map<String, String>? _currentAd;
Timer? _rotationTimer;
@override
void initState() {
super.initState();
// Initialize with a random ad
_selectRandomAd();
// Start the rotation timer
_startRotationTimer();
}
@override
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');
}
}
}
@override
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')),
);
},
),
),
),
],
);
}
} |