From 731f12cd63b62f5f52a07dbb675b4c1facaf0f0c Mon Sep 17 00:00:00 2001 From: Oleksandr Sobol Date: Thu, 20 Aug 2020 20:43:54 +0300 Subject: [PATCH] CAKE-27 | applied light theme to send and send template pages; made status bar is transparent; reworked menu widget and base send widget; applied switch between light and dark themes --- lib/di.dart | 7 + lib/main.dart | 22 +- lib/palette.dart | 1 + .../dashboard/widgets/menu_widget.dart | 163 ++-- lib/src/screens/send/send_page.dart | 25 +- lib/src/screens/send/send_template_page.dart | 26 +- .../send/widgets/base_send_widget.dart | 705 +++++++++--------- lib/src/widgets/address_text_field.dart | 16 +- lib/src/widgets/template_tile.dart | 5 +- lib/src/widgets/top_panel.dart | 14 +- lib/store/theme_changer_store.dart | 13 + lib/themes.dart | 51 +- .../settings/settings_view_model.dart | 7 +- 13 files changed, 583 insertions(+), 472 deletions(-) create mode 100644 lib/store/theme_changer_store.dart diff --git a/lib/di.dart b/lib/di.dart index dabb7c4e4..1d903d7f7 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -27,7 +27,9 @@ import 'package:cake_wallet/src/screens/receive/receive_page.dart'; import 'package:cake_wallet/src/screens/send/send_page.dart'; import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart'; +import 'package:cake_wallet/store/theme_changer_store.dart'; import 'package:cake_wallet/store/wallet_list_store.dart'; +import 'package:cake_wallet/theme_changer.dart'; import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart'; import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart'; @@ -318,3 +320,8 @@ Future setup( getIt.registerFactory(() => ExchangeTemplatePage(getIt.get())); } + +void setupThemeChangerStore(ThemeChanger themeChanger) { + getIt.registerSingleton( + ThemeChangerStore(themeChanger: themeChanger)); +} diff --git a/lib/main.dart b/lib/main.dart index 912099978..a6de6e231 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/reactions/bootstrap.dart'; +import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart'; @@ -52,6 +53,8 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/domain/common/language.dart'; import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart'; +bool isThemeChangerRegistered = false; + void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -197,7 +200,8 @@ class CakeWalletApp extends StatelessWidget { @override Widget build(BuildContext context) { - final settingsStore = Provider.of(context); + //final settingsStore = Provider.of(context); + final settingsStore = getIt.get().settingsStore; return ChangeNotifierProvider( create: (_) => ThemeChanger( @@ -228,12 +232,20 @@ class MaterialAppWithTheme extends StatelessWidget { final transactionDescriptions = Provider.of>(context); - final statusBarColor = - settingsStore.isDarkTheme ? Colors.black : Colors.white; + if (!isThemeChangerRegistered) { + setupThemeChangerStore(theme); + isThemeChangerRegistered = true; + } + + /*final statusBarColor = + settingsStore.isDarkTheme ? Colors.black : Colors.white;*/ + final _settingsStore = getIt.get().settingsStore; + + final statusBarColor = Colors.transparent; final statusBarBrightness = - settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; + _settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; final statusBarIconBrightness = - settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; + _settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( statusBarColor: statusBarColor, diff --git a/lib/palette.dart b/lib/palette.dart index 0eebf247f..13790ee14 100644 --- a/lib/palette.dart +++ b/lib/palette.dart @@ -29,6 +29,7 @@ class Palette { static const Color gray = Color.fromRGBO(112, 147, 186, 1.0); static const Color wildPeriwinkle = Color.fromRGBO(219, 227, 243, 1.0); static const Color darkGray = Color.fromRGBO(122, 147, 186, 1.0); + static const Color shadowWhite = Color.fromRGBO(242, 245, 255, 1.0); // FIXME: Rename. static const Color eee = Color.fromRGBO(236, 239, 245, 1.0); diff --git a/lib/src/screens/dashboard/widgets/menu_widget.dart b/lib/src/screens/dashboard/widgets/menu_widget.dart index 834026779..ed32d755d 100644 --- a/lib/src/screens/dashboard/widgets/menu_widget.dart +++ b/lib/src/screens/dashboard/widgets/menu_widget.dart @@ -3,6 +3,7 @@ import 'package:cake_wallet/palette.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/src/domain/common/wallet_type.dart'; import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart'; +import 'package:flutter/rendering.dart'; class MenuWidget extends StatefulWidget { MenuWidget({this.type, this.name, this.subname}); @@ -23,7 +24,6 @@ class MenuWidgetState extends State { double menuWidth; double screenWidth; double screenHeight; - double opacity; double headerHeight; double tileHeight; @@ -35,11 +35,10 @@ class MenuWidgetState extends State { menuWidth = 0; screenWidth = 0; screenHeight = 0; - opacity = 0; headerHeight = 125; tileHeight = 75; - fromTopEdge = 50; + fromTopEdge = 30; fromBottomEdge = 21; super.initState(); @@ -52,7 +51,6 @@ class MenuWidgetState extends State { setState(() { menuWidth = screenWidth; - opacity = 1; if (screenHeight > largeScreen) { final scale = screenHeight / largeScreen; @@ -69,41 +67,43 @@ class MenuWidgetState extends State { final walletMenu = WalletMenu(context); final itemCount = walletMenu.items.length; - return SafeArea( - child: Row( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Padding( + return Row( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( padding: EdgeInsets.only(left: 24), child: Container( height: 60, width: 4, decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(2)), - color: PaletteDark.gray), + borderRadius: BorderRadius.all(Radius.circular(2)), + color: PaletteDark.gray), )), - SizedBox(width: 12), - Expanded( - child: ClipRRect( - borderRadius: BorderRadius.only( + SizedBox(width: 12), + Expanded( + child: ClipRRect( + borderRadius: BorderRadius.only( topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)), - child: Container( - width: menuWidth, - height: double.infinity, - color: Theme.of(context).textTheme.body2.decorationColor, - child: SingleChildScrollView( - child: Column( - children: [ - Container( + child: Container( + width: menuWidth, + height: double.infinity, + color: Theme.of(context).textTheme.body2.color, + alignment: Alignment.topCenter, + child: ListView.separated( + itemBuilder: (_, index) { + + if (index == 0) { + return Container( height: headerHeight, color: Theme.of(context).textTheme.body2.color, padding: EdgeInsets.only( left: 24, top: fromTopEdge, right: 24, - bottom: fromBottomEdge), + bottom: fromBottomEdge + ), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ @@ -141,70 +141,63 @@ class MenuWidgetState extends State { )) ], ), - ), - Container( - height: 1, - color: Theme.of(context).primaryTextTheme.caption.decorationColor, - ), - ListView.separated( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemBuilder: (_, index) { + ); + } - final item = walletMenu.items[index]; - final image = walletMenu.images[index] ?? Offstage(); - final isLastTile = index == itemCount - 1; + index--; - return GestureDetector( - onTap: () { - Navigator.of(context).pop(); - walletMenu.action(index); - }, - child: Container( - height: isLastTile - ? headerHeight - : tileHeight, - padding: isLastTile - ? EdgeInsets.only( - left: 24, - right: 24, - top: fromBottomEdge, - bottom: fromTopEdge) - : EdgeInsets.only(left: 24, right: 24), - alignment: isLastTile ? Alignment.topLeft : null, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - image, - SizedBox(width: 16), - Expanded( - child: Text( - item, - style: TextStyle( - color: Theme.of(context).textTheme - .display2.color, - fontSize: 16, - fontWeight: FontWeight.bold), - )) - ], - ), - ) - ); - }, - separatorBuilder: (_, index) => Container( - height: 1, - color: Theme.of(context).primaryTextTheme.caption.decorationColor, + final item = walletMenu.items[index]; + final image = walletMenu.images[index] ?? Offstage(); + final isLastTile = index == itemCount - 1; + + return GestureDetector( + onTap: () { + Navigator.of(context).pop(); + walletMenu.action(index); + }, + child: Container( + color: Theme.of(context).textTheme.body2.decorationColor, + height: isLastTile + ? headerHeight + : tileHeight, + padding: isLastTile + ? EdgeInsets.only( + left: 24, + right: 24, + top: fromBottomEdge, + //bottom: fromTopEdge + ) + : EdgeInsets.only(left: 24, right: 24), + alignment: isLastTile ? Alignment.topLeft : null, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + image, + SizedBox(width: 16), + Expanded( + child: Text( + item, + style: TextStyle( + color: Theme.of(context).textTheme + .display2.color, + fontSize: 16, + fontWeight: FontWeight.bold), + )) + ], ), - itemCount: itemCount) - ], + ) + ); + }, + separatorBuilder: (_, index) => Container( + height: 1, + color: Theme.of(context).primaryTextTheme.caption.decorationColor, ), - ), - ), - ) - ) - ], - ) + itemCount: itemCount + 1), + ), + ) + ) + ], ); } diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 7902370b0..3f973f4db 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -1,7 +1,6 @@ import 'package:cake_wallet/view_model/send_view_model.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/send/widgets/base_send_widget.dart'; @@ -14,15 +13,33 @@ class SendPage extends BasePage { String get title => sendViewModel.pageTitle; @override - Color get backgroundLightColor => PaletteDark.nightBlue; + Color get titleColor => Colors.white; @override - Color get backgroundDarkColor => PaletteDark.nightBlue; + Color get backgroundLightColor => Colors.transparent; + + @override + Color get backgroundDarkColor => Colors.transparent; @override bool get resizeToAvoidBottomPadding => false; @override Widget body(BuildContext context) => - BaseSendWidget(sendViewModel: sendViewModel); + 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) + ) + ); + } } diff --git a/lib/src/screens/send/send_template_page.dart b/lib/src/screens/send/send_template_page.dart index 19f9f8ca8..1f49a3f9a 100644 --- a/lib/src/screens/send/send_template_page.dart +++ b/lib/src/screens/send/send_template_page.dart @@ -1,6 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:cake_wallet/palette.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'; @@ -15,15 +14,34 @@ class SendTemplatePage extends BasePage { String get title => S.current.exchange_new_template; @override - Color get backgroundLightColor => PaletteDark.nightBlue; + Color get titleColor => Colors.white; @override - Color get backgroundDarkColor => PaletteDark.nightBlue; + Color get backgroundLightColor => Colors.transparent; + + @override + Color get backgroundDarkColor => Colors.transparent; @override bool get resizeToAvoidBottomPadding => false; @override Widget body(BuildContext context) => - BaseSendWidget(sendViewModel: sendViewModel, isTemplate: true); + 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) + ) + ); + } } \ 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 1bc5a5359..4e8552e5f 100644 --- a/lib/src/screens/send/widgets/base_send_widget.dart +++ b/lib/src/screens/send/widgets/base_send_widget.dart @@ -22,11 +22,15 @@ import 'package:cake_wallet/routes.dart'; class BaseSendWidget extends StatelessWidget { BaseSendWidget({ @required this.sendViewModel, + @required this.leading, + @required this.middle, this.isTemplate = false }); final SendViewModel sendViewModel; final bool isTemplate; + final Widget leading; + final Widget middle; final _addressController = TextEditingController(); final _cryptoAmountController = TextEditingController(); @@ -42,371 +46,386 @@ class BaseSendWidget extends StatelessWidget { _setEffects(context); - return Container( - color: PaletteDark.backgroundColor, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: Column( - children: [ - TopPanel( - color: PaletteDark.nightBlue, - edgeInsets: EdgeInsets.fromLTRB(24, 24, 24, 32), - widget: Form( - key: _formKey, - child: Column(children: [ - isTemplate - ? BaseTextFormField( - controller: _nameController, - hintText: S.of(context).send_name, - borderColor: PaletteDark.lightVioletBlue, - textStyle: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.white - ), - placeholderTextStyle: TextStyle( - color: PaletteDark.darkCyanBlue, - 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), - focusNode: _focusNode, - onURIScanned: (uri) { - var address = ''; - var amount = ''; - - if (uri != null) { - address = uri.path; - amount = uri.queryParameters['tx_amount']; - } else { - address = uri.toString(); - } - - _addressController.text = address; - _cryptoAmountController.text = amount; - }, - options: [ - AddressTextFieldOption.paste, - AddressTextFieldOption.qrCode, - AddressTextFieldOption.addressBook - ], - buttonColor: PaletteDark.buttonNightBlue, - borderColor: PaletteDark.lightVioletBlue, - textStyle: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.white - ), - hintStyle: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: PaletteDark.darkCyanBlue - ), - 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 + ':', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Colors.white, - )), - ), - suffixIcon: isTemplate - ? Offstage() - : Padding( - padding: EdgeInsets.only(bottom: 2), - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width: MediaQuery.of(context).size.width/2, - alignment: Alignment.centerLeft, - child: Text( - ' / ' + sendViewModel.balance, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 14, - color: PaletteDark.darkCyanBlue - ) - ), - ), - Container( - height: 34, - width: 34, - margin: EdgeInsets.only(left: 12, bottom: 8), - decoration: BoxDecoration( - color: PaletteDark.buttonNightBlue, - 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: PaletteDark.lightBlueGrey - ) - ), - ), - ), - ) - ], - ), - ), - hintText: '0.0000', - borderColor: PaletteDark.lightVioletBlue, - textStyle: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.white - ), - placeholderTextStyle: TextStyle( - color: PaletteDark.darkCyanBlue, - fontWeight: FontWeight.w500, - fontSize: 14), - validator: sendViewModel.amountValidator - ) - ); - } - ), - Padding( - padding: const EdgeInsets.only(top: 20), - child: BaseTextFormField( - controller: _fiatAmountController, - keyboardType: TextInputType.numberWithOptions( - signed: false, decimal: true), - inputFormatters: [ - BlacklistingTextInputFormatter( - RegExp('[\\-|\\ |\\,]')) - ], - prefixIcon: Padding( - padding: EdgeInsets.only(top: 9), - child: Text( - sendViewModel.fiat.title + ':', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Colors.white, - )), - ), - hintText: '0.00', - borderColor: PaletteDark.lightVioletBlue, + return ScrollableWithBottomSection( + contentPadding: EdgeInsets.only(bottom: 24), + content: Column( + children: [ + TopPanel( + edgeInsets: EdgeInsets.all(0), + gradient: LinearGradient(colors: [ + Theme.of(context).primaryTextTheme.subhead.color, + Theme.of(context).primaryTextTheme.subhead.decorationColor, + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight), + widget: Form( + key: _formKey, + child: Column(children: [ + CupertinoNavigationBar( + leading: leading, + middle: middle, + backgroundColor: Colors.transparent, + border: null, + ), + Padding( + padding: EdgeInsets.fromLTRB(24, 24, 24, 32), + 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: PaletteDark.darkCyanBlue, + color: Theme.of(context).primaryTextTheme.headline.decorationColor, fontWeight: FontWeight.w500, fontSize: 14), + validator: sendViewModel.templateValidator, ) - ), - isTemplate - ? Offstage() - : Padding( - padding: const EdgeInsets.only(top: 24), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(S.of(context).send_estimated_fee, - style: TextStyle( - fontSize: 12, + : Offstage(), + Padding( + padding: EdgeInsets.only(top: isTemplate ? 20 : 0), + child: AddressTextField( + controller: _addressController, + placeholder: S.of(context).send_address( + sendViewModel.cryptoCurrencyTitle), + focusNode: _focusNode, + onURIScanned: (uri) { + var address = ''; + var amount = ''; + + if (uri != null) { + address = uri.path; + amount = uri.queryParameters['tx_amount']; + } else { + address = uri.toString(); + } + + _addressController.text = address; + _cryptoAmountController.text = amount; + }, + options: [ + AddressTextFieldOption.paste, + AddressTextFieldOption.qrCode, + AddressTextFieldOption.addressBook + ], + buttonColor: Theme.of(context).primaryTextTheme.display1.color, + borderColor: Theme.of(context).primaryTextTheme.headline.color, + textStyle: TextStyle( + fontSize: 14, fontWeight: FontWeight.w500, - color: Colors.white, - )), - Text( - sendViewModel.estimatedFee.toString() + ' ' - + sendViewModel.currency.title, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Colors.white, - )) - ], - ), - ) - ]), - ), + color: Colors.white + ), + hintStyle: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + 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 + ':', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Colors.white, + )), + ), + suffixIcon: isTemplate + ? Offstage() + : Padding( + padding: EdgeInsets.only(bottom: 2), + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: MediaQuery.of(context).size.width/2, + alignment: Alignment.centerLeft, + child: Text( + ' / ' + sendViewModel.balance, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).primaryTextTheme.headline.decorationColor + ) + ), + ), + Container( + height: 34, + width: 34, + margin: EdgeInsets.only(left: 12, bottom: 8), + 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 + ) + ); + } + ), + Padding( + padding: const EdgeInsets.only(top: 20), + child: BaseTextFormField( + controller: _fiatAmountController, + keyboardType: TextInputType.numberWithOptions( + signed: false, decimal: true), + inputFormatters: [ + BlacklistingTextInputFormatter( + RegExp('[\\-|\\ |\\,]')) + ], + prefixIcon: Padding( + padding: EdgeInsets.only(top: 9), + child: Text( + sendViewModel.fiat.title + ':', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Colors.white, + )), + ), + hintText: '0.00', + 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), + ) + ), + isTemplate + ? Offstage() + : Padding( + padding: const 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, + )), + Text( + sendViewModel.estimatedFee.toString() + ' ' + + sendViewModel.currency.title, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Theme.of(context).primaryTextTheme.display2.color, + )) + ], + ), + ) + ], + ), + ) + ]), ), - isTemplate - ? Offstage() - : Padding( - padding: EdgeInsets.only( - top: 30, - left: 24, - bottom: 24 - ), + ), + 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.title.color + ), + ) + ], + ), + ), + isTemplate + ? Offstage() + : Container( + height: 40, + width: double.infinity, + padding: EdgeInsets.only(left: 24), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, child: Row( - mainAxisAlignment: MainAxisAlignment.start, children: [ - Text( - S.of(context).send_templates, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - color: PaletteDark.darkCyanBlue + 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), + 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() + ); + } + ); + }, + ); + } + ); + } ) ], ), ), - 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: PaletteDark.darkCyanBlue, - 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: PaletteDark.darkCyanBlue - ), - ), - ) - ), - ), - ), - 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( + ) + ], + ), + 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) + : Observer(builder: (_) { + return LoadingPrimaryButton( 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(); + print('SENT!!!'); } }, - 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: Colors.blue, - textColor: Colors.white, - isLoading: sendViewModel.state is TransactionIsCreating || - sendViewModel.state is TransactionCommitting, - isDisabled: - false // FIXME !(syncStore.status is SyncedSyncStatus), - ); - }), - ), + 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), + ); + }), ); } diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart index 3e96a9e76..16ec36c62 100644 --- a/lib/src/widgets/address_text_field.dart +++ b/lib/src/widgets/address_text_field.dart @@ -112,7 +112,9 @@ class AddressTextField extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(6))), child: Image.asset( - 'assets/images/duplicate.png')), + 'assets/images/duplicate.png', + color: Theme.of(context).primaryTextTheme.display1.decorationColor, + )), )), ], if (this.options.contains(AddressTextFieldOption.qrCode)) ...[ @@ -128,7 +130,9 @@ class AddressTextField extends StatelessWidget { color: buttonColor ?? Theme.of(context).accentTextTheme.title.color, borderRadius: BorderRadius.all(Radius.circular(6))), - child: Image.asset('assets/images/qr_code_icon.png')), + child: Image.asset('assets/images/qr_code_icon.png', + color: Theme.of(context).primaryTextTheme.display1.decorationColor, + )), )) ], if (this @@ -147,7 +151,9 @@ class AddressTextField extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(6))), child: Image.asset( - 'assets/images/open_book.png')), + 'assets/images/open_book.png', + color: Theme.of(context).primaryTextTheme.display1.decorationColor, + )), )) ], if (this @@ -166,7 +172,9 @@ class AddressTextField extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(6))), child: Image.asset( - 'assets/images/receive_icon_raw.png')), + 'assets/images/receive_icon_raw.png', + color: Theme.of(context).primaryTextTheme.display1.decorationColor, + )), )), ], ], diff --git a/lib/src/widgets/template_tile.dart b/lib/src/widgets/template_tile.dart index ab6724ece..fbff8b6c1 100644 --- a/lib/src/widgets/template_tile.dart +++ b/lib/src/widgets/template_tile.dart @@ -47,8 +47,7 @@ class TemplateTileState extends State { @override Widget build(BuildContext context) { - //final color = isRemovable ? Colors.white : Theme.of(context).primaryTextTheme.title.color; - final color = Colors.white; + final color = isRemovable ? Colors.white : Theme.of(context).primaryTextTheme.title.color; final toIcon = Image.asset('assets/images/to_icon.png', color: color); final content = Row( @@ -106,7 +105,7 @@ class TemplateTileState extends State { child: Container( height: 40, padding: EdgeInsets.only(left: 24, right: 24), - color: PaletteDark.darkVioletBlue, + color: Theme.of(context).primaryTextTheme.display3.decorationColor, child: content, ), ), diff --git a/lib/src/widgets/top_panel.dart b/lib/src/widgets/top_panel.dart index 5e2cc2c91..d456d1a39 100644 --- a/lib/src/widgets/top_panel.dart +++ b/lib/src/widgets/top_panel.dart @@ -2,25 +2,28 @@ import 'package:flutter/material.dart'; class TopPanel extends StatefulWidget { TopPanel({ - @required this.color, @required this.widget, - this.edgeInsets = const EdgeInsets.all(24) + this.edgeInsets = const EdgeInsets.all(24), + this.color, + this.gradient }); final Color color; final Widget widget; final EdgeInsets edgeInsets; + final Gradient gradient; @override - TopPanelState createState() => TopPanelState(color, widget, edgeInsets); + TopPanelState createState() => TopPanelState(widget, edgeInsets, color, gradient); } class TopPanelState extends State { - TopPanelState(this._color, this._widget, this._edgeInsets); + TopPanelState(this._widget, this._edgeInsets, this._color, this._gradient); final Color _color; final Widget _widget; final EdgeInsets _edgeInsets; + final Gradient _gradient; @override Widget build(BuildContext context) { @@ -32,7 +35,8 @@ class TopPanelState extends State { bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24) ), - color: _color + color: _color, + gradient: _gradient ), child: _widget, ); diff --git a/lib/store/theme_changer_store.dart b/lib/store/theme_changer_store.dart new file mode 100644 index 000000000..8c2e366ca --- /dev/null +++ b/lib/store/theme_changer_store.dart @@ -0,0 +1,13 @@ +import 'package:cake_wallet/theme_changer.dart'; +import 'package:mobx/mobx.dart'; + +part 'theme_changer_store.g.dart'; + +class ThemeChangerStore = ThemeChangerStoreBase with _$ThemeChangerStore; + +abstract class ThemeChangerStoreBase with Store { + ThemeChangerStoreBase({this.themeChanger}); + + @observable + ThemeChanger themeChanger; +} \ No newline at end of file diff --git a/lib/themes.dart b/lib/themes.dart index f3d25b4f1..887ac072e 100644 --- a/lib/themes.dart +++ b/lib/themes.dart @@ -80,25 +80,35 @@ class Themes { color: Palette.darkGray, // transaction/trade details titles decorationColor: Colors.white.withOpacity(0.5), // placeholder ), - - - - subhead: TextStyle( - color: Colors.white.withOpacity(0.5) // send, exchange, buy buttons on dashboard page + color: Palette.blueCraiola, // first gradient color (send page) + decorationColor: Palette.pinkFlamingo // second gradient color (send page) ), headline: TextStyle( - color: Palette.lightBlueGrey // historyPanelText + color: Colors.white.withOpacity(0.5), // text field border color (send page) + decorationColor: Colors.white.withOpacity(0.5), // text field hint color (send page) ), display1: TextStyle( - color: Colors.white // menuList + color: Colors.white.withOpacity(0.2), // text field button color (send page) + decorationColor: Colors.white // text field button icon color (send page) ), display2: TextStyle( - color: Palette.lavender // menuHeader + color: Colors.white.withOpacity(0.5), // estimated fee (send page) + decorationColor: Palette.shadowWhite // template dotted border (send page) ), display3: TextStyle( - color: Palette.lavender // historyPanelButton + color: Palette.darkBlueCraiola, // template new text (send page) + decorationColor: Palette.shadowWhite // template background color (send page) ), + + + + + + + + + display4: TextStyle( color: Palette.oceanBlue // QR code ), @@ -182,7 +192,7 @@ class Themes { decorationColor: PaletteDark.nightBlue // background of tiles (receive page) ), display3: TextStyle( - color: Colors.blue, // text color of current tile (receive page) + color: Palette.blueCraiola, // text color of current tile (receive page) decorationColor: PaletteDark.lightOceanBlue // background of current tile (receive page) ), display4: TextStyle( @@ -215,24 +225,29 @@ class Themes { color: PaletteDark.lightBlueGrey, // transaction/trade details titles decorationColor: Colors.grey, // placeholder ), - - - subhead: TextStyle( - color: PaletteDark.lightDistantBlue // send, exchange, buy buttons on dashboard page + color: PaletteDark.darkNightBlue, // first gradient color (send page) + decorationColor: PaletteDark.darkNightBlue // second gradient color (send page) ), headline: TextStyle( - color: PaletteDark.pigeonBlue // historyPanelText + color: PaletteDark.lightVioletBlue, // text field border color (send page) + decorationColor: PaletteDark.darkCyanBlue, // text field hint color (send page) ), display1: TextStyle( - color: PaletteDark.lightNightBlue // menuList + color: PaletteDark.buttonNightBlue, // text field button color (send page) + decorationColor: PaletteDark.gray // text field button icon color (send page) ), display2: TextStyle( - color: PaletteDark.headerNightBlue // menuHeader + color: Colors.white, // estimated fee (send page) + decorationColor: PaletteDark.darkCyanBlue // template dotted border (send page) ), display3: TextStyle( - color: PaletteDark.moderateNightBlue // historyPanelButton + color: PaletteDark.darkCyanBlue, // template new text (send page) + decorationColor: PaletteDark.darkVioletBlue // template background color (send page) ), + + + display4: TextStyle( color: PaletteDark.gray // QR code ), diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart index 892b8493e..0986a8310 100644 --- a/lib/view_model/settings/settings_view_model.dart +++ b/lib/view_model/settings/settings_view_model.dart @@ -1,3 +1,6 @@ +import 'package:cake_wallet/di.dart'; +import 'package:cake_wallet/store/theme_changer_store.dart'; +import 'package:cake_wallet/themes.dart'; import 'package:flutter/cupertino.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/routes.dart'; @@ -69,7 +72,9 @@ abstract class SettingsViewModelBase with Store { title: S.current.settings_dark_mode, value: () => _settingsStore.isDarkTheme, onValueChange: (bool value) { - // FIXME: Implement me + _settingsStore.isDarkTheme = value; + getIt.get().themeChanger.setTheme( + value ? Themes.darkTheme : Themes.lightTheme); }) ], [