dev
dart 257 lines 8.71 KB
Raw
1 import 'dart:ui';
2
3 import 'package:auto_size_text/auto_size_text.dart';
4 import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
5 import 'package:cake_wallet/src/widgets/section_divider.dart';
6 import 'package:flutter/material.dart';
7
8 class AlertButtonStyle {
9 final Color backgroundColor;
10 final Color textColor;
11 final FontWeight fontWeight;
12
13 const AlertButtonStyle(
14 {required this.backgroundColor, required this.textColor, this.fontWeight = FontWeight.w400});
15
16 factory AlertButtonStyle.primary(BuildContext context) => AlertButtonStyle(
17 backgroundColor: Theme.of(context).colorScheme.primary,
18 textColor: Theme.of(context).colorScheme.onPrimary,
19 );
20
21 factory AlertButtonStyle.secondary(BuildContext context) => AlertButtonStyle(
22 backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
23 textColor: Theme.of(context).colorScheme.primary,
24 );
25
26 factory AlertButtonStyle.error(BuildContext context) => AlertButtonStyle(
27 backgroundColor: Theme.of(context).colorScheme.errorContainer,
28 textColor: Theme.of(context).colorScheme.error,
29 fontWeight: FontWeight.w500);
30 }
31
32 class BaseAlertDialog extends StatelessWidget {
33 String? get headerText => '';
34
35 String? get titleText => '';
36
37 double? get titleTextSize => 18;
38
39 String get contentText => '';
40
41 Widget? get contentTextWidget => null;
42
43 String get leftActionButtonText => '';
44
45 String get rightActionButtonText => '';
46
47 bool get isDividerExists => false;
48
49 bool get isBottomDividerExists => true;
50
51 VoidCallback get actionLeft => () {};
52
53 VoidCallback get actionRight => () {};
54
55 bool get barrierDismissible => true;
56
57 String? get headerImageUrl => null;
58
59 Key? leftActionButtonKey;
60
61 Key? rightActionButtonKey;
62
63 Key? dialogKey;
64
65 AlertButtonStyle? get leftAlertButtonStyle => null;
66
67 AlertButtonStyle? get rightAlertButtonStyle => null;
68
69 bool get showLeftButton => true;
70
71 Widget title(BuildContext context) {
72 return Text(
73 titleText!,
74 textAlign: TextAlign.center,
75 style: Theme.of(context).textTheme.bodyMedium!.copyWith(
76 fontSize: titleTextSize,
77 fontWeight: FontWeight.w600,
78 color: Theme.of(context).colorScheme.onSurface,
79 decoration: TextDecoration.none,
80 ),
81 );
82 }
83
84 Widget headerTitle(BuildContext context) {
85 return Padding(
86 padding: const EdgeInsets.only(top: 10.0),
87 child: Text(
88 headerText!,
89 textAlign: TextAlign.center,
90 style: Theme.of(context).textTheme.bodyMedium!.copyWith(
91 fontSize: 25,
92 fontWeight: FontWeight.w600,
93 color: Theme.of(context).colorScheme.onSurface,
94 decoration: TextDecoration.none,
95 ),
96 ),
97 );
98 }
99
100 Widget content(BuildContext context) {
101 return SingleChildScrollView(
102 child: Column(
103 mainAxisSize: MainAxisSize.min,
104 children: [
105 contentTextWidget ??
106 Text(
107 contentText,
108 textAlign: TextAlign.center,
109 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
110 fontSize: 14,
111 decoration: TextDecoration.none,
112 ),
113 ),
114 ],
115 ),
116 );
117 }
118
119 Widget actionButtons(BuildContext context) {
120 final rightButtonStyle = rightAlertButtonStyle ?? AlertButtonStyle.primary(context);
121 final leftButtonStyle = leftAlertButtonStyle ?? AlertButtonStyle.secondary(context);
122
123 return Row(
124 mainAxisAlignment: MainAxisAlignment.center,
125 mainAxisSize: MainAxisSize.max,
126 spacing: 8,
127 children: <Widget>[
128 if (showLeftButton)
129 Expanded(
130 child: GestureDetector(
131 key: leftActionButtonKey,
132 onTap: actionLeft,
133 child: Container(
134 decoration: BoxDecoration(
135 borderRadius: BorderRadius.circular(999999),
136 color: leftButtonStyle.backgroundColor),
137 child: Padding(
138 padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8),
139 child: AutoSizeText(
140 maxLines: 1,
141 leftActionButtonText,
142 textAlign: TextAlign.center,
143 style: TextStyle(
144 fontSize: 16,
145 color: leftButtonStyle.textColor,
146 fontWeight: leftButtonStyle.fontWeight)),
147 ),
148 )),
149 ),
150 Expanded(
151 child: GestureDetector(
152 key: rightActionButtonKey,
153 onTap: actionRight,
154 child: Container(
155 decoration: BoxDecoration(
156 borderRadius: BorderRadius.circular(999999),
157 color: rightButtonStyle.backgroundColor),
158 child: Padding(
159 padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8),
160 child: AutoSizeText(
161 maxLines: 1,
162 rightActionButtonText,
163 textAlign: TextAlign.center,
164 style: TextStyle(
165 fontSize: 16,
166 color: rightButtonStyle.textColor,
167 fontWeight: rightButtonStyle.fontWeight)),
168 ),
169 )),
170 ),
171 ],
172 );
173 }
174
175 Widget headerImage(BuildContext context, String imageUrl) {
176 return Positioned(
177 top: -50,
178 left: 0,
179 right: 0,
180 child: CircleAvatar(
181 radius: 50,
182 backgroundColor: Theme.of(context).colorScheme.surfaceContainerHighest,
183 child: ClipOval(
184 child: CakeImageWidget(imageUrl: imageUrl, width: 100, height: 100, fit: BoxFit.cover),
185 ),
186 ),
187 );
188 }
189
190 @override
191 Widget build(BuildContext context) {
192 return GestureDetector(
193 key: key,
194 onTap: () => barrierDismissible ? Navigator.of(context).pop() : null,
195 child: Container(
196 color: Colors.transparent,
197 child: BackdropFilter(
198 filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
199 child: Container(
200 decoration: BoxDecoration(color: Theme.of(context).colorScheme.onSurface.withAlpha(25)),
201 child: Center(
202 child: Padding(
203 padding: const EdgeInsets.all(16.0),
204 child: GestureDetector(
205 onTap: () => null,
206 child: Material(
207 borderRadius: BorderRadius.circular(24),
208 child: Container(
209 decoration: BoxDecoration(
210 borderRadius: BorderRadius.circular(24),
211 color: Theme.of(context).colorScheme.surface,
212 ),
213 child: Padding(
214 padding: const EdgeInsets.all(24.0),
215 child: Stack(
216 clipBehavior: Clip.none,
217 children: [
218 if (headerImageUrl != null) headerImage(context, headerImageUrl!),
219 Column(
220 mainAxisSize: MainAxisSize.min,
221 children: <Widget>[
222 if (headerImageUrl != null) const SizedBox(height: 50),
223 Column(
224 crossAxisAlignment: CrossAxisAlignment.center,
225 children: <Widget>[
226 if (headerText?.isNotEmpty ?? false) headerTitle(context),
227 titleText != null ? title(context) : SizedBox(height: 16),
228 isDividerExists
229 ? Padding(
230 padding: EdgeInsets.only(top: 16, bottom: 8),
231 child: const HorizontalSectionDivider(),
232 )
233 : Offstage(),
234 Padding(
235 padding: EdgeInsets.symmetric(vertical: 25),
236 child: content(context),
237 )
238 ],
239 ),
240 // if (isBottomDividerExists) const HorizontalSectionDivider(),
241 actionButtons(context)
242 ],
243 ),
244 ],
245 ),
246 ),
247 ),
248 ),
249 ),
250 ),
251 ),
252 ),
253 ),
254 ),
255 );
256 }
257 }