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());