1+ import 'dart:async' ;
2+
13import 'package:flutter/material.dart' ;
24import 'package:flutter_news_app_mobile_client_full_source_code/l10n/app_localizations.dart' ;
35import 'package:ui_kit/ui_kit.dart' ;
@@ -6,15 +8,53 @@ import 'package:ui_kit/ui_kit.dart';
68/// A dialog widget that displays a placeholder for an interstitial ad in demo mode.
79///
810/// This dialog mimics a full-screen interstitial ad but contains only static
9- /// text to indicate it's a demo.
11+ /// text to indicate it's a demo. It includes a countdown before the close
12+ /// button is enabled.
1013/// {@endtemplate}
11- class DemoInterstitialAdDialog extends StatelessWidget {
14+ class DemoInterstitialAdDialog extends StatefulWidget {
1215 /// {@macro demo_interstitial_ad_dialog}
1316 const DemoInterstitialAdDialog ({super .key});
1417
18+ @override
19+ State <DemoInterstitialAdDialog > createState () =>
20+ _DemoInterstitialAdDialogState ();
21+ }
22+
23+ class _DemoInterstitialAdDialogState extends State <DemoInterstitialAdDialog > {
24+ static const int _countdownDuration = 5 ;
25+ int _countdown = _countdownDuration;
26+ Timer ? _timer;
27+
28+ @override
29+ void initState () {
30+ super .initState ();
31+ _startTimer ();
32+ }
33+
34+ void _startTimer () {
35+ _timer = Timer .periodic (const Duration (seconds: 1 ), (timer) {
36+ if (_countdown > 0 ) {
37+ setState (() {
38+ _countdown-- ;
39+ });
40+ } else {
41+ _timer? .cancel ();
42+ }
43+ });
44+ }
45+
46+ @override
47+ void dispose () {
48+ _timer? .cancel ();
49+ super .dispose ();
50+ }
51+
1552 @override
1653 Widget build (BuildContext context) {
1754 final theme = Theme .of (context);
55+ final l10n = AppLocalizations .of (context);
56+ final canClose = _countdown == 0 ;
57+
1858 return Dialog .fullscreen (
1959 backgroundColor: theme.colorScheme.surface,
2060 child: Stack (
@@ -25,15 +65,15 @@ class DemoInterstitialAdDialog extends StatelessWidget {
2565 mainAxisAlignment: MainAxisAlignment .center,
2666 children: [
2767 Text (
28- AppLocalizations . of (context) .demoInterstitialAdText,
68+ l10n .demoInterstitialAdText,
2969 style: theme.textTheme.titleLarge? .copyWith (
3070 color: theme.colorScheme.onSurface,
3171 ),
3272 textAlign: TextAlign .center,
3373 ),
3474 const SizedBox (height: AppSpacing .md),
3575 Text (
36- AppLocalizations . of (context) .demoInterstitialAdDescription,
76+ l10n .demoInterstitialAdDescription,
3777 style: theme.textTheme.bodyMedium? .copyWith (
3878 color: theme.colorScheme.onSurfaceVariant,
3979 ),
@@ -46,13 +86,39 @@ class DemoInterstitialAdDialog extends StatelessWidget {
4686 Positioned (
4787 top: AppSpacing .lg,
4888 right: AppSpacing .lg,
49- child: IconButton (
50- icon: Icon (Icons .close, color: theme.colorScheme.onSurface),
51- onPressed: () {
52- // Dismiss the dialog.
53- Navigator .of (context).pop ();
54- },
55- ),
89+ child: canClose
90+ ? IconButton (
91+ icon:
92+ Icon (Icons .close, color: theme.colorScheme.onSurface),
93+ onPressed: () => Navigator .of (context).pop (),
94+ )
95+ : Container (
96+ padding: const EdgeInsets .symmetric (
97+ horizontal: AppSpacing .sm,
98+ vertical: AppSpacing .xs,
99+ ),
100+ decoration: BoxDecoration (
101+ color: theme.colorScheme.onSurface.withOpacity (0.1 ),
102+ borderRadius: BorderRadius .circular (AppSpacing .lg),
103+ ),
104+ child: Row (
105+ mainAxisSize: MainAxisSize .min,
106+ children: [
107+ Text (
108+ '$_countdown ' ,
109+ style: theme.textTheme.bodySmall? .copyWith (
110+ color: theme.colorScheme.onSurface,
111+ fontWeight: FontWeight .bold,
112+ ),
113+ ),
114+ const SizedBox (width: AppSpacing .xs),
115+ Icon (
116+ Icons .close,
117+ color: theme.colorScheme.onSurface.withOpacity (0.5 ),
118+ ),
119+ ],
120+ ),
121+ ),
56122 ),
57123 ],
58124 ),
0 commit comments