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
+}