dev
dart 189 lines 7.34 KB
Raw
1 import 'package:cake_wallet/src/widgets/trail_button.dart';
2 import 'package:cake_wallet/view_model/send/template_view_model.dart';
3 import 'package:flutter_mobx/flutter_mobx.dart';
4 import 'package:flutter/material.dart';
5 import 'package:cake_wallet/src/screens/base_page.dart';
6 import 'package:cake_wallet/generated/i18n.dart';
7 import 'package:cake_wallet/view_model/send/send_template_view_model.dart';
8 import 'package:cake_wallet/src/widgets/primary_button.dart';
9 import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart';
10 import 'package:cake_wallet/src/screens/send/widgets/send_template_card.dart';
11 import 'package:smooth_page_indicator/smooth_page_indicator.dart';
12
13 class SendTemplatePage extends BasePage {
14 SendTemplatePage({required this.sendTemplateViewModel});
15
16 final SendTemplateViewModel sendTemplateViewModel;
17 final _formKey = GlobalKey<FormState>();
18 final controller = PageController(initialPage: 0);
19
20 @override
21 String get title => S.current.exchange_new_template;
22
23 @override
24 bool get extendBodyBehindAppBar => true;
25
26 @override
27 bool get gradientAll => true;
28
29 @override
30 AppBarStyle get appBarStyle => AppBarStyle.transparent;
31
32 @override
33 Function(BuildContext)? get pushToNextWidget => (context) {
34 FocusScopeNode currentFocus = FocusScope.of(context);
35 if (!currentFocus.hasPrimaryFocus) {
36 currentFocus.focusedChild?.unfocus();
37 }
38 };
39
40 @override
41 Widget trailing(context) => Observer(
42 builder: (_) {
43 return sendTemplateViewModel.recipients.length > 1
44 ? TrailButton(
45 caption: S.of(context).remove,
46 onPressed: () {
47 int pageToJump = (controller.page?.round() ?? 0) - 1;
48 pageToJump = pageToJump > 0 ? pageToJump : 0;
49 final recipient = _defineCurrentRecipient();
50 sendTemplateViewModel.removeRecipient(recipient);
51 controller.jumpToPage(pageToJump);
52 },
53 )
54 : TrailButton(
55 caption: S.of(context).clear,
56 onPressed: () {
57 final recipient = _defineCurrentRecipient();
58 _formKey.currentState?.reset();
59 recipient.reset();
60 },
61 );
62 },
63 );
64
65 @override
66 Widget body(BuildContext context) {
67 return Form(
68 key: _formKey,
69 child: ScrollableWithBottomSection(
70 contentPadding: EdgeInsets.only(bottom: 24),
71 content: FocusTraversalGroup(
72 policy: OrderedTraversalPolicy(),
73 child: Column(
74 children: [
75 Container(
76 height: 460,
77 child: Observer(
78 builder: (_) {
79 return PageView.builder(
80 scrollDirection: Axis.horizontal,
81 controller: controller,
82 itemCount: sendTemplateViewModel.recipients.length,
83 itemBuilder: (_, index) {
84 final template = sendTemplateViewModel.recipients[index];
85 return SendTemplateCard(
86 template: template,
87 index: index,
88 sendTemplateViewModel: sendTemplateViewModel,
89 );
90 },
91 );
92 },
93 ),
94 ),
95 Padding(
96 padding: EdgeInsets.only(top: 10, left: 24, right: 24, bottom: 10),
97 child: Container(
98 height: 10,
99 child: Observer(
100 builder: (_) {
101 final count = sendTemplateViewModel.recipients.length;
102
103 return count > 1
104 ? Semantics(
105 button: false,
106 label: 'Page Indicator',
107 hint: 'Swipe to change receiver',
108 excludeSemantics: true,
109 child: SmoothPageIndicator(
110 controller: controller,
111 count: count,
112 effect: ScrollingDotsEffect(
113 spacing: 6.0,
114 radius: 6.0,
115 dotWidth: 6.0,
116 dotHeight: 6.0,
117 dotColor: Theme.of(context).colorScheme.outlineVariant,
118 activeDotColor: Theme.of(context).colorScheme.primary,
119 ),
120 ),
121 )
122 : Offstage();
123 },
124 ),
125 ),
126 ),
127 ],
128 ),
129 ),
130 bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
131 bottomSection: Column(
132 children: [
133 if (sendTemplateViewModel.hasMultiRecipient)
134 Padding(
135 padding: EdgeInsets.only(bottom: 12),
136 child: PrimaryButton(
137 onPressed: () {
138 sendTemplateViewModel.addRecipient();
139 Future.delayed(const Duration(milliseconds: 250), () {
140 controller.jumpToPage(sendTemplateViewModel.recipients.length - 1);
141 });
142 },
143 text: S.of(context).add_receiver,
144 color: Colors.transparent,
145 textColor: Theme.of(context).colorScheme.onSurfaceVariant,
146 isDottedBorder: true,
147 borderColor: Theme.of(context).colorScheme.surfaceContainerHighest,
148 ),
149 ),
150 PrimaryButton(
151 onPressed: () {
152 if (_formKey.currentState != null && _formKey.currentState!.validate()) {
153 final mainTemplate = sendTemplateViewModel.recipients[0];
154 final additionalRecipients = sendTemplateViewModel.recipients
155 .map((element) => element.toTemplate(
156 cryptoCurrency: element.selectedCurrency.title,
157 fiatCurrency: sendTemplateViewModel.fiatCurrency))
158 .toList();
159
160 sendTemplateViewModel.addTemplate(
161 isCurrencySelected: mainTemplate.isCryptoSelected,
162 name: mainTemplate.name,
163 address: mainTemplate.address,
164 cryptoCurrency: mainTemplate.selectedCurrency.title,
165 amount: mainTemplate.output.cryptoAmount,
166 amountFiat: mainTemplate.output.fiatAmount,
167 additionalRecipients: additionalRecipients,
168 );
169 Navigator.of(context).pop();
170 }
171 },
172 text: S.of(context).save,
173 color: Theme.of(context).colorScheme.primary,
174 textColor: Theme.of(context).colorScheme.onPrimary,
175 )
176 ],
177 ),
178 ),
179 );
180 }
181
182 TemplateViewModel _defineCurrentRecipient() {
183 if (controller.page == null) {
184 throw Exception('Controller page is null');
185 }
186 final itemCount = controller.page!.round();
187 return sendTemplateViewModel.recipients[itemCount];
188 }
189 }