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')),
                );
              },
            ),
          ),
        ),
      ],
    );
  }
}