CAKE-31 | created wallet_restoration_from_keys_vm; applied new design to restore_wallet_from_keys_page, restore_wallet_from_seed_details, new_wallet_page, new_wallet_type_page, seed_language_page; reworked seed_language_selector, seed_language_picker, select_button

OleksandrSobol committed Sep 4, 2020 at 13:40 UTC f1ec962b61887b29121238cecdc44f6b19dfa605
13 files changed +322 -393
lib/di.dart
+11
@@ -57,6 +57,7 @@ import 'package:mobx/mobx.dart';
57 import 'package:shared_preferences/shared_preferences.dart';
58 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
59 import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
60 +import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart';
61 import 'package:cake_wallet/core/wallet_creation_service.dart';
62 import 'package:cake_wallet/store/app_store.dart';
63 import 'package:cake_wallet/src/domain/common/wallet_type.dart';
@@ -156,6 +157,16 @@ Future setup(
157 type: type, language: language, seed: mnemonic);
158 });
159
160 + getIt
161 + .registerFactoryParam<WalletRestorationFromKeysVM, List, void>((args, _) {
162 + final type = args.first as WalletType;
163 + final language = args[1] as String;
164 +
165 + return WalletRestorationFromKeysVM(
166 + getIt.get<WalletCreationService>(param1: type), walletInfoSource,
167 + type: type, language: language);
168 + });
169 +
170 getIt.registerFactory<WalletAddressListViewModel>(
171 () => WalletAddressListViewModel(wallet: getIt.get<AppStore>().wallet));
172
lib/router.dart
+7 -10
@@ -2,6 +2,7 @@ import 'package:cake_wallet/src/screens/dashboard/dashboard_page.dart';
2 import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart';
3 import 'package:cake_wallet/view_model/wallet_new_vm.dart';
4 import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
5 +import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart';
6 import 'package:flutter/cupertino.dart';
7 import 'package:flutter/material.dart';
8 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
@@ -165,6 +166,7 @@ class Router {
166 builder: (_) => NewWalletTypePage(
167 onTypeSelected: (context, type) => Navigator.of(context)
168 .pushNamed(Routes.restoreWalletOptions, arguments: type),
169 + isNewWallet: false,
170 ));
171
172 case Routes.restoreOptions:
@@ -236,17 +238,12 @@ class Router {
238 ? args[1] as String
239 : 'English'; // FIXME: Unnamed constant; English default and only one language for bitcoin.
240
241 + final walletRestorationFromKeysVM =
242 + getIt.get<WalletRestorationFromKeysVM>(param1: [type, language]);
243 +
244 return CupertinoPageRoute<void>(
240 - builder: (_) =>
241 - ProxyProvider<AuthenticationStore, WalletRestorationStore>(
242 - update: (_, authStore, __) => WalletRestorationStore(
243 - authStore: authStore,
244 - sharedPreferences: sharedPreferences,
245 - walletListService: walletListService),
246 - child: RestoreWalletFromKeysPage(
247 - walletsService: walletListService,
248 - walletService: walletService,
249 - sharedPreferences: sharedPreferences)));
245 + builder: (_) => RestoreWalletFromKeysPage(
246 + walletRestorationFromKeysVM: walletRestorationFromKeysVM));
247
248 case Routes.dashboard:
249 return CupertinoPageRoute<void>(
lib/src/screens/new_wallet/new_wallet_page.dart
+20 -7
@@ -1,3 +1,5 @@
1 +import 'package:cake_wallet/di.dart';
2 +import 'package:cake_wallet/store/settings_store.dart';
3 import 'package:mobx/mobx.dart';
4 import 'package:flutter_mobx/flutter_mobx.dart';
5 import 'package:flutter/material.dart';
@@ -40,6 +42,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
42 static const aspectRatioImage = 1.22;
43
44 final walletNameImage = Image.asset('assets/images/wallet_name.png');
45 + final walletNameLightImage = Image.asset('assets/images/wallet_name_light.png');
46 final _formKey = GlobalKey<FormState>();
47 final _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>();
48 ReactionDisposer _stateReaction;
@@ -72,6 +75,9 @@ class _WalletNameFormState extends State<WalletNameForm> {
75
76 @override
77 Widget build(BuildContext context) {
78 + final walletImage = getIt.get<SettingsStore>().isDarkTheme
79 + ? walletNameImage : walletNameLightImage;
80 +
81 return Container(
82 padding: EdgeInsets.only(top: 24),
83 child: ScrollableWithBottomSection(
@@ -82,7 +88,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
88 padding: EdgeInsets.only(left: 12, right: 12),
89 child: AspectRatio(
90 aspectRatio: aspectRatioImage,
85 - child: FittedBox(child: walletNameImage, fit: BoxFit.fill)),
91 + child: FittedBox(child: walletImage, fit: BoxFit.fill)),
92 ),
93 Padding(
94 padding: EdgeInsets.only(top: 24),
@@ -98,19 +104,26 @@ class _WalletNameFormState extends State<WalletNameForm> {
104 Theme.of(context).primaryTextTheme.title.color),
105 decoration: InputDecoration(
106 hintStyle: TextStyle(
101 - fontSize: 16.0,
107 + fontSize: 18.0,
108 + fontWeight: FontWeight.w500,
109 color: Theme.of(context)
103 - .primaryTextTheme
104 - .caption
110 + .accentTextTheme
111 + .display3
112 .color),
113 hintText: S.of(context).wallet_name,
114 focusedBorder: UnderlineInputBorder(
115 borderSide: BorderSide(
109 - color: Theme.of(context).dividerColor,
116 + color: Theme.of(context)
117 + .accentTextTheme
118 + .display3
119 + .decorationColor,
120 width: 1.0)),
121 enabledBorder: UnderlineInputBorder(
122 borderSide: BorderSide(
113 - color: Theme.of(context).dividerColor,
123 + color: Theme.of(context)
124 + .accentTextTheme
125 + .display3
126 + .decorationColor,
127 width: 1.0))),
128 validator: WalletNameValidator())),
129 ),
@@ -122,7 +135,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
135 textAlign: TextAlign.center,
136 style: TextStyle(
137 fontSize: 16.0,
125 - fontWeight: FontWeight.w600,
138 + fontWeight: FontWeight.w500,
139 color: Theme.of(context).primaryTextTheme.title.color),
140 ),
141 ),
lib/src/screens/new_wallet/new_wallet_type_page.dart
+14 -17
@@ -1,4 +1,6 @@
1 +import 'package:cake_wallet/di.dart';
2 import 'package:cake_wallet/src/domain/common/wallet_type.dart';
3 +import 'package:cake_wallet/store/settings_store.dart';
4 import 'package:flutter/material.dart';
5 import 'package:flutter/cupertino.dart';
6 import 'package:cake_wallet/generated/i18n.dart';
@@ -6,15 +8,17 @@ import 'package:cake_wallet/src/screens/base_page.dart';
8 import 'package:cake_wallet/src/widgets/primary_button.dart';
9 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
10 import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
9 -import 'package:cake_wallet/routes.dart';
11
12 class NewWalletTypePage extends BasePage {
12 - NewWalletTypePage({this.onTypeSelected});
13 + NewWalletTypePage({this.onTypeSelected, this.isNewWallet = true});
14
15 final void Function(BuildContext, WalletType) onTypeSelected;
16 + final bool isNewWallet;
17
18 @override
17 - String get title => S.current.new_wallet;
19 + String get title => isNewWallet
20 + ? S.current.new_wallet
21 + : S.current.wallet_list_restore_wallet;
22
23 @override
24 Widget body(BuildContext context) =>
@@ -38,6 +42,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
42 final bitcoinIcon =
43 Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
44 final walletTypeImage = Image.asset('assets/images/wallet_type.png');
45 + final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png');
46
47 WalletType selected;
48 List<WalletType> types;
@@ -50,6 +55,9 @@ class WalletTypeFormState extends State<WalletTypeForm> {
55
56 @override
57 Widget build(BuildContext context) {
58 + final walletImage = getIt.get<SettingsStore>().isDarkTheme
59 + ? walletTypeImage : walletTypeLightImage;
60 +
61 return Container(
62 padding: EdgeInsets.only(top: 24),
63 child: ScrollableWithBottomSection(
@@ -61,7 +69,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
69 padding: EdgeInsets.only(left: 12, right: 12),
70 child: AspectRatio(
71 aspectRatio: aspectRatioImage,
64 - child: FittedBox(child: walletTypeImage, fit: BoxFit.fill)),
72 + child: FittedBox(child: walletImage, fit: BoxFit.fill)),
73 ),
74 Padding(
75 padding: EdgeInsets.only(top: 48),
@@ -70,7 +78,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
78 textAlign: TextAlign.center,
79 style: TextStyle(
80 fontSize: 16,
73 - fontWeight: FontWeight.w600,
81 + fontWeight: FontWeight.w500,
82 color: Theme.of(context).primaryTextTheme.title.color),
83 ),
84 ),
@@ -79,8 +87,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
87 child: SelectButton(
88 image: _iconFor(type),
89 text: walletTypeToString(type),
82 - color: _backgroundColorFor(selected == type),
83 - textColor: _textColorFor(selected == type),
90 + isSelected: selected == type,
91 onTap: () => setState(() => selected = type)),
92 ))
93 ],
@@ -97,16 +104,6 @@ class WalletTypeFormState extends State<WalletTypeForm> {
104 );
105 }
106
100 - // FIXME: Move color selection inside ui element; add isSelected to buttons.
101 -
102 - Color _backgroundColorFor(bool isSelected) => isSelected
103 - ? Theme.of(context).accentTextTheme.title.decorationColor
104 - : Theme.of(context).accentTextTheme.title.backgroundColor;
105 -
106 - Color _textColorFor(bool isSelected) => isSelected
107 - ? Theme.of(context).primaryTextTheme.title.backgroundColor
108 - : Theme.of(context).primaryTextTheme.title.color;
109 -
107 Image _iconFor(WalletType type) {
108 switch (type) {
109 case WalletType.monero:
lib/src/screens/new_wallet/widgets/select_button.dart
+17 -10
@@ -4,21 +4,30 @@ class SelectButton extends StatelessWidget {
4 SelectButton({
5 @required this.image,
6 @required this.text,
7 - @required this.color,
8 - @required this.textColor,
7 @required this.onTap,
8 + this.isSelected = false,
9 });
10
11 final Image image;
12 final String text;
14 - final Color color;
15 - final Color textColor;
13 + final bool isSelected;
14 final VoidCallback onTap;
15
18 - final selectArrowImage = Image.asset('assets/images/select_arrow.png');
19 -
16 @override
17 Widget build(BuildContext context) {
18 + final color = isSelected
19 + ? Theme.of(context).accentTextTheme.subtitle.decorationColor
20 + : Theme.of(context).accentTextTheme.caption.color;
21 + final textColor = isSelected
22 + ? Theme.of(context).accentTextTheme.headline.decorationColor
23 + : Theme.of(context).primaryTextTheme.title.color;
24 + final arrowColor = isSelected
25 + ? Theme.of(context).accentTextTheme.headline.decorationColor
26 + : Theme.of(context).accentTextTheme.subhead.color;
27 +
28 + final selectArrowImage = Image.asset('assets/images/select_arrow.png',
29 + color: arrowColor);
30 +
31 return GestureDetector(
32 onTap: onTap,
33 child: Container(
@@ -39,9 +48,7 @@ class SelectButton extends StatelessWidget {
48 mainAxisAlignment: MainAxisAlignment.start,
49 crossAxisAlignment: CrossAxisAlignment.center,
50 children: <Widget>[
42 - image != null
43 - ? image
44 - : Offstage(),
51 + image ?? Offstage(),
52 Padding(
53 padding: image != null
54 ? EdgeInsets.only(left: 15)
@@ -50,7 +57,7 @@ class SelectButton extends StatelessWidget {
57 text,
58 style: TextStyle(
59 fontSize: 18,
53 - fontWeight: FontWeight.w600,
60 + fontWeight: FontWeight.w500,
61 color: textColor
62 ),
63 ),
lib/src/screens/restore/restore_wallet_from_keys_page.dart
+68 -136
@@ -1,40 +1,36 @@
1 -import 'package:mobx/mobx.dart';
2 -import 'package:provider/provider.dart';
3 -import 'package:shared_preferences/shared_preferences.dart';
1 +import 'package:cake_wallet/core/validator.dart';
2 +import 'package:cake_wallet/palette.dart';
3 import 'package:flutter/services.dart';
4 import 'package:flutter/cupertino.dart';
5 import 'package:flutter/material.dart';
6 import 'package:flutter_mobx/flutter_mobx.dart';
7 import 'package:cake_wallet/generated/i18n.dart';
9 -import 'package:cake_wallet/src/domain/services/wallet_list_service.dart';
10 -import 'package:cake_wallet/src/domain/services/wallet_service.dart';
11 -import 'package:cake_wallet/src/stores/wallet_restoration/wallet_restoration_store.dart';
12 -import 'package:cake_wallet/src/stores/wallet_restoration/wallet_restoration_state.dart';
8 import 'package:cake_wallet/src/screens/base_page.dart';
9 import 'package:cake_wallet/src/widgets/primary_button.dart';
10 import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
11 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
17 -import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart';
12 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
13 +import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart';
14 +import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
15
16 class RestoreWalletFromKeysPage extends BasePage {
17 RestoreWalletFromKeysPage(
22 - {@required this.walletsService,
23 - @required this.sharedPreferences,
24 - @required this.walletService});
18 + {@required this.walletRestorationFromKeysVM});
19
26 - final WalletListService walletsService;
27 - final WalletService walletService;
28 - final SharedPreferences sharedPreferences;
20 + final WalletRestorationFromKeysVM walletRestorationFromKeysVM;
21
22 @override
23 String get title => S.current.restore_title_from_keys;
24
25 @override
34 - Widget body(BuildContext context) => RestoreFromKeysFrom();
26 + Widget body(BuildContext context) => RestoreFromKeysFrom(walletRestorationFromKeysVM);
27 }
28
29 class RestoreFromKeysFrom extends StatefulWidget {
30 + RestoreFromKeysFrom(this.walletRestorationFromKeysVM);
31 +
32 + final WalletRestorationFromKeysVM walletRestorationFromKeysVM;
33 +
34 @override
35 _RestoreFromKeysFromState createState() => _RestoreFromKeysFromState();
36 }
@@ -46,6 +42,23 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
42 final _addressController = TextEditingController();
43 final _viewKeyController = TextEditingController();
44 final _spendKeyController = TextEditingController();
45 + final _wifController = TextEditingController();
46 +
47 + @override
48 + void initState() {
49 + _nameController.addListener(() =>
50 + widget.walletRestorationFromKeysVM.name = _nameController.text);
51 + _addressController.addListener(() =>
52 + widget.walletRestorationFromKeysVM.address = _addressController.text);
53 + _viewKeyController.addListener(() =>
54 + widget.walletRestorationFromKeysVM.viewKey = _viewKeyController.text);
55 + _spendKeyController.addListener(() =>
56 + widget.walletRestorationFromKeysVM.spendKey = _spendKeyController.text);
57 + _wifController.addListener(() =>
58 + widget.walletRestorationFromKeysVM.wif = _wifController.text);
59 +
60 + super.initState();
61 + }
62
63 @override
64 void dispose() {
@@ -53,31 +66,14 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
66 _addressController.dispose();
67 _viewKeyController.dispose();
68 _spendKeyController.dispose();
69 + _wifController.dispose();
70 super.dispose();
71 }
72
59 - void onHandleControllers(WalletRestorationStore walletRestorationStore) {
60 - if (_nameController.text.isNotEmpty &&
61 - _addressController.text.isNotEmpty &&
62 - _viewKeyController.text.isNotEmpty &&
63 - _spendKeyController.text.isNotEmpty) {
64 - walletRestorationStore.setDisabledState(false);
65 - } else {
66 - walletRestorationStore.setDisabledState(true);
67 - }
68 - }
69 -
73 @override
74 Widget build(BuildContext context) {
72 - final walletRestorationStore = Provider.of<WalletRestorationStore>(context);
73 - final seedLanguageStore = Provider.of<SeedLanguageStore>(context);
74 -
75 - _nameController.addListener(() {onHandleControllers(walletRestorationStore);});
76 - _addressController.addListener(() {onHandleControllers(walletRestorationStore);});
77 - _viewKeyController.addListener(() {onHandleControllers(walletRestorationStore);});
78 - _spendKeyController.addListener(() {onHandleControllers(walletRestorationStore);});
75
80 - reaction((_) => walletRestorationStore.state, (WalletRestorationState state) {
76 + /*reaction((_) => walletRestorationStore.state, (WalletRestorationState state) {
77 if (state is WalletRestoredSuccessfully) {
78 Navigator.of(context).popUntil((route) => route.isFirst);
79 }
@@ -96,7 +92,7 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
92 });
93 });
94 }
99 - });
95 + });*/
96
97 return Container(
98 padding: EdgeInsets.only(left: 24, right: 24),
@@ -110,66 +106,39 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
106 Flexible(
107 child: Container(
108 padding: EdgeInsets.only(top: 20.0),
113 - child: TextFormField(
114 - style: TextStyle(
115 - fontSize: 16.0,
116 - color: Theme.of(context).primaryTextTheme.title.color
117 - ),
109 + child: BaseTextFormField(
110 controller: _nameController,
119 - decoration: InputDecoration(
120 - hintStyle: TextStyle(
121 - color: Theme.of(context).primaryTextTheme.caption.color,
122 - fontSize: 16
123 - ),
124 - hintText: S.of(context).restore_wallet_name,
125 - focusedBorder: UnderlineInputBorder(
126 - borderSide: BorderSide(
127 - color: Theme.of(context).dividerColor,
128 - width: 1.0)),
129 - enabledBorder: UnderlineInputBorder(
130 - borderSide: BorderSide(
131 - color: Theme.of(context).dividerColor,
132 - width: 1.0))),
133 - validator: (value) {
134 - walletRestorationStore.validateWalletName(value);
135 - return walletRestorationStore.errorMessage;
136 - },
137 - ),
111 + hintText: S.of(context).restore_wallet_name,
112 + validator: WalletNameValidator(),
113 + )
114 ))
115 ],
116 ),
117 + if (!widget.walletRestorationFromKeysVM.hasRestorationHeight)
118 + Row(
119 + children: <Widget>[
120 + Flexible(
121 + child: Container(
122 + padding: EdgeInsets.only(top: 20.0),
123 + child: BaseTextFormField(
124 + controller: _wifController,
125 + hintText: 'WIF',
126 + )
127 + ))
128 + ],
129 + ),
130 + if (widget.walletRestorationFromKeysVM.hasRestorationHeight) ... [
131 Row(
132 children: <Widget>[
133 Flexible(
134 child: Container(
135 padding: EdgeInsets.only(top: 20.0),
146 - child: TextFormField(
147 - style: TextStyle(
148 - fontSize: 16.0,
149 - color: Theme.of(context).primaryTextTheme.title.color
150 - ),
136 + child: BaseTextFormField(
137 controller: _addressController,
138 keyboardType: TextInputType.multiline,
139 maxLines: null,
154 - decoration: InputDecoration(
155 - hintStyle: TextStyle(
156 - color: Theme.of(context).primaryTextTheme.caption.color,
157 - fontSize: 16
158 - ),
159 - hintText: S.of(context).restore_address,
160 - focusedBorder: UnderlineInputBorder(
161 - borderSide: BorderSide(
162 - color: Theme.of(context).dividerColor,
163 - width: 1.0)),
164 - enabledBorder: UnderlineInputBorder(
165 - borderSide: BorderSide(
166 - color: Theme.of(context).dividerColor,
167 - width: 1.0))),
168 - validator: (value) {
169 - walletRestorationStore.validateAddress(value);
170 - return walletRestorationStore.errorMessage;
171 - },
172 - ),
140 + hintText: S.of(context).restore_address,
141 + )
142 ))
143 ],
144 ),
@@ -178,31 +147,10 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
147 Flexible(
148 child: Container(
149 padding: EdgeInsets.only(top: 20.0),
181 - child: TextFormField(
182 - style: TextStyle(
183 - fontSize: 16.0,
184 - color: Theme.of(context).primaryTextTheme.title.color
185 - ),
150 + child: BaseTextFormField(
151 controller: _viewKeyController,
187 - decoration: InputDecoration(
188 - hintStyle: TextStyle(
189 - color: Theme.of(context).primaryTextTheme.caption.color,
190 - fontSize: 16
191 - ),
192 - hintText: S.of(context).restore_view_key_private,
193 - focusedBorder: UnderlineInputBorder(
194 - borderSide: BorderSide(
195 - color: Theme.of(context).dividerColor,
196 - width: 1.0)),
197 - enabledBorder: UnderlineInputBorder(
198 - borderSide: BorderSide(
199 - color: Theme.of(context).dividerColor,
200 - width: 1.0))),
201 - validator: (value) {
202 - walletRestorationStore.validateKeys(value);
203 - return walletRestorationStore.errorMessage;
204 - },
205 - ),
152 + hintText: S.of(context).restore_view_key_private,
153 + )
154 ))
155 ],
156 ),
@@ -211,35 +159,19 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
159 Flexible(
160 child: Container(
161 padding: EdgeInsets.only(top: 20.0),
214 - child: TextFormField(
215 - style: TextStyle(
216 - fontSize: 16.0,
217 - color: Theme.of(context).primaryTextTheme.title.color
218 - ),
162 + child: BaseTextFormField(
163 controller: _spendKeyController,
220 - decoration: InputDecoration(
221 - hintStyle: TextStyle(
222 - color: Theme.of(context).primaryTextTheme.caption.color,
223 - fontSize: 16
224 - ),
225 - hintText: S.of(context).restore_spend_key_private,
226 - focusedBorder: UnderlineInputBorder(
227 - borderSide: BorderSide(
228 - color: Theme.of(context).dividerColor,
229 - width: 1.0)),
230 - enabledBorder: UnderlineInputBorder(
231 - borderSide: BorderSide(
232 - color: Theme.of(context).dividerColor,
233 - width: 1.0))),
234 - validator: (value) {
235 - walletRestorationStore.validateKeys(value);
236 - return walletRestorationStore.errorMessage;
237 - },
238 - ),
164 + hintText: S.of(context).restore_spend_key_private,
165 + )
166 ))
167 ],
168 ),
242 - BlockchainHeightWidget(key: _blockchainHeightKey),
169 + BlockchainHeightWidget(
170 + key: _blockchainHeightKey,
171 + onHeightChange: (height) {
172 + widget.walletRestorationFromKeysVM.height = height;
173 + print(height);
174 + })],
175 ]),
176 ),
177 bottomSectionPadding: EdgeInsets.only(bottom: 24),
@@ -247,19 +179,19 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
179 return LoadingPrimaryButton(
180 onPressed: () {
181 if (_formKey.currentState.validate()) {
250 - walletRestorationStore.restoreFromKeys(
182 + /*walletRestorationStore.restoreFromKeys(
183 name: _nameController.text,
184 language: seedLanguageStore.selectedSeedLanguage,
185 address: _addressController.text,
186 viewKey: _viewKeyController.text,
187 spendKey: _spendKeyController.text,
256 - restoreHeight: _blockchainHeightKey.currentState.height);
188 + restoreHeight: _blockchainHeightKey.currentState.height);*/
189 }
190 },
191 text: S.of(context).restore_recover,
260 - color: Colors.green,
192 + color: Palette.blueCraiola,
193 textColor: Colors.white,
262 - isDisabled: walletRestorationStore.disabledState,
194 + //isDisabled: walletRestorationStore.disabledState,
195 );
196 }),
197 ),
lib/src/screens/restore/restore_wallet_from_seed_details.dart
+5 -21
@@ -1,3 +1,4 @@
1 +import 'package:cake_wallet/palette.dart';
2 import 'package:mobx/mobx.dart';
3 import 'package:flutter/material.dart';
4 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -9,6 +10,7 @@ import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
10 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
11 import 'package:cake_wallet/src/widgets/primary_button.dart';
12 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
13 +import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
14 import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
15
16 class RestoreWalletFromSeedDetailsPage extends BasePage {
@@ -91,27 +93,9 @@ class _RestoreFromSeedDetailsFormState
93 Flexible(
94 child: Container(
95 padding: EdgeInsets.only(top: 20.0),
94 - child: TextFormField(
95 - style: TextStyle(
96 - fontSize: 16.0,
97 - color: Theme.of(context).primaryTextTheme.title.color),
96 + child: BaseTextFormField(
97 controller: _nameController,
99 - decoration: InputDecoration(
100 - hintStyle: TextStyle(
101 - color: Theme.of(context)
102 - .primaryTextTheme
103 - .caption
104 - .color,
105 - fontSize: 16),
106 - hintText: S.of(context).restore_wallet_name,
107 - focusedBorder: UnderlineInputBorder(
108 - borderSide: BorderSide(
109 - color: Theme.of(context).dividerColor,
110 - width: 1.0)),
111 - enabledBorder: UnderlineInputBorder(
112 - borderSide: BorderSide(
113 - color: Theme.of(context).dividerColor,
114 - width: 1.0))),
98 + hintText: S.of(context).restore_wallet_name,
99 validator: WalletNameValidator(),
100 ),
101 ))
@@ -137,7 +121,7 @@ class _RestoreFromSeedDetailsFormState
121 isLoading:
122 widget.walletRestorationFromSeedVM.state is WalletCreating,
123 text: S.of(context).restore_recover,
140 - color: Colors.green,
124 + color: Palette.blueCraiola,
125 textColor: Colors.white,
126 isDisabled: _nameController.text.isNotEmpty,
127 );
lib/src/screens/seed_language/seed_language_page.dart
+11 -5
@@ -1,5 +1,6 @@
1 +import 'package:cake_wallet/di.dart';
2 import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
2 -import 'package:provider/provider.dart';
3 +import 'package:cake_wallet/store/settings_store.dart';
4 import 'package:flutter_mobx/flutter_mobx.dart';
5 import 'package:flutter/material.dart';
6 import 'package:flutter/cupertino.dart';
@@ -7,8 +8,6 @@ import 'package:cake_wallet/generated/i18n.dart';
8 import 'package:cake_wallet/src/screens/base_page.dart';
9 import 'package:cake_wallet/src/widgets/primary_button.dart';
10 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
10 -import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart';
11 -import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
11 import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart';
12
13 class SeedLanguage extends BasePage {
@@ -16,6 +15,9 @@ class SeedLanguage extends BasePage {
15
16 final Function(BuildContext, String) onConfirm;
17
18 + @override
19 + String get title => S.current.wallet_list_restore_wallet;
20 +
21 @override
22 Widget body(BuildContext context) => SeedLanguageForm(onConfirm: onConfirm);
23 }
@@ -33,10 +35,14 @@ class SeedLanguageFormState extends State<SeedLanguageForm> {
35 static const aspectRatioImage = 1.22;
36
37 final walletNameImage = Image.asset('assets/images/wallet_name.png');
38 + final walletNameLightImage = Image.asset('assets/images/wallet_name_light.png');
39 final _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>();
40
41 @override
42 Widget build(BuildContext context) {
43 + final walletImage = getIt.get<SettingsStore>().isDarkTheme
44 + ? walletNameImage : walletNameLightImage;
45 +
46 return Container(
47 padding: EdgeInsets.only(top: 24),
48 child: ScrollableWithBottomSection(
@@ -47,7 +53,7 @@ class SeedLanguageFormState extends State<SeedLanguageForm> {
53 padding: EdgeInsets.only(left: 12, right: 12),
54 child: AspectRatio(
55 aspectRatio: aspectRatioImage,
50 - child: FittedBox(child: walletNameImage, fit: BoxFit.fill)),
56 + child: FittedBox(child: walletImage, fit: BoxFit.fill)),
57 ),
58 Padding(
59 padding: EdgeInsets.only(top: 40),
@@ -56,7 +62,7 @@ class SeedLanguageFormState extends State<SeedLanguageForm> {
62 textAlign: TextAlign.center,
63 style: TextStyle(
64 fontSize: 16.0,
59 - fontWeight: FontWeight.w600,
65 + fontWeight: FontWeight.w500,
66 color: Theme.of(context).primaryTextTheme.title.color),
67 ),
68 ),
lib/src/screens/seed_language/widgets/seed_language_picker.dart
+86 -142
@@ -1,9 +1,9 @@
1 import 'dart:ui';
2 +import 'package:cake_wallet/src/widgets/alert_background.dart';
3 +import 'package:cake_wallet/src/widgets/alert_close_button.dart';
4 import 'package:flutter/cupertino.dart';
5 import 'package:flutter/material.dart';
6 import 'package:cake_wallet/palette.dart';
5 -import 'package:provider/provider.dart';
6 -import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart';
7 import 'package:cake_wallet/generated/i18n.dart';
8
9 List<Image> flagImages = [
@@ -57,170 +57,111 @@ class SeedLanguagePicker extends StatefulWidget {
57 class SeedLanguagePickerState extends State<SeedLanguagePicker> {
58 SeedLanguagePickerState({this.selected});
59
60 + final closeButton = Image.asset('assets/images/close.png');
61 String selected;
62
63 @override
64 Widget build(BuildContext context) {
64 - return GestureDetector(
65 - onTap: () => Navigator.of(context).pop(),
66 - child: Container(
67 - color: Colors.transparent,
68 - child: BackdropFilter(
69 - filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
70 - child: Container(
71 - decoration: BoxDecoration(
72 - color: PaletteDark.darkNightBlue.withOpacity(0.75)),
73 - child: Center(
74 - child: Column(
75 - mainAxisSize: MainAxisSize.min,
76 - children: <Widget>[
77 - Container(
78 - padding: EdgeInsets.only(left: 24, right: 24),
79 - child: Text(
80 - S.of(context).seed_choose,
81 - textAlign: TextAlign.center,
82 - style: TextStyle(
83 - fontSize: 18,
84 - fontWeight: FontWeight.bold,
85 - decoration: TextDecoration.none,
86 - color: Colors.white),
65 + return AlertBackground(
66 + child: Stack(
67 + alignment: Alignment.center,
68 + children: <Widget>[
69 + Column(
70 + mainAxisSize: MainAxisSize.min,
71 + children: <Widget>[
72 + Container(
73 + padding: EdgeInsets.only(left: 24, right: 24),
74 + child: Text(
75 + S.of(context).seed_choose,
76 + textAlign: TextAlign.center,
77 + style: TextStyle(
78 + fontSize: 18,
79 + fontWeight: FontWeight.bold,
80 + fontFamily: 'Poppins',
81 + decoration: TextDecoration.none,
82 + color: Colors.white
83 ),
84 ),
89 - Padding(
90 - padding: EdgeInsets.only(top: 24),
91 - child: GestureDetector(
92 - onTap: () => null,
93 - child: Container(
94 - height: 300,
95 - width: 300,
96 - decoration: BoxDecoration(
97 - borderRadius: BorderRadius.all(Radius.circular(14)),
98 - color: Theme.of(context).dividerColor),
99 - child: GridView.count(
100 - shrinkWrap: true,
101 - crossAxisCount: 3,
102 - childAspectRatio: 1,
103 - physics: const NeverScrollableScrollPhysics(),
104 - crossAxisSpacing: 1,
105 - mainAxisSpacing: 1,
106 - children: List.generate(9, (index) {
107 - if (index == 8) {
108 - return gridTile(
109 - isCurrent: false,
110 - place: Places.bottomRight,
111 - image: null,
112 - text: '',
113 - onTap: null);
114 - } else {
115 - final code = languageCodes[index];
116 - final flag = flagImages[index];
117 - final isCurrent =
118 - index == seedLanguages.indexOf(selected);
119 -
120 - if (index == 0) {
121 - return gridTile(
122 - isCurrent: isCurrent,
123 - place: Places.topLeft,
124 - image: flag,
125 - text: code,
126 - onTap: () {
127 - selected = seedLanguages[index];
128 - Navigator.of(context).pop(selected);
129 - });
130 - }
131 -
132 - if (index == 2) {
133 - return gridTile(
134 - isCurrent: isCurrent,
135 - place: Places.topRight,
136 - image: flag,
137 - text: code,
138 - onTap: () {
139 - selected = seedLanguages[index];
140 - Navigator.of(context).pop(selected);
141 - });
142 - }
143 -
144 - if (index == 6) {
145 - return gridTile(
146 - isCurrent: isCurrent,
147 - place: Places.bottomLeft,
148 - image: flag,
149 - text: code,
150 - onTap: () {
151 - selected = seedLanguages[index];
152 - Navigator.of(context).pop(selected);
153 - });
85 + ),
86 + Padding(
87 + padding: EdgeInsets.only(top: 24),
88 + child: ClipRRect(
89 + borderRadius: BorderRadius.all(Radius.circular(14)),
90 + child: Container(
91 + height: 300,
92 + width: 300,
93 + color: Theme.of(context).accentTextTheme.title.backgroundColor,
94 + child: GridView.count(
95 + shrinkWrap: true,
96 + crossAxisCount: 3,
97 + childAspectRatio: 1,
98 + physics: const NeverScrollableScrollPhysics(),
99 + crossAxisSpacing: 1,
100 + mainAxisSpacing: 1,
101 + children: List.generate(9, (index) {
102 +
103 + if (index == 8) {
104 +
105 + return gridTile(
106 + isCurrent: false,
107 + image: null,
108 + text: '',
109 + onTap: null);
110 +
111 + }
112 +
113 + final code = languageCodes[index];
114 + final flag = flagImages[index];
115 + final isCurrent =
116 + index == seedLanguages.indexOf(selected);
117 +
118 + return gridTile(
119 + isCurrent: isCurrent,
120 + image: flag,
121 + text: code,
122 + onTap: () {
123 + selected = seedLanguages[index];
124 + Navigator.of(context).pop(selected);
125 }
155 -
156 - return gridTile(
157 - isCurrent: isCurrent,
158 - place: Places.inside,
159 - image: flag,
160 - text: code,
161 - onTap: () {
162 - selected = seedLanguages[index];
163 - Navigator.of(context).pop(selected);
164 - });
165 - }
166 - }),
167 - ),
126 + );
127 + }),
128 ),
129 ),
170 - )
171 - ],
172 - ),
130 + ),
131 + )
132 + ],
133 ),
174 - ),
175 - ),
176 - ),
134 + AlertCloseButton(image: closeButton)
135 + ],
136 + )
137 );
138 }
139
180 - Widget gridTile(
181 - {@required bool isCurrent,
182 - @required Places place,
183 - @required Image image,
184 - @required String text,
185 - @required VoidCallback onTap}) {
186 - BorderRadius borderRadius;
140 + Widget gridTile({
141 + @required bool isCurrent,
142 + @required Image image,
143 + @required String text,
144 + @required VoidCallback onTap}) {
145 +
146 final color = isCurrent
188 - ? Theme.of(context).accentTextTheme.subtitle.decorationColor
189 - : Theme.of(context).primaryTextTheme.display1.color;
147 + ? Theme.of(context).textTheme.body2.color
148 + : Theme.of(context).accentTextTheme.title.color;
149 final textColor = isCurrent
191 - ? Colors.blue
150 + ? Palette.blueCraiola
151 : Theme.of(context).primaryTextTheme.title.color;
152
194 - switch (place) {
195 - case Places.topLeft:
196 - borderRadius = BorderRadius.only(topLeft: Radius.circular(14));
197 - break;
198 - case Places.topRight:
199 - borderRadius = BorderRadius.only(topRight: Radius.circular(14));
200 - break;
201 - case Places.bottomLeft:
202 - borderRadius = BorderRadius.only(bottomLeft: Radius.circular(14));
203 - break;
204 - case Places.bottomRight:
205 - borderRadius = BorderRadius.only(bottomRight: Radius.circular(14));
206 - break;
207 - case Places.inside:
208 - borderRadius = BorderRadius.all(Radius.circular(0));
209 - break;
210 - }
211 -
153 return GestureDetector(
154 onTap: onTap,
155 child: Container(
156 padding: EdgeInsets.all(10),
216 - decoration: BoxDecoration(borderRadius: borderRadius, color: color),
157 + color: color,
158 child: Center(
159 child: Row(
160 mainAxisSize: MainAxisSize.min,
161 mainAxisAlignment: MainAxisAlignment.center,
162 crossAxisAlignment: CrossAxisAlignment.center,
163 children: <Widget>[
223 - image != null ? image : Offstage(),
164 + image ?? Offstage(),
165 Padding(
166 padding: image != null
167 ? EdgeInsets.only(left: 10)
@@ -229,14 +170,17 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
170 text,
171 style: TextStyle(
172 fontSize: 18,
232 - fontWeight: FontWeight.bold,
173 + fontWeight: FontWeight.w600,
174 + fontFamily: 'Poppins',
175 decoration: TextDecoration.none,
234 - color: textColor),
176 + color: textColor
177 + ),
178 ),
179 )
180 ],
181 ),
182 ),
240 - ));
183 + )
184 + );
185 }
186 }
lib/src/widgets/blockchain_height_widget.dart
+8 -42
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
2 import 'package:intl/intl.dart';
3 import 'package:cake_wallet/generated/i18n.dart';
4 import 'package:cake_wallet/src/domain/monero/get_height_by_date.dart';
5 +import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
6
7 class BlockchainHeightWidget extends StatefulWidget {
8 BlockchainHeightWidget({GlobalKey key, this.onHeightChange})
@@ -46,26 +47,12 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
47 Flexible(
48 child: Container(
49 padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
49 - child: TextFormField(
50 - style: TextStyle(
51 - fontSize: 16.0,
52 - color: Theme.of(context).primaryTextTheme.title.color),
50 + child: BaseTextFormField(
51 controller: restoreHeightController,
52 keyboardType: TextInputType.numberWithOptions(
53 signed: false, decimal: false),
56 - decoration: InputDecoration(
57 - hintStyle: TextStyle(
58 - color: Theme.of(context).primaryTextTheme.caption.color,
59 - fontSize: 16),
60 - hintText: S.of(context).widgets_restore_from_blockheight,
61 - focusedBorder: UnderlineInputBorder(
62 - borderSide: BorderSide(
63 - color: Theme.of(context).dividerColor, width: 1.0)),
64 - enabledBorder: UnderlineInputBorder(
65 - borderSide: BorderSide(
66 - color: Theme.of(context).dividerColor,
67 - width: 1.0))),
68 - ),
54 + hintText: S.of(context).widgets_restore_from_blockheight,
55 + )
56 ))
57 ],
58 ),
@@ -75,7 +62,7 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
62 S.of(context).widgets_or,
63 style: TextStyle(
64 fontSize: 16.0,
78 - fontWeight: FontWeight.bold,
65 + fontWeight: FontWeight.w500,
66 color: Theme.of(context).primaryTextTheme.title.color),
67 ),
68 ),
@@ -86,31 +73,10 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
73 child: InkWell(
74 onTap: () => _selectDate(context),
75 child: IgnorePointer(
89 - child: TextFormField(
90 - style: TextStyle(
91 - fontSize: 16.0,
92 - color: Theme.of(context).primaryTextTheme.title.color),
93 - decoration: InputDecoration(
94 - hintStyle: TextStyle(
95 - color: Theme.of(context)
96 - .primaryTextTheme
97 - .caption
98 - .color,
99 - fontSize: 16),
100 - hintText: S.of(context).widgets_restore_from_date,
101 - focusedBorder: UnderlineInputBorder(
102 - borderSide: BorderSide(
103 - color: Theme.of(context).dividerColor,
104 - width: 1.0)),
105 - enabledBorder: UnderlineInputBorder(
106 - borderSide: BorderSide(
107 - color: Theme.of(context).dividerColor,
108 - width: 1.0))),
76 + child: BaseTextFormField(
77 controller: dateController,
110 - validator: (value) {
111 - return null;
112 - },
113 - ),
78 + hintText: S.of(context).widgets_restore_from_date,
79 + )
80 ),
81 ),
82 ))
lib/src/widgets/seed_language_selector.dart
+3 -3
@@ -34,14 +34,14 @@ class SeedLanguageSelectorState extends State<SeedLanguageSelector> {
34 return SelectButton(
35 image: null,
36 text: seedLocales[seedLanguages.indexOf(selected)],
37 - color: Theme.of(context).accentTextTheme.title.backgroundColor,
38 - textColor: Theme.of(context).primaryTextTheme.title.color,
37 onTap: () async {
38 final selected = await showDialog<String>(
39 context: context,
40 builder: (BuildContext context) =>
41 SeedLanguagePicker(key: _pickerKey, selected: this.selected));
44 - setState(() => this.selected = selected);
42 + if (selected != null) {
43 + setState(() => this.selected = selected);
44 + }
45 });
46 }
47 }
lib/themes.dart
+8
@@ -156,6 +156,10 @@ class Themes {
156 color: Palette.shadowWhite, // action button color (address text field)
157 decorationColor: Palette.darkGray // hint text (seed widget)
158 ),
159 + display3: TextStyle(
160 + color: Palette.darkGray, // hint text (new wallet page)
161 + decorationColor: Palette.periwinkleCraiola // underline (new wallet page)
162 + ),
163 ),
164
165
@@ -323,6 +327,10 @@ class Themes {
327 color: PaletteDark.nightBlue, // action button color (address text field)
328 decorationColor: PaletteDark.darkCyanBlue // hint text (seed widget)
329 ),
330 + display3: TextStyle(
331 + color: PaletteDark.cyanBlue, // hint text (new wallet page)
332 + decorationColor: PaletteDark.darkGrey // underline (new wallet page)
333 + ),
334 ),
335
336
lib/view_model/wallet_restoration_from_keys_vm.dart new
+64
@@ -0,0 +1,64 @@
1 +import 'package:flutter/foundation.dart';
2 +import 'package:hive/hive.dart';
3 +import 'package:mobx/mobx.dart';
4 +import 'package:cake_wallet/monero/monero_wallet_service.dart';
5 +import 'package:cake_wallet/bitcoin/bitcoin_wallet_creation_credentials.dart';
6 +import 'package:cake_wallet/core/generate_wallet_password.dart';
7 +import 'package:cake_wallet/core/wallet_creation_service.dart';
8 +import 'package:cake_wallet/core/wallet_credentials.dart';
9 +import 'package:cake_wallet/src/domain/common/wallet_type.dart';
10 +import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
11 +import 'package:cake_wallet/src/domain/common/wallet_info.dart';
12 +
13 +part 'wallet_restoration_from_keys_vm.g.dart';
14 +
15 +class WalletRestorationFromKeysVM = WalletRestorationFromKeysVMBase
16 + with _$WalletRestorationFromKeysVM;
17 +
18 +abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
19 + with Store {
20 + WalletRestorationFromKeysVMBase(this._walletCreationService, Box<WalletInfo> walletInfoSource,
21 + {@required WalletType type, @required this.language})
22 + : super(walletInfoSource, type: type, isRecovery: true);
23 +
24 + @observable
25 + int height;
26 +
27 + @observable
28 + String viewKey;
29 +
30 + @observable
31 + String spendKey;
32 +
33 + @observable
34 + String wif;
35 +
36 + @observable
37 + String address;
38 +
39 + bool get hasRestorationHeight => type == WalletType.monero;
40 +
41 + final String language;
42 + final WalletCreationService _walletCreationService;
43 +
44 + @override
45 + WalletCredentials getCredentials(dynamic options) {
46 + final password = generateWalletPassword(type);
47 +
48 + switch (type) {
49 + case WalletType.monero:
50 + return MoneroRestoreWalletFromKeysCredentials(
51 + name: name, password: password, language: language, address: address,
52 + viewKey: viewKey, spendKey: spendKey, height: height);
53 + case WalletType.bitcoin:
54 + return BitcoinRestoreWalletFromWIFCredentials(
55 + name: name, password: password, wif: wif);
56 + default:
57 + return null;
58 + }
59 + }
60 +
61 + @override
62 + Future<void> process(WalletCredentials credentials) async =>
63 + _walletCreationService.restoreFromKeys(credentials);
64 +}