diff --git a/lib/di.dart b/lib/di.dart index 0f59c702f..85dd7154b 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -39,6 +39,7 @@ import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart'; import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart'; import 'package:cake_wallet/view_model/anonpay_details_view_model.dart'; +import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart'; @@ -873,6 +874,8 @@ Future setup({ getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get())); + getIt.registerFactory(()=> MarketPlaceViewModel(getIt.get())); + getIt.registerFactory(() => IoniaAuthViewModel(ioniaService: getIt.get())); getIt.registerFactoryParam( @@ -902,7 +905,7 @@ Future setup({ return IoniaVerifyIoniaOtp(getIt.get(), email, isSignIn); }); - getIt.registerFactory(() => IoniaWelcomePage(getIt.get())); + getIt.registerFactory(() => IoniaWelcomePage()); getIt.registerFactoryParam((List args, _) { final merchant = args.first as IoniaMerchant; diff --git a/lib/router.dart b/lib/router.dart index e61d3f0ac..902af61dc 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -175,7 +175,6 @@ Route createRoute(RouteSettings settings) { fullscreenDialog: true); } else if (isSingleCoin) { return MaterialPageRoute( - fullscreenDialog: true, builder: (_) => getIt.get( param1: availableWalletTypes.first )); @@ -196,7 +195,6 @@ Route createRoute(RouteSettings settings) { case Routes.restoreWallet: return MaterialPageRoute( - fullscreenDialog: true, builder: (_) => getIt.get( param1: settings.arguments as WalletType)); @@ -206,6 +204,7 @@ Route createRoute(RouteSettings settings) { case Routes.dashboard: return CupertinoPageRoute( + settings: settings, builder: (_) => getIt.get()); case Routes.send: @@ -468,7 +467,8 @@ Route createRoute(RouteSettings settings) { return CupertinoPageRoute( builder: (_) => getIt.get()); case Routes.ioniaManageCardsPage: - return CupertinoPageRoute(builder: (_) => getIt.get()); + return CupertinoPageRoute( + builder: (_) => getIt.get()); case Routes.ioniaBuyGiftCardPage: final args = settings.arguments as List; @@ -536,7 +536,6 @@ Route createRoute(RouteSettings settings) { case Routes.anonPayInvoicePage: final args = settings.arguments as List; return CupertinoPageRoute( - fullscreenDialog: true, builder: (_) => getIt.get(param1: args)); case Routes.anonPayReceivePage: diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index 2b485aa7a..47a62f53a 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -5,7 +5,7 @@ import 'package:cake_wallet/entities/main_actions.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart'; import 'package:cake_wallet/utils/version_comparator.dart'; -import 'package:cake_wallet/wallet_type_utils.dart'; +import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/yat_emoji_id.dart'; @@ -27,8 +27,6 @@ import 'package:mobx/mobx.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:cake_wallet/main.dart'; -import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart'; -import 'package:url_launcher/url_launcher.dart'; import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart'; class DashboardPage extends StatelessWidget { @@ -251,7 +249,12 @@ class _DashboardPageView extends BasePage { if (dashboardViewModel.shouldShowMarketPlaceInDashboard) { pages.add(Semantics( label: 'Marketplace Page', - child: MarketPlacePage(dashboardViewModel: dashboardViewModel))); + child: MarketPlacePage( + dashboardViewModel: dashboardViewModel, + marketPlaceViewModel: getIt.get(), + ), + ), + ); } pages.add(Semantics(label: 'Balance Page', child: balancePage)); pages.add(Semantics( diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart index e5fa42390..e8fa54b49 100644 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart +++ b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart @@ -1,7 +1,9 @@ +import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/entities/main_actions.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_action_button.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; +import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -70,7 +72,10 @@ class DesktopDashboardActions extends StatelessWidget { ], ), Expanded( - child: MarketPlacePage(dashboardViewModel: dashboardViewModel), + child: MarketPlacePage( + dashboardViewModel: dashboardViewModel, + marketPlaceViewModel: getIt.get(), + ), ), ], ); diff --git a/lib/src/screens/dashboard/widgets/address_page.dart b/lib/src/screens/dashboard/widgets/address_page.dart index a5fac2053..82a867058 100644 --- a/lib/src/screens/dashboard/widgets/address_page.dart +++ b/lib/src/screens/dashboard/widgets/address_page.dart @@ -273,7 +273,7 @@ class AddressPage extends BasePage { reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) { switch (option) { case ReceivePageOption.anonPayInvoice: - Navigator.pushReplacementNamed( + Navigator.pushNamed( context, Routes.anonPayInvoicePage, arguments: [addressListViewModel.address.address, option], @@ -285,7 +285,7 @@ class AddressPage extends BasePage { final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink); if (clearnetUrl != null && onionUrl != null) { - Navigator.pushReplacementNamed( + Navigator.pushNamed( context, Routes.anonPayReceivePage, arguments: AnonpayDonationLinkInfo( @@ -295,7 +295,7 @@ class AddressPage extends BasePage { ), ); } else { - Navigator.pushReplacementNamed( + Navigator.pushNamed( context, Routes.anonPayInvoicePage, arguments: [addressListViewModel.address.address, option], diff --git a/lib/src/screens/dashboard/widgets/market_place_page.dart b/lib/src/screens/dashboard/widgets/market_place_page.dart index fe0eb9ec8..248353aca 100644 --- a/lib/src/screens/dashboard/widgets/market_place_page.dart +++ b/lib/src/screens/dashboard/widgets/market_place_page.dart @@ -3,16 +3,20 @@ import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/market_place_item.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; +import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:url_launcher/url_launcher.dart'; class MarketPlacePage extends StatelessWidget { - - MarketPlacePage({required this.dashboardViewModel}); + MarketPlacePage({ + required this.dashboardViewModel, + required this.marketPlaceViewModel, + }); final DashboardViewModel dashboardViewModel; + final MarketPlaceViewModel marketPlaceViewModel; final _scrollController = ScrollController(); @override @@ -48,7 +52,7 @@ class MarketPlacePage extends StatelessWidget { children: [ SizedBox(height: 20), MarketPlaceItem( - onTap: () =>_navigatorToGiftCardsPage(context), + onTap: () => _navigatorToGiftCardsPage(context), title: S.of(context).cake_pay_title, subTitle: S.of(context).cake_pay_subtitle, ), @@ -70,12 +74,13 @@ class MarketPlacePage extends StatelessWidget { ), ); } + void _navigatorToGiftCardsPage(BuildContext context) { final walletType = dashboardViewModel.type; switch (walletType) { case WalletType.haven: - showPopUp( + showPopUp( context: context, builder: (BuildContext context) { return AlertWithOneAction( @@ -85,9 +90,14 @@ class MarketPlacePage extends StatelessWidget { buttonAction: () => Navigator.of(context).pop()); }); break; - default: - Navigator.of(context).pushNamed(Routes.ioniaWelcomePage); + default: + marketPlaceViewModel.isIoniaUserAuthenticated().then((value) { + if (value) { + Navigator.pushNamed(context, Routes.ioniaManageCardsPage); + return; + } + Navigator.of(context).pushNamed(Routes.ioniaWelcomePage); + }); } } - } diff --git a/lib/src/screens/ionia/auth/ionia_welcome_page.dart b/lib/src/screens/ionia/auth/ionia_welcome_page.dart index 4d0cf69c0..91d09c2db 100644 --- a/lib/src/screens/ionia/auth/ionia_welcome_page.dart +++ b/lib/src/screens/ionia/auth/ionia_welcome_page.dart @@ -3,14 +3,11 @@ import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/typography.dart'; -import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/src/widgets/framework.dart'; import 'package:cake_wallet/generated/i18n.dart'; -import 'package:mobx/mobx.dart'; class IoniaWelcomePage extends BasePage { - IoniaWelcomePage(this._cardsListViewModel); + IoniaWelcomePage(); @override Widget middle(BuildContext context) { @@ -25,15 +22,8 @@ class IoniaWelcomePage extends BasePage { ); } - final IoniaGiftCardsListViewModel _cardsListViewModel; - @override Widget body(BuildContext context) { - reaction((_) => _cardsListViewModel.isLoggedIn, (bool state) { - if (state) { - Navigator.pushReplacementNamed(context, Routes.ioniaManageCardsPage); - } - }); return Padding( padding: const EdgeInsets.all(24.0), child: Column( @@ -41,7 +31,7 @@ class IoniaWelcomePage extends BasePage { children: [ Column( children: [ - SizedBox(height: 100), + SizedBox(height: 90), Text( S.of(context).about_cake_pay, style: TextStyle( diff --git a/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart b/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart index 9baa38f24..80ebada1f 100644 --- a/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart +++ b/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart @@ -17,7 +17,7 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; class IoniaManageCardsPage extends BasePage { - IoniaManageCardsPage(this._cardsListViewModel) { + IoniaManageCardsPage(this._cardsListViewModel): searchFocusNode = FocusNode() { _searchController.addListener(() { if (_searchController.text != _cardsListViewModel.searchString) { _searchDebounce.run(() { @@ -29,6 +29,7 @@ class IoniaManageCardsPage extends BasePage { _cardsListViewModel.getMerchants(); } + final FocusNode searchFocusNode; final IoniaGiftCardsListViewModel _cardsListViewModel; final _searchDebounce = Debounce(Duration(milliseconds: 500)); @@ -86,7 +87,14 @@ class IoniaManageCardsPage extends BasePage { //highlightColor: Colors.transparent, //splashColor: Colors.transparent, //padding: EdgeInsets.all(0), - onPressed: () => Navigator.pop(context), + onPressed: (){ + if (searchFocusNode.hasFocus) { + searchFocusNode.unfocus(); + return; + } + + Navigator.of(context).pop(); + }, child: _backButton), ), ); @@ -149,6 +157,7 @@ class IoniaManageCardsPage extends BasePage { Expanded( child: _SearchWidget( controller: _searchController, + focusNode: searchFocusNode, )), SizedBox(width: 10), filterButton @@ -266,9 +275,10 @@ class _SearchWidget extends StatelessWidget { const _SearchWidget({ Key? key, required this.controller, + required this.focusNode, }) : super(key: key); final TextEditingController controller; - + final FocusNode focusNode; @override Widget build(BuildContext context) { final searchIcon = Padding( @@ -280,6 +290,7 @@ class _SearchWidget extends StatelessWidget { ); return TextField( + focusNode: focusNode, style: TextStyle(color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!), controller: controller, decoration: InputDecoration( diff --git a/lib/src/screens/receive/anonpay_invoice_page.dart b/lib/src/screens/receive/anonpay_invoice_page.dart index 199c33e09..41bd5f6fd 100644 --- a/lib/src/screens/receive/anonpay_invoice_page.dart +++ b/lib/src/screens/receive/anonpay_invoice_page.dart @@ -27,8 +27,7 @@ class AnonPayInvoicePage extends BasePage { AnonPayInvoicePage( this.anonInvoicePageViewModel, this.receiveOptionViewModel, - ) : _amountFocusNode = FocusNode() { - } + ) : _amountFocusNode = FocusNode() {} final _nameController = TextEditingController(); final _emailController = TextEditingController(); @@ -53,6 +52,11 @@ class AnonPayInvoicePage extends BasePage { @override AppBarStyle get appBarStyle => AppBarStyle.transparent; + @override + void onClose(BuildContext context) { + Navigator.popUntil(context, ModalRoute.withName(Routes.dashboard)); + } + @override Widget middle(BuildContext context) => PresentReceiveOptionPicker(receiveOptionViewModel: receiveOptionViewModel); @@ -65,114 +69,125 @@ class AnonPayInvoicePage extends BasePage { anonInvoicePageViewModel.reset(); }); + Future _onNavigateBack(BuildContext context) async { + onClose(context); + return false; + } + @override Widget body(BuildContext context) { WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context)); - return KeyboardActions( - disableScroll: true, - config: KeyboardActionsConfig( - keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - keyboardBarColor: Theme.of(context) + return WillPopScope( + onWillPop: () => _onNavigateBack(context), + child: KeyboardActions( + disableScroll: true, + config: KeyboardActionsConfig( + keyboardActionsPlatform: KeyboardActionsPlatform.IOS, + keyboardBarColor: Theme.of(context) .accentTextTheme! .bodyLarge! .backgroundColor!, - nextFocus: false, - actions: [ - KeyboardActionsItem( - focusNode: _amountFocusNode, - toolbarButtons: [(_) => KeyboardDoneButton()], - ), - ]), - child: Container( - color: Theme.of(context).colorScheme.background, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: Container( - decoration: DeviceInfo.instance.isMobile ? BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), - gradient: LinearGradient( - colors: [ - Theme.of(context).primaryTextTheme!.titleSmall!.color!, - Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!, - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight, + nextFocus: false, + actions: [ + KeyboardActionsItem( + focusNode: _amountFocusNode, + toolbarButtons: [(_) => KeyboardDoneButton()], ), - ) : null, - child: Observer(builder: (_) { - return Padding( - padding: EdgeInsets.fromLTRB(24, 120, 24, 0), - child: AnonInvoiceForm( - nameController: _nameController, - descriptionController: _descriptionController, - amountController: _amountController, - emailController: _emailController, - depositAmountFocus: _amountFocusNode, - formKey: _formKey, - isInvoice: receiveOptionViewModel.selectedReceiveOption == - ReceivePageOption.anonPayInvoice, - anonInvoicePageViewModel: anonInvoicePageViewModel, - ), - ); - }), - ), - bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), - bottomSection: Observer(builder: (_) { - final isInvoice = - receiveOptionViewModel.selectedReceiveOption == ReceivePageOption.anonPayInvoice; - return Column( - children: [ - Padding( - padding: EdgeInsets.only(bottom: 15), - child: Center( - child: Text( - isInvoice - ? S.of(context).anonpay_description("an invoice", "pay") - : S.of(context).anonpay_description("a donation link", "donate"), - textAlign: TextAlign.center, - style: TextStyle( - color: Theme.of(context) + ]), + child: Container( + color: Theme.of(context).colorScheme.background, + child: ScrollableWithBottomSection( + contentPadding: EdgeInsets.only(bottom: 24), + content: Container( + decoration: DeviceInfo.instance.isMobile + ? BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), + gradient: LinearGradient( + colors: [ + Theme.of(context).primaryTextTheme!.titleSmall!.color!, + Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!, + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ) + : null, + child: Observer(builder: (_) { + return Padding( + padding: EdgeInsets.fromLTRB(24, 120, 24, 0), + child: AnonInvoiceForm( + nameController: _nameController, + descriptionController: _descriptionController, + amountController: _amountController, + emailController: _emailController, + depositAmountFocus: _amountFocusNode, + formKey: _formKey, + isInvoice: receiveOptionViewModel.selectedReceiveOption == + ReceivePageOption.anonPayInvoice, + anonInvoicePageViewModel: anonInvoicePageViewModel, + ), + ); + }), + ), + bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), + bottomSection: Observer(builder: (_) { + final isInvoice = + receiveOptionViewModel.selectedReceiveOption == ReceivePageOption.anonPayInvoice; + return Column( + children: [ + Padding( + padding: EdgeInsets.only(bottom: 15), + child: Center( + child: Text( + isInvoice + ? S.of(context).anonpay_description("an invoice", "pay") + : S.of(context).anonpay_description("a donation link", "donate"), + textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context) .primaryTextTheme! .displayLarge! .decorationColor!, fontWeight: FontWeight.w500, fontSize: 12), + ), ), ), - ), - LoadingPrimaryButton( - text: - isInvoice ? S.of(context).create_invoice : S.of(context).create_donation_link, - onPressed: () { - anonInvoicePageViewModel.setRequestParams( - inputAmount: _amountController.text, - inputName: _nameController.text, - inputEmail: _emailController.text, - inputDescription: _descriptionController.text, - ); - if (anonInvoicePageViewModel.receipientEmail.isNotEmpty && - _formKey.currentState != null && - !_formKey.currentState!.validate()) { - return; - } - if (isInvoice) { - anonInvoicePageViewModel.createInvoice(); - } else { - anonInvoicePageViewModel.generateDonationLink(); - } - }, - color: Theme.of(context) + LoadingPrimaryButton( + text: isInvoice + ? S.of(context).create_invoice + : S.of(context).create_donation_link, + onPressed: () { + anonInvoicePageViewModel.setRequestParams( + inputAmount: _amountController.text, + inputName: _nameController.text, + inputEmail: _emailController.text, + inputDescription: _descriptionController.text, + ); + if (anonInvoicePageViewModel.receipientEmail.isNotEmpty && + _formKey.currentState != null && + !_formKey.currentState!.validate()) { + return; + } + if (isInvoice) { + anonInvoicePageViewModel.createInvoice(); + } else { + anonInvoicePageViewModel.generateDonationLink(); + } + }, + color: Theme.of(context) .accentTextTheme! .bodyLarge! .color!, - textColor: Colors.white, - isLoading: anonInvoicePageViewModel.state is IsExecutingState, - ), - ], - ); - }), + textColor: Colors.white, + isLoading: anonInvoicePageViewModel.state is IsExecutingState, + ), + ], + ); + }), + ), ), ), ); diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart index 8e4407b3c..6adf9b858 100644 --- a/lib/src/screens/restore/wallet_restore_page.dart +++ b/lib/src/screens/restore/wallet_restore_page.dart @@ -266,6 +266,8 @@ class WalletRestorePage extends BasePage { } void _confirmForm() { + // Dismissing all visible keyboard to provide context for navigation + FocusManager.instance.primaryFocus?.unfocus(); final formContext = walletRestoreViewModel.mode == WalletRestoreMode.seed ? walletRestoreFromSeedFormKey.currentContext : walletRestoreFromKeysFormKey.currentContext; diff --git a/lib/view_model/dashboard/market_place_view_model.dart b/lib/view_model/dashboard/market_place_view_model.dart new file mode 100644 index 000000000..470041127 --- /dev/null +++ b/lib/view_model/dashboard/market_place_view_model.dart @@ -0,0 +1,17 @@ +import 'package:cake_wallet/ionia/ionia_service.dart'; +import 'package:mobx/mobx.dart'; + +part 'market_place_view_model.g.dart'; + +class MarketPlaceViewModel = MarketPlaceViewModelBase with _$MarketPlaceViewModel; + +abstract class MarketPlaceViewModelBase with Store { + final IoniaService _ioniaService; + + MarketPlaceViewModelBase(this._ioniaService); + + + Future isIoniaUserAuthenticated() async { + return await _ioniaService.isLogined(); + } +} \ No newline at end of file diff --git a/lib/view_model/ionia/ionia_gift_cards_list_view_model.dart b/lib/view_model/ionia/ionia_gift_cards_list_view_model.dart index 77d8af6c2..b4974c420 100644 --- a/lib/view_model/ionia/ionia_gift_cards_list_view_model.dart +++ b/lib/view_model/ionia/ionia_gift_cards_list_view_model.dart @@ -16,12 +16,10 @@ abstract class IoniaGiftCardsListViewModelBase with Store { ioniaCategories = IoniaCategory.allCategories, selectedIndices = ObservableList.of([IoniaCategory.all]), scrollOffsetFromTop = 0.0, - isLoggedIn = false, merchantState = InitialIoniaMerchantLoadingState(), createCardState = IoniaCreateCardState(), searchString = '', ioniaMerchantList = [] { - _getAuthStatus().then((value) => isLoggedIn = value); } final IoniaService ioniaService; @@ -45,24 +43,17 @@ abstract class IoniaGiftCardsListViewModelBase with Store { @observable List ioniaMerchants; - @observable - bool isLoggedIn; - @observable List ioniaCategories; @observable ObservableList selectedIndices; - Future _getAuthStatus() async { - return await ioniaService.isLogined(); - } - @action Future createCard() async { try { createCardState = IoniaCreateCardLoading(); - final card = await ioniaService.createCard(); + await ioniaService.createCard(); createCardState = IoniaCreateCardSuccess(); } catch (e) { createCardState = IoniaCreateCardFailure(error: e.toString());