dev
dart 208 lines 6.39 KB
Raw
1 import 'package:auto_size_text/auto_size_text.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cake_wallet/src/screens/integrations/deuro/widgets/numpad.dart';
4 import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart';
5 import 'package:cake_wallet/src/widgets/primary_button.dart';
6 import 'package:cw_core/amount/money.dart';
7 import 'package:flutter/material.dart';
8
9 class SavingsEditSheet extends BaseBottomSheet {
10 final Money? balance;
11 final String? balanceTitle;
12
13 const SavingsEditSheet({
14 required super.titleText,
15 super.titleIconPath,
16 this.balance,
17 this.balanceTitle,
18 required super.footerType,
19 required super.maxHeight,
20 });
21
22 @override
23 Widget contentWidget(BuildContext context) => SizedBox(
24 height: 500,
25 child: _SavingsEditBody(
26 balance: balance,
27 balanceTitle: balanceTitle,
28 ),
29 );
30
31 Widget footerWidget(BuildContext context) => SizedBox.shrink();
32 }
33
34 class _SavingsEditBody extends StatefulWidget {
35 final Money? balance;
36 final String? balanceTitle;
37
38 const _SavingsEditBody({this.balance, this.balanceTitle});
39
40 @override
41 State<StatefulWidget> createState() => _SavingsEditBodyState();
42 }
43
44 class _SavingsEditBodyState extends State<_SavingsEditBody> {
45 @override
46 void initState() {
47 WidgetsBinding.instance.addPostFrameCallback((_) => _numpadFocusNode.requestFocus());
48 super.initState();
49 }
50
51 @override
52 void dispose() {
53 _numpadFocusNode.dispose();
54 super.dispose();
55 }
56
57 String amount = '0';
58 bool isValid = false;
59 final FocusNode _numpadFocusNode = FocusNode();
60
61 void _onPressedAll() => setState(() {
62 amount = widget.balance!.toString();
63 isValid = _validate();
64 });
65
66 void _onNumberPressed(int i) => setState(() {
67 amount = amount == '0' ? i.toString() : '${amount}${i}';
68 isValid = _validate();
69 });
70
71 void _onDeletePressed() => setState(() {
72 amount = amount.length > 1 ? amount.substring(0, amount.length - 1) : '0';
73 isValid = _validate();
74 });
75
76 void _onDecimalPressed() => setState(() {
77 amount = '${amount.replaceAll('.', '')}.';
78 isValid = _validate();
79 });
80
81 bool _validate() {
82 try {
83 final amountBigInt = Money.parse(amount, widget.balance!.currency);
84 return widget.balance! >= amountBigInt && amountBigInt.sign > 0;
85 } catch (_) {
86 return false;
87 }
88 }
89
90 @override
91 Widget build(BuildContext context) => SafeArea(
92 child: Column(children: [
93 Expanded(
94 child: Center(
95 child: Padding(
96 padding: const EdgeInsets.only(left: 26, right: 26, top: 10),
97 child: AutoSizeText(
98 "${amount.toString()} dEuro",
99 maxLines: 1,
100 maxFontSize: 32,
101 style: Theme.of(context).textTheme.headlineMedium?.copyWith(
102 fontWeight: FontWeight.w600,
103 fontSize: 32,
104 color: Theme.of(context).colorScheme.onSurface,
105 ),
106 textAlign: TextAlign.center,
107 ),
108 ),
109 )),
110 if (widget.balance != null && widget.balanceTitle != null) ...[
111 Divider(),
112 AssetBalanceRow(
113 title: widget.balanceTitle!,
114 amount: widget.balance!.toStringWithSymbol(fractionalDigits: 6),
115 onAllPressed: _onPressedAll,
116 ),
117 ],
118 NumberPad(
119 focusNode: _numpadFocusNode,
120 onNumberPressed: _onNumberPressed,
121 onDeletePressed: _onDeletePressed,
122 onDecimalPressed: _onDecimalPressed,
123 ),
124 Padding(
125 padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
126 child: LoadingPrimaryButton(
127 onPressed: () => Navigator.pop(context, amount),
128 text: S.of(context).confirm,
129 color: Theme.of(context).colorScheme.primary,
130 textColor: Theme.of(context).colorScheme.onPrimary,
131 isLoading: false,
132 isDisabled: !isValid,
133 ),
134 )
135 ]),
136 );
137 }
138
139 class AssetBalanceRow extends StatelessWidget {
140 final String title;
141 final String amount;
142 final VoidCallback onAllPressed;
143
144 const AssetBalanceRow({
145 super.key,
146 required this.title,
147 required this.amount,
148 required this.onAllPressed,
149 });
150
151 @override
152 Widget build(BuildContext context) => Padding(
153 padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
154 child: Row(
155 mainAxisAlignment: MainAxisAlignment.spaceBetween,
156 crossAxisAlignment: CrossAxisAlignment.center,
157 children: [
158 Column(
159 crossAxisAlignment: CrossAxisAlignment.start,
160 children: [
161 Row(
162 children: [
163 Text(
164 title,
165 style: Theme.of(context).textTheme.bodySmall?.copyWith(
166 color: Theme.of(context).colorScheme.onSurfaceVariant,
167 height: 1,
168 ),
169 ),
170 ],
171 ),
172 SizedBox(height: 6),
173 AutoSizeText(
174 amount,
175 style: Theme.of(context).textTheme.bodyLarge?.copyWith(
176 color: Theme.of(context).colorScheme.onSurface,
177 fontWeight: FontWeight.w400,
178 height: 1,
179 ),
180 maxLines: 1,
181 textAlign: TextAlign.start,
182 ),
183 ],
184 ),
185 SizedBox(
186 child: Center(
187 child: InkWell(
188 onTap: onAllPressed,
189 child: Container(
190 decoration: BoxDecoration(
191 borderRadius: BorderRadius.circular(20),
192 color: Theme.of(context).colorScheme.surfaceContainer,
193 ),
194 padding: EdgeInsets.fromLTRB(15, 10, 15, 10),
195 child: Text(
196 S.of(context).all,
197 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
198 color: Theme.of(context).colorScheme.onSurface,
199 ),
200 ),
201 ),
202 ),
203 ),
204 ),
205 ],
206 ),
207 );
208 }