From 9074bee6db574c12b241617fe95c928f88c8b7f9 Mon Sep 17 00:00:00 2001 From: M Date: Wed, 2 Sep 2020 11:47:41 +0300 Subject: [PATCH] Merge redesign part 2. --- lib/src/screens/send/send_page.dart | 24 +- lib/src/screens/send/send_template_page.dart | 25 +- .../send/widgets/base_send_widget.dart | 869 ++++++++++-------- lib/store/settings_store.dart | 2 +- .../exchange/exchange_view_model.dart | 73 +- lib/view_model/send/send_view_model.dart | 17 +- 6 files changed, 570 insertions(+), 440 deletions(-) diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 53ee495e6..187523de2 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -95,16 +95,26 @@ class SendPage extends BasePage { // } } - @override - Widget body(BuildContext context) { - return super.build(context); - } - // @override - // Widget build(BuildContext context) { - // return BaseSendWidget(sendViewModel: sendViewModel); + // Widget body(BuildContext context) { + // return super.build(context); // } + @override + Widget body(BuildContext context) => BaseSendWidget( + sendViewModel: sendViewModel, + leading: leading(context), + middle: middle(context), + ); + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomPadding: resizeToAvoidBottomPadding, + body: Container( + color: Theme.of(context).backgroundColor, child: body(context))); + } + // @override // Widget build(BuildContext context) { // _setEffects(context); diff --git a/lib/src/screens/send/send_template_page.dart b/lib/src/screens/send/send_template_page.dart index 1f49a3f9a..5487dc71e 100644 --- a/lib/src/screens/send/send_template_page.dart +++ b/lib/src/screens/send/send_template_page.dart @@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/view_model/send_view_model.dart'; +import 'package:cake_wallet/view_model/send/send_view_model.dart'; import 'package:cake_wallet/src/screens/send/widgets/base_send_widget.dart'; class SendTemplatePage extends BasePage { @@ -26,22 +26,17 @@ class SendTemplatePage extends BasePage { bool get resizeToAvoidBottomPadding => false; @override - Widget body(BuildContext context) => - BaseSendWidget( - sendViewModel: sendViewModel, - leading: leading(context), - middle: middle(context), - isTemplate: true - ); + Widget body(BuildContext context) => BaseSendWidget( + sendViewModel: sendViewModel, + leading: leading(context), + middle: middle(context), + isTemplate: true); @override Widget build(BuildContext context) { return Scaffold( - resizeToAvoidBottomPadding: resizeToAvoidBottomPadding, - body: Container( - color: Theme.of(context).backgroundColor, - child: body(context) - ) - ); + resizeToAvoidBottomPadding: resizeToAvoidBottomPadding, + body: Container( + color: Theme.of(context).backgroundColor, child: body(context))); } -} \ No newline at end of file +} diff --git a/lib/src/screens/send/widgets/base_send_widget.dart b/lib/src/screens/send/widgets/base_send_widget.dart index 94f970b95..bfbf3ae9a 100644 --- a/lib/src/screens/send/widgets/base_send_widget.dart +++ b/lib/src/screens/send/widgets/base_send_widget.dart @@ -1,10 +1,12 @@ +import 'dart:ui'; import 'package:cake_wallet/src/domain/common/transaction_priority.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; +import 'package:cake_wallet/view_model/send/send_view_model_state.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:cake_wallet/view_model/send_view_model.dart'; +import 'package:cake_wallet/view_model/send/send_view_model.dart'; import 'package:flutter/services.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:mobx/mobx.dart'; @@ -22,12 +24,11 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/routes.dart'; class BaseSendWidget extends StatelessWidget { - BaseSendWidget({ - @required this.sendViewModel, - @required this.leading, - @required this.middle, - this.isTemplate = false - }); + BaseSendWidget( + {@required this.sendViewModel, + @required this.leading, + @required this.middle, + this.isTemplate = false}); final SendViewModel sendViewModel; final bool isTemplate; @@ -45,7 +46,6 @@ class BaseSendWidget extends StatelessWidget { @override Widget build(BuildContext context) { - _setEffects(context); return ScrollableWithBottomSection( @@ -57,9 +57,7 @@ class BaseSendWidget extends StatelessWidget { gradient: LinearGradient(colors: [ Theme.of(context).primaryTextTheme.subhead.color, Theme.of(context).primaryTextTheme.subhead.decorationColor, - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight), + ], begin: Alignment.topLeft, end: Alignment.bottomRight), widget: Form( key: _formKey, child: Column(children: [ @@ -74,28 +72,34 @@ class BaseSendWidget extends StatelessWidget { child: Column( children: [ isTemplate - ? BaseTextFormField( - controller: _nameController, - hintText: S.of(context).send_name, - borderColor: Theme.of(context).primaryTextTheme.headline.color, - textStyle: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.white - ), - placeholderTextStyle: TextStyle( - color: Theme.of(context).primaryTextTheme.headline.decorationColor, - fontWeight: FontWeight.w500, - fontSize: 14), - validator: sendViewModel.templateValidator, - ) - : Offstage(), + ? BaseTextFormField( + controller: _nameController, + hintText: S.of(context).send_name, + borderColor: Theme.of(context) + .primaryTextTheme + .headline + .color, + textStyle: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.white), + placeholderTextStyle: TextStyle( + color: Theme.of(context) + .primaryTextTheme + .headline + .decorationColor, + fontWeight: FontWeight.w500, + fontSize: 14), + validator: sendViewModel.templateValidator, + ) + : Offstage(), Padding( padding: EdgeInsets.only(top: isTemplate ? 20 : 0), child: AddressTextField( controller: _addressController, - placeholder: S.of(context).send_address( - sendViewModel.cryptoCurrencyTitle), + // placeholder: S + // .of(context) + // .send_address(sendViewModel.cryptoCurrencyTitle), focusNode: _focusNode, onURIScanned: (uri) { var address = ''; @@ -116,113 +120,127 @@ class BaseSendWidget extends StatelessWidget { AddressTextFieldOption.qrCode, AddressTextFieldOption.addressBook ], - buttonColor: Theme.of(context).primaryTextTheme.display1.color, - borderColor: Theme.of(context).primaryTextTheme.headline.color, + buttonColor: + Theme.of(context).primaryTextTheme.display1.color, + borderColor: + Theme.of(context).primaryTextTheme.headline.color, textStyle: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, - color: Colors.white - ), + color: Colors.white), hintStyle: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, - color: Theme.of(context).primaryTextTheme.headline.decorationColor - ), + color: Theme.of(context) + .primaryTextTheme + .headline + .decorationColor), validator: sendViewModel.addressValidator, ), ), - Observer( - builder: (_) { - return Padding( - padding: const EdgeInsets.only(top: 20), - child: BaseTextFormField( - controller: _cryptoAmountController, - keyboardType: TextInputType.numberWithOptions( - signed: false, decimal: true), - inputFormatters: [ - BlacklistingTextInputFormatter( - RegExp('[\\-|\\ |\\,]')) - ], - prefixIcon: Padding( - padding: EdgeInsets.only(top: 9), - child: Text(sendViewModel.currency.title + ':', + Observer(builder: (_) { + return Padding( + padding: const EdgeInsets.only(top: 20), + child: BaseTextFormField( + controller: _cryptoAmountController, + keyboardType: TextInputType.numberWithOptions( + signed: false, decimal: true), + inputFormatters: [ + BlacklistingTextInputFormatter( + RegExp('[\\-|\\ |\\,]')) + ], + prefixIcon: Padding( + padding: EdgeInsets.only(top: 9), + child: + Text(sendViewModel.currency.title + ':', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, )), - ), - suffixIcon: isTemplate + ), + suffixIcon: isTemplate ? Offstage() : Container( - height: 32, - width: 32, - margin: EdgeInsets.only(left: 14, top: 4, bottom: 10), - decoration: BoxDecoration( - color: Theme.of(context).primaryTextTheme.display1.color, - borderRadius: BorderRadius.all(Radius.circular(6)) - ), - child: InkWell( - onTap: () => sendViewModel.setSendAll(), - child: Center( - child: Text(S.of(context).all, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Theme.of(context).primaryTextTheme.display1.decorationColor - ) + height: 32, + width: 32, + margin: EdgeInsets.only( + left: 14, top: 4, bottom: 10), + decoration: BoxDecoration( + color: Theme.of(context) + .primaryTextTheme + .display1 + .color, + borderRadius: BorderRadius.all( + Radius.circular(6))), + child: InkWell( + onTap: () => + sendViewModel.setSendAll(), + child: Center( + child: Text(S.of(context).all, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Theme.of(context) + .primaryTextTheme + .display1 + .decorationColor)), ), ), ), - ), - hintText: '0.0000', - borderColor: Theme.of(context).primaryTextTheme.headline.color, - textStyle: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.white - ), - placeholderTextStyle: TextStyle( - color: Theme.of(context).primaryTextTheme.headline.decorationColor, - fontWeight: FontWeight.w500, - fontSize: 14), - validator: sendViewModel.amountValidator - ) - ); - } - ), + hintText: '0.0000', + borderColor: Theme.of(context) + .primaryTextTheme + .headline + .color, + textStyle: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.white), + placeholderTextStyle: TextStyle( + color: Theme.of(context) + .primaryTextTheme + .headline + .decorationColor, + fontWeight: FontWeight.w500, + fontSize: 14), + validator: sendViewModel.amountValidator)); + }), isTemplate - ? Offstage() - : Observer( - builder: (_) => Padding( - padding: EdgeInsets.only(top: 10), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - S.of(context).available_balance + ':', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Theme.of(context).primaryTextTheme.headline.decorationColor - ), - ) - ), - Text( - sendViewModel.balance, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Theme.of(context).primaryTextTheme.headline.decorationColor - ), - ) - ], - ), - ) - ), + ? Offstage() + : Observer( + builder: (_) => Padding( + padding: EdgeInsets.only(top: 10), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + S.of(context).available_balance + ':', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .primaryTextTheme + .headline + .decorationColor), + )), + Text( + sendViewModel.balance, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .primaryTextTheme + .headline + .decorationColor), + ) + ], + ), + )), Padding( padding: const EdgeInsets.only(top: 20), child: BaseTextFormField( @@ -235,8 +253,7 @@ class BaseSendWidget extends StatelessWidget { ], prefixIcon: Padding( padding: EdgeInsets.only(top: 9), - child: Text( - sendViewModel.fiat.title + ':', + child: Text(sendViewModel.fiat.title + ':', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, @@ -244,62 +261,71 @@ class BaseSendWidget extends StatelessWidget { )), ), hintText: '0.00', - borderColor: Theme.of(context).primaryTextTheme.headline.color, + borderColor: Theme.of(context) + .primaryTextTheme + .headline + .color, textStyle: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, - color: Colors.white - ), + color: Colors.white), placeholderTextStyle: TextStyle( - color: Theme.of(context).primaryTextTheme.headline.decorationColor, + color: Theme.of(context) + .primaryTextTheme + .headline + .decorationColor, fontWeight: FontWeight.w500, fontSize: 14), - ) - ), + )), isTemplate - ? Offstage() - : Observer( - builder: (_) => GestureDetector( - onTap: () => _setTransactionPriority(context), - child: Container( - padding: EdgeInsets.only(top: 24), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(S.of(context).send_estimated_fee, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w500, - //color: Theme.of(context).primaryTextTheme.display2.color, - color: Colors.white - )), - Container( - child: Row( - children: [ - Text( - sendViewModel.estimatedFee.toString() + ' ' - + sendViewModel.currency.title, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - //color: Theme.of(context).primaryTextTheme.display2.color, - color: Colors.white - )), - Padding( - padding: EdgeInsets.only(left: 5), - child: Icon( - Icons.arrow_forward_ios, - size: 12, - color: Colors.white,), - ) - ], + ? Offstage() + : Observer( + builder: (_) => GestureDetector( + onTap: () => + _setTransactionPriority(context), + child: Container( + padding: EdgeInsets.only(top: 24), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text(S.of(context).send_estimated_fee, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + //color: Theme.of(context).primaryTextTheme.display2.color, + color: Colors.white)), + Container( + child: Row( + children: [ + Text( + sendViewModel.estimatedFee + .toString() + + ' ' + + sendViewModel + .currency.title, + style: TextStyle( + fontSize: 12, + fontWeight: + FontWeight.w600, + //color: Theme.of(context).primaryTextTheme.display2.color, + color: Colors.white)), + Padding( + padding: + EdgeInsets.only(left: 5), + child: Icon( + Icons.arrow_forward_ios, + size: 12, + color: Colors.white, + ), + ) + ], + ), + ) + ], + ), ), - ) - ], - ), - ), - ) - ) + )) ], ), ) @@ -307,156 +333,158 @@ class BaseSendWidget extends StatelessWidget { ), ), isTemplate - ? Offstage() - : Padding( - padding: EdgeInsets.only( - top: 30, - left: 24, - bottom: 24 - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - S.of(context).send_templates, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - color: Theme.of(context).primaryTextTheme.display4.color + ? Offstage() + : Padding( + padding: EdgeInsets.only(top: 30, left: 24, bottom: 24), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + S.of(context).send_templates, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .primaryTextTheme + .display4 + .color), + ) + ], ), - ) - ], - ), - ), + ), isTemplate - ? Offstage() - : Container( - height: 40, - width: double.infinity, - padding: EdgeInsets.only(left: 24), - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - GestureDetector( - onTap: () => Navigator.of(context) - .pushNamed(Routes.sendTemplate), - child: Container( - padding: EdgeInsets.only(left: 1, right: 10), - child: DottedBorder( - borderType: BorderType.RRect, - dashPattern: [6, 4], - color: Theme.of(context).primaryTextTheme.display2.decorationColor, - strokeWidth: 2, - radius: Radius.circular(20), + ? Offstage() + : Container( + height: 40, + width: double.infinity, + padding: EdgeInsets.only(left: 24), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + GestureDetector( + onTap: () => Navigator.of(context) + .pushNamed(Routes.sendTemplate), child: Container( - height: 34, - width: 75, - padding: EdgeInsets.only(left: 10, right: 10), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(20)), - color: Colors.transparent, - ), - child: Text( - S.of(context).send_new, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Theme.of(context).primaryTextTheme.display3.color - ), - ), - ) - ), + padding: EdgeInsets.only(left: 1, right: 10), + child: DottedBorder( + borderType: BorderType.RRect, + dashPattern: [6, 4], + color: Theme.of(context) + .primaryTextTheme + .display2 + .decorationColor, + strokeWidth: 2, + radius: Radius.circular(20), + child: Container( + height: 34, + width: 75, + padding: EdgeInsets.only(left: 10, right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(20)), + color: Colors.transparent, + ), + child: Text( + S.of(context).send_new, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .primaryTextTheme + .display3 + .color), + ), + )), + ), + ), + // Observer( + // builder: (_) { + // final templates = sendViewModel.templates; + // final itemCount = templates.length; + + // return ListView.builder( + // scrollDirection: Axis.horizontal, + // shrinkWrap: true, + // physics: NeverScrollableScrollPhysics(), + // itemCount: itemCount, + // itemBuilder: (context, index) { + // final template = templates[index]; + + // return TemplateTile( + // key: UniqueKey(), + // to: template.name, + // amount: template.amount, + // from: template.cryptoCurrency, + // onTap: () { + // _addressController.text = template.address; + // _cryptoAmountController.text = template.amount; + // getOpenaliasRecord(context); + // }, + // onRemove: () { + // showDialog( + // context: context, + // builder: (dialogContext) { + // return AlertWithTwoActions( + // alertTitle: S.of(context).template, + // alertContent: S.of(context).confirm_delete_template, + // leftButtonText: S.of(context).delete, + // rightButtonText: S.of(context).cancel, + // actionLeftButton: () { + // Navigator.of(dialogContext).pop(); + // sendViewModel.sendTemplateStore.remove(template: template); + // sendViewModel.sendTemplateStore.update(); + // }, + // actionRightButton: () => Navigator.of(dialogContext).pop() + // ); + // } + // ); + // }, + // ); + // } + // ); + // } + // ) + ], ), ), - Observer( - builder: (_) { - final templates = sendViewModel.templates; - final itemCount = templates.length; - - return ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: itemCount, - itemBuilder: (context, index) { - final template = templates[index]; - - return TemplateTile( - key: UniqueKey(), - to: template.name, - amount: template.amount, - from: template.cryptoCurrency, - onTap: () { - _addressController.text = template.address; - _cryptoAmountController.text = template.amount; - getOpenaliasRecord(context); - }, - onRemove: () { - showDialog( - context: context, - builder: (dialogContext) { - return AlertWithTwoActions( - alertTitle: S.of(context).template, - alertContent: S.of(context).confirm_delete_template, - leftButtonText: S.of(context).delete, - rightButtonText: S.of(context).cancel, - actionLeftButton: () { - Navigator.of(dialogContext).pop(); - sendViewModel.sendTemplateStore.remove(template: template); - sendViewModel.sendTemplateStore.update(); - }, - actionRightButton: () => Navigator.of(dialogContext).pop() - ); - } - ); - }, - ); - } - ); - } - ) - ], - ), - ), - ) + ) ], ), bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), bottomSection: isTemplate ? PrimaryButton( - onPressed: () { - if (_formKey.currentState.validate()) { - sendViewModel.sendTemplateStore.addTemplate( - name: _nameController.text, - address: _addressController.text, - cryptoCurrency: sendViewModel.currency.title, - amount: _cryptoAmountController.text - ); - sendViewModel.sendTemplateStore.update(); - Navigator.of(context).pop(); - } - }, - text: S.of(context).save, - color: Colors.green, - textColor: Colors.white) + onPressed: () { + if (_formKey.currentState.validate()) { + // sendViewModel.sendTemplateStore.addTemplate( + // name: _nameController.text, + // address: _addressController.text, + // cryptoCurrency: sendViewModel.currency.title, + // amount: _cryptoAmountController.text); + // sendViewModel.sendTemplateStore.update(); + Navigator.of(context).pop(); + } + }, + text: S.of(context).save, + color: Colors.green, + textColor: Colors.white) : Observer(builder: (_) { - return LoadingPrimaryButton( - onPressed: () { - if (_formKey.currentState.validate()) { - print('SENT!!!'); - } - }, - text: S.of(context).send, - color: Palette.blueCraiola, - textColor: Colors.white, - isLoading: sendViewModel.state is TransactionIsCreating || - sendViewModel.state is TransactionCommitting, - isDisabled: - false // FIXME !(syncStore.status is SyncedSyncStatus), - ); - }), + return LoadingPrimaryButton( + onPressed: () { + if (_formKey.currentState.validate()) { + print('SENT!!!'); + } + }, + text: S.of(context).send, + color: Palette.blueCraiola, + textColor: Colors.white, + isLoading: sendViewModel.state is TransactionIsCreating || + sendViewModel.state is TransactionCommitting, + isDisabled: + false // FIXME !(syncStore.status is SyncedSyncStatus), + ); + }), ); } @@ -465,6 +493,13 @@ class BaseSendWidget extends StatelessWidget { return; } + reaction((_) => sendViewModel.sendAll, (bool all) { + if (all) { + _cryptoAmountController.text = S.current.all; + _fiatAmountController.text = null; + } + }); + reaction((_) => sendViewModel.fiatAmount, (String amount) { if (amount != _fiatAmountController.text) { _fiatAmountController.text = amount; @@ -472,6 +507,10 @@ class BaseSendWidget extends StatelessWidget { }); reaction((_) => sendViewModel.cryptoAmount, (String amount) { + if (sendViewModel.sendAll && amount != S.current.all) { + sendViewModel.sendAll = false; + } + if (amount != _cryptoAmountController.text) { _cryptoAmountController.text = amount; } @@ -487,29 +526,7 @@ class BaseSendWidget extends StatelessWidget { final address = _addressController.text; if (sendViewModel.address != address) { - sendViewModel.changeAddress(address); - } - }); - - _fiatAmountController.addListener(() { - final fiatAmount = _fiatAmountController.text; - - if (sendViewModel.fiatAmount != fiatAmount) { - sendViewModel.changeFiatAmount(fiatAmount); - } - }); - - _cryptoAmountController.addListener(() { - final cryptoAmount = _cryptoAmountController.text; - - if (sendViewModel.cryptoAmount != cryptoAmount) { - sendViewModel.changeCryptoAmount(cryptoAmount); - } - }); - - _focusNode.addListener(() { - if (!_focusNode.hasFocus && _addressController.text.isNotEmpty) { - getOpenaliasRecord(context); + sendViewModel.address = address; } }); @@ -519,44 +536,126 @@ class BaseSendWidget extends StatelessWidget { showDialog( context: context, builder: (BuildContext context) { - return AlertDialog( - title: Text(S.of(context).error), - content: Text(state.error), - actions: [ - FlatButton( - child: Text(S.of(context).ok), - onPressed: () => Navigator.of(context).pop()) - ], - ); + return AlertWithOneAction( + alertTitle: S.of(context).error, + alertContent: state.error, + buttonText: S.of(context).ok, + buttonAction: () => Navigator.of(context).pop()); }); }); } if (state is TransactionCreatedSuccessfully) { -// WidgetsBinding.instance.addPostFrameCallback((_) { -// showDialog( -// context: context, -// builder: (BuildContext context) { -// return ConfirmSendingAlert( -// alertTitle: S.of(context).confirm_sending, -// amount: S.of(context).send_amount, -// amountValue: sendStore.pendingTransaction.amount, -// fee: S.of(context).send_fee, -// feeValue: sendStore.pendingTransaction.fee, -// leftButtonText: S.of(context).ok, -// rightButtonText: S.of(context).cancel, -// actionLeftButton: () { -// Navigator.of(context).pop(); -// sendStore.commitTransaction(); -// showDialog( -// context: context, -// builder: (BuildContext context) { -// return SendingAlert(sendStore: sendStore); -// }); -// }, -// actionRightButton: () => Navigator.of(context).pop()); -// }); -// }); + WidgetsBinding.instance.addPostFrameCallback((_) { + showDialog( + context: context, + builder: (BuildContext context) { + return ConfirmSendingAlert( + alertTitle: S.of(context).confirm_sending, + amount: S.of(context).send_amount, + amountValue: + sendViewModel.pendingTransaction.amountFormatted, + fee: S.of(context).send_fee, + feeValue: sendViewModel.pendingTransaction.feeFormatted, + leftButtonText: S.of(context).ok, + rightButtonText: S.of(context).cancel, + actionLeftButton: () { + Navigator.of(context).pop(); + sendViewModel.commitTransaction(); + showDialog( + context: context, + builder: (BuildContext context) { + return Observer(builder: (_) { + final state = sendViewModel.state; + + if (state is TransactionCommitted) { + return Stack( + children: [ + Container( + color: Theme.of(context).backgroundColor, + child: Center( + child: Image.asset( + 'assets/images/birthday_cake.png'), + ), + ), + Center( + child: Padding( + padding: EdgeInsets.only( + top: 220, left: 24, right: 24), + child: Text( + S.of(context).send_success, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + color: Theme.of(context) + .primaryTextTheme + .title + .color, + decoration: TextDecoration.none, + ), + ), + ), + ), + Positioned( + left: 24, + right: 24, + bottom: 24, + child: PrimaryButton( + onPressed: () => + Navigator.of(context).pop(), + text: S.of(context).send_got_it, + color: Colors.blue, + textColor: Colors.white)) + ], + ); + } + + return Stack( + children: [ + Container( + color: Theme.of(context).backgroundColor, + child: Center( + child: Image.asset( + 'assets/images/birthday_cake.png'), + ), + ), + BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 3.0, sigmaY: 3.0), + child: Container( + decoration: BoxDecoration( + color: Theme.of(context) + .backgroundColor + .withOpacity(0.25)), + child: Center( + child: Padding( + padding: EdgeInsets.only(top: 220), + child: Text( + S.of(context).send_sending, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + color: Theme.of(context) + .primaryTextTheme + .title + .color, + decoration: TextDecoration.none, + ), + ), + ), + ), + ), + ) + ], + ); + }); + }); + }, + actionRightButton: () => Navigator.of(context).pop()); + }); + }); } if (state is TransactionCommitted) { @@ -571,22 +670,24 @@ class BaseSendWidget extends StatelessWidget { } Future getOpenaliasRecord(BuildContext context) async { - final isOpenalias = await sendViewModel.isOpenaliasRecord(_addressController.text); + // final isOpenalias = + // await sendViewModel.isOpenaliasRecord(_addressController.text); - if (isOpenalias) { - _addressController.text = sendViewModel.recordAddress; + // if (isOpenalias) { + // _addressController.text = sendViewModel.recordAddress; - await showDialog( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).openalias_alert_title, - alertContent: S.of(context).openalias_alert_content(sendViewModel.recordName), - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop() - ); - }); - } + // await showDialog( + // context: context, + // builder: (BuildContext context) { + // return AlertWithOneAction( + // alertTitle: S.of(context).openalias_alert_title, + // alertContent: S + // .of(context) + // .openalias_alert_content(sendViewModel.recordName), + // buttonText: S.of(context).ok, + // buttonAction: () => Navigator.of(context).pop()); + // }); + // } } Future _setTransactionPriority(BuildContext context) async { @@ -595,14 +696,14 @@ class BaseSendWidget extends StatelessWidget { await showDialog( builder: (_) => Picker( - items: items, - selectedAtIndex: selectedItem, - title: S.of(context).please_select, - mainAxisAlignment: MainAxisAlignment.center, - onItemSelected: (TransactionPriority priority) => - sendViewModel.setTransactionPriority(priority), - isAlwaysShowScrollThumb: true, - ), + items: items, + selectedAtIndex: selectedItem, + title: S.of(context).please_select, + mainAxisAlignment: MainAxisAlignment.center, + onItemSelected: (TransactionPriority priority) => null, + // sendViewModel.setTransactionPriority(priority), + isAlwaysShowScrollThumb: true, + ), context: context); } -} \ No newline at end of file +} diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 0251fbce8..f27943be4 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -138,7 +138,7 @@ abstract class SettingsStoreBase with Store { sharedPreferences.getBool(shouldSaveRecipientAddressKey); final allowBiometricalAuthentication = sharedPreferences.getBool(allowBiometricalAuthenticationKey) ?? false; - final savedDarkTheme = sharedPreferences.getBool(currentDarkTheme) ?? true; + final savedDarkTheme = sharedPreferences.getBool(currentDarkTheme) ?? false; final actionListDisplayMode = ObservableList(); actionListDisplayMode.addAll(deserializeActionlistDisplayModes( sharedPreferences.getInt(displayActionListModeKey) ?? diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index 44430a073..7ab3a1044 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -1,5 +1,6 @@ import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/src/domain/common/crypto_currency.dart'; +import 'package:cake_wallet/src/domain/common/wallet_type.dart'; import 'package:cake_wallet/src/domain/exchange/exchange_provider.dart'; import 'package:cake_wallet/src/domain/exchange/limits.dart'; import 'package:cake_wallet/src/domain/exchange/trade.dart'; @@ -25,22 +26,18 @@ part 'exchange_view_model.g.dart'; class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel; abstract class ExchangeViewModelBase with Store { - ExchangeViewModelBase({ - this.wallet, - this.trades, - this.exchangeTemplateStore, - this.tradesStore}) { - + ExchangeViewModelBase( + {this.wallet, + this.trades, + this.exchangeTemplateStore, + this.tradesStore}) { providerList = [ XMRTOExchangeProvider(), ChangeNowExchangeProvider(), MorphTokenExchangeProvider(trades: trades) ]; - provider = providerList[ 0 ]; - - depositCurrency = CryptoCurrency.xmr; - receiveCurrency = CryptoCurrency.btc; + _initialPairBasedOnWallet(); isDepositAddressEnabled = !(depositCurrency == wallet.currency); isReceiveAddressEnabled = !(receiveCurrency == wallet.currency); depositAmount = ''; @@ -50,6 +47,7 @@ abstract class ExchangeViewModelBase with Store { limitsState = LimitsInitialState(); tradeState = ExchangeTradeStateInitial(); _cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12; + provider = providersForCurrentPair().first; loadLimits(); } @@ -140,8 +138,11 @@ abstract class ExchangeViewModelBase with Store { provider .calculateAmount( - from: depositCurrency, to: receiveCurrency, amount: _amount) - .then((amount) => _cryptoNumberFormat.format(amount).toString().replaceAll(RegExp("\\,"), "")) + from: depositCurrency, to: receiveCurrency, amount: _amount) + .then((amount) => _cryptoNumberFormat + .format(amount) + .toString() + .replaceAll(RegExp('\\,'), '')) .then((amount) => depositAmount = amount); } @@ -158,8 +159,11 @@ abstract class ExchangeViewModelBase with Store { final _amount = double.parse(amount); provider .calculateAmount( - from: depositCurrency, to: receiveCurrency, amount: _amount) - .then((amount) => _cryptoNumberFormat.format(amount).toString().replaceAll(RegExp("\\,"), "")) + from: depositCurrency, to: receiveCurrency, amount: _amount) + .then((amount) => _cryptoNumberFormat + .format(amount) + .toString() + .replaceAll(RegExp('\\,'), '')) .then((amount) => receiveAmount = amount); } @@ -217,11 +221,13 @@ abstract class ExchangeViewModelBase with Store { if (limitsState is LimitsLoadedSuccessfully && amount != null) { if (double.parse(amount) < limits.min) { - tradeState = TradeIsCreatedFailure(error: S.current.error_text_minimal_limit('${provider.description}', - '${limits.min}', currency.toString())); + tradeState = TradeIsCreatedFailure( + error: S.current.error_text_minimal_limit('${provider.description}', + '${limits.min}', currency.toString())); } else if (limits.max != null && double.parse(amount) > limits.max) { - tradeState = TradeIsCreatedFailure(error: S.current.error_text_maximum_limit('${provider.description}', - '${limits.max}', currency.toString())); + tradeState = TradeIsCreatedFailure( + error: S.current.error_text_maximum_limit('${provider.description}', + '${limits.max}', currency.toString())); } else { try { tradeState = TradeIsCreating(); @@ -235,9 +241,10 @@ abstract class ExchangeViewModelBase with Store { } } } else { - tradeState = TradeIsCreatedFailure(error: S.current.error_text_limits_loading_failed('${provider.description}')); + tradeState = TradeIsCreatedFailure( + error: S.current + .error_text_limits_loading_failed('${provider.description}')); } - } @action @@ -261,9 +268,9 @@ abstract class ExchangeViewModelBase with Store { {CryptoCurrency from, CryptoCurrency to}) { final providers = providerList .where((provider) => provider.pairList - .where((pair) => - pair.from == depositCurrency && pair.to == receiveCurrency) - .isNotEmpty) + .where((pair) => + pair.from == depositCurrency && pair.to == receiveCurrency) + .isNotEmpty) .toList(); return providers; @@ -272,12 +279,12 @@ abstract class ExchangeViewModelBase with Store { void _onPairChange() { final isPairExist = provider.pairList .where((pair) => - pair.from == depositCurrency && pair.to == receiveCurrency) + pair.from == depositCurrency && pair.to == receiveCurrency) .isNotEmpty; if (!isPairExist) { final provider = - _providerForPair(from: depositCurrency, to: receiveCurrency); + _providerForPair(from: depositCurrency, to: receiveCurrency); if (provider != null) { changeProvider(provider: provider); @@ -295,4 +302,18 @@ abstract class ExchangeViewModelBase with Store { return providers.isNotEmpty ? providers[0] : null; } -} \ No newline at end of file + void _initialPairBasedOnWallet() { + switch (wallet.type) { + case WalletType.monero: + depositCurrency = CryptoCurrency.xmr; + receiveCurrency = CryptoCurrency.btc; + break; + case WalletType.bitcoin: + depositCurrency = CryptoCurrency.btc; + receiveCurrency = CryptoCurrency.xmr; + break; + default: + break; + } + } +} diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 81be508e6..b03ca02d1 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -1,7 +1,8 @@ -import 'package:cake_wallet/src/domain/common/calculate_fiat_amount.dart'; -import 'package:cake_wallet/store/dashboard/fiat_convertation_store.dart'; import 'package:intl/intl.dart'; import 'package:mobx/mobx.dart'; +import 'package:cake_wallet/core/template_validator.dart'; +import 'package:cake_wallet/src/domain/common/calculate_fiat_amount.dart'; +import 'package:cake_wallet/store/dashboard/fiat_convertation_store.dart'; import 'package:cake_wallet/core/address_validator.dart'; import 'package:cake_wallet/core/amount_validator.dart'; import 'package:cake_wallet/core/pending_transaction.dart'; @@ -28,7 +29,7 @@ abstract class SendViewModelBase with Store { : state = InitialSendViewModelState(), _cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12, // FIXME: need to be based on wallet type. - all = false; + sendAll = false; @observable SendViewModelState state; @@ -43,7 +44,7 @@ abstract class SendViewModelBase with Store { String address; @observable - bool all; + bool sendAll; FiatCurrency get fiat => _settingsStore.fiatCurrency; @@ -59,6 +60,8 @@ abstract class SendViewModelBase with Store { Validator get addressValidator => AddressValidator(type: _wallet.currency); + Validator get templateValidator => TemplateValidator(); + PendingTransaction pendingTransaction; @computed @@ -83,7 +86,7 @@ abstract class SendViewModelBase with Store { final NumberFormat _cryptoNumberFormat; @action - void setAll() => all = true; + void setSendAll() => sendAll = true; @action void reset() { @@ -118,7 +121,7 @@ abstract class SendViewModelBase with Store { void setCryptoAmount(String amount) { // FIXME: hardcoded value. if (amount.toUpperCase() != 'ALL') { - all = false; + sendAll = false; } cryptoAmount = amount; @@ -162,7 +165,7 @@ abstract class SendViewModelBase with Store { Object _credentials() { final amount = - !all ? double.parse(cryptoAmount.replaceAll(',', '.')) : null; + !sendAll ? double.parse(cryptoAmount.replaceAll(',', '.')) : null; switch (_wallet.type) { case WalletType.bitcoin: