diff --git a/assets/images/copy_address.png b/assets/images/copy_address.png new file mode 100644 index 000000000..282fec6d5 Binary files /dev/null and b/assets/images/copy_address.png differ diff --git a/lib/di.dart b/lib/di.dart index e8f878327..f885ab20c 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -183,7 +183,9 @@ Future setup( closable: false)); getIt.registerFactory( - () => DashboardPage(walletViewModel: getIt.get())); + () => DashboardPage( + walletViewModel: getIt.get(), + addressListViewModel: getIt.get())); getIt.registerFactory(() => ReceivePage( addressListViewModel: getIt.get())); diff --git a/lib/palette.dart b/lib/palette.dart index 0daa53148..98bfe3fd7 100644 --- a/lib/palette.dart +++ b/lib/palette.dart @@ -34,6 +34,7 @@ class PaletteDark { static const Color backgroundColor = Color.fromRGBO(25, 35, 60, 1.0); static const Color nightBlue = Color.fromRGBO(35, 47, 79, 1.0); static const Color wildNightBlue = Color.fromRGBO(39, 53, 96, 1.0); + static const Color distantNightBlue = Color.fromRGBO(46, 57, 96, 1.0); static const Color cyanBlue = Color.fromRGBO(99, 113, 150, 1.0); static const Color darkCyanBlue = Color.fromRGBO(91, 112, 146, 1.0); static const Color orangeYellow = Color.fromRGBO(243, 166, 50, 1.0); @@ -41,6 +42,9 @@ class PaletteDark { static const Color oceanBlue = Color.fromRGBO(27, 39, 71, 1.0); static const Color lightNightBlue = Color.fromRGBO(39, 52, 89, 1.0); static const Color wildBlue = Color.fromRGBO(165, 176, 205, 1.0); + static const Color lightBlueGrey = Color.fromRGBO(125, 141, 183, 1.0); + static const Color darkGrey = Color.fromRGBO(118, 131, 169, 1.0); + static const Color dividerColor = Color.fromRGBO(48, 59, 95, 1.0); // FIXME: Rename. static const Color eee = Color.fromRGBO(236, 239, 245, 1.0); diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index b32b72e64..7a2fed936 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -9,13 +9,18 @@ import 'package:cake_wallet/palette.dart'; import 'package:dots_indicator/dots_indicator.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/action_button.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart'; +import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart'; +import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; class DashboardPage extends BasePage { - DashboardPage({@required this.walletViewModel}); + DashboardPage({ + @required this.walletViewModel, + @required this.addressListViewModel, + }); @override Color get backgroundLightColor => PaletteDark.backgroundColor; @@ -54,13 +59,14 @@ class DashboardPage extends BasePage { } final DashboardViewModel walletViewModel; + final WalletAddressListViewModel addressListViewModel; final sendImage = Image.asset('assets/images/upload.png', height: 22.24, width: 24, color: Colors.white); final exchangeImage = Image.asset('assets/images/transfer.png', height: 24.27, width: 22.25, color: Colors.white); final receiveImage = Image.asset('assets/images/download.png', height: 22.24, width: 24, color: Colors.white); - final controller = PageController(initialPage: 0); + final controller = PageController(initialPage: 1); var pages = []; bool _isEffectsInstalled = false; @@ -147,6 +153,7 @@ class DashboardPage extends BasePage { return; } + pages.add(AddressPage(addressListViewModel: addressListViewModel)); pages.add(BalancePage(dashboardViewModel: walletViewModel)); pages.add(TransactionsPage(dashboardViewModel: walletViewModel)); diff --git a/lib/src/screens/dashboard/widgets/address_page.dart b/lib/src/screens/dashboard/widgets/address_page.dart new file mode 100644 index 000000000..35134d51b --- /dev/null +++ b/lib/src/screens/dashboard/widgets/address_page.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; +import 'package:cake_wallet/palette.dart'; +import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart'; +import 'package:cake_wallet/routes.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +class AddressPage extends StatelessWidget { + AddressPage({@required this.addressListViewModel}); + + final WalletAddressListViewModel addressListViewModel; + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.fromLTRB(24, 24, 24, 32), + child: Column( + children: [ + Expanded( + child: Center( + child: QRWidget(addressListViewModel: addressListViewModel), + ) + ), + GestureDetector( + onTap: () => Navigator.of(context).pushNamed(Routes.receive), + child: Container( + height: 50, + padding: EdgeInsets.only(left: 24, right: 12), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(25)), + color: PaletteDark.nightBlue + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + S.of(context).addresses, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.white + ), + ), + Icon( + Icons.arrow_forward_ios, + size: 14, + color: Colors.white, + ) + ], + ), + ), + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/src/screens/receive/widgets/qr_widget.dart b/lib/src/screens/receive/widgets/qr_widget.dart new file mode 100644 index 000000000..ea78b676d --- /dev/null +++ b/lib/src/screens/receive/widgets/qr_widget.dart @@ -0,0 +1,134 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart'; +import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; +import 'package:cake_wallet/core/amount_validator.dart'; +import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; +import 'package:cake_wallet/palette.dart'; + +class QRWidget extends StatelessWidget { + QRWidget({ + @required this.addressListViewModel, + this.isAmountFieldShow = false + }) : amountController = TextEditingController(), + _formKey = GlobalKey() { + amountController.addListener(() => addressListViewModel.amount = + _formKey.currentState.validate() ? amountController.text : ''); + } + + final WalletAddressListViewModel addressListViewModel; + final bool isAmountFieldShow; + final TextEditingController amountController; + final GlobalKey _formKey; + + @override + Widget build(BuildContext context) { + final copyImage = Image.asset('assets/images/copy_address.png', + color: PaletteDark.lightBlueGrey); + final addressTopOffset = isAmountFieldShow ? 60.0 : 40.0; + + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row(children: [ + Spacer(flex: 2), + Observer( + builder: (_) => Flexible( + flex: 3, + child: Center( + child: AspectRatio( + aspectRatio: 1.0, + child: QrImage( + data: addressListViewModel.uri.toString(), + backgroundColor: Colors.transparent, + foregroundColor: PaletteDark.lightBlueGrey, + ))))), + Spacer(flex: 2) + ]), + Padding( + padding: EdgeInsets.only(top: 20), + child: Text( + 'Scan the QR code to get the address', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: PaletteDark.cyanBlue + ), + ), + ), + isAmountFieldShow + ? Padding( + padding: EdgeInsets.only(top: 60), + child: Row( + children: [ + Expanded( + child: Form( + key: _formKey, + child: BaseTextFormField( + controller: amountController, + keyboardType: + TextInputType.numberWithOptions(decimal: true), + inputFormatters: [ + BlacklistingTextInputFormatter( + RegExp('[\\-|\\ |\\,]')) + ], + textAlign: TextAlign.center, + hintText: S.of(context).receive_amount, + borderColor: PaletteDark.darkGrey, + validator: AmountValidator(), + autovalidate: true, + placeholderTextStyle: TextStyle( + color: PaletteDark.cyanBlue, + fontSize: 18, + fontWeight: FontWeight.w500)))) + ], + ), + ) + : Offstage(), + Padding( + padding: EdgeInsets.only(top: addressTopOffset), + child: Builder( + builder: (context) => Observer( + builder: (context) => GestureDetector( + onTap: () { + Clipboard.setData(ClipboardData( + text: addressListViewModel.address.address)); + Scaffold.of(context).showSnackBar(SnackBar( + content: Text( + S.of(context).copied_to_clipboard, + style: TextStyle(color: Colors.white), + ), + backgroundColor: Colors.green, + duration: Duration(milliseconds: 500), + )); + }, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Text( + addressListViewModel.address.address, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.white), + ), + ), + Padding( + padding: EdgeInsets.only(left: 12), + child: copyImage, + ) + ], + ), + ))), + ) + ], + ); + } +} \ No newline at end of file diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index fac416af8..322dd4403 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -54,7 +54,7 @@ abstract class DashboardViewModelBase with Store { subname = _wallet.account?.label; } - currentPage = 0; + currentPage = 1; } @observable