Merge redesign part 2.
M committed
Sep 2, 2020 at 11:47 UTC
9074bee6db574c12b241617fe95c928f88c8b7f9
6 files changed
+570
-440
lib/src/screens/send/send_page.dart
+17
-7
@@ -95,16 +95,26 @@ class SendPage extends BasePage {
95
// }
96
}
97
98
- @override
99
- Widget body(BuildContext context) {
100
- return super.build(context);
101
- }
102
-
98
// @override
104
- // Widget build(BuildContext context) {
105
- // return BaseSendWidget(sendViewModel: sendViewModel);
99
+ // Widget body(BuildContext context) {
100
+ // return super.build(context);
101
// }
102
103
+ @override
104
+ Widget body(BuildContext context) => BaseSendWidget(
105
+ sendViewModel: sendViewModel,
106
+ leading: leading(context),
107
+ middle: middle(context),
108
+ );
109
+
110
+ @override
111
+ Widget build(BuildContext context) {
112
+ return Scaffold(
113
+ resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
114
+ body: Container(
115
+ color: Theme.of(context).backgroundColor, child: body(context)));
116
+ }
117
+
118
// @override
119
// Widget build(BuildContext context) {
120
// _setEffects(context);
lib/src/screens/send/send_template_page.dart
+10
-15
@@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart';
2
import 'package:flutter/material.dart';
3
import 'package:cake_wallet/src/screens/base_page.dart';
4
import 'package:cake_wallet/generated/i18n.dart';
5
-import 'package:cake_wallet/view_model/send_view_model.dart';
5
+import 'package:cake_wallet/view_model/send/send_view_model.dart';
6
import 'package:cake_wallet/src/screens/send/widgets/base_send_widget.dart';
7
8
class SendTemplatePage extends BasePage {
@@ -26,22 +26,17 @@ class SendTemplatePage extends BasePage {
26
bool get resizeToAvoidBottomPadding => false;
27
28
@override
29
- Widget body(BuildContext context) =>
30
- BaseSendWidget(
31
- sendViewModel: sendViewModel,
32
- leading: leading(context),
33
- middle: middle(context),
34
- isTemplate: true
35
- );
29
+ Widget body(BuildContext context) => BaseSendWidget(
30
+ sendViewModel: sendViewModel,
31
+ leading: leading(context),
32
+ middle: middle(context),
33
+ isTemplate: true);
34
35
@override
36
Widget build(BuildContext context) {
37
return Scaffold(
40
- resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
41
- body: Container(
42
- color: Theme.of(context).backgroundColor,
43
- child: body(context)
44
- )
45
- );
38
+ resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
39
+ body: Container(
40
+ color: Theme.of(context).backgroundColor, child: body(context)));
41
}
47
-}
\ No newline at end of file
42
+}
lib/src/screens/send/widgets/base_send_widget.dart
+485
-384
@@ -1,10 +1,12 @@
1
+import 'dart:ui';
2
import 'package:cake_wallet/src/domain/common/transaction_priority.dart';
3
import 'package:cake_wallet/src/widgets/picker.dart';
4
import 'package:cake_wallet/src/widgets/primary_button.dart';
5
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
6
+import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
7
import 'package:flutter/cupertino.dart';
8
import 'package:flutter/material.dart';
7
-import 'package:cake_wallet/view_model/send_view_model.dart';
9
+import 'package:cake_wallet/view_model/send/send_view_model.dart';
10
import 'package:flutter/services.dart';
11
import 'package:flutter_mobx/flutter_mobx.dart';
12
import 'package:mobx/mobx.dart';
@@ -22,12 +24,11 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
24
import 'package:cake_wallet/routes.dart';
25
26
class BaseSendWidget extends StatelessWidget {
25
- BaseSendWidget({
26
- @required this.sendViewModel,
27
- @required this.leading,
28
- @required this.middle,
29
- this.isTemplate = false
30
- });
27
+ BaseSendWidget(
28
+ {@required this.sendViewModel,
29
+ @required this.leading,
30
+ @required this.middle,
31
+ this.isTemplate = false});
32
33
final SendViewModel sendViewModel;
34
final bool isTemplate;
@@ -45,7 +46,6 @@ class BaseSendWidget extends StatelessWidget {
46
47
@override
48
Widget build(BuildContext context) {
48
-
49
_setEffects(context);
50
51
return ScrollableWithBottomSection(
@@ -57,9 +57,7 @@ class BaseSendWidget extends StatelessWidget {
57
gradient: LinearGradient(colors: [
58
Theme.of(context).primaryTextTheme.subhead.color,
59
Theme.of(context).primaryTextTheme.subhead.decorationColor,
60
- ],
61
- begin: Alignment.topLeft,
62
- end: Alignment.bottomRight),
60
+ ], begin: Alignment.topLeft, end: Alignment.bottomRight),
61
widget: Form(
62
key: _formKey,
63
child: Column(children: <Widget>[
@@ -74,28 +72,34 @@ class BaseSendWidget extends StatelessWidget {
72
child: Column(
73
children: <Widget>[
74
isTemplate
77
- ? BaseTextFormField(
78
- controller: _nameController,
79
- hintText: S.of(context).send_name,
80
- borderColor: Theme.of(context).primaryTextTheme.headline.color,
81
- textStyle: TextStyle(
82
- fontSize: 14,
83
- fontWeight: FontWeight.w500,
84
- color: Colors.white
85
- ),
86
- placeholderTextStyle: TextStyle(
87
- color: Theme.of(context).primaryTextTheme.headline.decorationColor,
88
- fontWeight: FontWeight.w500,
89
- fontSize: 14),
90
- validator: sendViewModel.templateValidator,
91
- )
92
- : Offstage(),
75
+ ? BaseTextFormField(
76
+ controller: _nameController,
77
+ hintText: S.of(context).send_name,
78
+ borderColor: Theme.of(context)
79
+ .primaryTextTheme
80
+ .headline
81
+ .color,
82
+ textStyle: TextStyle(
83
+ fontSize: 14,
84
+ fontWeight: FontWeight.w500,
85
+ color: Colors.white),
86
+ placeholderTextStyle: TextStyle(
87
+ color: Theme.of(context)
88
+ .primaryTextTheme
89
+ .headline
90
+ .decorationColor,
91
+ fontWeight: FontWeight.w500,
92
+ fontSize: 14),
93
+ validator: sendViewModel.templateValidator,
94
+ )
95
+ : Offstage(),
96
Padding(
97
padding: EdgeInsets.only(top: isTemplate ? 20 : 0),
98
child: AddressTextField(
99
controller: _addressController,
97
- placeholder: S.of(context).send_address(
98
- sendViewModel.cryptoCurrencyTitle),
100
+ // placeholder: S
101
+ // .of(context)
102
+ // .send_address(sendViewModel.cryptoCurrencyTitle),
103
focusNode: _focusNode,
104
onURIScanned: (uri) {
105
var address = '';
@@ -116,113 +120,127 @@ class BaseSendWidget extends StatelessWidget {
120
AddressTextFieldOption.qrCode,
121
AddressTextFieldOption.addressBook
122
],
119
- buttonColor: Theme.of(context).primaryTextTheme.display1.color,
120
- borderColor: Theme.of(context).primaryTextTheme.headline.color,
123
+ buttonColor:
124
+ Theme.of(context).primaryTextTheme.display1.color,
125
+ borderColor:
126
+ Theme.of(context).primaryTextTheme.headline.color,
127
textStyle: TextStyle(
128
fontSize: 14,
129
fontWeight: FontWeight.w500,
124
- color: Colors.white
125
- ),
130
+ color: Colors.white),
131
hintStyle: TextStyle(
132
fontSize: 14,
133
fontWeight: FontWeight.w500,
129
- color: Theme.of(context).primaryTextTheme.headline.decorationColor
130
- ),
134
+ color: Theme.of(context)
135
+ .primaryTextTheme
136
+ .headline
137
+ .decorationColor),
138
validator: sendViewModel.addressValidator,
139
),
140
),
134
- Observer(
135
- builder: (_) {
136
- return Padding(
137
- padding: const EdgeInsets.only(top: 20),
138
- child: BaseTextFormField(
139
- controller: _cryptoAmountController,
140
- keyboardType: TextInputType.numberWithOptions(
141
- signed: false, decimal: true),
142
- inputFormatters: [
143
- BlacklistingTextInputFormatter(
144
- RegExp('[\\-|\\ |\\,]'))
145
- ],
146
- prefixIcon: Padding(
147
- padding: EdgeInsets.only(top: 9),
148
- child: Text(sendViewModel.currency.title + ':',
141
+ Observer(builder: (_) {
142
+ return Padding(
143
+ padding: const EdgeInsets.only(top: 20),
144
+ child: BaseTextFormField(
145
+ controller: _cryptoAmountController,
146
+ keyboardType: TextInputType.numberWithOptions(
147
+ signed: false, decimal: true),
148
+ inputFormatters: [
149
+ BlacklistingTextInputFormatter(
150
+ RegExp('[\\-|\\ |\\,]'))
151
+ ],
152
+ prefixIcon: Padding(
153
+ padding: EdgeInsets.only(top: 9),
154
+ child:
155
+ Text(sendViewModel.currency.title + ':',
156
style: TextStyle(
157
fontSize: 16,
158
fontWeight: FontWeight.w600,
159
color: Colors.white,
160
)),
154
- ),
155
- suffixIcon: isTemplate
161
+ ),
162
+ suffixIcon: isTemplate
163
? Offstage()
164
: Container(
158
- height: 32,
159
- width: 32,
160
- margin: EdgeInsets.only(left: 14, top: 4, bottom: 10),
161
- decoration: BoxDecoration(
162
- color: Theme.of(context).primaryTextTheme.display1.color,
163
- borderRadius: BorderRadius.all(Radius.circular(6))
164
- ),
165
- child: InkWell(
166
- onTap: () => sendViewModel.setSendAll(),
167
- child: Center(
168
- child: Text(S.of(context).all,
169
- textAlign: TextAlign.center,
170
- style: TextStyle(
171
- fontSize: 12,
172
- fontWeight: FontWeight.bold,
173
- color: Theme.of(context).primaryTextTheme.display1.decorationColor
174
- )
165
+ height: 32,
166
+ width: 32,
167
+ margin: EdgeInsets.only(
168
+ left: 14, top: 4, bottom: 10),
169
+ decoration: BoxDecoration(
170
+ color: Theme.of(context)
171
+ .primaryTextTheme
172
+ .display1
173
+ .color,
174
+ borderRadius: BorderRadius.all(
175
+ Radius.circular(6))),
176
+ child: InkWell(
177
+ onTap: () =>
178
+ sendViewModel.setSendAll(),
179
+ child: Center(
180
+ child: Text(S.of(context).all,
181
+ textAlign: TextAlign.center,
182
+ style: TextStyle(
183
+ fontSize: 12,
184
+ fontWeight: FontWeight.bold,
185
+ color: Theme.of(context)
186
+ .primaryTextTheme
187
+ .display1
188
+ .decorationColor)),
189
),
190
),
191
),
178
- ),
179
- hintText: '0.0000',
180
- borderColor: Theme.of(context).primaryTextTheme.headline.color,
181
- textStyle: TextStyle(
182
- fontSize: 14,
183
- fontWeight: FontWeight.w500,
184
- color: Colors.white
185
- ),
186
- placeholderTextStyle: TextStyle(
187
- color: Theme.of(context).primaryTextTheme.headline.decorationColor,
188
- fontWeight: FontWeight.w500,
189
- fontSize: 14),
190
- validator: sendViewModel.amountValidator
191
- )
192
- );
193
- }
194
- ),
192
+ hintText: '0.0000',
193
+ borderColor: Theme.of(context)
194
+ .primaryTextTheme
195
+ .headline
196
+ .color,
197
+ textStyle: TextStyle(
198
+ fontSize: 14,
199
+ fontWeight: FontWeight.w500,
200
+ color: Colors.white),
201
+ placeholderTextStyle: TextStyle(
202
+ color: Theme.of(context)
203
+ .primaryTextTheme
204
+ .headline
205
+ .decorationColor,
206
+ fontWeight: FontWeight.w500,
207
+ fontSize: 14),
208
+ validator: sendViewModel.amountValidator));
209
+ }),
210
isTemplate
196
- ? Offstage()
197
- : Observer(
198
- builder: (_) => Padding(
199
- padding: EdgeInsets.only(top: 10),
200
- child: Row(
201
- mainAxisSize: MainAxisSize.max,
202
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
203
- children: <Widget>[
204
- Expanded(
205
- child: Text(
206
- S.of(context).available_balance + ':',
207
- style: TextStyle(
208
- fontSize: 12,
209
- fontWeight: FontWeight.w600,
210
- color: Theme.of(context).primaryTextTheme.headline.decorationColor
211
- ),
212
- )
213
- ),
214
- Text(
215
- sendViewModel.balance,
216
- style: TextStyle(
217
- fontSize: 12,
218
- fontWeight: FontWeight.w600,
219
- color: Theme.of(context).primaryTextTheme.headline.decorationColor
220
- ),
221
- )
222
- ],
223
- ),
224
- )
225
- ),
211
+ ? Offstage()
212
+ : Observer(
213
+ builder: (_) => Padding(
214
+ padding: EdgeInsets.only(top: 10),
215
+ child: Row(
216
+ mainAxisSize: MainAxisSize.max,
217
+ mainAxisAlignment:
218
+ MainAxisAlignment.spaceBetween,
219
+ children: <Widget>[
220
+ Expanded(
221
+ child: Text(
222
+ S.of(context).available_balance + ':',
223
+ style: TextStyle(
224
+ fontSize: 12,
225
+ fontWeight: FontWeight.w600,
226
+ color: Theme.of(context)
227
+ .primaryTextTheme
228
+ .headline
229
+ .decorationColor),
230
+ )),
231
+ Text(
232
+ sendViewModel.balance,
233
+ style: TextStyle(
234
+ fontSize: 12,
235
+ fontWeight: FontWeight.w600,
236
+ color: Theme.of(context)
237
+ .primaryTextTheme
238
+ .headline
239
+ .decorationColor),
240
+ )
241
+ ],
242
+ ),
243
+ )),
244
Padding(
245
padding: const EdgeInsets.only(top: 20),
246
child: BaseTextFormField(
@@ -235,8 +253,7 @@ class BaseSendWidget extends StatelessWidget {
253
],
254
prefixIcon: Padding(
255
padding: EdgeInsets.only(top: 9),
238
- child: Text(
239
- sendViewModel.fiat.title + ':',
256
+ child: Text(sendViewModel.fiat.title + ':',
257
style: TextStyle(
258
fontSize: 16,
259
fontWeight: FontWeight.w600,
@@ -244,62 +261,71 @@ class BaseSendWidget extends StatelessWidget {
261
)),
262
),
263
hintText: '0.00',
247
- borderColor: Theme.of(context).primaryTextTheme.headline.color,
264
+ borderColor: Theme.of(context)
265
+ .primaryTextTheme
266
+ .headline
267
+ .color,
268
textStyle: TextStyle(
269
fontSize: 14,
270
fontWeight: FontWeight.w500,
251
- color: Colors.white
252
- ),
271
+ color: Colors.white),
272
placeholderTextStyle: TextStyle(
254
- color: Theme.of(context).primaryTextTheme.headline.decorationColor,
273
+ color: Theme.of(context)
274
+ .primaryTextTheme
275
+ .headline
276
+ .decorationColor,
277
fontWeight: FontWeight.w500,
278
fontSize: 14),
257
- )
258
- ),
279
+ )),
280
isTemplate
260
- ? Offstage()
261
- : Observer(
262
- builder: (_) => GestureDetector(
263
- onTap: () => _setTransactionPriority(context),
264
- child: Container(
265
- padding: EdgeInsets.only(top: 24),
266
- child: Row(
267
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
268
- children: <Widget>[
269
- Text(S.of(context).send_estimated_fee,
270
- style: TextStyle(
271
- fontSize: 12,
272
- fontWeight: FontWeight.w500,
273
- //color: Theme.of(context).primaryTextTheme.display2.color,
274
- color: Colors.white
275
- )),
276
- Container(
277
- child: Row(
278
- children: <Widget>[
279
- Text(
280
- sendViewModel.estimatedFee.toString() + ' '
281
- + sendViewModel.currency.title,
282
- style: TextStyle(
283
- fontSize: 12,
284
- fontWeight: FontWeight.w600,
285
- //color: Theme.of(context).primaryTextTheme.display2.color,
286
- color: Colors.white
287
- )),
288
- Padding(
289
- padding: EdgeInsets.only(left: 5),
290
- child: Icon(
291
- Icons.arrow_forward_ios,
292
- size: 12,
293
- color: Colors.white,),
294
- )
295
- ],
281
+ ? Offstage()
282
+ : Observer(
283
+ builder: (_) => GestureDetector(
284
+ onTap: () =>
285
+ _setTransactionPriority(context),
286
+ child: Container(
287
+ padding: EdgeInsets.only(top: 24),
288
+ child: Row(
289
+ mainAxisAlignment:
290
+ MainAxisAlignment.spaceBetween,
291
+ children: <Widget>[
292
+ Text(S.of(context).send_estimated_fee,
293
+ style: TextStyle(
294
+ fontSize: 12,
295
+ fontWeight: FontWeight.w500,
296
+ //color: Theme.of(context).primaryTextTheme.display2.color,
297
+ color: Colors.white)),
298
+ Container(
299
+ child: Row(
300
+ children: <Widget>[
301
+ Text(
302
+ sendViewModel.estimatedFee
303
+ .toString() +
304
+ ' ' +
305
+ sendViewModel
306
+ .currency.title,
307
+ style: TextStyle(
308
+ fontSize: 12,
309
+ fontWeight:
310
+ FontWeight.w600,
311
+ //color: Theme.of(context).primaryTextTheme.display2.color,
312
+ color: Colors.white)),
313
+ Padding(
314
+ padding:
315
+ EdgeInsets.only(left: 5),
316
+ child: Icon(
317
+ Icons.arrow_forward_ios,
318
+ size: 12,
319
+ color: Colors.white,
320
+ ),
321
+ )
322
+ ],
323
+ ),
324
+ )
325
+ ],
326
+ ),
327
),
297
- )
298
- ],
299
- ),
300
- ),
301
- )
302
- )
328
+ ))
329
],
330
),
331
)
@@ -307,156 +333,158 @@ class BaseSendWidget extends StatelessWidget {
333
),
334
),
335
isTemplate
310
- ? Offstage()
311
- : Padding(
312
- padding: EdgeInsets.only(
313
- top: 30,
314
- left: 24,
315
- bottom: 24
316
- ),
317
- child: Row(
318
- mainAxisAlignment: MainAxisAlignment.start,
319
- children: <Widget>[
320
- Text(
321
- S.of(context).send_templates,
322
- style: TextStyle(
323
- fontSize: 18,
324
- fontWeight: FontWeight.w600,
325
- color: Theme.of(context).primaryTextTheme.display4.color
336
+ ? Offstage()
337
+ : Padding(
338
+ padding: EdgeInsets.only(top: 30, left: 24, bottom: 24),
339
+ child: Row(
340
+ mainAxisAlignment: MainAxisAlignment.start,
341
+ children: <Widget>[
342
+ Text(
343
+ S.of(context).send_templates,
344
+ style: TextStyle(
345
+ fontSize: 18,
346
+ fontWeight: FontWeight.w600,
347
+ color: Theme.of(context)
348
+ .primaryTextTheme
349
+ .display4
350
+ .color),
351
+ )
352
+ ],
353
),
327
- )
328
- ],
329
- ),
330
- ),
354
+ ),
355
isTemplate
332
- ? Offstage()
333
- : Container(
334
- height: 40,
335
- width: double.infinity,
336
- padding: EdgeInsets.only(left: 24),
337
- child: SingleChildScrollView(
338
- scrollDirection: Axis.horizontal,
339
- child: Row(
340
- children: <Widget>[
341
- GestureDetector(
342
- onTap: () => Navigator.of(context)
343
- .pushNamed(Routes.sendTemplate),
344
- child: Container(
345
- padding: EdgeInsets.only(left: 1, right: 10),
346
- child: DottedBorder(
347
- borderType: BorderType.RRect,
348
- dashPattern: [6, 4],
349
- color: Theme.of(context).primaryTextTheme.display2.decorationColor,
350
- strokeWidth: 2,
351
- radius: Radius.circular(20),
356
+ ? Offstage()
357
+ : Container(
358
+ height: 40,
359
+ width: double.infinity,
360
+ padding: EdgeInsets.only(left: 24),
361
+ child: SingleChildScrollView(
362
+ scrollDirection: Axis.horizontal,
363
+ child: Row(
364
+ children: <Widget>[
365
+ GestureDetector(
366
+ onTap: () => Navigator.of(context)
367
+ .pushNamed(Routes.sendTemplate),
368
child: Container(
353
- height: 34,
354
- width: 75,
355
- padding: EdgeInsets.only(left: 10, right: 10),
356
- alignment: Alignment.center,
357
- decoration: BoxDecoration(
358
- borderRadius: BorderRadius.all(Radius.circular(20)),
359
- color: Colors.transparent,
360
- ),
361
- child: Text(
362
- S.of(context).send_new,
363
- style: TextStyle(
364
- fontSize: 14,
365
- fontWeight: FontWeight.w600,
366
- color: Theme.of(context).primaryTextTheme.display3.color
367
- ),
368
- ),
369
- )
370
- ),
371
- ),
372
- ),
373
- Observer(
374
- builder: (_) {
375
- final templates = sendViewModel.templates;
376
- final itemCount = templates.length;
369
+ padding: EdgeInsets.only(left: 1, right: 10),
370
+ child: DottedBorder(
371
+ borderType: BorderType.RRect,
372
+ dashPattern: [6, 4],
373
+ color: Theme.of(context)
374
+ .primaryTextTheme
375
+ .display2
376
+ .decorationColor,
377
+ strokeWidth: 2,
378
+ radius: Radius.circular(20),
379
+ child: Container(
380
+ height: 34,
381
+ width: 75,
382
+ padding: EdgeInsets.only(left: 10, right: 10),
383
+ alignment: Alignment.center,
384
+ decoration: BoxDecoration(
385
+ borderRadius:
386
+ BorderRadius.all(Radius.circular(20)),
387
+ color: Colors.transparent,
388
+ ),
389
+ child: Text(
390
+ S.of(context).send_new,
391
+ style: TextStyle(
392
+ fontSize: 14,
393
+ fontWeight: FontWeight.w600,
394
+ color: Theme.of(context)
395
+ .primaryTextTheme
396
+ .display3
397
+ .color),
398
+ ),
399
+ )),
400
+ ),
401
+ ),
402
+ // Observer(
403
+ // builder: (_) {
404
+ // final templates = sendViewModel.templates;
405
+ // final itemCount = templates.length;
406
378
- return ListView.builder(
379
- scrollDirection: Axis.horizontal,
380
- shrinkWrap: true,
381
- physics: NeverScrollableScrollPhysics(),
382
- itemCount: itemCount,
383
- itemBuilder: (context, index) {
384
- final template = templates[index];
407
+ // return ListView.builder(
408
+ // scrollDirection: Axis.horizontal,
409
+ // shrinkWrap: true,
410
+ // physics: NeverScrollableScrollPhysics(),
411
+ // itemCount: itemCount,
412
+ // itemBuilder: (context, index) {
413
+ // final template = templates[index];
414
386
- return TemplateTile(
387
- key: UniqueKey(),
388
- to: template.name,
389
- amount: template.amount,
390
- from: template.cryptoCurrency,
391
- onTap: () {
392
- _addressController.text = template.address;
393
- _cryptoAmountController.text = template.amount;
394
- getOpenaliasRecord(context);
395
- },
396
- onRemove: () {
397
- showDialog<void>(
398
- context: context,
399
- builder: (dialogContext) {
400
- return AlertWithTwoActions(
401
- alertTitle: S.of(context).template,
402
- alertContent: S.of(context).confirm_delete_template,
403
- leftButtonText: S.of(context).delete,
404
- rightButtonText: S.of(context).cancel,
405
- actionLeftButton: () {
406
- Navigator.of(dialogContext).pop();
407
- sendViewModel.sendTemplateStore.remove(template: template);
408
- sendViewModel.sendTemplateStore.update();
409
- },
410
- actionRightButton: () => Navigator.of(dialogContext).pop()
411
- );
412
- }
413
- );
414
- },
415
- );
416
- }
417
- );
418
- }
419
- )
420
- ],
421
- ),
422
- ),
423
- )
415
+ // return TemplateTile(
416
+ // key: UniqueKey(),
417
+ // to: template.name,
418
+ // amount: template.amount,
419
+ // from: template.cryptoCurrency,
420
+ // onTap: () {
421
+ // _addressController.text = template.address;
422
+ // _cryptoAmountController.text = template.amount;
423
+ // getOpenaliasRecord(context);
424
+ // },
425
+ // onRemove: () {
426
+ // showDialog<void>(
427
+ // context: context,
428
+ // builder: (dialogContext) {
429
+ // return AlertWithTwoActions(
430
+ // alertTitle: S.of(context).template,
431
+ // alertContent: S.of(context).confirm_delete_template,
432
+ // leftButtonText: S.of(context).delete,
433
+ // rightButtonText: S.of(context).cancel,
434
+ // actionLeftButton: () {
435
+ // Navigator.of(dialogContext).pop();
436
+ // sendViewModel.sendTemplateStore.remove(template: template);
437
+ // sendViewModel.sendTemplateStore.update();
438
+ // },
439
+ // actionRightButton: () => Navigator.of(dialogContext).pop()
440
+ // );
441
+ // }
442
+ // );
443
+ // },
444
+ // );
445
+ // }
446
+ // );
447
+ // }
448
+ // )
449
+ ],
450
+ ),
451
+ ),
452
+ )
453
],
454
),
455
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
456
bottomSection: isTemplate
457
? PrimaryButton(
429
- onPressed: () {
430
- if (_formKey.currentState.validate()) {
431
- sendViewModel.sendTemplateStore.addTemplate(
432
- name: _nameController.text,
433
- address: _addressController.text,
434
- cryptoCurrency: sendViewModel.currency.title,
435
- amount: _cryptoAmountController.text
436
- );
437
- sendViewModel.sendTemplateStore.update();
438
- Navigator.of(context).pop();
439
- }
440
- },
441
- text: S.of(context).save,
442
- color: Colors.green,
443
- textColor: Colors.white)
458
+ onPressed: () {
459
+ if (_formKey.currentState.validate()) {
460
+ // sendViewModel.sendTemplateStore.addTemplate(
461
+ // name: _nameController.text,
462
+ // address: _addressController.text,
463
+ // cryptoCurrency: sendViewModel.currency.title,
464
+ // amount: _cryptoAmountController.text);
465
+ // sendViewModel.sendTemplateStore.update();
466
+ Navigator.of(context).pop();
467
+ }
468
+ },
469
+ text: S.of(context).save,
470
+ color: Colors.green,
471
+ textColor: Colors.white)
472
: Observer(builder: (_) {
445
- return LoadingPrimaryButton(
446
- onPressed: () {
447
- if (_formKey.currentState.validate()) {
448
- print('SENT!!!');
449
- }
450
- },
451
- text: S.of(context).send,
452
- color: Palette.blueCraiola,
453
- textColor: Colors.white,
454
- isLoading: sendViewModel.state is TransactionIsCreating ||
455
- sendViewModel.state is TransactionCommitting,
456
- isDisabled:
457
- false // FIXME !(syncStore.status is SyncedSyncStatus),
458
- );
459
- }),
473
+ return LoadingPrimaryButton(
474
+ onPressed: () {
475
+ if (_formKey.currentState.validate()) {
476
+ print('SENT!!!');
477
+ }
478
+ },
479
+ text: S.of(context).send,
480
+ color: Palette.blueCraiola,
481
+ textColor: Colors.white,
482
+ isLoading: sendViewModel.state is TransactionIsCreating ||
483
+ sendViewModel.state is TransactionCommitting,
484
+ isDisabled:
485
+ false // FIXME !(syncStore.status is SyncedSyncStatus),
486
+ );
487
+ }),
488
);
489
}
490
@@ -465,6 +493,13 @@ class BaseSendWidget extends StatelessWidget {
493
return;
494
}
495
496
+ reaction((_) => sendViewModel.sendAll, (bool all) {
497
+ if (all) {
498
+ _cryptoAmountController.text = S.current.all;
499
+ _fiatAmountController.text = null;
500
+ }
501
+ });
502
+
503
reaction((_) => sendViewModel.fiatAmount, (String amount) {
504
if (amount != _fiatAmountController.text) {
505
_fiatAmountController.text = amount;
@@ -472,6 +507,10 @@ class BaseSendWidget extends StatelessWidget {
507
});
508
509
reaction((_) => sendViewModel.cryptoAmount, (String amount) {
510
+ if (sendViewModel.sendAll && amount != S.current.all) {
511
+ sendViewModel.sendAll = false;
512
+ }
513
+
514
if (amount != _cryptoAmountController.text) {
515
_cryptoAmountController.text = amount;
516
}
@@ -487,29 +526,7 @@ class BaseSendWidget extends StatelessWidget {
526
final address = _addressController.text;
527
528
if (sendViewModel.address != address) {
490
- sendViewModel.changeAddress(address);
491
- }
492
- });
493
-
494
- _fiatAmountController.addListener(() {
495
- final fiatAmount = _fiatAmountController.text;
496
-
497
- if (sendViewModel.fiatAmount != fiatAmount) {
498
- sendViewModel.changeFiatAmount(fiatAmount);
499
- }
500
- });
501
-
502
- _cryptoAmountController.addListener(() {
503
- final cryptoAmount = _cryptoAmountController.text;
504
-
505
- if (sendViewModel.cryptoAmount != cryptoAmount) {
506
- sendViewModel.changeCryptoAmount(cryptoAmount);
507
- }
508
- });
509
-
510
- _focusNode.addListener(() {
511
- if (!_focusNode.hasFocus && _addressController.text.isNotEmpty) {
512
- getOpenaliasRecord(context);
529
+ sendViewModel.address = address;
530
}
531
});
532
@@ -519,44 +536,126 @@ class BaseSendWidget extends StatelessWidget {
536
showDialog<void>(
537
context: context,
538
builder: (BuildContext context) {
522
- return AlertDialog(
523
- title: Text(S.of(context).error),
524
- content: Text(state.error),
525
- actions: <Widget>[
526
- FlatButton(
527
- child: Text(S.of(context).ok),
528
- onPressed: () => Navigator.of(context).pop())
529
- ],
530
- );
539
+ return AlertWithOneAction(
540
+ alertTitle: S.of(context).error,
541
+ alertContent: state.error,
542
+ buttonText: S.of(context).ok,
543
+ buttonAction: () => Navigator.of(context).pop());
544
});
545
});
546
}
547
548
if (state is TransactionCreatedSuccessfully) {
536
-// WidgetsBinding.instance.addPostFrameCallback((_) {
537
-// showDialog<void>(
538
-// context: context,
539
-// builder: (BuildContext context) {
540
-// return ConfirmSendingAlert(
541
-// alertTitle: S.of(context).confirm_sending,
542
-// amount: S.of(context).send_amount,
543
-// amountValue: sendStore.pendingTransaction.amount,
544
-// fee: S.of(context).send_fee,
545
-// feeValue: sendStore.pendingTransaction.fee,
546
-// leftButtonText: S.of(context).ok,
547
-// rightButtonText: S.of(context).cancel,
548
-// actionLeftButton: () {
549
-// Navigator.of(context).pop();
550
-// sendStore.commitTransaction();
551
-// showDialog<void>(
552
-// context: context,
553
-// builder: (BuildContext context) {
554
-// return SendingAlert(sendStore: sendStore);
555
-// });
556
-// },
557
-// actionRightButton: () => Navigator.of(context).pop());
558
-// });
559
-// });
549
+ WidgetsBinding.instance.addPostFrameCallback((_) {
550
+ showDialog<void>(
551
+ context: context,
552
+ builder: (BuildContext context) {
553
+ return ConfirmSendingAlert(
554
+ alertTitle: S.of(context).confirm_sending,
555
+ amount: S.of(context).send_amount,
556
+ amountValue:
557
+ sendViewModel.pendingTransaction.amountFormatted,
558
+ fee: S.of(context).send_fee,
559
+ feeValue: sendViewModel.pendingTransaction.feeFormatted,
560
+ leftButtonText: S.of(context).ok,
561
+ rightButtonText: S.of(context).cancel,
562
+ actionLeftButton: () {
563
+ Navigator.of(context).pop();
564
+ sendViewModel.commitTransaction();
565
+ showDialog<void>(
566
+ context: context,
567
+ builder: (BuildContext context) {
568
+ return Observer(builder: (_) {
569
+ final state = sendViewModel.state;
570
+
571
+ if (state is TransactionCommitted) {
572
+ return Stack(
573
+ children: <Widget>[
574
+ Container(
575
+ color: Theme.of(context).backgroundColor,
576
+ child: Center(
577
+ child: Image.asset(
578
+ 'assets/images/birthday_cake.png'),
579
+ ),
580
+ ),
581
+ Center(
582
+ child: Padding(
583
+ padding: EdgeInsets.only(
584
+ top: 220, left: 24, right: 24),
585
+ child: Text(
586
+ S.of(context).send_success,
587
+ textAlign: TextAlign.center,
588
+ style: TextStyle(
589
+ fontSize: 22,
590
+ fontWeight: FontWeight.bold,
591
+ color: Theme.of(context)
592
+ .primaryTextTheme
593
+ .title
594
+ .color,
595
+ decoration: TextDecoration.none,
596
+ ),
597
+ ),
598
+ ),
599
+ ),
600
+ Positioned(
601
+ left: 24,
602
+ right: 24,
603
+ bottom: 24,
604
+ child: PrimaryButton(
605
+ onPressed: () =>
606
+ Navigator.of(context).pop(),
607
+ text: S.of(context).send_got_it,
608
+ color: Colors.blue,
609
+ textColor: Colors.white))
610
+ ],
611
+ );
612
+ }
613
+
614
+ return Stack(
615
+ children: <Widget>[
616
+ Container(
617
+ color: Theme.of(context).backgroundColor,
618
+ child: Center(
619
+ child: Image.asset(
620
+ 'assets/images/birthday_cake.png'),
621
+ ),
622
+ ),
623
+ BackdropFilter(
624
+ filter: ImageFilter.blur(
625
+ sigmaX: 3.0, sigmaY: 3.0),
626
+ child: Container(
627
+ decoration: BoxDecoration(
628
+ color: Theme.of(context)
629
+ .backgroundColor
630
+ .withOpacity(0.25)),
631
+ child: Center(
632
+ child: Padding(
633
+ padding: EdgeInsets.only(top: 220),
634
+ child: Text(
635
+ S.of(context).send_sending,
636
+ textAlign: TextAlign.center,
637
+ style: TextStyle(
638
+ fontSize: 22,
639
+ fontWeight: FontWeight.bold,
640
+ color: Theme.of(context)
641
+ .primaryTextTheme
642
+ .title
643
+ .color,
644
+ decoration: TextDecoration.none,
645
+ ),
646
+ ),
647
+ ),
648
+ ),
649
+ ),
650
+ )
651
+ ],
652
+ );
653
+ });
654
+ });
655
+ },
656
+ actionRightButton: () => Navigator.of(context).pop());
657
+ });
658
+ });
659
}
660
661
if (state is TransactionCommitted) {
@@ -571,22 +670,24 @@ class BaseSendWidget extends StatelessWidget {
670
}
671
672
Future<void> getOpenaliasRecord(BuildContext context) async {
574
- final isOpenalias = await sendViewModel.isOpenaliasRecord(_addressController.text);
673
+ // final isOpenalias =
674
+ // await sendViewModel.isOpenaliasRecord(_addressController.text);
675
576
- if (isOpenalias) {
577
- _addressController.text = sendViewModel.recordAddress;
676
+ // if (isOpenalias) {
677
+ // _addressController.text = sendViewModel.recordAddress;
678
579
- await showDialog<void>(
580
- context: context,
581
- builder: (BuildContext context) {
582
- return AlertWithOneAction(
583
- alertTitle: S.of(context).openalias_alert_title,
584
- alertContent: S.of(context).openalias_alert_content(sendViewModel.recordName),
585
- buttonText: S.of(context).ok,
586
- buttonAction: () => Navigator.of(context).pop()
587
- );
588
- });
589
- }
679
+ // await showDialog<void>(
680
+ // context: context,
681
+ // builder: (BuildContext context) {
682
+ // return AlertWithOneAction(
683
+ // alertTitle: S.of(context).openalias_alert_title,
684
+ // alertContent: S
685
+ // .of(context)
686
+ // .openalias_alert_content(sendViewModel.recordName),
687
+ // buttonText: S.of(context).ok,
688
+ // buttonAction: () => Navigator.of(context).pop());
689
+ // });
690
+ // }
691
}
692
693
Future<void> _setTransactionPriority(BuildContext context) async {
@@ -595,14 +696,14 @@ class BaseSendWidget extends StatelessWidget {
696
697
await showDialog<void>(
698
builder: (_) => Picker(
598
- items: items,
599
- selectedAtIndex: selectedItem,
600
- title: S.of(context).please_select,
601
- mainAxisAlignment: MainAxisAlignment.center,
602
- onItemSelected: (TransactionPriority priority) =>
603
- sendViewModel.setTransactionPriority(priority),
604
- isAlwaysShowScrollThumb: true,
605
- ),
699
+ items: items,
700
+ selectedAtIndex: selectedItem,
701
+ title: S.of(context).please_select,
702
+ mainAxisAlignment: MainAxisAlignment.center,
703
+ onItemSelected: (TransactionPriority priority) => null,
704
+ // sendViewModel.setTransactionPriority(priority),
705
+ isAlwaysShowScrollThumb: true,
706
+ ),
707
context: context);
708
}
608
-}
\ No newline at end of file
709
+}
lib/store/settings_store.dart
+1
-1
@@ -138,7 +138,7 @@ abstract class SettingsStoreBase with Store {
138
sharedPreferences.getBool(shouldSaveRecipientAddressKey);
139
final allowBiometricalAuthentication =
140
sharedPreferences.getBool(allowBiometricalAuthenticationKey) ?? false;
141
- final savedDarkTheme = sharedPreferences.getBool(currentDarkTheme) ?? true;
141
+ final savedDarkTheme = sharedPreferences.getBool(currentDarkTheme) ?? false;
142
final actionListDisplayMode = ObservableList<ActionListDisplayMode>();
143
actionListDisplayMode.addAll(deserializeActionlistDisplayModes(
144
sharedPreferences.getInt(displayActionListModeKey) ??
lib/view_model/exchange/exchange_view_model.dart
+47
-26
@@ -1,5 +1,6 @@
1
import 'package:cake_wallet/core/wallet_base.dart';
2
import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
3
+import 'package:cake_wallet/src/domain/common/wallet_type.dart';
4
import 'package:cake_wallet/src/domain/exchange/exchange_provider.dart';
5
import 'package:cake_wallet/src/domain/exchange/limits.dart';
6
import 'package:cake_wallet/src/domain/exchange/trade.dart';
@@ -25,22 +26,18 @@ part 'exchange_view_model.g.dart';
26
class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel;
27
28
abstract class ExchangeViewModelBase with Store {
28
- ExchangeViewModelBase({
29
- this.wallet,
30
- this.trades,
31
- this.exchangeTemplateStore,
32
- this.tradesStore}) {
33
-
29
+ ExchangeViewModelBase(
30
+ {this.wallet,
31
+ this.trades,
32
+ this.exchangeTemplateStore,
33
+ this.tradesStore}) {
34
providerList = [
35
XMRTOExchangeProvider(),
36
ChangeNowExchangeProvider(),
37
MorphTokenExchangeProvider(trades: trades)
38
];
39
40
- provider = providerList[ 0 ];
41
-
42
- depositCurrency = CryptoCurrency.xmr;
43
- receiveCurrency = CryptoCurrency.btc;
40
+ _initialPairBasedOnWallet();
41
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
42
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
43
depositAmount = '';
@@ -50,6 +47,7 @@ abstract class ExchangeViewModelBase with Store {
47
limitsState = LimitsInitialState();
48
tradeState = ExchangeTradeStateInitial();
49
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12;
50
+ provider = providersForCurrentPair().first;
51
loadLimits();
52
}
53
@@ -140,8 +138,11 @@ abstract class ExchangeViewModelBase with Store {
138
139
provider
140
.calculateAmount(
143
- from: depositCurrency, to: receiveCurrency, amount: _amount)
144
- .then((amount) => _cryptoNumberFormat.format(amount).toString().replaceAll(RegExp("\\,"), ""))
141
+ from: depositCurrency, to: receiveCurrency, amount: _amount)
142
+ .then((amount) => _cryptoNumberFormat
143
+ .format(amount)
144
+ .toString()
145
+ .replaceAll(RegExp('\\,'), ''))
146
.then((amount) => depositAmount = amount);
147
}
148
@@ -158,8 +159,11 @@ abstract class ExchangeViewModelBase with Store {
159
final _amount = double.parse(amount);
160
provider
161
.calculateAmount(
161
- from: depositCurrency, to: receiveCurrency, amount: _amount)
162
- .then((amount) => _cryptoNumberFormat.format(amount).toString().replaceAll(RegExp("\\,"), ""))
162
+ from: depositCurrency, to: receiveCurrency, amount: _amount)
163
+ .then((amount) => _cryptoNumberFormat
164
+ .format(amount)
165
+ .toString()
166
+ .replaceAll(RegExp('\\,'), ''))
167
.then((amount) => receiveAmount = amount);
168
}
169
@@ -217,11 +221,13 @@ abstract class ExchangeViewModelBase with Store {
221
222
if (limitsState is LimitsLoadedSuccessfully && amount != null) {
223
if (double.parse(amount) < limits.min) {
220
- tradeState = TradeIsCreatedFailure(error: S.current.error_text_minimal_limit('${provider.description}',
221
- '${limits.min}', currency.toString()));
224
+ tradeState = TradeIsCreatedFailure(
225
+ error: S.current.error_text_minimal_limit('${provider.description}',
226
+ '${limits.min}', currency.toString()));
227
} else if (limits.max != null && double.parse(amount) > limits.max) {
223
- tradeState = TradeIsCreatedFailure(error: S.current.error_text_maximum_limit('${provider.description}',
224
- '${limits.max}', currency.toString()));
228
+ tradeState = TradeIsCreatedFailure(
229
+ error: S.current.error_text_maximum_limit('${provider.description}',
230
+ '${limits.max}', currency.toString()));
231
} else {
232
try {
233
tradeState = TradeIsCreating();
@@ -235,9 +241,10 @@ abstract class ExchangeViewModelBase with Store {
241
}
242
}
243
} else {
238
- tradeState = TradeIsCreatedFailure(error: S.current.error_text_limits_loading_failed('${provider.description}'));
244
+ tradeState = TradeIsCreatedFailure(
245
+ error: S.current
246
+ .error_text_limits_loading_failed('${provider.description}'));
247
}
240
-
248
}
249
250
@action
@@ -261,9 +268,9 @@ abstract class ExchangeViewModelBase with Store {
268
{CryptoCurrency from, CryptoCurrency to}) {
269
final providers = providerList
270
.where((provider) => provider.pairList
264
- .where((pair) =>
265
- pair.from == depositCurrency && pair.to == receiveCurrency)
266
- .isNotEmpty)
271
+ .where((pair) =>
272
+ pair.from == depositCurrency && pair.to == receiveCurrency)
273
+ .isNotEmpty)
274
.toList();
275
276
return providers;
@@ -272,12 +279,12 @@ abstract class ExchangeViewModelBase with Store {
279
void _onPairChange() {
280
final isPairExist = provider.pairList
281
.where((pair) =>
275
- pair.from == depositCurrency && pair.to == receiveCurrency)
282
+ pair.from == depositCurrency && pair.to == receiveCurrency)
283
.isNotEmpty;
284
285
if (!isPairExist) {
286
final provider =
280
- _providerForPair(from: depositCurrency, to: receiveCurrency);
287
+ _providerForPair(from: depositCurrency, to: receiveCurrency);
288
289
if (provider != null) {
290
changeProvider(provider: provider);
@@ -295,4 +302,18 @@ abstract class ExchangeViewModelBase with Store {
302
return providers.isNotEmpty ? providers[0] : null;
303
}
304
298
-}
\ No newline at end of file
305
+ void _initialPairBasedOnWallet() {
306
+ switch (wallet.type) {
307
+ case WalletType.monero:
308
+ depositCurrency = CryptoCurrency.xmr;
309
+ receiveCurrency = CryptoCurrency.btc;
310
+ break;
311
+ case WalletType.bitcoin:
312
+ depositCurrency = CryptoCurrency.btc;
313
+ receiveCurrency = CryptoCurrency.xmr;
314
+ break;
315
+ default:
316
+ break;
317
+ }
318
+ }
319
+}
lib/view_model/send/send_view_model.dart
+10
-7
@@ -1,7 +1,8 @@
1
-import 'package:cake_wallet/src/domain/common/calculate_fiat_amount.dart';
2
-import 'package:cake_wallet/store/dashboard/fiat_convertation_store.dart';
1
import 'package:intl/intl.dart';
2
import 'package:mobx/mobx.dart';
3
+import 'package:cake_wallet/core/template_validator.dart';
4
+import 'package:cake_wallet/src/domain/common/calculate_fiat_amount.dart';
5
+import 'package:cake_wallet/store/dashboard/fiat_convertation_store.dart';
6
import 'package:cake_wallet/core/address_validator.dart';
7
import 'package:cake_wallet/core/amount_validator.dart';
8
import 'package:cake_wallet/core/pending_transaction.dart';
@@ -28,7 +29,7 @@ abstract class SendViewModelBase with Store {
29
: state = InitialSendViewModelState(),
30
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12,
31
// FIXME: need to be based on wallet type.
31
- all = false;
32
+ sendAll = false;
33
34
@observable
35
SendViewModelState state;
@@ -43,7 +44,7 @@ abstract class SendViewModelBase with Store {
44
String address;
45
46
@observable
46
- bool all;
47
+ bool sendAll;
48
49
FiatCurrency get fiat => _settingsStore.fiatCurrency;
50
@@ -59,6 +60,8 @@ abstract class SendViewModelBase with Store {
60
61
Validator get addressValidator => AddressValidator(type: _wallet.currency);
62
63
+ Validator get templateValidator => TemplateValidator();
64
+
65
PendingTransaction pendingTransaction;
66
67
@computed
@@ -83,7 +86,7 @@ abstract class SendViewModelBase with Store {
86
final NumberFormat _cryptoNumberFormat;
87
88
@action
86
- void setAll() => all = true;
89
+ void setSendAll() => sendAll = true;
90
91
@action
92
void reset() {
@@ -118,7 +121,7 @@ abstract class SendViewModelBase with Store {
121
void setCryptoAmount(String amount) {
122
// FIXME: hardcoded value.
123
if (amount.toUpperCase() != 'ALL') {
121
- all = false;
124
+ sendAll = false;
125
}
126
127
cryptoAmount = amount;
@@ -162,7 +165,7 @@ abstract class SendViewModelBase with Store {
165
166
Object _credentials() {
167
final amount =
165
- !all ? double.parse(cryptoAmount.replaceAll(',', '.')) : null;
168
+ !sendAll ? double.parse(cryptoAmount.replaceAll(',', '.')) : null;
169
170
switch (_wallet.type) {
171
case WalletType.bitcoin: