diff --git a/lib/di.dart b/lib/di.dart index a15c1811a..37061f8aa 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -57,6 +57,7 @@ import 'package:mobx/mobx.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart'; +import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart'; import 'package:cake_wallet/core/wallet_creation_service.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/src/domain/common/wallet_type.dart'; @@ -156,6 +157,16 @@ Future setup( type: type, language: language, seed: mnemonic); }); + getIt + .registerFactoryParam((args, _) { + final type = args.first as WalletType; + final language = args[1] as String; + + return WalletRestorationFromKeysVM( + getIt.get(param1: type), walletInfoSource, + type: type, language: language); + }); + getIt.registerFactory( () => WalletAddressListViewModel(wallet: getIt.get().wallet)); diff --git a/lib/router.dart b/lib/router.dart index ccff5677a..14f658e0c 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -2,6 +2,7 @@ import 'package:cake_wallet/src/screens/dashboard/dashboard_page.dart'; import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart'; import 'package:cake_wallet/view_model/wallet_new_vm.dart'; import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart'; +import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; @@ -165,6 +166,7 @@ class Router { builder: (_) => NewWalletTypePage( onTypeSelected: (context, type) => Navigator.of(context) .pushNamed(Routes.restoreWalletOptions, arguments: type), + isNewWallet: false, )); case Routes.restoreOptions: @@ -236,17 +238,12 @@ class Router { ? args[1] as String : 'English'; // FIXME: Unnamed constant; English default and only one language for bitcoin. + final walletRestorationFromKeysVM = + getIt.get(param1: [type, language]); + return CupertinoPageRoute( - builder: (_) => - ProxyProvider( - update: (_, authStore, __) => WalletRestorationStore( - authStore: authStore, - sharedPreferences: sharedPreferences, - walletListService: walletListService), - child: RestoreWalletFromKeysPage( - walletsService: walletListService, - walletService: walletService, - sharedPreferences: sharedPreferences))); + builder: (_) => RestoreWalletFromKeysPage( + walletRestorationFromKeysVM: walletRestorationFromKeysVM)); case Routes.dashboard: return CupertinoPageRoute( diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart index 1eaf95b46..473d2d6ce 100644 --- a/lib/src/screens/new_wallet/new_wallet_page.dart +++ b/lib/src/screens/new_wallet/new_wallet_page.dart @@ -1,3 +1,5 @@ +import 'package:cake_wallet/di.dart'; +import 'package:cake_wallet/store/settings_store.dart'; import 'package:mobx/mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter/material.dart'; @@ -40,6 +42,7 @@ class _WalletNameFormState extends State { static const aspectRatioImage = 1.22; final walletNameImage = Image.asset('assets/images/wallet_name.png'); + final walletNameLightImage = Image.asset('assets/images/wallet_name_light.png'); final _formKey = GlobalKey(); final _languageSelectorKey = GlobalKey(); ReactionDisposer _stateReaction; @@ -72,6 +75,9 @@ class _WalletNameFormState extends State { @override Widget build(BuildContext context) { + final walletImage = getIt.get().isDarkTheme + ? walletNameImage : walletNameLightImage; + return Container( padding: EdgeInsets.only(top: 24), child: ScrollableWithBottomSection( @@ -82,7 +88,7 @@ class _WalletNameFormState extends State { padding: EdgeInsets.only(left: 12, right: 12), child: AspectRatio( aspectRatio: aspectRatioImage, - child: FittedBox(child: walletNameImage, fit: BoxFit.fill)), + child: FittedBox(child: walletImage, fit: BoxFit.fill)), ), Padding( padding: EdgeInsets.only(top: 24), @@ -98,19 +104,26 @@ class _WalletNameFormState extends State { Theme.of(context).primaryTextTheme.title.color), decoration: InputDecoration( hintStyle: TextStyle( - fontSize: 16.0, + fontSize: 18.0, + fontWeight: FontWeight.w500, color: Theme.of(context) - .primaryTextTheme - .caption + .accentTextTheme + .display3 .color), hintText: S.of(context).wallet_name, focusedBorder: UnderlineInputBorder( borderSide: BorderSide( - color: Theme.of(context).dividerColor, + color: Theme.of(context) + .accentTextTheme + .display3 + .decorationColor, width: 1.0)), enabledBorder: UnderlineInputBorder( borderSide: BorderSide( - color: Theme.of(context).dividerColor, + color: Theme.of(context) + .accentTextTheme + .display3 + .decorationColor, width: 1.0))), validator: WalletNameValidator())), ), @@ -122,7 +135,7 @@ class _WalletNameFormState extends State { textAlign: TextAlign.center, style: TextStyle( fontSize: 16.0, - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w500, color: Theme.of(context).primaryTextTheme.title.color), ), ), diff --git a/lib/src/screens/new_wallet/new_wallet_type_page.dart b/lib/src/screens/new_wallet/new_wallet_type_page.dart index 9dfcfbf33..673bd9478 100644 --- a/lib/src/screens/new_wallet/new_wallet_type_page.dart +++ b/lib/src/screens/new_wallet/new_wallet_type_page.dart @@ -1,4 +1,6 @@ +import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/src/domain/common/wallet_type.dart'; +import 'package:cake_wallet/store/settings_store.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -6,15 +8,17 @@ import 'package:cake_wallet/src/screens/base_page.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/src/screens/new_wallet/widgets/select_button.dart'; -import 'package:cake_wallet/routes.dart'; class NewWalletTypePage extends BasePage { - NewWalletTypePage({this.onTypeSelected}); + NewWalletTypePage({this.onTypeSelected, this.isNewWallet = true}); final void Function(BuildContext, WalletType) onTypeSelected; + final bool isNewWallet; @override - String get title => S.current.new_wallet; + String get title => isNewWallet + ? S.current.new_wallet + : S.current.wallet_list_restore_wallet; @override Widget body(BuildContext context) => @@ -38,6 +42,7 @@ class WalletTypeFormState extends State { final bitcoinIcon = Image.asset('assets/images/bitcoin.png', height: 24, width: 24); final walletTypeImage = Image.asset('assets/images/wallet_type.png'); + final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png'); WalletType selected; List types; @@ -50,6 +55,9 @@ class WalletTypeFormState extends State { @override Widget build(BuildContext context) { + final walletImage = getIt.get().isDarkTheme + ? walletTypeImage : walletTypeLightImage; + return Container( padding: EdgeInsets.only(top: 24), child: ScrollableWithBottomSection( @@ -61,7 +69,7 @@ class WalletTypeFormState extends State { padding: EdgeInsets.only(left: 12, right: 12), child: AspectRatio( aspectRatio: aspectRatioImage, - child: FittedBox(child: walletTypeImage, fit: BoxFit.fill)), + child: FittedBox(child: walletImage, fit: BoxFit.fill)), ), Padding( padding: EdgeInsets.only(top: 48), @@ -70,7 +78,7 @@ class WalletTypeFormState extends State { textAlign: TextAlign.center, style: TextStyle( fontSize: 16, - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w500, color: Theme.of(context).primaryTextTheme.title.color), ), ), @@ -79,8 +87,7 @@ class WalletTypeFormState extends State { child: SelectButton( image: _iconFor(type), text: walletTypeToString(type), - color: _backgroundColorFor(selected == type), - textColor: _textColorFor(selected == type), + isSelected: selected == type, onTap: () => setState(() => selected = type)), )) ], @@ -97,16 +104,6 @@ class WalletTypeFormState extends State { ); } - // FIXME: Move color selection inside ui element; add isSelected to buttons. - - Color _backgroundColorFor(bool isSelected) => isSelected - ? Theme.of(context).accentTextTheme.title.decorationColor - : Theme.of(context).accentTextTheme.title.backgroundColor; - - Color _textColorFor(bool isSelected) => isSelected - ? Theme.of(context).primaryTextTheme.title.backgroundColor - : Theme.of(context).primaryTextTheme.title.color; - Image _iconFor(WalletType type) { switch (type) { case WalletType.monero: diff --git a/lib/src/screens/new_wallet/widgets/select_button.dart b/lib/src/screens/new_wallet/widgets/select_button.dart index 7e583ec4e..bd69a8015 100644 --- a/lib/src/screens/new_wallet/widgets/select_button.dart +++ b/lib/src/screens/new_wallet/widgets/select_button.dart @@ -4,21 +4,30 @@ class SelectButton extends StatelessWidget { SelectButton({ @required this.image, @required this.text, - @required this.color, - @required this.textColor, @required this.onTap, + this.isSelected = false, }); final Image image; final String text; - final Color color; - final Color textColor; + final bool isSelected; final VoidCallback onTap; - final selectArrowImage = Image.asset('assets/images/select_arrow.png'); - @override Widget build(BuildContext context) { + final color = isSelected + ? Theme.of(context).accentTextTheme.subtitle.decorationColor + : Theme.of(context).accentTextTheme.caption.color; + final textColor = isSelected + ? Theme.of(context).accentTextTheme.headline.decorationColor + : Theme.of(context).primaryTextTheme.title.color; + final arrowColor = isSelected + ? Theme.of(context).accentTextTheme.headline.decorationColor + : Theme.of(context).accentTextTheme.subhead.color; + + final selectArrowImage = Image.asset('assets/images/select_arrow.png', + color: arrowColor); + return GestureDetector( onTap: onTap, child: Container( @@ -39,9 +48,7 @@ class SelectButton extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ - image != null - ? image - : Offstage(), + image ?? Offstage(), Padding( padding: image != null ? EdgeInsets.only(left: 15) @@ -50,7 +57,7 @@ class SelectButton extends StatelessWidget { text, style: TextStyle( fontSize: 18, - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w500, color: textColor ), ), diff --git a/lib/src/screens/restore/restore_wallet_from_keys_page.dart b/lib/src/screens/restore/restore_wallet_from_keys_page.dart index 766ef7a0e..6f950f6e4 100644 --- a/lib/src/screens/restore/restore_wallet_from_keys_page.dart +++ b/lib/src/screens/restore/restore_wallet_from_keys_page.dart @@ -1,40 +1,36 @@ -import 'package:mobx/mobx.dart'; -import 'package:provider/provider.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:cake_wallet/core/validator.dart'; +import 'package:cake_wallet/palette.dart'; import 'package:flutter/services.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/domain/services/wallet_list_service.dart'; -import 'package:cake_wallet/src/domain/services/wallet_service.dart'; -import 'package:cake_wallet/src/stores/wallet_restoration/wallet_restoration_store.dart'; -import 'package:cake_wallet/src/stores/wallet_restoration/wallet_restoration_state.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; -import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; +import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart'; +import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; class RestoreWalletFromKeysPage extends BasePage { RestoreWalletFromKeysPage( - {@required this.walletsService, - @required this.sharedPreferences, - @required this.walletService}); + {@required this.walletRestorationFromKeysVM}); - final WalletListService walletsService; - final WalletService walletService; - final SharedPreferences sharedPreferences; + final WalletRestorationFromKeysVM walletRestorationFromKeysVM; @override String get title => S.current.restore_title_from_keys; @override - Widget body(BuildContext context) => RestoreFromKeysFrom(); + Widget body(BuildContext context) => RestoreFromKeysFrom(walletRestorationFromKeysVM); } class RestoreFromKeysFrom extends StatefulWidget { + RestoreFromKeysFrom(this.walletRestorationFromKeysVM); + + final WalletRestorationFromKeysVM walletRestorationFromKeysVM; + @override _RestoreFromKeysFromState createState() => _RestoreFromKeysFromState(); } @@ -46,6 +42,23 @@ class _RestoreFromKeysFromState extends State { final _addressController = TextEditingController(); final _viewKeyController = TextEditingController(); final _spendKeyController = TextEditingController(); + final _wifController = TextEditingController(); + + @override + void initState() { + _nameController.addListener(() => + widget.walletRestorationFromKeysVM.name = _nameController.text); + _addressController.addListener(() => + widget.walletRestorationFromKeysVM.address = _addressController.text); + _viewKeyController.addListener(() => + widget.walletRestorationFromKeysVM.viewKey = _viewKeyController.text); + _spendKeyController.addListener(() => + widget.walletRestorationFromKeysVM.spendKey = _spendKeyController.text); + _wifController.addListener(() => + widget.walletRestorationFromKeysVM.wif = _wifController.text); + + super.initState(); + } @override void dispose() { @@ -53,31 +66,14 @@ class _RestoreFromKeysFromState extends State { _addressController.dispose(); _viewKeyController.dispose(); _spendKeyController.dispose(); + _wifController.dispose(); super.dispose(); } - void onHandleControllers(WalletRestorationStore walletRestorationStore) { - if (_nameController.text.isNotEmpty && - _addressController.text.isNotEmpty && - _viewKeyController.text.isNotEmpty && - _spendKeyController.text.isNotEmpty) { - walletRestorationStore.setDisabledState(false); - } else { - walletRestorationStore.setDisabledState(true); - } - } - @override Widget build(BuildContext context) { - final walletRestorationStore = Provider.of(context); - final seedLanguageStore = Provider.of(context); - _nameController.addListener(() {onHandleControllers(walletRestorationStore);}); - _addressController.addListener(() {onHandleControllers(walletRestorationStore);}); - _viewKeyController.addListener(() {onHandleControllers(walletRestorationStore);}); - _spendKeyController.addListener(() {onHandleControllers(walletRestorationStore);}); - - reaction((_) => walletRestorationStore.state, (WalletRestorationState state) { + /*reaction((_) => walletRestorationStore.state, (WalletRestorationState state) { if (state is WalletRestoredSuccessfully) { Navigator.of(context).popUntil((route) => route.isFirst); } @@ -96,7 +92,7 @@ class _RestoreFromKeysFromState extends State { }); }); } - }); + });*/ return Container( padding: EdgeInsets.only(left: 24, right: 24), @@ -110,66 +106,39 @@ class _RestoreFromKeysFromState extends State { Flexible( child: Container( padding: EdgeInsets.only(top: 20.0), - child: TextFormField( - style: TextStyle( - fontSize: 16.0, - color: Theme.of(context).primaryTextTheme.title.color - ), + child: BaseTextFormField( controller: _nameController, - decoration: InputDecoration( - hintStyle: TextStyle( - color: Theme.of(context).primaryTextTheme.caption.color, - fontSize: 16 - ), - hintText: S.of(context).restore_wallet_name, - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0)), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0))), - validator: (value) { - walletRestorationStore.validateWalletName(value); - return walletRestorationStore.errorMessage; - }, - ), + hintText: S.of(context).restore_wallet_name, + validator: WalletNameValidator(), + ) )) ], ), + if (!widget.walletRestorationFromKeysVM.hasRestorationHeight) + Row( + children: [ + Flexible( + child: Container( + padding: EdgeInsets.only(top: 20.0), + child: BaseTextFormField( + controller: _wifController, + hintText: 'WIF', + ) + )) + ], + ), + if (widget.walletRestorationFromKeysVM.hasRestorationHeight) ... [ Row( children: [ Flexible( child: Container( padding: EdgeInsets.only(top: 20.0), - child: TextFormField( - style: TextStyle( - fontSize: 16.0, - color: Theme.of(context).primaryTextTheme.title.color - ), + child: BaseTextFormField( controller: _addressController, keyboardType: TextInputType.multiline, maxLines: null, - decoration: InputDecoration( - hintStyle: TextStyle( - color: Theme.of(context).primaryTextTheme.caption.color, - fontSize: 16 - ), - hintText: S.of(context).restore_address, - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0)), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0))), - validator: (value) { - walletRestorationStore.validateAddress(value); - return walletRestorationStore.errorMessage; - }, - ), + hintText: S.of(context).restore_address, + ) )) ], ), @@ -178,31 +147,10 @@ class _RestoreFromKeysFromState extends State { Flexible( child: Container( padding: EdgeInsets.only(top: 20.0), - child: TextFormField( - style: TextStyle( - fontSize: 16.0, - color: Theme.of(context).primaryTextTheme.title.color - ), + child: BaseTextFormField( controller: _viewKeyController, - decoration: InputDecoration( - hintStyle: TextStyle( - color: Theme.of(context).primaryTextTheme.caption.color, - fontSize: 16 - ), - hintText: S.of(context).restore_view_key_private, - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0)), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0))), - validator: (value) { - walletRestorationStore.validateKeys(value); - return walletRestorationStore.errorMessage; - }, - ), + hintText: S.of(context).restore_view_key_private, + ) )) ], ), @@ -211,35 +159,19 @@ class _RestoreFromKeysFromState extends State { Flexible( child: Container( padding: EdgeInsets.only(top: 20.0), - child: TextFormField( - style: TextStyle( - fontSize: 16.0, - color: Theme.of(context).primaryTextTheme.title.color - ), + child: BaseTextFormField( controller: _spendKeyController, - decoration: InputDecoration( - hintStyle: TextStyle( - color: Theme.of(context).primaryTextTheme.caption.color, - fontSize: 16 - ), - hintText: S.of(context).restore_spend_key_private, - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0)), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0))), - validator: (value) { - walletRestorationStore.validateKeys(value); - return walletRestorationStore.errorMessage; - }, - ), + hintText: S.of(context).restore_spend_key_private, + ) )) ], ), - BlockchainHeightWidget(key: _blockchainHeightKey), + BlockchainHeightWidget( + key: _blockchainHeightKey, + onHeightChange: (height) { + widget.walletRestorationFromKeysVM.height = height; + print(height); + })], ]), ), bottomSectionPadding: EdgeInsets.only(bottom: 24), @@ -247,19 +179,19 @@ class _RestoreFromKeysFromState extends State { return LoadingPrimaryButton( onPressed: () { if (_formKey.currentState.validate()) { - walletRestorationStore.restoreFromKeys( + /*walletRestorationStore.restoreFromKeys( name: _nameController.text, language: seedLanguageStore.selectedSeedLanguage, address: _addressController.text, viewKey: _viewKeyController.text, spendKey: _spendKeyController.text, - restoreHeight: _blockchainHeightKey.currentState.height); + restoreHeight: _blockchainHeightKey.currentState.height);*/ } }, text: S.of(context).restore_recover, - color: Colors.green, + color: Palette.blueCraiola, textColor: Colors.white, - isDisabled: walletRestorationStore.disabledState, + //isDisabled: walletRestorationStore.disabledState, ); }), ), diff --git a/lib/src/screens/restore/restore_wallet_from_seed_details.dart b/lib/src/screens/restore/restore_wallet_from_seed_details.dart index 5a83a8b3c..3225be9e7 100644 --- a/lib/src/screens/restore/restore_wallet_from_seed_details.dart +++ b/lib/src/screens/restore/restore_wallet_from_seed_details.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/palette.dart'; import 'package:mobx/mobx.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -9,6 +10,7 @@ import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; +import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart'; class RestoreWalletFromSeedDetailsPage extends BasePage { @@ -91,27 +93,9 @@ class _RestoreFromSeedDetailsFormState Flexible( child: Container( padding: EdgeInsets.only(top: 20.0), - child: TextFormField( - style: TextStyle( - fontSize: 16.0, - color: Theme.of(context).primaryTextTheme.title.color), + child: BaseTextFormField( controller: _nameController, - decoration: InputDecoration( - hintStyle: TextStyle( - color: Theme.of(context) - .primaryTextTheme - .caption - .color, - fontSize: 16), - hintText: S.of(context).restore_wallet_name, - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0)), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0))), + hintText: S.of(context).restore_wallet_name, validator: WalletNameValidator(), ), )) @@ -137,7 +121,7 @@ class _RestoreFromSeedDetailsFormState isLoading: widget.walletRestorationFromSeedVM.state is WalletCreating, text: S.of(context).restore_recover, - color: Colors.green, + color: Palette.blueCraiola, textColor: Colors.white, isDisabled: _nameController.text.isNotEmpty, ); diff --git a/lib/src/screens/seed_language/seed_language_page.dart b/lib/src/screens/seed_language/seed_language_page.dart index 48b2fd5b6..ccee8aae5 100644 --- a/lib/src/screens/seed_language/seed_language_page.dart +++ b/lib/src/screens/seed_language/seed_language_page.dart @@ -1,5 +1,6 @@ +import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/src/widgets/seed_language_selector.dart'; -import 'package:provider/provider.dart'; +import 'package:cake_wallet/store/settings_store.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; @@ -7,8 +8,6 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/screens/base_page.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/src/stores/seed_language/seed_language_store.dart'; -import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart'; import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart'; class SeedLanguage extends BasePage { @@ -16,6 +15,9 @@ class SeedLanguage extends BasePage { final Function(BuildContext, String) onConfirm; + @override + String get title => S.current.wallet_list_restore_wallet; + @override Widget body(BuildContext context) => SeedLanguageForm(onConfirm: onConfirm); } @@ -33,10 +35,14 @@ class SeedLanguageFormState extends State { static const aspectRatioImage = 1.22; final walletNameImage = Image.asset('assets/images/wallet_name.png'); + final walletNameLightImage = Image.asset('assets/images/wallet_name_light.png'); final _languageSelectorKey = GlobalKey(); @override Widget build(BuildContext context) { + final walletImage = getIt.get().isDarkTheme + ? walletNameImage : walletNameLightImage; + return Container( padding: EdgeInsets.only(top: 24), child: ScrollableWithBottomSection( @@ -47,7 +53,7 @@ class SeedLanguageFormState extends State { padding: EdgeInsets.only(left: 12, right: 12), child: AspectRatio( aspectRatio: aspectRatioImage, - child: FittedBox(child: walletNameImage, fit: BoxFit.fill)), + child: FittedBox(child: walletImage, fit: BoxFit.fill)), ), Padding( padding: EdgeInsets.only(top: 40), @@ -56,7 +62,7 @@ class SeedLanguageFormState extends State { textAlign: TextAlign.center, style: TextStyle( fontSize: 16.0, - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w500, color: Theme.of(context).primaryTextTheme.title.color), ), ), diff --git a/lib/src/screens/seed_language/widgets/seed_language_picker.dart b/lib/src/screens/seed_language/widgets/seed_language_picker.dart index cc476b294..47e43c7c7 100644 --- a/lib/src/screens/seed_language/widgets/seed_language_picker.dart +++ b/lib/src/screens/seed_language/widgets/seed_language_picker.dart @@ -1,9 +1,9 @@ import 'dart:ui'; +import 'package:cake_wallet/src/widgets/alert_background.dart'; +import 'package:cake_wallet/src/widgets/alert_close_button.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/palette.dart'; -import 'package:provider/provider.dart'; -import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart'; import 'package:cake_wallet/generated/i18n.dart'; List flagImages = [ @@ -57,170 +57,111 @@ class SeedLanguagePicker extends StatefulWidget { class SeedLanguagePickerState extends State { SeedLanguagePickerState({this.selected}); + final closeButton = Image.asset('assets/images/close.png'); String selected; @override Widget build(BuildContext context) { - return GestureDetector( - onTap: () => Navigator.of(context).pop(), - child: Container( - color: Colors.transparent, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0), - child: Container( - decoration: BoxDecoration( - color: PaletteDark.darkNightBlue.withOpacity(0.75)), - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: EdgeInsets.only(left: 24, right: 24), - child: Text( - S.of(context).seed_choose, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - decoration: TextDecoration.none, - color: Colors.white), + return AlertBackground( + child: Stack( + alignment: Alignment.center, + children: [ + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.only(left: 24, right: 24), + child: Text( + S.of(context).seed_choose, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + decoration: TextDecoration.none, + color: Colors.white ), ), - Padding( - padding: EdgeInsets.only(top: 24), - child: GestureDetector( - onTap: () => null, - child: Container( - height: 300, - width: 300, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(14)), - color: Theme.of(context).dividerColor), - child: GridView.count( - shrinkWrap: true, - crossAxisCount: 3, - childAspectRatio: 1, - physics: const NeverScrollableScrollPhysics(), - crossAxisSpacing: 1, - mainAxisSpacing: 1, - children: List.generate(9, (index) { - if (index == 8) { - return gridTile( - isCurrent: false, - place: Places.bottomRight, - image: null, - text: '', - onTap: null); - } else { - final code = languageCodes[index]; - final flag = flagImages[index]; - final isCurrent = - index == seedLanguages.indexOf(selected); + ), + Padding( + padding: EdgeInsets.only(top: 24), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(14)), + child: Container( + height: 300, + width: 300, + color: Theme.of(context).accentTextTheme.title.backgroundColor, + child: GridView.count( + shrinkWrap: true, + crossAxisCount: 3, + childAspectRatio: 1, + physics: const NeverScrollableScrollPhysics(), + crossAxisSpacing: 1, + mainAxisSpacing: 1, + children: List.generate(9, (index) { - if (index == 0) { - return gridTile( - isCurrent: isCurrent, - place: Places.topLeft, - image: flag, - text: code, - onTap: () { - selected = seedLanguages[index]; - Navigator.of(context).pop(selected); - }); + if (index == 8) { + + return gridTile( + isCurrent: false, + image: null, + text: '', + onTap: null); + + } + + final code = languageCodes[index]; + final flag = flagImages[index]; + final isCurrent = + index == seedLanguages.indexOf(selected); + + return gridTile( + isCurrent: isCurrent, + image: flag, + text: code, + onTap: () { + selected = seedLanguages[index]; + Navigator.of(context).pop(selected); } - - if (index == 2) { - return gridTile( - isCurrent: isCurrent, - place: Places.topRight, - image: flag, - text: code, - onTap: () { - selected = seedLanguages[index]; - Navigator.of(context).pop(selected); - }); - } - - if (index == 6) { - return gridTile( - isCurrent: isCurrent, - place: Places.bottomLeft, - image: flag, - text: code, - onTap: () { - selected = seedLanguages[index]; - Navigator.of(context).pop(selected); - }); - } - - return gridTile( - isCurrent: isCurrent, - place: Places.inside, - image: flag, - text: code, - onTap: () { - selected = seedLanguages[index]; - Navigator.of(context).pop(selected); - }); - } - }), - ), + ); + }), ), ), - ) - ], - ), + ), + ) + ], ), - ), - ), - ), + AlertCloseButton(image: closeButton) + ], + ) ); } - Widget gridTile( - {@required bool isCurrent, - @required Places place, - @required Image image, - @required String text, - @required VoidCallback onTap}) { - BorderRadius borderRadius; - final color = isCurrent - ? Theme.of(context).accentTextTheme.subtitle.decorationColor - : Theme.of(context).primaryTextTheme.display1.color; - final textColor = isCurrent - ? Colors.blue - : Theme.of(context).primaryTextTheme.title.color; + Widget gridTile({ + @required bool isCurrent, + @required Image image, + @required String text, + @required VoidCallback onTap}) { - switch (place) { - case Places.topLeft: - borderRadius = BorderRadius.only(topLeft: Radius.circular(14)); - break; - case Places.topRight: - borderRadius = BorderRadius.only(topRight: Radius.circular(14)); - break; - case Places.bottomLeft: - borderRadius = BorderRadius.only(bottomLeft: Radius.circular(14)); - break; - case Places.bottomRight: - borderRadius = BorderRadius.only(bottomRight: Radius.circular(14)); - break; - case Places.inside: - borderRadius = BorderRadius.all(Radius.circular(0)); - break; - } + final color = isCurrent + ? Theme.of(context).textTheme.body2.color + : Theme.of(context).accentTextTheme.title.color; + final textColor = isCurrent + ? Palette.blueCraiola + : Theme.of(context).primaryTextTheme.title.color; return GestureDetector( onTap: onTap, child: Container( padding: EdgeInsets.all(10), - decoration: BoxDecoration(borderRadius: borderRadius, color: color), + color: color, child: Center( child: Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - image != null ? image : Offstage(), + image ?? Offstage(), Padding( padding: image != null ? EdgeInsets.only(left: 10) @@ -229,14 +170,17 @@ class SeedLanguagePickerState extends State { text, style: TextStyle( fontSize: 18, - fontWeight: FontWeight.bold, + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', decoration: TextDecoration.none, - color: textColor), + color: textColor + ), ), ) ], ), ), - )); + ) + ); } } diff --git a/lib/src/widgets/blockchain_height_widget.dart b/lib/src/widgets/blockchain_height_widget.dart index 9e66d4077..2f6105887 100644 --- a/lib/src/widgets/blockchain_height_widget.dart +++ b/lib/src/widgets/blockchain_height_widget.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/domain/monero/get_height_by_date.dart'; +import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; class BlockchainHeightWidget extends StatefulWidget { BlockchainHeightWidget({GlobalKey key, this.onHeightChange}) @@ -46,26 +47,12 @@ class BlockchainHeightState extends State { Flexible( child: Container( padding: EdgeInsets.only(top: 20.0, bottom: 10.0), - child: TextFormField( - style: TextStyle( - fontSize: 16.0, - color: Theme.of(context).primaryTextTheme.title.color), + child: BaseTextFormField( controller: restoreHeightController, keyboardType: TextInputType.numberWithOptions( signed: false, decimal: false), - decoration: InputDecoration( - hintStyle: TextStyle( - color: Theme.of(context).primaryTextTheme.caption.color, - fontSize: 16), - hintText: S.of(context).widgets_restore_from_blockheight, - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, width: 1.0)), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0))), - ), + hintText: S.of(context).widgets_restore_from_blockheight, + ) )) ], ), @@ -75,7 +62,7 @@ class BlockchainHeightState extends State { S.of(context).widgets_or, style: TextStyle( fontSize: 16.0, - fontWeight: FontWeight.bold, + fontWeight: FontWeight.w500, color: Theme.of(context).primaryTextTheme.title.color), ), ), @@ -86,31 +73,10 @@ class BlockchainHeightState extends State { child: InkWell( onTap: () => _selectDate(context), child: IgnorePointer( - child: TextFormField( - style: TextStyle( - fontSize: 16.0, - color: Theme.of(context).primaryTextTheme.title.color), - decoration: InputDecoration( - hintStyle: TextStyle( - color: Theme.of(context) - .primaryTextTheme - .caption - .color, - fontSize: 16), - hintText: S.of(context).widgets_restore_from_date, - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0)), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0))), + child: BaseTextFormField( controller: dateController, - validator: (value) { - return null; - }, - ), + hintText: S.of(context).widgets_restore_from_date, + ) ), ), )) diff --git a/lib/src/widgets/seed_language_selector.dart b/lib/src/widgets/seed_language_selector.dart index f66cadb8e..74420d370 100644 --- a/lib/src/widgets/seed_language_selector.dart +++ b/lib/src/widgets/seed_language_selector.dart @@ -34,14 +34,14 @@ class SeedLanguageSelectorState extends State { return SelectButton( image: null, text: seedLocales[seedLanguages.indexOf(selected)], - color: Theme.of(context).accentTextTheme.title.backgroundColor, - textColor: Theme.of(context).primaryTextTheme.title.color, onTap: () async { final selected = await showDialog( context: context, builder: (BuildContext context) => SeedLanguagePicker(key: _pickerKey, selected: this.selected)); - setState(() => this.selected = selected); + if (selected != null) { + setState(() => this.selected = selected); + } }); } } diff --git a/lib/themes.dart b/lib/themes.dart index 452264e21..e2f75b7ff 100644 --- a/lib/themes.dart +++ b/lib/themes.dart @@ -156,6 +156,10 @@ class Themes { color: Palette.shadowWhite, // action button color (address text field) decorationColor: Palette.darkGray // hint text (seed widget) ), + display3: TextStyle( + color: Palette.darkGray, // hint text (new wallet page) + decorationColor: Palette.periwinkleCraiola // underline (new wallet page) + ), ), @@ -323,6 +327,10 @@ class Themes { color: PaletteDark.nightBlue, // action button color (address text field) decorationColor: PaletteDark.darkCyanBlue // hint text (seed widget) ), + display3: TextStyle( + color: PaletteDark.cyanBlue, // hint text (new wallet page) + decorationColor: PaletteDark.darkGrey // underline (new wallet page) + ), ), diff --git a/lib/view_model/wallet_restoration_from_keys_vm.dart b/lib/view_model/wallet_restoration_from_keys_vm.dart new file mode 100644 index 000000000..e0e0114c6 --- /dev/null +++ b/lib/view_model/wallet_restoration_from_keys_vm.dart @@ -0,0 +1,64 @@ +import 'package:flutter/foundation.dart'; +import 'package:hive/hive.dart'; +import 'package:mobx/mobx.dart'; +import 'package:cake_wallet/monero/monero_wallet_service.dart'; +import 'package:cake_wallet/bitcoin/bitcoin_wallet_creation_credentials.dart'; +import 'package:cake_wallet/core/generate_wallet_password.dart'; +import 'package:cake_wallet/core/wallet_creation_service.dart'; +import 'package:cake_wallet/core/wallet_credentials.dart'; +import 'package:cake_wallet/src/domain/common/wallet_type.dart'; +import 'package:cake_wallet/view_model/wallet_creation_vm.dart'; +import 'package:cake_wallet/src/domain/common/wallet_info.dart'; + +part 'wallet_restoration_from_keys_vm.g.dart'; + +class WalletRestorationFromKeysVM = WalletRestorationFromKeysVMBase + with _$WalletRestorationFromKeysVM; + +abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM + with Store { + WalletRestorationFromKeysVMBase(this._walletCreationService, Box walletInfoSource, + {@required WalletType type, @required this.language}) + : super(walletInfoSource, type: type, isRecovery: true); + + @observable + int height; + + @observable + String viewKey; + + @observable + String spendKey; + + @observable + String wif; + + @observable + String address; + + bool get hasRestorationHeight => type == WalletType.monero; + + final String language; + final WalletCreationService _walletCreationService; + + @override + WalletCredentials getCredentials(dynamic options) { + final password = generateWalletPassword(type); + + switch (type) { + case WalletType.monero: + return MoneroRestoreWalletFromKeysCredentials( + name: name, password: password, language: language, address: address, + viewKey: viewKey, spendKey: spendKey, height: height); + case WalletType.bitcoin: + return BitcoinRestoreWalletFromWIFCredentials( + name: name, password: password, wif: wif); + default: + return null; + } + } + + @override + Future process(WalletCredentials credentials) async => + _walletCreationService.restoreFromKeys(credentials); +}