CW-400 investigate cupertino nav bar null exception (#943)
* Fix null error on back navigation after pushReplacementNamed * Fix null error on back navigation after pushReplacementNamed * Close all visible keyboard for page navigation context * Fix issue with market place navigation * Remove focus before back navigation * Fix background color * Fix background color * Fix background color
Godwin Asuquo committed
Jun 8, 2023 at 02:16 UTC
e8446f0c9899592aa76f5969983b3410771d5c1b
12 files changed
+183
-137
lib/di.dart
+4
-1
@@ -39,6 +39,7 @@ import 'package:cake_wallet/utils/payment_request.dart';
39
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
40
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
41
import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
42
+import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
43
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
44
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
45
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
@@ -873,6 +874,8 @@ Future setup({
874
875
getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get<IoniaService>()));
876
877
+ getIt.registerFactory(()=> MarketPlaceViewModel(getIt.get<IoniaService>()));
878
+
879
getIt.registerFactory(() => IoniaAuthViewModel(ioniaService: getIt.get<IoniaService>()));
880
881
getIt.registerFactoryParam<IoniaMerchPurchaseViewModel, double, IoniaMerchant>(
@@ -902,7 +905,7 @@ Future setup({
905
return IoniaVerifyIoniaOtp(getIt.get<IoniaAuthViewModel>(), email, isSignIn);
906
});
907
905
- getIt.registerFactory(() => IoniaWelcomePage(getIt.get<IoniaGiftCardsListViewModel>()));
908
+ getIt.registerFactory(() => IoniaWelcomePage());
909
910
getIt.registerFactoryParam<IoniaBuyGiftCardPage, List, void>((List args, _) {
911
final merchant = args.first as IoniaMerchant;
lib/router.dart
+3
-4
@@ -175,7 +175,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
175
fullscreenDialog: true);
176
} else if (isSingleCoin) {
177
return MaterialPageRoute<void>(
178
- fullscreenDialog: true,
178
builder: (_) => getIt.get<WalletRestorePage>(
179
param1: availableWalletTypes.first
180
));
@@ -196,7 +195,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
195
196
case Routes.restoreWallet:
197
return MaterialPageRoute<void>(
199
- fullscreenDialog: true,
198
builder: (_) => getIt.get<WalletRestorePage>(
199
param1: settings.arguments as WalletType));
200
@@ -206,6 +204,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
204
205
case Routes.dashboard:
206
return CupertinoPageRoute<void>(
207
+ settings: settings,
208
builder: (_) => getIt.get<DashboardPage>());
209
210
case Routes.send:
@@ -468,7 +467,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
467
return CupertinoPageRoute<void>( builder: (_) => getIt.get<IoniaCreateAccountPage>());
468
469
case Routes.ioniaManageCardsPage:
471
- return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaManageCardsPage>());
470
+ return CupertinoPageRoute<void>(
471
+ builder: (_) => getIt.get<IoniaManageCardsPage>());
472
473
case Routes.ioniaBuyGiftCardPage:
474
final args = settings.arguments as List;
@@ -536,7 +536,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
536
case Routes.anonPayInvoicePage:
537
final args = settings.arguments as List;
538
return CupertinoPageRoute<void>(
539
- fullscreenDialog: true,
539
builder: (_) => getIt.get<AnonPayInvoicePage>(param1: args));
540
541
case Routes.anonPayReceivePage:
lib/src/screens/dashboard/dashboard_page.dart
+7
-4
@@ -5,7 +5,7 @@ import 'package:cake_wallet/entities/main_actions.dart';
5
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
6
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart';
7
import 'package:cake_wallet/utils/version_comparator.dart';
8
-import 'package:cake_wallet/wallet_type_utils.dart';
8
+import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
9
import 'package:cake_wallet/generated/i18n.dart';
10
import 'package:cake_wallet/routes.dart';
11
import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
@@ -27,8 +27,6 @@ import 'package:mobx/mobx.dart';
27
import 'package:shared_preferences/shared_preferences.dart';
28
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
29
import 'package:cake_wallet/main.dart';
30
-import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
31
-import 'package:url_launcher/url_launcher.dart';
30
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
31
32
class DashboardPage extends StatelessWidget {
@@ -251,7 +249,12 @@ class _DashboardPageView extends BasePage {
249
if (dashboardViewModel.shouldShowMarketPlaceInDashboard) {
250
pages.add(Semantics(
251
label: 'Marketplace Page',
254
- child: MarketPlacePage(dashboardViewModel: dashboardViewModel)));
252
+ child: MarketPlacePage(
253
+ dashboardViewModel: dashboardViewModel,
254
+ marketPlaceViewModel: getIt.get<MarketPlaceViewModel>(),
255
+ ),
256
+ ),
257
+ );
258
}
259
pages.add(Semantics(label: 'Balance Page', child: balancePage));
260
pages.add(Semantics(
lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
+6
-1
@@ -1,7 +1,9 @@
1
+import 'package:cake_wallet/di.dart';
2
import 'package:cake_wallet/entities/main_actions.dart';
3
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_action_button.dart';
4
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart';
5
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
6
+import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
7
import 'package:flutter/material.dart';
8
import 'package:flutter_mobx/flutter_mobx.dart';
9
@@ -70,7 +72,10 @@ class DesktopDashboardActions extends StatelessWidget {
72
],
73
),
74
Expanded(
73
- child: MarketPlacePage(dashboardViewModel: dashboardViewModel),
75
+ child: MarketPlacePage(
76
+ dashboardViewModel: dashboardViewModel,
77
+ marketPlaceViewModel: getIt.get<MarketPlaceViewModel>(),
78
+ ),
79
),
80
],
81
);
lib/src/screens/dashboard/widgets/address_page.dart
+3
-3
@@ -273,7 +273,7 @@ class AddressPage extends BasePage {
273
reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) {
274
switch (option) {
275
case ReceivePageOption.anonPayInvoice:
276
- Navigator.pushReplacementNamed(
276
+ Navigator.pushNamed(
277
context,
278
Routes.anonPayInvoicePage,
279
arguments: [addressListViewModel.address.address, option],
@@ -285,7 +285,7 @@ class AddressPage extends BasePage {
285
final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink);
286
287
if (clearnetUrl != null && onionUrl != null) {
288
- Navigator.pushReplacementNamed(
288
+ Navigator.pushNamed(
289
context,
290
Routes.anonPayReceivePage,
291
arguments: AnonpayDonationLinkInfo(
@@ -295,7 +295,7 @@ class AddressPage extends BasePage {
295
),
296
);
297
} else {
298
- Navigator.pushReplacementNamed(
298
+ Navigator.pushNamed(
299
context,
300
Routes.anonPayInvoicePage,
301
arguments: [addressListViewModel.address.address, option],
lib/src/screens/dashboard/widgets/market_place_page.dart
+17
-7
@@ -3,16 +3,20 @@ import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
3
import 'package:cake_wallet/src/widgets/market_place_item.dart';
4
import 'package:cake_wallet/utils/show_pop_up.dart';
5
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
6
+import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
7
import 'package:cw_core/wallet_type.dart';
8
import 'package:flutter/material.dart';
9
import 'package:cake_wallet/generated/i18n.dart';
10
import 'package:url_launcher/url_launcher.dart';
11
12
class MarketPlacePage extends StatelessWidget {
12
-
13
- MarketPlacePage({required this.dashboardViewModel});
13
+ MarketPlacePage({
14
+ required this.dashboardViewModel,
15
+ required this.marketPlaceViewModel,
16
+ });
17
18
final DashboardViewModel dashboardViewModel;
19
+ final MarketPlaceViewModel marketPlaceViewModel;
20
final _scrollController = ScrollController();
21
22
@override
@@ -48,7 +52,7 @@ class MarketPlacePage extends StatelessWidget {
52
children: <Widget>[
53
SizedBox(height: 20),
54
MarketPlaceItem(
51
- onTap: () =>_navigatorToGiftCardsPage(context),
55
+ onTap: () => _navigatorToGiftCardsPage(context),
56
title: S.of(context).cake_pay_title,
57
subTitle: S.of(context).cake_pay_subtitle,
58
),
@@ -70,12 +74,13 @@ class MarketPlacePage extends StatelessWidget {
74
),
75
);
76
}
77
+
78
void _navigatorToGiftCardsPage(BuildContext context) {
79
final walletType = dashboardViewModel.type;
80
81
switch (walletType) {
82
case WalletType.haven:
78
- showPopUp<void>(
83
+ showPopUp<void>(
84
context: context,
85
builder: (BuildContext context) {
86
return AlertWithOneAction(
@@ -85,9 +90,14 @@ class MarketPlacePage extends StatelessWidget {
90
buttonAction: () => Navigator.of(context).pop());
91
});
92
break;
88
- default:
89
- Navigator.of(context).pushNamed(Routes.ioniaWelcomePage);
93
+ default:
94
+ marketPlaceViewModel.isIoniaUserAuthenticated().then((value) {
95
+ if (value) {
96
+ Navigator.pushNamed(context, Routes.ioniaManageCardsPage);
97
+ return;
98
+ }
99
+ Navigator.of(context).pushNamed(Routes.ioniaWelcomePage);
100
+ });
101
}
102
}
92
-
103
}
lib/src/screens/ionia/auth/ionia_welcome_page.dart
+2
-12
@@ -3,14 +3,11 @@ import 'package:cake_wallet/routes.dart';
3
import 'package:cake_wallet/src/screens/base_page.dart';
4
import 'package:cake_wallet/src/widgets/primary_button.dart';
5
import 'package:cake_wallet/typography.dart';
6
-import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
6
import 'package:flutter/material.dart';
8
-import 'package:flutter/src/widgets/framework.dart';
7
import 'package:cake_wallet/generated/i18n.dart';
10
-import 'package:mobx/mobx.dart';
8
9
class IoniaWelcomePage extends BasePage {
13
- IoniaWelcomePage(this._cardsListViewModel);
10
+ IoniaWelcomePage();
11
12
@override
13
Widget middle(BuildContext context) {
@@ -25,15 +22,8 @@ class IoniaWelcomePage extends BasePage {
22
);
23
}
24
28
- final IoniaGiftCardsListViewModel _cardsListViewModel;
29
-
25
@override
26
Widget body(BuildContext context) {
32
- reaction((_) => _cardsListViewModel.isLoggedIn, (bool state) {
33
- if (state) {
34
- Navigator.pushReplacementNamed(context, Routes.ioniaManageCardsPage);
35
- }
36
- });
27
return Padding(
28
padding: const EdgeInsets.all(24.0),
29
child: Column(
@@ -41,7 +31,7 @@ class IoniaWelcomePage extends BasePage {
31
children: [
32
Column(
33
children: [
44
- SizedBox(height: 100),
34
+ SizedBox(height: 90),
35
Text(
36
S.of(context).about_cake_pay,
37
style: TextStyle(
lib/src/screens/ionia/cards/ionia_manage_cards_page.dart
+14
-3
@@ -17,7 +17,7 @@ import 'package:cake_wallet/generated/i18n.dart';
17
import 'package:flutter_mobx/flutter_mobx.dart';
18
19
class IoniaManageCardsPage extends BasePage {
20
- IoniaManageCardsPage(this._cardsListViewModel) {
20
+ IoniaManageCardsPage(this._cardsListViewModel): searchFocusNode = FocusNode() {
21
_searchController.addListener(() {
22
if (_searchController.text != _cardsListViewModel.searchString) {
23
_searchDebounce.run(() {
@@ -29,6 +29,7 @@ class IoniaManageCardsPage extends BasePage {
29
_cardsListViewModel.getMerchants();
30
31
}
32
+ final FocusNode searchFocusNode;
33
final IoniaGiftCardsListViewModel _cardsListViewModel;
34
35
final _searchDebounce = Debounce(Duration(milliseconds: 500));
@@ -86,7 +87,14 @@ class IoniaManageCardsPage extends BasePage {
87
//highlightColor: Colors.transparent,
88
//splashColor: Colors.transparent,
89
//padding: EdgeInsets.all(0),
89
- onPressed: () => Navigator.pop(context),
90
+ onPressed: (){
91
+ if (searchFocusNode.hasFocus) {
92
+ searchFocusNode.unfocus();
93
+ return;
94
+ }
95
+
96
+ Navigator.of(context).pop();
97
+ },
98
child: _backButton),
99
),
100
);
@@ -149,6 +157,7 @@ class IoniaManageCardsPage extends BasePage {
157
Expanded(
158
child: _SearchWidget(
159
controller: _searchController,
160
+ focusNode: searchFocusNode,
161
)),
162
SizedBox(width: 10),
163
filterButton
@@ -266,9 +275,10 @@ class _SearchWidget extends StatelessWidget {
275
const _SearchWidget({
276
Key? key,
277
required this.controller,
278
+ required this.focusNode,
279
}) : super(key: key);
280
final TextEditingController controller;
271
-
281
+ final FocusNode focusNode;
282
@override
283
Widget build(BuildContext context) {
284
final searchIcon = Padding(
@@ -280,6 +290,7 @@ class _SearchWidget extends StatelessWidget {
290
);
291
292
return TextField(
293
+ focusNode: focusNode,
294
style: TextStyle(color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!),
295
controller: controller,
296
decoration: InputDecoration(
lib/src/screens/receive/anonpay_invoice_page.dart
+107
-92
@@ -27,8 +27,7 @@ class AnonPayInvoicePage extends BasePage {
27
AnonPayInvoicePage(
28
this.anonInvoicePageViewModel,
29
this.receiveOptionViewModel,
30
- ) : _amountFocusNode = FocusNode() {
31
- }
30
+ ) : _amountFocusNode = FocusNode() {}
31
32
final _nameController = TextEditingController();
33
final _emailController = TextEditingController();
@@ -53,6 +52,11 @@ class AnonPayInvoicePage extends BasePage {
52
@override
53
AppBarStyle get appBarStyle => AppBarStyle.transparent;
54
55
+ @override
56
+ void onClose(BuildContext context) {
57
+ Navigator.popUntil(context, ModalRoute.withName(Routes.dashboard));
58
+ }
59
+
60
@override
61
Widget middle(BuildContext context) =>
62
PresentReceiveOptionPicker(receiveOptionViewModel: receiveOptionViewModel);
@@ -65,114 +69,125 @@ class AnonPayInvoicePage extends BasePage {
69
anonInvoicePageViewModel.reset();
70
});
71
72
+ Future<bool> _onNavigateBack(BuildContext context) async {
73
+ onClose(context);
74
+ return false;
75
+ }
76
+
77
@override
78
Widget body(BuildContext context) {
79
WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context));
80
72
- return KeyboardActions(
73
- disableScroll: true,
74
- config: KeyboardActionsConfig(
75
- keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
76
- keyboardBarColor: Theme.of(context)
81
+ return WillPopScope(
82
+ onWillPop: () => _onNavigateBack(context),
83
+ child: KeyboardActions(
84
+ disableScroll: true,
85
+ config: KeyboardActionsConfig(
86
+ keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
87
+ keyboardBarColor: Theme.of(context)
88
.accentTextTheme!
89
.bodyLarge!
90
.backgroundColor!,
80
- nextFocus: false,
81
- actions: [
82
- KeyboardActionsItem(
83
- focusNode: _amountFocusNode,
84
- toolbarButtons: [(_) => KeyboardDoneButton()],
85
- ),
86
- ]),
87
- child: Container(
88
- color: Theme.of(context).colorScheme.background,
89
- child: ScrollableWithBottomSection(
90
- contentPadding: EdgeInsets.only(bottom: 24),
91
- content: Container(
92
- decoration: DeviceInfo.instance.isMobile ? BoxDecoration(
93
- borderRadius: BorderRadius.only(
94
- bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
95
- gradient: LinearGradient(
96
- colors: [
97
- Theme.of(context).primaryTextTheme!.titleSmall!.color!,
98
- Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!,
99
- ],
100
- begin: Alignment.topLeft,
101
- end: Alignment.bottomRight,
91
+ nextFocus: false,
92
+ actions: [
93
+ KeyboardActionsItem(
94
+ focusNode: _amountFocusNode,
95
+ toolbarButtons: [(_) => KeyboardDoneButton()],
96
),
103
- ) : null,
104
- child: Observer(builder: (_) {
105
- return Padding(
106
- padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
107
- child: AnonInvoiceForm(
108
- nameController: _nameController,
109
- descriptionController: _descriptionController,
110
- amountController: _amountController,
111
- emailController: _emailController,
112
- depositAmountFocus: _amountFocusNode,
113
- formKey: _formKey,
114
- isInvoice: receiveOptionViewModel.selectedReceiveOption ==
115
- ReceivePageOption.anonPayInvoice,
116
- anonInvoicePageViewModel: anonInvoicePageViewModel,
117
- ),
118
- );
119
- }),
120
- ),
121
- bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
122
- bottomSection: Observer(builder: (_) {
123
- final isInvoice =
124
- receiveOptionViewModel.selectedReceiveOption == ReceivePageOption.anonPayInvoice;
125
- return Column(
126
- children: <Widget>[
127
- Padding(
128
- padding: EdgeInsets.only(bottom: 15),
129
- child: Center(
130
- child: Text(
131
- isInvoice
132
- ? S.of(context).anonpay_description("an invoice", "pay")
133
- : S.of(context).anonpay_description("a donation link", "donate"),
134
- textAlign: TextAlign.center,
135
- style: TextStyle(
136
- color: Theme.of(context)
97
+ ]),
98
+ child: Container(
99
+ color: Theme.of(context).colorScheme.background,
100
+ child: ScrollableWithBottomSection(
101
+ contentPadding: EdgeInsets.only(bottom: 24),
102
+ content: Container(
103
+ decoration: DeviceInfo.instance.isMobile
104
+ ? BoxDecoration(
105
+ borderRadius: BorderRadius.only(
106
+ bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
107
+ gradient: LinearGradient(
108
+ colors: [
109
+ Theme.of(context).primaryTextTheme!.titleSmall!.color!,
110
+ Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!,
111
+ ],
112
+ begin: Alignment.topLeft,
113
+ end: Alignment.bottomRight,
114
+ ),
115
+ )
116
+ : null,
117
+ child: Observer(builder: (_) {
118
+ return Padding(
119
+ padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
120
+ child: AnonInvoiceForm(
121
+ nameController: _nameController,
122
+ descriptionController: _descriptionController,
123
+ amountController: _amountController,
124
+ emailController: _emailController,
125
+ depositAmountFocus: _amountFocusNode,
126
+ formKey: _formKey,
127
+ isInvoice: receiveOptionViewModel.selectedReceiveOption ==
128
+ ReceivePageOption.anonPayInvoice,
129
+ anonInvoicePageViewModel: anonInvoicePageViewModel,
130
+ ),
131
+ );
132
+ }),
133
+ ),
134
+ bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
135
+ bottomSection: Observer(builder: (_) {
136
+ final isInvoice =
137
+ receiveOptionViewModel.selectedReceiveOption == ReceivePageOption.anonPayInvoice;
138
+ return Column(
139
+ children: <Widget>[
140
+ Padding(
141
+ padding: EdgeInsets.only(bottom: 15),
142
+ child: Center(
143
+ child: Text(
144
+ isInvoice
145
+ ? S.of(context).anonpay_description("an invoice", "pay")
146
+ : S.of(context).anonpay_description("a donation link", "donate"),
147
+ textAlign: TextAlign.center,
148
+ style: TextStyle(
149
+ color: Theme.of(context)
150
.primaryTextTheme!
151
.displayLarge!
152
.decorationColor!,
153
fontWeight: FontWeight.w500,
154
fontSize: 12),
155
+ ),
156
),
157
),
144
- ),
145
- LoadingPrimaryButton(
146
- text:
147
- isInvoice ? S.of(context).create_invoice : S.of(context).create_donation_link,
148
- onPressed: () {
149
- anonInvoicePageViewModel.setRequestParams(
150
- inputAmount: _amountController.text,
151
- inputName: _nameController.text,
152
- inputEmail: _emailController.text,
153
- inputDescription: _descriptionController.text,
154
- );
155
- if (anonInvoicePageViewModel.receipientEmail.isNotEmpty &&
156
- _formKey.currentState != null &&
157
- !_formKey.currentState!.validate()) {
158
- return;
159
- }
160
- if (isInvoice) {
161
- anonInvoicePageViewModel.createInvoice();
162
- } else {
163
- anonInvoicePageViewModel.generateDonationLink();
164
- }
165
- },
166
- color: Theme.of(context)
158
+ LoadingPrimaryButton(
159
+ text: isInvoice
160
+ ? S.of(context).create_invoice
161
+ : S.of(context).create_donation_link,
162
+ onPressed: () {
163
+ anonInvoicePageViewModel.setRequestParams(
164
+ inputAmount: _amountController.text,
165
+ inputName: _nameController.text,
166
+ inputEmail: _emailController.text,
167
+ inputDescription: _descriptionController.text,
168
+ );
169
+ if (anonInvoicePageViewModel.receipientEmail.isNotEmpty &&
170
+ _formKey.currentState != null &&
171
+ !_formKey.currentState!.validate()) {
172
+ return;
173
+ }
174
+ if (isInvoice) {
175
+ anonInvoicePageViewModel.createInvoice();
176
+ } else {
177
+ anonInvoicePageViewModel.generateDonationLink();
178
+ }
179
+ },
180
+ color: Theme.of(context)
181
.accentTextTheme!
182
.bodyLarge!
183
.color!,
170
- textColor: Colors.white,
171
- isLoading: anonInvoicePageViewModel.state is IsExecutingState,
172
- ),
173
- ],
174
- );
175
- }),
184
+ textColor: Colors.white,
185
+ isLoading: anonInvoicePageViewModel.state is IsExecutingState,
186
+ ),
187
+ ],
188
+ );
189
+ }),
190
+ ),
191
),
192
),
193
);
lib/src/screens/restore/wallet_restore_page.dart
+2
@@ -266,6 +266,8 @@ class WalletRestorePage extends BasePage {
266
}
267
268
void _confirmForm() {
269
+ // Dismissing all visible keyboard to provide context for navigation
270
+ FocusManager.instance.primaryFocus?.unfocus();
271
final formContext = walletRestoreViewModel.mode == WalletRestoreMode.seed
272
? walletRestoreFromSeedFormKey.currentContext
273
: walletRestoreFromKeysFormKey.currentContext;
lib/view_model/dashboard/market_place_view_model.dart
new
+17
@@ -0,0 +1,17 @@
1
+import 'package:cake_wallet/ionia/ionia_service.dart';
2
+import 'package:mobx/mobx.dart';
3
+
4
+part 'market_place_view_model.g.dart';
5
+
6
+class MarketPlaceViewModel = MarketPlaceViewModelBase with _$MarketPlaceViewModel;
7
+
8
+abstract class MarketPlaceViewModelBase with Store {
9
+ final IoniaService _ioniaService;
10
+
11
+ MarketPlaceViewModelBase(this._ioniaService);
12
+
13
+
14
+ Future<bool> isIoniaUserAuthenticated() async {
15
+ return await _ioniaService.isLogined();
16
+ }
17
+}
\ No newline at end of file
lib/view_model/ionia/ionia_gift_cards_list_view_model.dart
+1
-10
@@ -16,12 +16,10 @@ abstract class IoniaGiftCardsListViewModelBase with Store {
16
ioniaCategories = IoniaCategory.allCategories,
17
selectedIndices = ObservableList<IoniaCategory>.of([IoniaCategory.all]),
18
scrollOffsetFromTop = 0.0,
19
- isLoggedIn = false,
19
merchantState = InitialIoniaMerchantLoadingState(),
20
createCardState = IoniaCreateCardState(),
21
searchString = '',
22
ioniaMerchantList = <IoniaMerchant>[] {
24
- _getAuthStatus().then((value) => isLoggedIn = value);
23
}
24
25
final IoniaService ioniaService;
@@ -45,24 +43,17 @@ abstract class IoniaGiftCardsListViewModelBase with Store {
43
@observable
44
List<IoniaMerchant> ioniaMerchants;
45
48
- @observable
49
- bool isLoggedIn;
50
-
46
@observable
47
List<IoniaCategory> ioniaCategories;
48
49
@observable
50
ObservableList<IoniaCategory> selectedIndices;
51
57
- Future<bool> _getAuthStatus() async {
58
- return await ioniaService.isLogined();
59
- }
60
-
52
@action
53
Future<void> createCard() async {
54
try {
55
createCardState = IoniaCreateCardLoading();
65
- final card = await ioniaService.createCard();
56
+ await ioniaService.createCard();
57
createCardState = IoniaCreateCardSuccess();
58
} catch (e) {
59
createCardState = IoniaCreateCardFailure(error: e.toString());