dev
dart 342 lines 13.2 KB
Raw
1 import 'dart:math';
2
3 import 'package:auto_size_text/auto_size_text.dart';
4 import 'package:cake_wallet/entities/fiat_currency.dart';
5 import 'package:cake_wallet/generated/i18n.dart';
6 import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
7 import 'package:cake_wallet/themes/core/theme_extension.dart';
8 import 'package:cw_core/crypto_currency.dart';
9 import 'package:flutter/cupertino.dart';
10 import 'package:flutter/material.dart';
11
12 class SavingsCard extends StatelessWidget {
13 const SavingsCard({
14 super.key,
15 required this.interestRate,
16 required this.savingsBalance,
17 required this.currency,
18 required this.onAddSavingsPressed,
19 required this.onRemoveSavingsPressed,
20 required this.onApproveSavingsPressed,
21 required this.onTooltipPressed,
22 this.isEnabled = true,
23 this.isLoading = false,
24 this.fiatSavingsBalance,
25 this.fiatCurrency,
26 this.savingsBalanceV1,
27 this.fiatSavingsBalanceV1,
28 this.onWithdrawV1Pressed,
29 });
30
31 final bool isEnabled;
32 final bool isLoading;
33 final String interestRate;
34 final String savingsBalance;
35 final String? fiatSavingsBalance;
36 final String? savingsBalanceV1;
37 final String? fiatSavingsBalanceV1;
38 final FiatCurrency? fiatCurrency;
39 final CryptoCurrency currency;
40 final VoidCallback? onWithdrawV1Pressed;
41 final VoidCallback onAddSavingsPressed;
42 final VoidCallback onRemoveSavingsPressed;
43 final VoidCallback onApproveSavingsPressed;
44 final VoidCallback onTooltipPressed;
45
46 @override
47 Widget build(BuildContext context) => Container(
48 margin: const EdgeInsets.all(15),
49 decoration: BoxDecoration(
50 borderRadius: BorderRadius.circular(15),
51 color: Theme.of(context).colorScheme.surfaceContainerLowest,
52 ),
53 child: Column(children: [
54 Padding(
55 padding: const EdgeInsets.only(top: 10, bottom: 10, left: 20, right: 20),
56 child: Row(
57 children: [
58 Expanded(
59 child: Text(
60 'Current APR', // ToDo: Localize
61 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
62 color: Theme.of(context).colorScheme.onSurfaceVariant,
63 fontWeight: FontWeight.w500,
64 ),
65 softWrap: true,
66 ),
67 ),
68 Text(
69 interestRate,
70 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
71 color: Theme.of(context).colorScheme.onSurfaceVariant,
72 fontWeight: FontWeight.w800,
73 ),
74 softWrap: true,
75 ),
76 ],
77 ),
78 ),
79 Container(
80 decoration: BoxDecoration(
81 borderRadius: BorderRadius.circular(15),
82 gradient: LinearGradient(
83 colors: [
84 context.customColors.cardGradientColorPrimary,
85 context.customColors.cardGradientColorSecondary,
86 ],
87 begin: Alignment.topCenter,
88 end: Alignment.bottomCenter,
89 ),
90 ),
91 padding: const EdgeInsets.all(20),
92 child: Column(
93 children: [
94 Padding(
95 padding: const EdgeInsets.only(bottom: 20),
96 child: getAssetBalanceRow(
97 context,
98 title: S.of(context).deuro_savings_balance,
99 amount: savingsBalance,
100 fiatAmount: fiatSavingsBalance,
101 currency: currency,
102 fiatCurrency: fiatCurrency,
103 hideSymbol: false,
104 onTooltipPressed: onTooltipPressed,
105 ),
106 ),
107 if (savingsBalanceV1 != null)
108 Padding(
109 padding: const EdgeInsets.only(bottom: 20),
110 child: getAssetBalanceRow(
111 context,
112 title: "${S.of(context).deuro_savings_balance} V1",
113 amount: savingsBalanceV1!,
114 fiatAmount: fiatSavingsBalanceV1,
115 currency: currency,
116 fiatCurrency: fiatCurrency,
117 hideSymbol: true,
118 ),
119 ),
120 isLoading
121 ? CupertinoActivityIndicator(color: Theme.of(context).colorScheme.onSurface)
122 : Row(
123 mainAxisAlignment: MainAxisAlignment.spaceBetween,
124 children: savingsBalanceV1 != null
125 ? [
126 Expanded(
127 child: getButton(
128 context,
129 label: "${S.of(context).deuro_savings_remove} V1",
130 onPressed: onWithdrawV1Pressed ?? () {},
131 backgroundColor: Theme.of(context).colorScheme.primary,
132 color: Theme.of(context).colorScheme.onPrimary,
133 icon: Icons.arrow_downward,
134 ),
135 )
136 ]
137 : isEnabled
138 ? [
139 Expanded(
140 child: getButton(
141 context,
142 label: S.of(context).deuro_savings_add,
143 imagePath: 'assets/images/received.png',
144 onPressed: onAddSavingsPressed,
145 backgroundColor: Theme.of(context).colorScheme.primary,
146 color: Theme.of(context).colorScheme.onPrimary,
147 ),
148 ),
149 SizedBox(width: 12),
150 Expanded(
151 child: getButton(
152 context,
153 label: S.of(context).deuro_savings_remove,
154 imagePath: 'assets/images/upload.png',
155 onPressed: onRemoveSavingsPressed,
156 backgroundColor: Theme.of(context).colorScheme.surface,
157 color: Theme.of(context).colorScheme.onSecondaryContainer,
158 ),
159 ),
160 ]
161 : [
162 Expanded(
163 child: getButton(
164 context,
165 label: S.of(context).deuro_savings_approve_app,
166 onPressed: onApproveSavingsPressed,
167 backgroundColor: Theme.of(context).colorScheme.primary,
168 color: Theme.of(context).colorScheme.onPrimary,
169 icon: Icons.check,
170 ),
171 )
172 ],
173 ),
174 ],
175 ),
176 ),
177 ]),
178 );
179
180 static Widget getButton(
181 BuildContext context, {
182 required String label,
183 required VoidCallback onPressed,
184 required Color backgroundColor,
185 required Color color,
186 String? imagePath,
187 IconData? icon,
188 bool enabled = true,
189 double iconSize = 24,
190 }) {
191 backgroundColor = enabled ? backgroundColor : backgroundColor.withAlpha(130);
192 color = enabled ? color : color.withAlpha(130);
193
194 return Semantics(
195 label: label,
196 child: OutlinedButton(
197 onPressed: enabled ? onPressed : null,
198 style: OutlinedButton.styleFrom(
199 backgroundColor: backgroundColor,
200 side: BorderSide(
201 color: Theme.of(context).colorScheme.outlineVariant.withAlpha(0),
202 width: 0,
203 ),
204 shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
205 ),
206 child: Container(
207 padding: const EdgeInsets.symmetric(vertical: 12),
208 child: Row(
209 mainAxisAlignment: MainAxisAlignment.center,
210 children: [
211 if (imagePath != null) ...[
212 Image.asset(imagePath, height: iconSize, width: iconSize, color: color),
213 const SizedBox(width: 8),
214 ],
215 if (icon != null) ...[
216 Icon(icon, size: iconSize, color: color),
217 const SizedBox(width: 8),
218 ],
219 Text(
220 label,
221 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
222 color: color,
223 fontWeight: FontWeight.w700,
224 ),
225 ),
226 ],
227 ),
228 ),
229 ),
230 );
231 }
232
233 static Widget getAssetBalanceRow(
234 BuildContext context, {
235 required String title,
236 required String amount,
237 required CryptoCurrency currency,
238 bool hideSymbol = true,
239 VoidCallback? onTooltipPressed,
240 FiatCurrency? fiatCurrency,
241 String? fiatAmount,
242 }) =>
243 Row(
244 mainAxisAlignment: MainAxisAlignment.spaceBetween,
245 crossAxisAlignment: CrossAxisAlignment.center,
246 children: [
247 Column(
248 crossAxisAlignment: CrossAxisAlignment.start,
249 children: [
250 Row(
251 children: [
252 Text(
253 title,
254 style: Theme.of(context).textTheme.bodySmall?.copyWith(
255 color: Theme.of(context).colorScheme.onSurfaceVariant,
256 height: 1,
257 ),
258 ),
259 if (onTooltipPressed != null)
260 Padding(
261 padding: EdgeInsets.only(left: 4),
262 child: InkWell(
263 onTap: onTooltipPressed,
264 child: Icon(
265 CupertinoIcons.question_circle,
266 size: 13,
267 color: Theme.of(context).colorScheme.onSurfaceVariant,
268 ),
269 ),
270 ),
271 ],
272 ),
273 SizedBox(height: 6),
274 AutoSizeText(
275 amount,
276 style: Theme.of(context).textTheme.titleLarge?.copyWith(
277 color: Theme.of(context).colorScheme.onSurface,
278 fontWeight: FontWeight.w900,
279 fontSize: 24,
280 height: 1,
281 ),
282 maxLines: 1,
283 textAlign: TextAlign.start,
284 ),
285 if (fiatCurrency != null)
286 AutoSizeText(
287 "${fiatCurrency.title} $fiatAmount",
288 style: Theme.of(context).textTheme.titleLarge?.copyWith(
289 color: Theme.of(context).colorScheme.onSurfaceVariant,
290 fontWeight: FontWeight.w500,
291 fontSize: 16,
292 height: 1.5,
293 ),
294 maxLines: 1,
295 textAlign: TextAlign.start,
296 ),
297 ],
298 ),
299 if (!hideSymbol)
300 SizedBox(
301 child: Center(
302 child: Column(
303 children: [
304 CakeImageWidget(
305 imageUrl: currency.iconPath,
306 height: 40,
307 width: 40,
308 errorWidget: Container(
309 height: 30.0,
310 width: 30.0,
311 child: Center(
312 child: Text(
313 currency.title.substring(0, min(currency.title.length, 2)),
314 style: Theme.of(context).textTheme.bodySmall?.copyWith(
315 fontSize: 11,
316 color: Theme.of(context).colorScheme.onSurfaceVariant,
317 ),
318 ),
319 ),
320 decoration: BoxDecoration(
321 shape: BoxShape.circle,
322 color: Theme.of(context).colorScheme.surfaceContainer,
323 ),
324 ),
325 ),
326 const SizedBox(height: 3),
327 Text(
328 currency.title,
329 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
330 fontSize: 16,
331 fontWeight: FontWeight.w700,
332 color: Theme.of(context).colorScheme.onSurface,
333 height: 1,
334 ),
335 ),
336 ],
337 ),
338 ),
339 ),
340 ],
341 );
342 }