rework confirm sending screen for cake pay (#603)

* rework confirm sending allert * remove confirm_modal.dart * fix text color and buttons size

Serhii committed Nov 10, 2022 at 20:08 UTC 7d49dc47616559b8e94f72c54abd50a6eb9ea341
6 files changed +169 -253
lib/di.dart
+1
@@ -701,6 +701,7 @@ Future setup(
701 ioniaAnyPayService: getIt.get<IoniaAnyPay>(),
702 amount: amount,
703 ioniaMerchant: merchant,
704 + sendViewModel: getIt.get<SendViewModel>()
705 );
706 });
707
lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart
+23 -61
@@ -3,7 +3,6 @@ import 'package:cake_wallet/ionia/ionia_merchant.dart';
3 import 'package:cake_wallet/ionia/ionia_tip.dart';
4 import 'package:cake_wallet/palette.dart';
5 import 'package:cake_wallet/routes.dart';
6 -import 'package:cake_wallet/src/screens/ionia/widgets/confirm_modal.dart';
6 import 'package:cake_wallet/src/screens/ionia/widgets/ionia_alert_model.dart';
7 import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
8 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@@ -18,6 +17,7 @@ import 'package:cake_wallet/generated/i18n.dart';
17 import 'package:flutter_mobx/flutter_mobx.dart';
18 import 'package:mobx/mobx.dart';
19 import 'package:cake_wallet/src/screens/base_page.dart';
20 +import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
21
22 class IoniaBuyGiftCardDetailPage extends BasePage {
23 IoniaBuyGiftCardDetailPage(this.ioniaPurchaseViewModel);
@@ -295,73 +295,35 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
295
296 final amount = ioniaPurchaseViewModel.invoice!.totalAmount;
297 final addresses = ioniaPurchaseViewModel.invoice!.outAddresses;
298 + ioniaPurchaseViewModel.sendViewModel.outputs.first.setCryptoAmount(amount);
299 + ioniaPurchaseViewModel.sendViewModel.outputs.first.address = addresses.first;
300
301 await showPopUp<void>(
302 context: context,
303 builder: (_) {
302 - return IoniaConfirmModal(
304 + return ConfirmSendingAlert(
305 alertTitle: S.of(context).confirm_sending,
304 - alertContent: Container(
305 - height: 200,
306 - padding: EdgeInsets.all(15),
307 - child: Column(children: [
308 - Row(children: [
309 - Text(S.of(context).payment_id,
310 - textAlign: TextAlign.center,
311 - style: TextStyle(
312 - fontSize: 16,
313 - fontWeight: FontWeight.w400,
314 - color: PaletteDark.pigeonBlue,
315 - decoration: TextDecoration.none)),
316 - Text(ioniaPurchaseViewModel.invoice!.paymentId,
317 - style: TextStyle(
318 - fontSize: 16,
319 - fontWeight: FontWeight.w400,
320 - color: PaletteDark.pigeonBlue,
321 - decoration: TextDecoration.none))
322 - ], mainAxisAlignment: MainAxisAlignment.spaceBetween),
323 - SizedBox(height: 10),
324 - Row(children: [
325 - Text(S.of(context).amount,
326 - textAlign: TextAlign.center,
327 - style: TextStyle(
328 - fontSize: 16,
329 - fontWeight: FontWeight.w400,
330 - color: PaletteDark.pigeonBlue,
331 - decoration: TextDecoration.none)),
332 - Text('$amount ${ioniaPurchaseViewModel.invoice!.chain}',
333 - style: TextStyle(
334 - fontSize: 16,
335 - fontWeight: FontWeight.w400,
336 - color: PaletteDark.pigeonBlue,
337 - decoration: TextDecoration.none))
338 - ], mainAxisAlignment: MainAxisAlignment.spaceBetween),
339 - SizedBox(height: 25),
340 - Row(children: [
341 - Text(S.of(context).recipient_address,
342 - style: TextStyle(
343 - fontSize: 16,
344 - fontWeight: FontWeight.w400,
345 - color: PaletteDark.pigeonBlue,
346 - decoration: TextDecoration.none))
347 - ], mainAxisAlignment: MainAxisAlignment.center),
348 - Expanded(
349 - child: ListView.builder(
350 - itemBuilder: (_, int index) {
351 - return Text(addresses[index],
352 - style: TextStyle(
353 - fontSize: 14,
354 - fontWeight: FontWeight.w400,
355 - color: PaletteDark.pigeonBlue,
356 - decoration: TextDecoration.none));
357 - },
358 - itemCount: addresses.length,
359 - physics: NeverScrollableScrollPhysics()))
360 - ])),
306 + paymentId: S.of(context).payment_id,
307 + paymentIdValue: ioniaPurchaseViewModel.invoice!.paymentId,
308 + amount: S.of(context).send_amount,
309 + amountValue: '$amount ${ioniaPurchaseViewModel.invoice!.chain}',
310 + fiatAmountValue:
311 + '~ ${ioniaPurchaseViewModel.sendViewModel.outputs.first.fiatAmount} '
312 + '${ioniaPurchaseViewModel.sendViewModel.fiat.title}',
313 + fee: S.of(context).send_fee,
314 + feeValue:
315 + '${ioniaPurchaseViewModel.sendViewModel.outputs.first.estimatedFee} '
316 + '${ioniaPurchaseViewModel.invoice!.chain}',
317 + feeFiatAmount:
318 + '${ioniaPurchaseViewModel.sendViewModel.outputs.first.estimatedFeeFiatAmount} '
319 + '${ioniaPurchaseViewModel.sendViewModel.fiat.title}',
320 + outputs: ioniaPurchaseViewModel.sendViewModel.outputs,
321 rightButtonText: S.of(context).ok,
322 leftButtonText: S.of(context).cancel,
363 - leftActionColor: Color(0xffFF6600),
364 - rightActionColor: Theme.of(context).accentTextTheme!.bodyText1!.color!,
323 + alertLeftActionButtonTextColor: Colors.white,
324 + alertRightActionButtonTextColor: Colors.white,
325 + alertLeftActionButtonColor: Palette.brightOrange,
326 + alertRightActionButtonColor: Theme.of(context).textTheme!.subtitle2!.color,
327 actionRightButton: () async {
328 Navigator.of(context).pop();
329 await ioniaPurchaseViewModel.commitPaymentInvoice();
lib/src/screens/ionia/widgets/confirm_modal.dart deleted
-149
@@ -1,149 +0,0 @@
1 -import 'dart:ui';
2 -
3 -import 'package:cake_wallet/palette.dart';
4 -import 'package:flutter/material.dart';
5 -
6 -class IoniaConfirmModal extends StatelessWidget {
7 - IoniaConfirmModal({
8 - required this.alertTitle,
9 - required this.alertContent,
10 - required this.leftButtonText,
11 - required this.rightButtonText,
12 - required this.actionLeftButton,
13 - required this.actionRightButton,
14 - required this.leftActionColor,
15 - required this.rightActionColor,
16 - this.hideActions = false,
17 - });
18 -
19 - final String alertTitle;
20 - final Widget alertContent;
21 - final String leftButtonText;
22 - final String rightButtonText;
23 - final VoidCallback actionLeftButton;
24 - final VoidCallback actionRightButton;
25 - final Color leftActionColor;
26 - final Color rightActionColor;
27 - final bool hideActions;
28 -
29 - Widget actionButtons(BuildContext context) {
30 - return Row(
31 - mainAxisSize: MainAxisSize.max,
32 - children: <Widget>[
33 - IoniaActionButton(
34 - buttonText: leftButtonText,
35 - action: actionLeftButton,
36 - backgoundColor: leftActionColor,
37 - ),
38 - Container(
39 - width: 1,
40 - height: 52,
41 - color: Theme.of(context).dividerColor,
42 - ),
43 - IoniaActionButton(
44 - buttonText: rightButtonText,
45 - action: actionRightButton,
46 - backgoundColor: rightActionColor,
47 - ),
48 - ],
49 - );
50 - }
51 -
52 - Widget title(BuildContext context) {
53 - return Text(
54 - alertTitle,
55 - textAlign: TextAlign.center,
56 - style: TextStyle(
57 - fontSize: 20,
58 - fontFamily: 'Lato',
59 - fontWeight: FontWeight.w600,
60 - color: Theme.of(context).primaryTextTheme!.headline6!.color!,
61 - decoration: TextDecoration.none,
62 - ),
63 - );
64 - }
65 -
66 - @override
67 - Widget build(BuildContext context) {
68 - return Container(
69 - color: Colors.transparent,
70 - child: BackdropFilter(
71 - filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
72 - child: Container(
73 - decoration: BoxDecoration(color: PaletteDark.darkNightBlue.withOpacity(0.75)),
74 - child: Center(
75 - child: GestureDetector(
76 - onTap: () => null,
77 - child: ClipRRect(
78 - borderRadius: BorderRadius.all(Radius.circular(30)),
79 - child: Container(
80 - width: 327,
81 - color: Theme.of(context).accentTextTheme!.headline6!.decorationColor!,
82 - child: Column(
83 - mainAxisSize: MainAxisSize.min,
84 - children: [
85 - Padding(
86 - padding: EdgeInsets.fromLTRB(24, 20, 24, 0),
87 - child: title(context),
88 - ),
89 - Padding(
90 - padding: EdgeInsets.only(top: 16, bottom: 8),
91 - child: Container(
92 - height: 1,
93 - color: Theme.of(context).dividerColor,
94 - ),
95 - ),
96 - alertContent,
97 - actionButtons(context),
98 - ],
99 - ),
100 - ),
101 - ),
102 - ),
103 - ),
104 - ),
105 - ),
106 - );
107 - }
108 -}
109 -
110 -class IoniaActionButton extends StatelessWidget {
111 - const IoniaActionButton({
112 - required this.buttonText,
113 - required this.action,
114 - required this.backgoundColor,
115 - });
116 -
117 - final String buttonText;
118 - final VoidCallback action;
119 - final Color backgoundColor;
120 -
121 - @override
122 - Widget build(BuildContext context) {
123 - return Flexible(
124 - child: Container(
125 - height: 52,
126 - padding: EdgeInsets.only(left: 6, right: 6),
127 - color: backgoundColor,
128 - child: ButtonTheme(
129 - minWidth: double.infinity,
130 - child: TextButton(
131 - onPressed: action,
132 - // FIX-ME: ignored highlightColor and splashColor
133 - //highlightColor: Colors.transparent,
134 - //splashColor: Colors.transparent,
135 - child: Text(
136 - buttonText,
137 - textAlign: TextAlign.center,
138 - style: TextStyle(
139 - fontSize: 15,
140 - fontFamily: 'Lato',
141 - fontWeight: FontWeight.w600,
142 - color: backgoundColor != null ? Colors.white : Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!,
143 - decoration: TextDecoration.none,
144 - ),
145 - )),
146 - ),
147 - ));
148 - }
149 -}
lib/src/screens/send/widgets/confirm_sending_alert.dart
+84 -2
@@ -4,10 +4,13 @@ import 'package:flutter/material.dart';
4 import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
5 import 'package:cake_wallet/generated/i18n.dart';
6 import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
7 +import 'package:flutter/scheduler.dart';
8
9 class ConfirmSendingAlert extends BaseAlertDialog {
10 ConfirmSendingAlert({
11 required this.alertTitle,
12 + this.paymentId,
13 + this.paymentIdValue,
14 required this.amount,
15 required this.amountValue,
16 required this.fiatAmountValue,
@@ -19,9 +22,15 @@ class ConfirmSendingAlert extends BaseAlertDialog {
22 required this.rightButtonText,
23 required this.actionLeftButton,
24 required this.actionRightButton,
22 - this.alertBarrierDismissible = true});
25 + this.alertBarrierDismissible = true,
26 + this.alertLeftActionButtonTextColor,
27 + this.alertRightActionButtonTextColor,
28 + this.alertLeftActionButtonColor,
29 + this.alertRightActionButtonColor});
30
31 final String alertTitle;
32 + final String? paymentId;
33 + final String? paymentIdValue;
34 final String amount;
35 final String amountValue;
36 final String fiatAmountValue;
@@ -34,6 +43,10 @@ class ConfirmSendingAlert extends BaseAlertDialog {
43 final VoidCallback actionLeftButton;
44 final VoidCallback actionRightButton;
45 final bool alertBarrierDismissible;
46 + final Color? alertLeftActionButtonTextColor;
47 + final Color? alertRightActionButtonTextColor;
48 + final Color? alertLeftActionButtonColor;
49 + final Color? alertRightActionButtonColor;
50
51 @override
52 String get titleText => alertTitle;
@@ -56,8 +69,22 @@ class ConfirmSendingAlert extends BaseAlertDialog {
69 @override
70 bool get barrierDismissible => alertBarrierDismissible;
71
72 + @override
73 + Color? get leftActionButtonTextColor => alertLeftActionButtonTextColor;
74 +
75 + @override
76 + Color? get rightActionButtonTextColor => alertRightActionButtonTextColor;
77 +
78 + @override
79 + Color? get leftActionButtonColor => alertLeftActionButtonColor;
80 +
81 + @override
82 + Color? get rightActionButtonColor => alertRightActionButtonColor;
83 +
84 @override
85 Widget content(BuildContext context) => ConfirmSendingAlertContent(
86 + paymentId: paymentId,
87 + paymentIdValue: paymentIdValue,
88 amount: amount,
89 amountValue: amountValue,
90 fiatAmountValue: fiatAmountValue,
@@ -70,6 +97,8 @@ class ConfirmSendingAlert extends BaseAlertDialog {
97
98 class ConfirmSendingAlertContent extends StatefulWidget {
99 ConfirmSendingAlertContent({
100 + this.paymentId,
101 + this.paymentIdValue,
102 required this.amount,
103 required this.amountValue,
104 required this.fiatAmountValue,
@@ -78,6 +107,8 @@ class ConfirmSendingAlertContent extends StatefulWidget {
107 required this.feeFiatAmount,
108 required this.outputs});
109
110 + final String? paymentId;
111 + final String? paymentIdValue;
112 final String amount;
113 final String amountValue;
114 final String fiatAmountValue;
@@ -88,6 +119,8 @@ class ConfirmSendingAlertContent extends StatefulWidget {
119
120 @override
121 ConfirmSendingAlertContentState createState() => ConfirmSendingAlertContentState(
122 + paymentId: paymentId,
123 + paymentIdValue: paymentIdValue,
124 amount: amount,
125 amountValue: amountValue,
126 fiatAmountValue: fiatAmountValue,
@@ -100,6 +133,8 @@ class ConfirmSendingAlertContent extends StatefulWidget {
133
134 class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent> {
135 ConfirmSendingAlertContentState({
136 + this.paymentId,
137 + this.paymentIdValue,
138 required this.amount,
139 required this.amountValue,
140 required this.fiatAmountValue,
@@ -115,6 +150,8 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
150 : S.current.recipient_address;
151 }
152
153 + final String? paymentId;
154 + final String? paymentIdValue;
155 final String amount;
156 final String amountValue;
157 final String fiatAmountValue;
@@ -129,6 +166,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
166 double fromTop = 0;
167 String recipientTitle;
168 int itemCount;
169 + bool showScrollbar = false;
170
171 @override
172 Widget build(BuildContext context) {
@@ -140,6 +178,12 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
178 setState(() {});
179 });
180
181 + SchedulerBinding.instance.addPostFrameCallback((_) {
182 + setState(() {
183 + showScrollbar = controller.position.maxScrollExtent > 0;
184 + });
185 + });
186 +
187 return Stack(
188 alignment: Alignment.center,
189 clipBehavior: Clip.none,
@@ -150,6 +194,44 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
194 controller: controller,
195 child: Column(
196 children: <Widget>[
197 + if (paymentIdValue != null && paymentId != null)
198 + Padding(
199 + padding: EdgeInsets.only(bottom: 32),
200 + child: Row(
201 + mainAxisSize: MainAxisSize.max,
202 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
203 + crossAxisAlignment: CrossAxisAlignment.start,
204 + children: <Widget>[
205 + Text(
206 + paymentId!,
207 + style: TextStyle(
208 + fontSize: 16,
209 + fontWeight: FontWeight.normal,
210 + fontFamily: 'Lato',
211 + color: Theme.of(context).primaryTextTheme!
212 + .headline6!.color!,
213 + decoration: TextDecoration.none,
214 + ),
215 + ),
216 + Column(
217 + crossAxisAlignment: CrossAxisAlignment.end,
218 + children: [
219 + Text(
220 + paymentIdValue!,
221 + style: TextStyle(
222 + fontSize: 18,
223 + fontWeight: FontWeight.w600,
224 + fontFamily: 'Lato',
225 + color: Theme.of(context).primaryTextTheme!
226 + .headline6!.color!,
227 + decoration: TextDecoration.none,
228 + ),
229 + ),
230 + ],
231 + )
232 + ],
233 + ),
234 + ),
235 Row(
236 mainAxisSize: MainAxisSize.max,
237 mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -365,7 +447,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
447 )
448 )
449 ),
368 - if (itemCount > 1) CakeScrollbar(
450 + if (showScrollbar) CakeScrollbar(
451 backgroundHeight: backgroundHeight,
452 thumbHeight: thumbHeight,
453 fromTop: fromTop,
lib/src/widgets/base_alert_dialog.dart
+57 -41
@@ -11,6 +11,10 @@ class BaseAlertDialog extends StatelessWidget {
11 VoidCallback get actionLeft => () {};
12 VoidCallback get actionRight => () {};
13 bool get barrierDismissible => true;
14 + Color? get leftActionButtonTextColor => null;
15 + Color? get rightActionButtonTextColor => null;
16 + Color? get leftActionButtonColor => null;
17 + Color? get rightActionButtonColor => null;
18
19 Widget title(BuildContext context) {
20 return Text(
@@ -45,52 +49,64 @@ class BaseAlertDialog extends StatelessWidget {
49 height: 52,
50 child: Row(
51 mainAxisSize: MainAxisSize.max,
48 - mainAxisAlignment: MainAxisAlignment.center,
52 + crossAxisAlignment: CrossAxisAlignment.stretch,
53 children: <Widget>[
50 - Flexible(
51 - child: Container(
52 - width: double.infinity,
53 - color: Theme.of(context).accentTextTheme!.bodyText1!.decorationColor!,
54 - child: TextButton(
55 - onPressed: actionLeft,
56 - child: Text(
57 - leftActionButtonText,
58 - textAlign: TextAlign.center,
59 - style: TextStyle(
60 - fontSize: 15,
61 - fontFamily: 'Lato',
62 - fontWeight: FontWeight.w600,
63 - color: Theme.of(context).primaryTextTheme!.bodyText1!.backgroundColor!,
64 - decoration: TextDecoration.none,
65 - ),
66 - )),
67 - ),
68 - ),
54 + Expanded(
55 + child: TextButton(
56 + onPressed: actionLeft,
57 + style: TextButton.styleFrom(
58 + backgroundColor: leftActionButtonColor ??
59 + Theme.of(context)
60 + .accentTextTheme!
61 + .bodyText1!
62 + .decorationColor!,
63 + shape: const RoundedRectangleBorder(
64 + borderRadius: BorderRadius.all(Radius.zero))),
65 + child: Text(
66 + leftActionButtonText,
67 + textAlign: TextAlign.center,
68 + style: TextStyle(
69 + fontSize: 15,
70 + fontFamily: 'Lato',
71 + fontWeight: FontWeight.w600,
72 + color: leftActionButtonTextColor ??
73 + Theme.of(context).primaryTextTheme!
74 + .bodyText1!.backgroundColor!,
75 + decoration: TextDecoration.none,
76 + ),
77 + )),
78 + ),
79 Container(
80 width: 1,
81 color: Theme.of(context).dividerColor,
82 ),
73 - Flexible(
74 - child: Container(
75 - width: double.infinity,
76 - color: Theme.of(context).accentTextTheme!.bodyText2!.backgroundColor!,
77 - child: TextButton(
78 - onPressed: actionRight,
79 - child: Text(
80 - rightActionButtonText,
81 - textAlign: TextAlign.center,
82 - style: TextStyle(
83 - fontSize: 15,
84 - fontFamily: 'Lato',
85 - fontWeight: FontWeight.w600,
86 - color: Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!,
87 - decoration: TextDecoration.none,
88 - ),
89 - )),
90 - ),
91 - ),
92 - ],
93 - ));
83 + Expanded(
84 + child: TextButton(
85 + onPressed: actionRight,
86 + style: TextButton.styleFrom(
87 + backgroundColor: rightActionButtonColor ??
88 + Theme.of(context).accentTextTheme!
89 + .bodyText2!.backgroundColor!,
90 + shape: const RoundedRectangleBorder(
91 + borderRadius: BorderRadius.all(Radius.zero))),
92 + child: Text(
93 + rightActionButtonText,
94 + textAlign: TextAlign.center,
95 + style: TextStyle(
96 + fontSize: 15,
97 + fontFamily: 'Lato',
98 + fontWeight: FontWeight.w600,
99 + color: rightActionButtonTextColor ??
100 + Theme.of(context)
101 + .primaryTextTheme!
102 + .bodyText2!
103 + .backgroundColor!,
104 + decoration: TextDecoration.none,
105 + ),
106 + )),
107 + ),
108 + ],
109 + ));
110 }
111
112 @override
lib/view_model/ionia/ionia_purchase_merch_view_model.dart
+4
@@ -7,6 +7,7 @@ import 'package:cake_wallet/ionia/ionia_anypay.dart';
7 import 'package:cake_wallet/ionia/ionia_merchant.dart';
8 import 'package:cake_wallet/ionia/ionia_tip.dart';
9 import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
10 +import 'package:cake_wallet/view_model/send/send_view_model.dart';
11
12 part 'ionia_purchase_merch_view_model.g.dart';
13
@@ -17,6 +18,7 @@ abstract class IoniaMerchPurchaseViewModelBase with Store {
18 required this.ioniaAnyPayService,
19 required this.amount,
20 required this.ioniaMerchant,
21 + required this.sendViewModel,
22 }) : tipAmount = 0.0,
23 percentage = 0.0,
24 invoiceCreationState = InitialExecutionState(),
@@ -40,6 +42,8 @@ abstract class IoniaMerchPurchaseViewModelBase with Store {
42
43 final IoniaMerchant ioniaMerchant;
44
45 + final SendViewModel sendViewModel;
46 +
47 final IoniaAnyPay ioniaAnyPayService;
48
49 IoniaAnyPayPaymentInfo? paymentInfo;