From 83377e150a0e00c718b1de5dcee6937c87a39474 Mon Sep 17 00:00:00 2001 From: fabriziofff <26501317+fabriziofff@users.noreply.github.com> Date: Wed, 27 Apr 2022 17:47:35 +0200 Subject: [PATCH] chore: [IAI-24] Upgrade `react-navigation` to `v5` (#3836) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * replace NavigationInjectedProps with NavigationStackScreenProps * remove unused navigation params * update comments * camelcase * create AuthenticatioonParamsList * add OnboardingParamsList * add zendeskparamslist * fix typescript * remove feature flag from paginated messages routes * add messageRouteParams * rename * add ProfileParamsList * add ServicesParamsList * add WalletParamsList * remove console * add missing params to wallet * add placeholder for NavigatorScreenParams * remove zendesk route * bonusvacanze params * add bpdparamslist * CGN navigation params * siciliavola paramslist * eucovidcert params list * fix * mvlparamsList * onboardingBancomatParamsList * paypal params list * cobadge params list * bancomatpay params list * privative params list * satispay params list * remove InferNavigationParams * update react navigation * add navigationcontext * first update batch * fix navigator & imports * navigation porting * convert navigationparams * convert params * fix * fix * fix * porting * porting * porting * porting * remove all the old navigation import 💥 * wip restoring navigation * fix navigation actions * use CompatNavigationProps * clean * restore workunit * move navigators outside the tab navigator * update navigationactions * update navigationactions * rewire missing navigation paths * restore middleware & redux debug integration * tmp * Revert "tmp" This reverts commit afc88aa0e6e5d28b3003a08372e644af0754b0ec. * remove eslint * fix BaseScreenComponentFC * fix paypal * fix * fix cgn * restore email validation * remove unused code * restore navigation to CGN_LANDING_PLAYGROUND * restore tab navigator * change default background color * restore push notification navigation * restore internal link * fix uaDonations * update navigation to PayPalUpdatePspForPayment * fix test and remove code for external deep link handling * fix test * fix test * fix test * fix test * add legacynavigator compat * fix tests * add onReady navigation condition * fix test * fix test * update snapshot * fix test * fix CoBadge * fix test * fix test * fix test * fix test * delete deeplink * fix all tests! * clean testwrapper * test * Revert "test" This reverts commit cfa1e7db7e7c2c8bb8df7c3d78c28073ef82995a. * test * test * test fix timer * test e2e * disable back gesture on iOS * add a payment method in detox config * upgrade react-native-flag-secure-android * yarn.lock * remove comment * remove comment * fix missing wallet loading * Revert "test e2e" This reverts commit cd287dbd91994de5fc629da1cba8855c0dc409c8. * onWillFocus * fix profile * fix ContactPreferencesToggle onFocus * test e2e * test * test * test * test * test * test * test * test * test * test * test * test * test * restore * fix test * replace with const * remove stings * remove stings * remove strings * remove string * remove comments * remove comment * remove strings * make common type * remove async/await from trackScreen * fix ts * Fix merge error * fix ts * fix ts * remove unmock * fix paginated message navigation * fix merge * fix mixpanel navigation param * fix * fix navigation * deprecate workunit * yarn lock * fix merge * fix * fix gesture Co-authored-by: Cristiano Tofani Co-authored-by: Emilio Pavia Co-authored-by: Matteo Boschi --- ios/Podfile.lock | 6 + jest.config.js | 5 +- jestSetup.js | 3 + jestSetupAfterEnv.js | 3 + package.json | 10 +- scripts/api-config.json | 3 + ts/App.tsx | 7 +- ts/RootContainer.tsx | 71 +- .../reducers/__test__/versionInfo.test.tsx | 5 - ts/components/GoBackButton.tsx | 11 +- .../__tests__/LabelledItem.test.tsx | 30 +- ts/components/LabelledItem/index.tsx | 17 +- .../RemindEmailValidationOverlay.tsx | 25 +- .../__tests__/SectionStatusComponent.test.tsx | 29 +- ts/components/SectionStatus/index.tsx | 22 +- .../__tests__/ContextualInfo.test.tsx | 9 +- ts/components/helpers/withConditionalView.tsx | 31 +- ts/components/helpers/withValidatedEmail.tsx | 33 +- .../infoScreen/InfoScreenComponent.tsx | 4 +- ts/components/messages/PaymentButton.tsx | 4 +- .../messages/__tests__/PaymentButton.test.tsx | 8 +- .../MessageDetail/__tests__/CtaBar.test.tsx | 4 +- .../MedicalPrescriptionDueDateBar.test.tsx | 3 +- .../__snapshots__/CtaBar.test.tsx.snap | 479 ++- ...edicalPrescriptionDueDateBar.test.tsx.snap | 3636 ++++++++++++----- .../__tests__/MessageDetail.test.tsx | 19 +- .../paginated/__tests__/MessageList.test.tsx | 3 +- .../__tests__/MessagesInbox.test.tsx | 21 +- .../screens/AnimatedScreenContent.tsx | 2 +- ts/components/screens/BaseHeader.tsx | 10 +- .../__tests__/BaseScreenComponent.test.tsx | 22 +- .../screens/BaseScreenComponent/index.tsx | 24 +- .../screens/GenericErrorComponent.tsx | 4 +- ts/components/screens/ScreenContent.tsx | 2 +- .../ContactPreferencesToggles.test.tsx | 24 +- .../ContactPreferencesToggles/index.tsx | 24 +- ts/components/ui/FocusAwareStatusBar.tsx | 2 +- .../ui/Markdown/handlers/internalLink.ts | 198 +- .../OutcomeCodeMessageComponent.test.tsx | 9 +- .../wallet/__test__/PayWebViewModal.test.tsx | 3 +- .../bonus/bonusVacanze/navigation/action.ts | 107 +- .../bonusVacanze/navigation/navigator.ts | 9 +- .../screens/ActiveBonusScreen.tsx | 10 +- .../screens/BonusInformationScreen.tsx | 11 +- .../__tests__/AvailableBonusScreen.test.tsx | 4 +- .../RetryAfterDeletionFailsComponent.test.ts | 4 +- .../ThankYouSuccessComponent.test.ts | 4 +- .../base/PaymentMethodBpdToggle.tsx | 4 +- ts/features/bonus/bpd/navigation/actions.ts | 93 +- ts/features/bonus/bpd/navigation/navigator.ts | 37 +- ts/features/bonus/bpd/saga/index.ts | 12 +- ...> activateBpdOnNewPaymentMethods.test.tsx} | 12 + .../bpd/saga/orchestration/insertIban.ts | 2 +- .../orchestration/onboarding/enrollToBpd.ts | 7 +- .../onboarding/startOnboarding.ts | 2 +- .../optInPaymentMethodsHandler.ts | 14 +- .../__test__/BpdTransactionsScreen.test.tsx | 28 +- .../__test__/LoadTransactions.test.tsx | 39 +- .../__test__/TransactionsUnavailable.test.tsx | 18 +- .../BpdTransactionsRouterScreen.test.tsx | 4 +- .../__test__/TransactionsSectionList.test.tsx | 4 +- .../bpd/screens/iban/IbanCTAEditScreen.tsx | 8 +- .../BpdCTAStartOnboardingScreen.tsx | 20 +- ...ptInPaymentMethodsCashbackUpdateScreen.tsx | 26 +- .../OptInPaymentMethodsChoiceScreen.tsx | 14 +- ...aymentMethodsCashbackUpdateScreen.test.tsx | 4 +- .../OptInPaymentMethodsChoiceScreen.test.tsx | 4 +- ...MethodsThankYouDeleteMethodsScreen.test.ts | 4 +- ...ntMethodsThankYouKeepMethodsScreen.test.ts | 4 +- ts/features/bonus/cgn/navigation/actions.ts | 54 +- ts/features/bonus/cgn/navigation/navigator.ts | 21 +- ts/features/bonus/cgn/navigation/routes.ts | 6 +- .../activation/activationSaga.ts | 14 +- .../activation/handleActivationSaga.ts | 7 +- .../orchestration/eyca/eycaActivationSaga.ts | 8 +- .../bonus/cgn/screens/CgnDetailScreen.tsx | 15 +- .../CgnCTAStartActivationScreen.tsx | 12 +- .../merchants/CgnMerchantDetailScreen.tsx | 11 +- .../merchants/CgnMerchantLandingWebview.tsx | 17 +- .../CgnMerchantsCategoriesSelectionScreen.tsx | 11 +- .../merchants/CgnMerchantsListByCategory.tsx | 45 +- .../CheckResidenceComponent.test.tsx | 12 +- .../bonus/siciliaVola/navigation/actions.ts | 71 +- ts/features/euCovidCert/navigation/actions.ts | 30 +- .../euCovidCert/navigation/navigator.ts | 7 +- .../screens/BaseEuCovidCertificateLayout.tsx | 8 +- .../EuCovidCertificateRouterScreen.tsx | 13 +- .../EUCovidCertExpiredScreen.test.tsx | 4 +- .../EUCovidCertRevokedScreen.test.tsx | 4 +- .../__test__/EUCovidCertValidScreen.test.tsx | 41 +- .../EuCovidCertificateRouterScreen.test.tsx | 7 +- .../EuCovidCertNotFoundKoScreen.test.tsx | 4 +- .../EuCovidCertWrongFormatKoScreen.test.tsx | 4 +- .../EuCovidCertMarkdownDetailsScreen.tsx | 12 +- .../valid/EuCovidCertQrCodeFullScreen.tsx | 12 +- ts/features/mvl/navigation/actions.ts | 33 +- ts/features/mvl/navigation/navigator.ts | 7 +- ts/features/mvl/screens/MvlRouterScreen.tsx | 14 +- .../screens/__test__/MvlRouterScreen.test.tsx | 3 +- .../__test__/MvlAttachments.test.tsx | 4 +- .../__test__/UaDonationsBanner.test.tsx | 4 +- .../uaDonations/navigation/navigator.ts | 20 - .../uaDonations/screens/UAWebViewScreen.tsx | 51 +- .../bancomat/screen/BancomatDetailScreen.tsx | 11 +- .../__test__/BPayWalletPreview.test.tsx | 19 +- .../bancomatpay/screen/BPayDetailScreen.tsx | 11 +- .../__tests__/CobadgeWalletPreview.test.tsx | 34 +- .../cobadge/screen/CobadgeDetailScreen.tsx | 11 +- .../__test__/PagoPaPaymentCapability.test.tsx | 17 +- .../__test__/PaymentMethodCapability.test.tsx | 4 +- .../screen/CreditCardDetailScreen.tsx | 11 +- .../__tests__/CreditCardDetailScreen.test.tsx | 4 +- .../onboarding/bancomat/navigation/action.ts | 48 +- .../bancomat/navigation/navigator.ts | 9 +- .../bancomatPay/navigation/action.ts | 31 +- .../bancomatPay/navigation/navigator.ts | 9 +- .../onboarding/cobadge/navigation/action.ts | 33 +- .../cobadge/navigation/navigator.ts | 9 +- .../cobadge/screens/CoBadgeChooseType.tsx | 14 +- .../__tests__/CoBadgeChooseType.test.tsx | 19 +- .../SearchAvailableCoBadgeScreen.test.tsx | 4 +- .../__test__/CoBadgeStartScreen.test.tsx | 4 +- .../bpd/ActivateBpdOnNewCreditCardScreen.tsx | 14 +- .../common/searchBank/SearchBankScreen.tsx | 2 +- .../onboarding/paypal/navigation/navigator.ts | 7 +- .../paypal/saga/orchestration/index.ts | 15 +- .../screen/PayPalOnboardingCheckoutScreen.tsx | 36 +- .../screen/PayPalPspSelectionScreen.tsx | 36 +- .../screen/PayPalStartOnboardingScreen.tsx | 24 +- .../PayPalOnboardingCheckoutScreen.test.tsx | 4 +- ...boardingCompletedSuccessComponent.test.tsx | 4 +- .../PayPalPpsSelectionScreen.test.tsx | 3 +- .../__tests__/PayPalPspUpdateScreen.test.tsx | 3 +- .../PayPalStartOnboardingScreen.test.tsx | 4 +- ...ingCompletedSuccessComponent.test.tsx.snap | 849 ++-- .../paypal/store/actions/navigation.ts | 2 +- .../onboarding/privative/navigation/action.ts | 45 +- .../privative/navigation/navigator.ts | 9 +- .../AddPrivativeCardNumberScreen.test.tsx | 13 +- .../__tests__/AddPrivativeCardScreen.test.tsx | 3 +- .../__tests__/ChoosePrivativeIssuers.test.tsx | 4 +- .../SearchPrivativeCardScreen.test.tsx | 4 +- .../onboarding/satispay/navigation/action.ts | 32 +- .../satispay/navigation/navigator.ts | 9 +- .../wallet/paypal/PayPalWalletPreview.tsx | 19 +- .../paypal/screen/PayPalPspUpdateScreen.tsx | 51 +- .../__tests__/PrivativeWalletPreview.test.tsx | 19 +- .../screen/PrivativeDetailScreen.tsx | 11 +- .../satispay/screen/SatispayDetailScreen.tsx | 11 +- .../components/ZendeskSupportComponent.tsx | 60 +- .../ZendeskSupportComponent.test.tsx | 114 +- ts/features/zendesk/navigation/navigator.tsx | 9 +- ts/features/zendesk/navigation/params.ts | 3 +- .../zendesk/saga/orchestration/index.ts | 10 +- .../zendesk/screens/ZendeskAskPermissions.tsx | 16 +- .../zendesk/screens/ZendeskChooseCategory.tsx | 60 +- .../screens/ZendeskChooseSubCategory.tsx | 38 +- .../screens/ZendeskSupportHelpCenter.tsx | 12 +- .../__tests__/ZendeskAskPermissions.test.tsx | 3 +- .../__tests__/ZendeskChooseCategory.test.tsx | 62 +- .../ZendeskChooseSubCategory.test.tsx | 33 +- .../__tests__/ZendeskPanicMode.test.tsx | 3 +- .../ZendeskSupportHelpCenter.test.tsx | 3 +- .../zendesk/store/actions/navigation.ts | 31 - ts/navigation/AppNavigator.ts | 93 - ts/navigation/AppStackNavigator.tsx | 143 + ts/navigation/AuthenticationNavigator.ts | 22 +- ts/navigation/MainNavigator.tsx | 179 - ts/navigation/MessagesNavigator.ts | 82 +- ts/navigation/NavigationService.ts | 72 +- ts/navigation/OnboardingNavigator.ts | 37 +- ts/navigation/ProfileNavigator.ts | 19 +- ts/navigation/ServicesNavigator.ts | 24 +- ts/navigation/TabNavigator.tsx | 96 + ts/navigation/WalletNavigator.ts | 34 +- ts/navigation/params/AppParamsList.ts | 62 +- ts/navigation/params/MainParamsList.ts | 6 - ts/navigation/params/MainTabParamsList.ts | 9 + ts/navigation/params/MessagesParamsList.ts | 10 +- ts/navigation/params/OnboardingParamsList.ts | 1 + ts/navigation/params/ProfileParamsList.ts | 2 +- ts/navigation/params/ServicesParamsList.ts | 8 +- ts/navigation/params/WalletParamsList.ts | 40 +- ts/navigation/routes.ts | 1 + ts/sagas/__tests__/premiumMessages.test.ts | 6 +- ts/sagas/index.ts | 2 - ts/sagas/mixpanel.ts | 9 +- ts/sagas/premiumMessages.ts | 6 +- ts/sagas/startup.ts | 17 +- ....test.ts => checkAcceptedTosSaga.test.tsx} | 12 + ...test.ts => checkProfileEmailSaga.test.tsx} | 53 +- .../__tests__/checkProfileEnabledSaga.test.ts | 8 +- .../__tests__/saveNavigationStateSaga.test.ts | 55 - .../startup/checkAcknowledgedEmailSaga.ts | 14 +- ts/sagas/startup/saveNavigationStateSaga.ts | 40 - ts/sagas/wallet.ts | 6 +- ts/sagas/watchNavigateToDeepLinkSaga.ts | 33 - ts/sagas/workUnit/index.ts | 25 +- .../authentication/CardSelectionScreen.tsx | 14 +- ts/screens/authentication/IdpLoginScreen.tsx | 15 +- .../InvalidNfcConnectionScreen.tsx | 9 +- ts/screens/authentication/LandingScreen.tsx | 31 +- .../SpidCIEInformationScreen.tsx | 13 +- .../authentication/SpidInformationScreen.tsx | 13 +- .../TestAuthenticationScreen.tsx | 2 +- .../cie/CieAuthorizeDataUsageScreen.tsx | 13 +- .../cie/CieCardReaderScreen.tsx | 67 +- .../cie/CieConsentDataUsageScreen.tsx | 14 +- .../cie/CieExpiredOrInvalidScreen.tsx | 10 +- .../cie/CiePinLockedTemporarilyScreen.tsx | 15 +- .../authentication/cie/CiePinScreen.tsx | 26 +- .../cie/CieWrongCiePinScreen.tsx | 13 +- .../messages/MessageDetailScreen/index.tsx | 10 +- ts/screens/messages/MessageRouterScreen.tsx | 11 +- ts/screens/messages/MessagesHomeScreen.tsx | 19 +- .../__test__/MessageRouterScreen.test.tsx | 64 +- .../paginated/MessageDetailScreen.tsx | 11 +- .../paginated/MessageRouterScreen.tsx | 15 +- .../messages/paginated/MessagesHomeScreen.tsx | 86 +- .../__tests__/MessageRouterScreen.test.tsx | 47 +- ts/screens/modal/__test__/RootModal.test.tsx | 39 +- ts/screens/onboarding/EmailInsertScreen.tsx | 16 +- ts/screens/onboarding/EmailReadScreen.tsx | 12 +- ts/screens/onboarding/FingerprintScreen.tsx | 11 +- .../OnboardingServicesPreferenceScreen.tsx | 14 +- ts/screens/onboarding/PinScreen.tsx | 19 +- ts/screens/onboarding/TosScreen.tsx | 15 +- .../profile/CalendarsPreferencesScreen.tsx | 10 +- .../profile/DownloadProfileDataScreen.tsx | 8 +- ts/screens/profile/EmailForwardingScreen.tsx | 15 +- ts/screens/profile/FiscalCodeScreen.tsx | 12 +- ts/screens/profile/PreferencesScreen.tsx | 15 +- ts/screens/profile/PrivacyMainScreen.tsx | 29 +- ts/screens/profile/ProfileMainScreen.tsx | 66 +- .../profile/RemoveAccountDetailsScreen.tsx | 2 +- .../profile/RemoveAccountSuccessScreen.tsx | 8 +- .../__test__/ProfileDataScreen.test.tsx | 4 +- .../profile/__test__/SecurityScreen.test.tsx | 4 +- ts/screens/services/ServiceDetailsScreen.tsx | 11 +- ts/screens/services/ServicesHomeScreen.tsx | 7 +- .../__tests__/ServiceDetailsScreen.test.tsx | 3 +- ts/screens/wallet/AddCardScreen.tsx | 10 +- .../AddCreditCardOutcomeCodeMessage.tsx | 14 +- ts/screens/wallet/AddPaymentMethodScreen.tsx | 18 +- .../wallet/ConfirmCardDetailsScreen.tsx | 16 +- .../wallet/PaymentHistoryDetailsScreen.tsx | 14 +- ts/screens/wallet/PaymentsHistoryScreen.tsx | 7 +- .../wallet/TransactionDetailsScreen.tsx | 20 +- ts/screens/wallet/WalletHomeScreen.tsx | 22 +- .../wallet/__tests__/AddCardScreen.test.tsx | 26 +- .../ConfirmCardDetailScreen.test.tsx | 11 +- .../__tests__/WalletHomeScreen.test.tsx | 9 +- ...reditCardOnboardingAttemptDetailScreen.tsx | 14 +- .../CreditCardOnboardingAttemptsScreen.tsx | 15 +- .../payment/ConfirmPaymentMethodScreen.tsx | 79 +- .../payment/ManualDataInsertionScreen.tsx | 19 +- .../payment/PaymentOutcomeCodeMessage.tsx | 11 +- .../payment/PickPaymentMethodScreen.tsx | 11 +- ts/screens/wallet/payment/PickPspScreen.tsx | 10 +- .../wallet/payment/ScanQrCodeScreen.tsx | 16 +- .../wallet/payment/TransactionErrorScreen.tsx | 63 +- .../payment/TransactionSummaryScreen.tsx | 43 +- .../ConfirmPaymentMethodScreen.test.tsx | 73 +- .../PickPaymentMethodScreen.test.tsx | 4 +- .../payment/__tests__/PickPspScreen.test.tsx | 3 +- .../__tests__/TransactionErrorScreen.test.tsx | 4 +- ts/store/actions/deepLink.ts | 41 - ts/store/actions/navigation.ts | 262 +- ts/store/actions/types.ts | 2 - ts/store/middlewares/navigation.ts | 23 +- ts/store/reducers/deepLink.ts | 42 - ts/store/reducers/index.ts | 4 +- ts/store/reducers/types.ts | 2 - ts/utils/__tests__/fetch.test.ts | 10 +- ts/utils/__tests__/internalLink.test.ts | 34 +- ts/utils/deepLink.ts | 19 - ts/utils/hooks/useLoadPotValue.ts | 6 +- ts/utils/hooks/useOnFocus.tsx | 8 +- ts/utils/navigation.ts | 63 +- ts/utils/testWrapper.tsx | 127 +- yarn.lock | 158 +- 281 files changed, 6982 insertions(+), 4327 deletions(-) create mode 100644 jestSetupAfterEnv.js rename ts/features/bonus/bpd/saga/orchestration/__tests__/{activateBpdOnNewPaymentMethods.test.ts => activateBpdOnNewPaymentMethods.test.tsx} (93%) delete mode 100644 ts/features/uaDonations/navigation/navigator.ts delete mode 100644 ts/features/zendesk/store/actions/navigation.ts delete mode 100644 ts/navigation/AppNavigator.ts create mode 100644 ts/navigation/AppStackNavigator.tsx delete mode 100644 ts/navigation/MainNavigator.tsx create mode 100644 ts/navigation/TabNavigator.tsx delete mode 100644 ts/navigation/params/MainParamsList.ts create mode 100644 ts/navigation/params/MainTabParamsList.ts rename ts/sagas/startup/__tests__/{checkAcceptedTosSaga.test.ts => checkAcceptedTosSaga.test.tsx} (83%) rename ts/sagas/startup/__tests__/{checkProfileEmailSaga.test.ts => checkProfileEmailSaga.test.tsx} (51%) delete mode 100644 ts/sagas/startup/__tests__/saveNavigationStateSaga.test.ts delete mode 100644 ts/sagas/startup/saveNavigationStateSaga.ts delete mode 100644 ts/sagas/watchNavigateToDeepLinkSaga.ts delete mode 100644 ts/store/actions/deepLink.ts delete mode 100644 ts/store/reducers/deepLink.ts delete mode 100644 ts/utils/deepLink.ts diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 57353430f6e..5cf73cac736 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -324,6 +324,8 @@ PODS: - React - react-native-pdf (6.4.0): - React-Core + - react-native-safe-area-context (3.3.2): + - React-Core - react-native-screen-brightness (2.0.0-alpha): - React - react-native-slider (3.0.3): @@ -556,6 +558,7 @@ DEPENDENCIES: - react-native-image-picker (from `../node_modules/react-native-image-picker`) - react-native-mixpanel (from `../node_modules/react-native-mixpanel`) - react-native-pdf (from `../node_modules/react-native-pdf`) + - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-screen-brightness (from `../node_modules/react-native-screen-brightness`) - "react-native-slider (from `../node_modules/@react-native-community/slider`)" - react-native-splash-screen (from `../node_modules/react-native-splash-screen`) @@ -700,6 +703,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-mixpanel" react-native-pdf: :path: "../node_modules/react-native-pdf" + react-native-safe-area-context: + :path: "../node_modules/react-native-safe-area-context" react-native-screen-brightness: :path: "../node_modules/react-native-screen-brightness" react-native-slider: @@ -829,6 +834,7 @@ SPEC CHECKSUMS: react-native-image-picker: a6e56460d34905c849ada551db30897dc7f3d535 react-native-mixpanel: d644efe1ca33d2646d5cba29e24a13ebc9b37209 react-native-pdf: a6a5a3f0bdf340eb2eed6c96034424d2cc3f84b0 + react-native-safe-area-context: 584dc04881deb49474363f3be89e4ca0e854c057 react-native-screen-brightness: 9eefe6db96a5d757e63cdfce8e48d7c9039f2af2 react-native-slider: e99fc201cefe81270fc9d81714a7a0f5e566b168 react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 diff --git a/jest.config.js b/jest.config.js index 1d7a5f0d727..263023292d0 100644 --- a/jest.config.js +++ b/jest.config.js @@ -11,6 +11,9 @@ module.exports = { }, setupFiles: ["./jestSetup.js"], globalSetup: "./jestGlobalSetup.js", - setupFilesAfterEnv: ["@testing-library/jest-native/extend-expect"], + setupFilesAfterEnv: [ + "@testing-library/jest-native/extend-expect", + "./jestSetupAfterEnv.js" + ], collectCoverage: true }; diff --git a/jestSetup.js b/jestSetup.js index 45701ca9905..db972594a01 100644 --- a/jestSetup.js +++ b/jestSetup.js @@ -7,6 +7,7 @@ import {NativeModules} from "react-native"; import mockAsyncStorage from "@react-native-community/async-storage/jest/async-storage-mock"; import mockClipboard from "@react-native-clipboard/clipboard/jest/clipboard-mock.js"; import nodeFetch from "node-fetch"; +import mockRNDeviceInfo from "react-native-device-info/jest/react-native-device-info-mock"; // eslint-disable-next-line functional/immutable-data NativeModules.RNGestureHandlerModule = { @@ -92,3 +93,5 @@ jest.mock("@gorhom/bottom-sheet", () => { } }; }); + +jest.mock("react-native-device-info", () => mockRNDeviceInfo); diff --git a/jestSetupAfterEnv.js b/jestSetupAfterEnv.js new file mode 100644 index 00000000000..504999a402d --- /dev/null +++ b/jestSetupAfterEnv.js @@ -0,0 +1,3 @@ +global.beforeEach(() => { + jest.useFakeTimers(); +}); diff --git a/package.json b/package.json index 057d6efed49..b9747d635cb 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,11 @@ "@react-native-community/datetimepicker": "^3.5.2", "@react-native-community/push-notification-ios": "^1.8.0", "@react-native-community/slider": "^3.0.3", + "@react-navigation/bottom-tabs": "^5.11.15", + "@react-navigation/compat": "^5.3.20", + "@react-navigation/drawer": "^5.12.9", + "@react-navigation/native": "^5.9.8", + "@react-navigation/stack": "^5.14.9", "@redux-saga/testing-utils": "^1.1.3", "abort-controller": "^1.0.2", "async-mutex": "^0.1.3", @@ -139,6 +144,7 @@ "react-native-reanimated": "^2.7.0", "react-native-render-html": "^6.3.1", "react-native-responsive-screen": "^1.4.1", + "react-native-safe-area-context": "^3.3.2", "react-native-screen-brightness": "^2.0.0-alpha", "react-native-screens": "^2.18.1", "react-native-sha256": "1.2.3", @@ -148,10 +154,6 @@ "react-native-vector-icons": "^7.0.0", "react-native-view-shot": "3.1.2", "react-native-webview": "^11.13.0", - "react-navigation": "^4.4.4", - "react-navigation-drawer": "^1.4.0", - "react-navigation-stack": "^1.7.3", - "react-navigation-tabs": "^2.11.1", "react-redux": "7.2.4", "reactotron-react-native": "^5.0.0", "reactotron-redux": "^3.1.3", diff --git a/scripts/api-config.json b/scripts/api-config.json index 8ceb9ad178a..355e0f37211 100644 --- a/scripts/api-config.json +++ b/scripts/api-config.json @@ -26,6 +26,9 @@ "payment": { "amount": 2222, "pspFeeAmount": 100 + }, + "methods": { + "walletCreditCardCount":1 } }, "features": { diff --git a/ts/App.tsx b/ts/App.tsx index db06cc559ae..5496174a651 100644 --- a/ts/App.tsx +++ b/ts/App.tsx @@ -10,16 +10,15 @@ import { LightModalProvider } from "./components/ui/LightModal"; import RootContainer from "./RootContainer"; import theme from "./theme"; -// Infer the `RootState` and `AppDispatch` types from the store itselfexport +// Infer the `RootState` and `AppDispatch` types from the store itself export export type RootState = ReturnType; export type AppDispatch = typeof store.dispatch; /** * Main component of the application - * - * TODO: Add a loading screen @https://www.pivotaltracker.com/story/show/155583084 + * @constructor */ -export const App: React.SFC = () => ( +export const App: React.FunctionComponent = () => ( diff --git a/ts/RootContainer.tsx b/ts/RootContainer.tsx index 402bc4b58e5..07d622874a8 100644 --- a/ts/RootContainer.tsx +++ b/ts/RootContainer.tsx @@ -1,10 +1,8 @@ import { Root } from "native-base"; import * as React from "react"; -import { AppState, Linking, Platform, StatusBar } from "react-native"; +import { AppState, Platform, StatusBar } from "react-native"; import SplashScreen from "react-native-splash-screen"; -import { createAppContainer } from "react-navigation"; import { connect } from "react-redux"; -import customVariables from "./theme/variables"; import configurePushNotifications from "./boot/configurePushNotification"; import { BetaTestingOverlay } from "./components/BetaTestingOverlay"; import FlagSecureComponent from "./components/FlagSecure"; @@ -13,28 +11,22 @@ import VersionInfoOverlay from "./components/VersionInfoOverlay"; import { testOverlayCaption } from "./config"; import { setLocale } from "./i18n"; -import AppNavigator from "./navigation/AppNavigator"; -import NavigationService from "./navigation/NavigationService"; +import { IONavigationContainer } from "./navigation/AppStackNavigator"; import RootModal from "./screens/modal/RootModal"; import { applicationChangeState, ApplicationState } from "./store/actions/application"; import { setDebugCurrentRouteName } from "./store/actions/debug"; -import { navigateToDeepLink, setDeepLink } from "./store/actions/deepLink"; import { navigateBack } from "./store/actions/navigation"; -import { trackScreen } from "./store/middlewares/navigation"; import { isDebugModeEnabledSelector } from "./store/reducers/debug"; import { preferredLanguageSelector } from "./store/reducers/persistedPreferences"; import { GlobalState } from "./store/reducers/types"; -import { getNavigateActionFromDeepLink } from "./utils/deepLink"; -import { getCurrentRouteName } from "./utils/navigation"; +import customVariables from "./theme/variables"; import { isStringNullyOrEmpty } from "./utils/strings"; type Props = ReturnType & typeof mapDispatchToProps; -const AppContainer = createAppContainer(AppNavigator); - /** * The main container of the application with: * - the Navigator @@ -51,29 +43,10 @@ class RootContainer extends React.PureComponent { configurePushNotifications(); } - private handleOpenUrlEvent = (event: { url: string }): void => - this.navigateToUrlHandler(event.url); - private handleApplicationActivity = (activity: ApplicationState) => this.props.applicationChangeState(activity); - private navigateToUrlHandler = (url: string | null) => { - if (!url) { - return; - } - const action = getNavigateActionFromDeepLink(url); - // immediately navigate to the resolved action - this.props.setDeepLink(action, true); - }; - public componentDidMount() { - if (Platform.OS === "android") { - Linking.getInitialURL() - .then(this.navigateToUrlHandler) - .catch(console.error); // eslint-disable-line no-console - } else { - Linking.addEventListener("url", this.handleOpenUrlEvent); - } // boot: send the status of the application this.handleApplicationActivity(AppState.currentState); AppState.addEventListener("change", this.handleApplicationActivity); @@ -93,30 +66,10 @@ class RootContainer extends React.PureComponent { }); public componentWillUnmount() { - if (Platform.OS === "ios") { - Linking.removeEventListener("url", this.handleOpenUrlEvent); - } - AppState.removeEventListener("change", this.handleApplicationActivity); } public componentDidUpdate() { - // FIXME: the logic here is a bit weird: there is an event handler - // (navigateToUrlHandler) that will dispatch a redux action for - // setting a "deep link" in the redux state - in turn, the update - // of the redux state triggers an update of the RootComponent that - // dispatches a navigate action from componentDidUpdate - can't we - // just listen for SET_DEEPLINK from a saga and dispatch the - // navigate action from there? - // FIXME: how does this logic interacts with the logic that handles the deep - // link in the startup saga? - const { - deepLinkState: { deepLink, immediate } - } = this.props; - - if (immediate && deepLink) { - this.props.navigateToDeepLink(deepLink); - } this.updateLocale(); } @@ -134,18 +87,9 @@ class RootContainer extends React.PureComponent { backgroundColor={customVariables.androidStatusBarColor} /> {Platform.OS === "android" && } - { - NavigationService.setTopLevelNavigator(navigatorRef); - }} - onNavigationStateChange={(prevState, currentState) => { - NavigationService.setCurrentState(currentState); - this.props.setDebugCurrentRouteName( - getCurrentRouteName(currentState) ?? "Undefined" - ); - trackScreen(prevState, currentState); - }} - /> + + + {this.props.isDebugModeEnabled && } {!isStringNullyOrEmpty(testOverlayCaption) && ( { const mapStateToProps = (state: GlobalState) => ({ preferredLanguage: preferredLanguageSelector(state), - deepLinkState: state.deepLink, isDebugModeEnabled: isDebugModeEnabledSelector(state) }); const mapDispatchToProps = { applicationChangeState, - setDeepLink, - navigateToDeepLink, navigateBack, setDebugCurrentRouteName }; diff --git a/ts/common/versionInfo/store/reducers/__test__/versionInfo.test.tsx b/ts/common/versionInfo/store/reducers/__test__/versionInfo.test.tsx index 7afda306ada..24117d30ffc 100644 --- a/ts/common/versionInfo/store/reducers/__test__/versionInfo.test.tsx +++ b/ts/common/versionInfo/store/reducers/__test__/versionInfo.test.tsx @@ -14,11 +14,6 @@ import { isAppSupportedSelector } from "../versionInfo"; -jest.mock("react-native-device-info", () => ({ - getVersion: jest.fn(), - getReadableVersion: jest.fn() -})); - describe("versionInfo selectors", () => { describe("When the store is in initial state", () => { it("isAppSupportedSelector should return true", () => { diff --git a/ts/components/GoBackButton.tsx b/ts/components/GoBackButton.tsx index 02b29c01ab7..d5fee92207c 100644 --- a/ts/components/GoBackButton.tsx +++ b/ts/components/GoBackButton.tsx @@ -1,8 +1,8 @@ +import { CommonActions } from "@react-navigation/native"; import * as React from "react"; import { BackHandler } from "react-native"; -import { withNavigation } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import I18n from "../i18n"; +import NavigationService from "../navigation/NavigationService"; import variables from "../theme/variables"; import ButtonDefaultOpacity from "./ButtonDefaultOpacity"; import IconFont from "./ui/IconFont"; @@ -13,7 +13,7 @@ interface OwnProps { white?: boolean; } -type Props = NavigationStackScreenProps & OwnProps; +type Props = OwnProps; class GoBackButton extends React.PureComponent { public static defaultProps: Partial = { @@ -34,7 +34,8 @@ class GoBackButton extends React.PureComponent { return true; }; - private handleOnPressDefault = () => this.props.navigation.goBack(null); + private handleOnPressDefault = () => + NavigationService.dispatchNavigationAction(CommonActions.goBack()); private getOnPressHandler = () => typeof this.props.onPress === "function" @@ -64,4 +65,4 @@ class GoBackButton extends React.PureComponent { } } -export default withNavigation(GoBackButton); +export default GoBackButton; diff --git a/ts/components/LabelledItem/__tests__/LabelledItem.test.tsx b/ts/components/LabelledItem/__tests__/LabelledItem.test.tsx index 0f49c472cb1..e54dbab82ed 100644 --- a/ts/components/LabelledItem/__tests__/LabelledItem.test.tsx +++ b/ts/components/LabelledItem/__tests__/LabelledItem.test.tsx @@ -1,12 +1,12 @@ -import { fireEvent, render } from "@testing-library/react-native"; +import { fireEvent } from "@testing-library/react-native"; import { isString } from "lodash"; import React from "react"; +import { createStore } from "redux"; +import { applicationChangeState } from "../../../store/actions/application"; +import { appReducer } from "../../../store/reducers"; +import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; import { LabelledItem, Props } from "../index"; -jest.mock("react-navigation", () => ({ - NavigationEvents: "mockNavigationEvents" -})); - const textInputProps = { inputProps: { value: "value" } } as Props; @@ -33,15 +33,6 @@ describe("Test LabelledItem", () => { expect(component.queryByText(label)).toBeTruthy(); }); - it("should render NavigationEvents if hasNavigationEvents is true and onPress is defined", () => { - const component = renderComponent({ - ...textInputProps, - hasNavigationEvents: true, - onPress - }); - expect(component.queryByTestId("NavigationEvents")).not.toBeNull(); - }); - it("should render ButtonDefaultOpacity if iconPosition is left and icon is defined", () => { const component = renderComponent({ ...textInputProps, @@ -174,4 +165,13 @@ describe("Test LabelledItem", () => { }); }); -const renderComponent = (props: Props) => render(); +const renderComponent = (props: Props) => { + const globalState = appReducer(undefined, applicationChangeState("active")); + const store = createStore(appReducer, globalState as any); + return renderScreenFakeNavRedux( + () => , + "DUMMY", + {}, + store + ); +}; diff --git a/ts/components/LabelledItem/index.tsx b/ts/components/LabelledItem/index.tsx index 31f384b683c..6e03d79d129 100644 --- a/ts/components/LabelledItem/index.tsx +++ b/ts/components/LabelledItem/index.tsx @@ -9,7 +9,9 @@ * icon | * input */ -import { Item, View, Input as InputNativeBase } from "native-base"; +import { NavigationEvents } from "@react-navigation/compat"; +import color from "color"; +import { Input as InputNativeBase, Item, View } from "native-base"; import * as React from "react"; import { useState } from "react"; import { @@ -19,15 +21,13 @@ import { TextInputFocusEventData, TextInputProps } from "react-native"; -import { NavigationEvents } from "react-navigation"; -import color from "color"; import { TextInputMaskProps } from "react-native-masked-text"; - -import { isStringNullyOrEmpty } from "../../utils/strings"; -import { makeFontStyleObject } from "../core/fonts"; import I18n from "../../i18n"; import variables from "../../theme/variables"; import { WithTestID } from "../../types/WithTestID"; + +import { isStringNullyOrEmpty } from "../../utils/strings"; +import { makeFontStyleObject } from "../core/fonts"; import { H5 } from "../core/typography/H5"; import { IOColors } from "../core/variables/IOColors"; import TextInputMask from "../ui/MaskedInput"; @@ -183,10 +183,7 @@ export const LabelledItem: React.FC = ({ testID="Item" > {props.hasNavigationEvents && props.onPress && ( - + )} {iconPosition === "left" && props.icon && ( diff --git a/ts/components/RemindEmailValidationOverlay.tsx b/ts/components/RemindEmailValidationOverlay.tsx index 2c8088a3ea1..2542be0ead1 100644 --- a/ts/components/RemindEmailValidationOverlay.tsx +++ b/ts/components/RemindEmailValidationOverlay.tsx @@ -9,6 +9,8 @@ import * as React from "react"; import { Alert, BackHandler, StyleSheet } from "react-native"; import { connect } from "react-redux"; import I18n from "../i18n"; +import NavigationService from "../navigation/NavigationService"; +import ROUTES from "../navigation/routes"; import { navigateBack, navigateToEmailInsertScreen @@ -44,7 +46,6 @@ import IconFont from "./ui/IconFont"; import Markdown from "./ui/Markdown"; type OwnProp = { - closeModalAndNavigateToEmailInsertScreen: () => void; onClose: () => void; }; @@ -315,11 +316,22 @@ class RemindEmailValidationOverlay extends React.PureComponent { bordered: true, disabled: this.state.isLoading, onPress: () => { - if (!isOnboardingCompleted) { - this.props.closeModalAndNavigateToEmailInsertScreen(); - return; + /** + * TODO: this is a temp workaround to complete porting a react-navigation v5 + * without a full rework of all the related email / isOnboardingCompleted screens + * Will be removed in https://pagopa.atlassian.net/browse/IAI-139 . We want: + * - Have a common component with the shared logic + * - Compose the common logic with the navigation stack dependent logic and isolate the dependent navigation logic + */ + if ( + NavigationService.getCurrentRouteName() === ROUTES.WALLET_HOME + ) { + NavigationService.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.INSERT_EMAIL_SCREEN + }); + } else { + navigateToEmailInsertScreen(); } - this.props.navigateToEmailInsertScreen(); }, title: I18n.t("email.edit.title") }} @@ -417,9 +429,6 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ // Refresh profile to check if the email address has been validated dispatch(profileLoadRequest()); }, - navigateToEmailInsertScreen: () => { - navigateToEmailInsertScreen(); - }, acknowledgeEmailInsert: () => dispatch(emailAcknowledged()), dispatchAcknowledgeOnEmailValidation: (maybeAcknowledged: Option) => dispatch(acknowledgeOnEmailValidation(maybeAcknowledged)), diff --git a/ts/components/SectionStatus/__tests__/SectionStatusComponent.test.tsx b/ts/components/SectionStatus/__tests__/SectionStatusComponent.test.tsx index 447109586bd..655816e0a51 100644 --- a/ts/components/SectionStatus/__tests__/SectionStatusComponent.test.tsx +++ b/ts/components/SectionStatus/__tests__/SectionStatusComponent.test.tsx @@ -1,17 +1,17 @@ -import configureMockStore from "redux-mock-store"; -import { render, fireEvent } from "@testing-library/react-native"; -import { Provider } from "react-redux"; -import * as React from "react"; +import { fireEvent } from "@testing-library/react-native"; import { none, some } from "fp-ts/lib/Option"; -import SectionStatusComponent from "../index"; -import I18n, { setLocale } from "../../../i18n"; -import { openWebUrl } from "../../../utils/url"; -import { IOColors } from "../../core/variables/IOColors"; +import * as React from "react"; +import configureMockStore from "redux-mock-store"; import { LevelEnum, SectionStatus } from "../../../../definitions/content/SectionStatus"; +import I18n, { setLocale } from "../../../i18n"; import { SectionStatusKey } from "../../../store/reducers/backendStatus"; +import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; +import { openWebUrl } from "../../../utils/url"; +import { IOColors } from "../../core/variables/IOColors"; +import SectionStatusComponent from "../index"; jest.mock("../../../utils/url"); @@ -186,12 +186,9 @@ const getComponent = ( sectionKey: SectionStatusKey, store?: ReturnType ) => - render( - - - + renderScreenFakeNavRedux( + () => , + "DUMMY", + {}, + store || mockStore(mockSectionStatusState("messages", sectionStatus)) ); diff --git a/ts/components/SectionStatus/index.tsx b/ts/components/SectionStatus/index.tsx index af0e3d0f58c..8c1aff2a61e 100644 --- a/ts/components/SectionStatus/index.tsx +++ b/ts/components/SectionStatus/index.tsx @@ -1,20 +1,20 @@ -import React, { useCallback } from "react"; -import { connect } from "react-redux"; +import { useNavigation } from "@react-navigation/native"; import _ from "lodash"; +import React, { useCallback } from "react"; import { Pressable, View } from "react-native"; -import { GlobalState } from "../../store/reducers/types"; +import { connect } from "react-redux"; +import { LevelEnum } from "../../../definitions/content/SectionStatus"; +import I18n from "../../i18n"; import { SectionStatusKey, sectionStatusSelector } from "../../store/reducers/backendStatus"; -import I18n from "../../i18n"; +import { GlobalState } from "../../store/reducers/types"; +import { getFullLocale } from "../../utils/locale"; import { maybeNotNullyString } from "../../utils/strings"; import { openWebUrl } from "../../utils/url"; -import { getFullLocale } from "../../utils/locale"; -import { LevelEnum } from "../../../definitions/content/SectionStatus"; -import { useNavigationContext } from "../../utils/hooks/useOnFocus"; -import { IOColors, IOColorType } from "../core/variables/IOColors"; import { Link } from "../core/typography/Link"; +import { IOColors, IOColorType } from "../core/variables/IOColors"; import StatusContent from "./StatusContent"; type OwnProps = { @@ -56,7 +56,7 @@ const InnerSectionStatus = ( const maybeWebUrl = maybeNotNullyString( sectionStatus.web_url && sectionStatus.web_url[locale] ); - const navigation = useNavigationContext(); + const navigation = useNavigation(); const color = getStatusTextColor(sectionStatus.level); @@ -68,8 +68,8 @@ const InnerSectionStatus = ( React.useEffect(() => { handleOnSectionRef(); - const unsubscribe = navigation?.addListener("didFocus", handleOnSectionRef); - return () => unsubscribe?.remove(); + navigation?.addListener("focus", handleOnSectionRef); + return () => navigation?.removeListener("focus", handleOnSectionRef); }, [handleOnSectionRef, navigation, viewRef]); return maybeWebUrl.fold( diff --git a/ts/components/__tests__/ContextualInfo.test.tsx b/ts/components/__tests__/ContextualInfo.test.tsx index a07ae645a1c..91ba2fb933b 100644 --- a/ts/components/__tests__/ContextualInfo.test.tsx +++ b/ts/components/__tests__/ContextualInfo.test.tsx @@ -1,14 +1,13 @@ +import { fireEvent, RenderAPI } from "@testing-library/react-native"; import React from "react"; -import { NavigationParams } from "react-navigation"; import { BackHandler, Text } from "react-native"; import { createStore } from "redux"; -import { fireEvent, RenderAPI } from "@testing-library/react-native"; +import ROUTES from "../../navigation/routes"; import { applicationChangeState } from "../../store/actions/application"; +import { appReducer } from "../../store/reducers"; import { GlobalState } from "../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../utils/testWrapper"; -import ROUTES from "../../navigation/routes"; -import { appReducer } from "../../store/reducers"; import ContextualInfo from "../ContextualInfo"; jest.useFakeTimers(); @@ -86,7 +85,7 @@ describe("ContextualInfo component", () => { function renderComponent(props: React.ComponentProps) { const globalState = appReducer(undefined, applicationChangeState("active")); - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( () => , ROUTES.WALLET_CHECKOUT_3DS_SCREEN, {}, diff --git a/ts/components/helpers/withConditionalView.tsx b/ts/components/helpers/withConditionalView.tsx index e6482beb3b0..e5f42fddb2f 100644 --- a/ts/components/helpers/withConditionalView.tsx +++ b/ts/components/helpers/withConditionalView.tsx @@ -1,6 +1,15 @@ import hoistNonReactStatics from "hoist-non-react-statics"; import React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; +import { StyleSheet, View } from "react-native"; +import { IOStackNavigationRouteProps } from "../../navigation/params/AppParamsList"; +import { IOColors } from "../core/variables/IOColors"; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: IOColors.white + } +}); /** * A HOC to display the WrappedComponent when the check function is verified, @@ -16,17 +25,21 @@ export function withConditionalView( * the condition component to ensure the navigation can address the proper * navigation parameters */ - type nullN = Record; - type NP = P extends NavigationStackScreenProps ? N : nullN; - type NC = C extends NavigationStackScreenProps ? N : nullN; - type NN = NavigationStackScreenProps; + type nullN = Record; + type NP = P extends IOStackNavigationRouteProps ? N : nullN; + type NC = C extends IOStackNavigationRouteProps ? N : nullN; + type NN = IOStackNavigationRouteProps; class ConditionalView extends React.PureComponent<(P | C) & T & NN> { public render() { - return check(this.props as T) ? ( - - ) : ( - + return ( + + {check(this.props as T) ? ( + + ) : ( + + )} + ); } } diff --git a/ts/components/helpers/withValidatedEmail.tsx b/ts/components/helpers/withValidatedEmail.tsx index 9867de334ab..32ee8196fd0 100644 --- a/ts/components/helpers/withValidatedEmail.tsx +++ b/ts/components/helpers/withValidatedEmail.tsx @@ -1,24 +1,26 @@ +import { NavigationEvents } from "@react-navigation/compat"; import { none } from "fp-ts/lib/Option"; import React from "react"; import { View } from "react-native"; -import { NavigationEvents, StackActions } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import RemindEmailValidationOverlay from "../../components/RemindEmailValidationOverlay"; -import { LightModalContextInterface } from "../ui/LightModal"; -import { navigateToEmailInsertScreen } from "../../store/actions/navigation"; +import { + AppParamsList, + IOStackNavigationRouteProps +} from "../../navigation/params/AppParamsList"; import { acknowledgeOnEmailValidation } from "../../store/actions/profile"; import { Dispatch } from "../../store/actions/types"; import { emailValidationSelector } from "../../store/reducers/emailValidation"; import { isProfileEmailValidatedSelector } from "../../store/reducers/profile"; import { GlobalState } from "../../store/reducers/types"; -import { withLightModalContext } from "./withLightModalContext"; +import { LightModalContextInterface } from "../ui/LightModal"; import { withConditionalView } from "./withConditionalView"; +import { withLightModalContext } from "./withLightModalContext"; export type ModalProps = LightModalContextInterface & ReturnType & - NavigationStackScreenProps; + IOStackNavigationRouteProps; /* ModalRemindEmailValidationOverlay is the component that allows viewing the email reminder via light modal. @@ -45,14 +47,6 @@ class ModalRemindEmailValidationOverlay extends React.Component { this.props.dispatchAcknowledgeOnEmailValidation(); }; - private handleForcedClose = () => { - // due a known bug (see https://github.com/react-navigation/react-navigation/issues/4867) - // when the user is in onboarding phase and he asks to go to insert email screen - // the navigation is forced reset - this.props.navigation.dispatch(StackActions.popToTop()); - navigateToEmailInsertScreen(); - }; - public render() { return ( @@ -60,14 +54,9 @@ class ModalRemindEmailValidationOverlay extends React.Component { onWillBlur={() => { this.hideModal(); }} - onDidFocus={() => { + onWillFocus={() => { this.props.showModal( - + ); }} /> @@ -104,7 +93,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ * A HOC to display the WrappedComponent when the email is validated, otherwise the RemindEmailValidationOverlay will be displayed * * TODO: fix workaround introduced to solve bug on navigation during the onboarding (https://github.com/react-navigation/react-navigation/issues/4867) - * If the didFocus and the blur related events are not fired, at forward navigation the hideModal is dispatched manually + * If the willFocus and the blur related events are not fired, at forward navigation the hideModal is dispatched manually */ export function withValidatedEmail

( WrappedComponent: React.ComponentType

diff --git a/ts/components/infoScreen/InfoScreenComponent.tsx b/ts/components/infoScreen/InfoScreenComponent.tsx index f37cace88fc..dc3fc4dec4f 100644 --- a/ts/components/infoScreen/InfoScreenComponent.tsx +++ b/ts/components/infoScreen/InfoScreenComponent.tsx @@ -1,7 +1,7 @@ +import { NavigationEvents } from "@react-navigation/compat"; import { View } from "native-base"; import * as React from "react"; import { StyleSheet, Text } from "react-native"; -import { NavigationEvents } from "react-navigation"; import themeVariables from "../../theme/variables"; import { setAccessibilityFocus } from "../../utils/accessibility"; import { Body } from "../core/typography/Body"; @@ -57,7 +57,7 @@ export const InfoScreenComponent: React.FunctionComponent = props => { return ( - setAccessibilityFocus(elementRef)} /> + setAccessibilityFocus(elementRef)} /> {props.image}

({ - getVersion: jest.fn(), - getReadableVersion: jest.fn() -})); - describe("PaymentButton", () => { jest.useFakeTimers(); minAppVersionAppVersionTestCases.forEach(t => { @@ -90,7 +84,7 @@ const testPaymentButton = ( expect(isProfileEmailValidatedSelector(finalStore.getState())).toBe(true); - const testComponent = renderScreenFakeNavRedux( + const testComponent = renderScreenFakeNavRedux( () => ( ) => { const store: ReturnType = mockStore(globalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , ROUTES.MESSAGE_DETAIL, {}, diff --git a/ts/components/messages/paginated/MessageDetail/__tests__/MedicalPrescriptionDueDateBar.test.tsx b/ts/components/messages/paginated/MessageDetail/__tests__/MedicalPrescriptionDueDateBar.test.tsx index c4b9869817e..13d8c5009c0 100644 --- a/ts/components/messages/paginated/MessageDetail/__tests__/MedicalPrescriptionDueDateBar.test.tsx +++ b/ts/components/messages/paginated/MessageDetail/__tests__/MedicalPrescriptionDueDateBar.test.tsx @@ -1,6 +1,5 @@ import React from "react"; import configureMockStore from "redux-mock-store"; -import { NavigationParams } from "react-navigation"; import MedicalPrescriptionDueDateBar from "../MedicalPrescriptionDueDateBar"; import { toUIMessageDetails } from "../../../../../store/reducers/entities/messages/transformers"; @@ -86,7 +85,7 @@ const renderComponent = ( const store: ReturnType = mockStore(globalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , ROUTES.MESSAGE_DETAIL, {}, diff --git a/ts/components/messages/paginated/MessageDetail/__tests__/__snapshots__/CtaBar.test.tsx.snap b/ts/components/messages/paginated/MessageDetail/__tests__/__snapshots__/CtaBar.test.tsx.snap index 2786b5d6fa6..e79ef877abd 100644 --- a/ts/components/messages/paginated/MessageDetail/__tests__/__snapshots__/CtaBar.test.tsx.snap +++ b/ts/components/messages/paginated/MessageDetail/__tests__/__snapshots__/CtaBar.test.tsx.snap @@ -2,28 +2,131 @@ exports[`the \`CtaBar\` component when neither \`paymentData\` nor \`dueDate\` are defined for the message details should match the snapshot (no buttons) 1`] = ` - + + + + + + + + + + MESSAGE_DETAIL + + + + + + + - - - + needsOffscreenAlphaCompositing={false} + pointerEvents="box-none" + style={ + Object { + "flex": 1, + } + } + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + `; diff --git a/ts/components/messages/paginated/MessageDetail/__tests__/__snapshots__/MedicalPrescriptionDueDateBar.test.tsx.snap b/ts/components/messages/paginated/MessageDetail/__tests__/__snapshots__/MedicalPrescriptionDueDateBar.test.tsx.snap index ac5b51ad081..cb5f68f1631 100644 --- a/ts/components/messages/paginated/MessageDetail/__tests__/__snapshots__/MedicalPrescriptionDueDateBar.test.tsx.snap +++ b/ts/components/messages/paginated/MessageDetail/__tests__/__snapshots__/MedicalPrescriptionDueDateBar.test.tsx.snap @@ -2,319 +2,131 @@ exports[`MedicalPrescriptionDueDateBar component when payment info is expired should match the snapshot 1`] = ` - - - + + "backgroundColor": "rgb(255, 255, 255)", + "borderBottomColor": "rgb(216, 216, 216)", + "flex": 1, + "shadowColor": "rgb(216, 216, 216)", + "shadowOffset": Object { + "height": 0.5, + "width": 0, + }, + "shadowOpacity": 0.85, + "shadowRadius": 0, + } + } + /> + - + - - - - - - - - - - - - + } + > - - The prescription expired at - - 13.29 - - on - 12/01/2021 + MESSAGE_DETAIL - + - - -`; - -exports[`MedicalPrescriptionDueDateBar component when payment info is expiring should match the snapshot 1`] = ` - - - - - - - - - - + + - - - + - - - - - - - - This prescription expires today - + + + + + + + + + + + + + + + + + + + + + + + + + + + + The prescription expired at + + 13.29 + + on + + 12/01/2021 + + + + + + + + + + + + + + + + - + `; -exports[`MedicalPrescriptionDueDateBar component when payment info is not expirable should match the snapshot 1`] = ` +exports[`MedicalPrescriptionDueDateBar component when payment info is expiring should match the snapshot 1`] = ` - - - + + "backgroundColor": "rgb(255, 255, 255)", + "borderBottomColor": "rgb(216, 216, 216)", + "flex": 1, + "shadowColor": "rgb(216, 216, 216)", + "shadowOffset": Object { + "height": 0.5, + "width": 0, + }, + "shadowOpacity": 0.85, + "shadowRadius": 0, + } + } + /> + + - - This prescription expires the - 12/01/2021 + MESSAGE_DETAIL - - - - + + + + + + + + + + - - - - - - - - - - - - - + } + > - + - $ - - + - Reminder - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This prescription expires today + + + + + + + + + + + + + - + `; -exports[`MedicalPrescriptionDueDateBar component when payment info is valid should match the snapshot 1`] = ` +exports[`MedicalPrescriptionDueDateBar component when payment info is not expirable should match the snapshot 1`] = ` - + + + + + + + + + + MESSAGE_DETAIL + + + + + + + - - - - - This prescription expires the - - 12/01/2021 - - - - - + - - - + - + - - - - - - - - - - + + + + + + + + + + + + This prescription expires the + + 12/01/2021 + + + + + + + + + + + + + + + + + + + + + $ + + + Reminder + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`MedicalPrescriptionDueDateBar component when payment info is valid should match the snapshot 1`] = ` + + + + + + + + + + + + + MESSAGE_DETAIL + + + + + + + + + + + + + - + - $ - - + - Reminder - + + + + + + + + + + + + + + + This prescription expires the + + 12/01/2021 + + + + + + + + + + + + + + + + + + + + + $ + + + Reminder + + + + + + + + + + + + + + + - + `; diff --git a/ts/components/messages/paginated/__tests__/MessageDetail.test.tsx b/ts/components/messages/paginated/__tests__/MessageDetail.test.tsx index e12627a9ab7..ca7ed6d869e 100644 --- a/ts/components/messages/paginated/__tests__/MessageDetail.test.tsx +++ b/ts/components/messages/paginated/__tests__/MessageDetail.test.tsx @@ -1,23 +1,22 @@ import React from "react"; import configureMockStore from "redux-mock-store"; -import { NavigationParams } from "react-navigation"; - -import { appReducer } from "../../../../store/reducers"; -import { applicationChangeState } from "../../../../store/actions/application"; -import { GlobalState } from "../../../../store/reducers/types"; -import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; -import ROUTES from "../../../../navigation/routes"; import { medicalPrescription, paymentValidInvalidAfterDueDate } from "../../../../__mocks__/message"; +import { service_1 } from "../../../../__mocks__/messages"; +import I18n from "../../../../i18n"; +import ROUTES from "../../../../navigation/routes"; +import { applicationChangeState } from "../../../../store/actions/application"; + +import { appReducer } from "../../../../store/reducers"; import { toUIMessage, toUIMessageDetails } from "../../../../store/reducers/entities/messages/transformers"; -import { service_1 } from "../../../../__mocks__/messages"; import { toUIService } from "../../../../store/reducers/entities/services/transformers"; -import I18n from "../../../../i18n"; +import { GlobalState } from "../../../../store/reducers/types"; +import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; import MessageDetail from "../MessageDetail"; jest.useFakeTimers(); @@ -131,7 +130,7 @@ const renderComponent = (props: React.ComponentProps) => { const store: ReturnType = mockStore(globalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , ROUTES.MESSAGES_HOME, {}, diff --git a/ts/components/messages/paginated/__tests__/MessageList.test.tsx b/ts/components/messages/paginated/__tests__/MessageList.test.tsx index 36ad71c3645..28767d31ae9 100644 --- a/ts/components/messages/paginated/__tests__/MessageList.test.tsx +++ b/ts/components/messages/paginated/__tests__/MessageList.test.tsx @@ -1,7 +1,6 @@ import React from "react"; import { Text } from "react-native"; import configureMockStore from "redux-mock-store"; -import { NavigationParams } from "react-navigation"; import { pot } from "@pagopa/ts-commons"; import { none } from "fp-ts/lib/Option"; @@ -132,7 +131,7 @@ const renderComponent = ( } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , ROUTES.MESSAGES_HOME, {}, diff --git a/ts/components/messages/paginated/__tests__/MessagesInbox.test.tsx b/ts/components/messages/paginated/__tests__/MessagesInbox.test.tsx index 74bb17fa856..2d29c59038f 100644 --- a/ts/components/messages/paginated/__tests__/MessagesInbox.test.tsx +++ b/ts/components/messages/paginated/__tests__/MessagesInbox.test.tsx @@ -1,18 +1,17 @@ -import React from "react"; -import configureMockStore from "redux-mock-store"; -import { NavigationParams } from "react-navigation"; import { pot } from "@pagopa/ts-commons"; -import { none } from "fp-ts/lib/Option"; import { fireEvent } from "@testing-library/react-native"; - -import MessagesInbox from "../MessagesInbox"; -import { appReducer } from "../../../../store/reducers"; +import { none } from "fp-ts/lib/Option"; +import React from "react"; +import configureMockStore from "redux-mock-store"; +import { successReloadMessagesPayload } from "../../../../__mocks__/messages"; +import ROUTES from "../../../../navigation/routes"; import { applicationChangeState } from "../../../../store/actions/application"; +import { appReducer } from "../../../../store/reducers"; +import { AllPaginated } from "../../../../store/reducers/entities/messages/allPaginated"; import { GlobalState } from "../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; -import ROUTES from "../../../../navigation/routes"; -import { AllPaginated } from "../../../../store/reducers/entities/messages/allPaginated"; -import { successReloadMessagesPayload } from "../../../../__mocks__/messages"; + +import MessagesInbox from "../MessagesInbox"; jest.useFakeTimers(); @@ -53,7 +52,7 @@ const renderComponent = (props: React.ComponentProps) => { } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , ROUTES.MESSAGES_HOME, {}, diff --git a/ts/components/screens/AnimatedScreenContent.tsx b/ts/components/screens/AnimatedScreenContent.tsx index 44ed45a53c1..41c9e0a7ef8 100644 --- a/ts/components/screens/AnimatedScreenContent.tsx +++ b/ts/components/screens/AnimatedScreenContent.tsx @@ -3,6 +3,7 @@ * - scroll to top on its focus * - provide a dynanic subheader appearing on scroll */ +import { NavigationEvents } from "@react-navigation/compat"; import { View } from "native-base"; import * as React from "react"; import { @@ -14,7 +15,6 @@ import { StyleSheet, ViewStyle } from "react-native"; -import { NavigationEvents } from "react-navigation"; import { isIphoneX } from "react-native-iphone-x-helper"; import customVariables from "../../theme/variables"; diff --git a/ts/components/screens/BaseHeader.tsx b/ts/components/screens/BaseHeader.tsx index 2c3932b64f8..17ff1ca3d07 100644 --- a/ts/components/screens/BaseHeader.tsx +++ b/ts/components/screens/BaseHeader.tsx @@ -1,14 +1,16 @@ +import { NavigationEvents } from "@react-navigation/compat"; import { fromNullable } from "fp-ts/lib/Option"; import { Millisecond } from "italia-ts-commons/lib/units"; import { Body, Left, Right, Text, View } from "native-base"; import * as React from "react"; import { FC, Ref } from "react"; import { AccessibilityInfo, ColorValue, StyleSheet } from "react-native"; -import { NavigationEvents } from "react-navigation"; import { connect } from "react-redux"; import IconFont from "../../components/ui/IconFont"; +import I18n from "../../i18n"; import { navigateBack } from "../../store/actions/navigation"; import { Dispatch } from "../../store/actions/types"; +import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; import { isPagoPATestEnabledSelector } from "../../store/reducers/persistedPreferences"; import { isSearchEnabledSelector } from "../../store/reducers/search"; import { GlobalState } from "../../store/reducers/types"; @@ -16,12 +18,10 @@ import variables from "../../theme/variables"; import { setAccessibilityFocus } from "../../utils/accessibility"; import { isStringNullyOrEmpty, maybeNotNullyString } from "../../utils/strings"; import ButtonDefaultOpacity from "../ButtonDefaultOpacity"; +import { IOColors, IOColorType } from "../core/variables/IOColors"; import GoBackButton from "../GoBackButton"; import SearchButton, { SearchType } from "../search/SearchButton"; import AppHeader from "../ui/AppHeader"; -import I18n from "../../i18n"; -import { IOColors, IOColorType } from "../core/variables/IOColors"; -import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; type HelpButtonProps = { onShowHelp: () => void; @@ -268,7 +268,7 @@ class BaseHeaderComponent extends React.PureComponent { {fromNullable(this.props.accessibilityEvents).fold( true, ({ avoidNavigationEventsUsage }) => !avoidNavigationEventsUsage - ) && } + ) && } ); }; diff --git a/ts/components/screens/BaseScreenComponent/__tests__/BaseScreenComponent.test.tsx b/ts/components/screens/BaseScreenComponent/__tests__/BaseScreenComponent.test.tsx index 82337a35bb4..bef7b7f6f18 100644 --- a/ts/components/screens/BaseScreenComponent/__tests__/BaseScreenComponent.test.tsx +++ b/ts/components/screens/BaseScreenComponent/__tests__/BaseScreenComponent.test.tsx @@ -1,22 +1,20 @@ -import React from "react"; -import { NavigationParams } from "react-navigation"; import { fireEvent } from "@testing-library/react-native"; - -import configureMockStore from "redux-mock-store"; import { some } from "fp-ts/lib/Option"; +import React from "react"; import { Store } from "redux"; +import configureMockStore from "redux-mock-store"; +import { ToolEnum } from "../../../../../definitions/content/AssistanceToolConfig"; +import { BackendStatus } from "../../../../../definitions/content/BackendStatus"; +import { Config } from "../../../../../definitions/content/Config"; +import * as zendeskActions from "../../../../features/zendesk/store/actions"; +import ROUTES from "../../../../navigation/routes"; +import { applicationChangeState } from "../../../../store/actions/application"; import { appReducer } from "../../../../store/reducers"; +import { BackendStatusState } from "../../../../store/reducers/backendStatus"; import { GlobalState } from "../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; -import { applicationChangeState } from "../../../../store/actions/application"; -import ROUTES from "../../../../navigation/routes"; import BaseScreenComponent, { Props } from "../index"; -import { BackendStatusState } from "../../../../store/reducers/backendStatus"; -import { BackendStatus } from "../../../../../definitions/content/BackendStatus"; -import { ToolEnum } from "../../../../../definitions/content/AssistanceToolConfig"; -import { Config } from "../../../../../definitions/content/Config"; -import * as zendeskActions from "../../../../features/zendesk/store/actions"; jest.useFakeTimers(); @@ -91,7 +89,7 @@ describe("BaseScreenComponent", () => { function renderComponent(props = defaultProps, store: Store) { return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , ROUTES.MESSAGES_HOME, {}, diff --git a/ts/components/screens/BaseScreenComponent/index.tsx b/ts/components/screens/BaseScreenComponent/index.tsx index 8e490a0d6e0..ee26960fbe0 100644 --- a/ts/components/screens/BaseScreenComponent/index.tsx +++ b/ts/components/screens/BaseScreenComponent/index.tsx @@ -1,24 +1,23 @@ -import { fromNullable } from "fp-ts/lib/Option"; import { Container } from "native-base"; import { connectStyle } from "native-base-shoutem-theme"; import mapPropsToStyleNames from "native-base/src/utils/mapPropsToStyleNames"; import React, { ComponentProps, PropsWithChildren, ReactNode } from "react"; import { ColorValue } from "react-native"; import { useDispatch } from "react-redux"; +import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; import { TranslationKeys } from "../../../../locales/locales"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; -import { SearchType } from "../../search/SearchButton"; -import { AccessibilityEvents, BaseHeader } from "../BaseHeader"; import { zendeskSupportStart } from "../../../features/zendesk/store/actions"; import { useIOSelector } from "../../../store/hooks"; +import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; +import { currentRouteSelector } from "../../../store/reducers/navigation"; +import { FAQsCategoriesType } from "../../../utils/faq"; import { assistanceToolRemoteConfig, resetCustomFields } from "../../../utils/supportAssistance"; -import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; -import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; -import { FAQsCategoriesType } from "../../../utils/faq"; +import { SearchType } from "../../search/SearchButton"; +import { AccessibilityEvents, BaseHeader } from "../BaseHeader"; export type ContextualHelpProps = { title: string; @@ -73,10 +72,13 @@ const BaseScreenComponentFC = React.forwardRef( titleColor } = props; - // We should check for undefined context because the BaseScreen is used also in the Modal layer, without the navigation context. - const currentScreenName = fromNullable(useNavigationContext()) - .map(x => x.state.routeName) - .getOrElse("n/a"); + /** + * We have to use the deprecated currentRouteSelector because, at the moment, some BaseScreenComponent + * are outside the navigation context. + * TODO: Full usage of navigation header and modal, in order to have always the right context + * + */ + const currentScreenName = useIOSelector(currentRouteSelector); const dispatch = useDispatch(); const assistanceToolConfig = useIOSelector(assistanceToolConfigSelector); diff --git a/ts/components/screens/GenericErrorComponent.tsx b/ts/components/screens/GenericErrorComponent.tsx index 7005e0d4efd..c280a8cd365 100644 --- a/ts/components/screens/GenericErrorComponent.tsx +++ b/ts/components/screens/GenericErrorComponent.tsx @@ -1,8 +1,8 @@ +import { NavigationEvents } from "@react-navigation/compat"; import { fromNullable } from "fp-ts/lib/Option"; import { Content, Text, View } from "native-base"; import * as React from "react"; import { Image, ImageSourcePropType, StyleSheet } from "react-native"; -import { NavigationEvents } from "react-navigation"; import I18n from "../../i18n"; import customVariables from "../../theme/variables"; import { WithTestID } from "../../types/WithTestID"; @@ -79,7 +79,7 @@ export default class GenericErrorComponent extends React.PureComponent { {this.props.avoidNavigationEvents !== true && ( setAccessibilityFocus(this.elementRef)} + onWillFocus={() => setAccessibilityFocus(this.elementRef)} /> )} ; } ) => - render( - + renderScreenFakeNavRedux( + () => ( - + ), + "route", + {}, + store ); diff --git a/ts/components/services/ContactPreferencesToggles/index.tsx b/ts/components/services/ContactPreferencesToggles/index.tsx index b103d73c6f4..e6209d48f91 100644 --- a/ts/components/services/ContactPreferencesToggles/index.tsx +++ b/ts/components/services/ContactPreferencesToggles/index.tsx @@ -1,29 +1,29 @@ +import { useIsFocused } from "@react-navigation/native"; +import { fromNullable } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { connect } from "react-redux"; -import { fromNullable } from "fp-ts/lib/Option"; -import { GlobalState } from "../../../store/reducers/types"; -import I18n from "../../../i18n"; -import ItemSeparatorComponent from "../../ItemSeparatorComponent"; import { NotificationChannelEnum } from "../../../../definitions/backend/NotificationChannel"; -import { Dispatch } from "../../../store/actions/types"; -import { - servicePreferenceSelector, - ServicePreferenceState -} from "../../../store/reducers/entities/services/servicePreference"; import { ServiceId } from "../../../../definitions/backend/ServiceId"; +import I18n from "../../../i18n"; import { loadServicePreference, upsertServicePreference } from "../../../store/actions/services/servicePreference"; +import { Dispatch } from "../../../store/actions/types"; +import { + servicePreferenceSelector, + ServicePreferenceState +} from "../../../store/reducers/entities/services/servicePreference"; +import { GlobalState } from "../../../store/reducers/types"; import { isServicePreferenceResponseSuccess, ServicePreference } from "../../../types/services/ServicePreferenceResponse"; import { isStrictSome } from "../../../utils/pot"; import { showToast } from "../../../utils/showToast"; +import ItemSeparatorComponent from "../../ItemSeparatorComponent"; import SectionHeader from "../SectionHeader"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; import PreferenceToggleRow from "./PreferenceToggleRow"; type Item = "email" | "push" | "inbox"; @@ -70,9 +70,7 @@ const ContactPreferencesToggle: React.FC = (props: Props) => { [serviceId, loadServicePreference] ); - const nav = useNavigationContext(); - - const isFocused = nav?.isFocused(); + const isFocused = useIsFocused(); useEffect(() => { loadPreferences(); diff --git a/ts/components/ui/FocusAwareStatusBar.tsx b/ts/components/ui/FocusAwareStatusBar.tsx index 050a07e25cd..0523f304640 100644 --- a/ts/components/ui/FocusAwareStatusBar.tsx +++ b/ts/components/ui/FocusAwareStatusBar.tsx @@ -1,7 +1,7 @@ +import { NavigationEvents } from "@react-navigation/compat"; import * as React from "react"; import { useState } from "react"; import { StatusBar, StatusBarProps } from "react-native"; -import { NavigationEvents } from "react-navigation"; /** * FocusAwareStatusBar makes the status bar component aware of diff --git a/ts/components/ui/Markdown/handlers/internalLink.ts b/ts/components/ui/Markdown/handlers/internalLink.ts index b290ecb15f4..61715bfa776 100644 --- a/ts/components/ui/Markdown/handlers/internalLink.ts +++ b/ts/components/ui/Markdown/handlers/internalLink.ts @@ -1,8 +1,8 @@ /** * An handler for application internal links */ +import { CommonActions, NavigationAction } from "@react-navigation/native"; import { fromNullable, none, Option } from "fp-ts/lib/Option"; -import { NavigationActions } from "react-navigation"; import URLParse from "url-parse"; import { bpdEnabled, @@ -10,83 +10,152 @@ import { svEnabled, uaDonationsEnabled } from "../../../../config"; -import NavigationService from "../../../../navigation/NavigationService"; -import ROUTES from "../../../../navigation/routes"; -import { Dispatch } from "../../../../store/actions/types"; -import { isTestEnv } from "../../../../utils/environment"; -import { addInternalRouteNavigation } from "../../../../store/actions/internalRouteNavigation"; import BPD_ROUTES from "../../../../features/bonus/bpd/navigation/routes"; import CGN_ROUTES from "../../../../features/bonus/cgn/navigation/routes"; import SV_ROUTES from "../../../../features/bonus/siciliaVola/navigation/routes"; import UADONATION_ROUTES from "../../../../features/uaDonations/navigation/routes"; +import NavigationService from "../../../../navigation/NavigationService"; +import ROUTES from "../../../../navigation/routes"; +import { addInternalRouteNavigation } from "../../../../store/actions/internalRouteNavigation"; +import { Dispatch } from "../../../../store/actions/types"; +import { isTestEnv } from "../../../../utils/environment"; // Prefix to match deeplink uri like `ioit://PROFILE_MAIN` const IO_INTERNAL_LINK_PROTOCOL = "ioit:"; export const IO_INTERNAL_LINK_PREFIX = IO_INTERNAL_LINK_PROTOCOL + "//"; -const ROUTE_NAMES: ReadonlyArray = [ - ROUTES.MESSAGES_HOME, - ROUTES.PROFILE_PREFERENCES_HOME, - ROUTES.SERVICES_HOME, - ROUTES.PROFILE_MAIN, - ROUTES.PROFILE_PRIVACY, - ROUTES.PROFILE_PRIVACY_MAIN, - ROUTES.WALLET_HOME, - ROUTES.PAYMENTS_HISTORY_SCREEN, - ROUTES.CREDIT_CARD_ONBOARDING_ATTEMPTS_SCREEN -]; +/** + * TODO: All the mapping Route -> NavigationAction is a temporary solution to allow backward compatibility during the react-navigation v5 phase. + * This handling will be integrated in react-navigation in a next iteration. + * Please, if you add another rule consider that this custom handling will be removed. + */ + +// TODO: string should be replaced with a strong type that express all the allowed routes +const routesToNavigationAction: Record = { + [ROUTES.MESSAGES_HOME]: CommonActions.navigate(ROUTES.MAIN, { + screen: ROUTES.MESSAGES_HOME + }), + [ROUTES.PROFILE_PREFERENCES_HOME]: CommonActions.navigate( + ROUTES.PROFILE_NAVIGATOR, + { + screen: ROUTES.PROFILE_PREFERENCES_HOME + } + ), + [ROUTES.WALLET_HOME]: CommonActions.navigate(ROUTES.MAIN, { + screen: ROUTES.WALLET_HOME + }), + [ROUTES.SERVICES_HOME]: CommonActions.navigate(ROUTES.MAIN, { + screen: ROUTES.SERVICES_HOME + }), + [ROUTES.PROFILE_MAIN]: CommonActions.navigate(ROUTES.MAIN, { + screen: ROUTES.PROFILE_MAIN + }), + [ROUTES.PROFILE_PRIVACY]: CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PRIVACY + }), + [ROUTES.PROFILE_PRIVACY_MAIN]: CommonActions.navigate( + ROUTES.PROFILE_NAVIGATOR, + { + screen: ROUTES.PROFILE_PRIVACY_MAIN + } + ), + [ROUTES.PROFILE_PRIVACY_MAIN]: CommonActions.navigate( + ROUTES.PROFILE_NAVIGATOR, + { + screen: ROUTES.PROFILE_PRIVACY_MAIN + } + ), + [ROUTES.PAYMENTS_HISTORY_SCREEN]: CommonActions.navigate( + ROUTES.WALLET_NAVIGATOR, + { + screen: ROUTES.PAYMENTS_HISTORY_SCREEN + } + ), + [ROUTES.CREDIT_CARD_ONBOARDING_ATTEMPTS_SCREEN]: CommonActions.navigate( + ROUTES.WALLET_NAVIGATOR, + { + screen: ROUTES.CREDIT_CARD_ONBOARDING_ATTEMPTS_SCREEN + } + ) +}; + +const legacyRoutesToNavigationAction: Record = { + PREFERENCES_SERVICES: CommonActions.navigate(ROUTES.MAIN, { + screen: ROUTES.SERVICES_HOME + }), + PREFERENCES_HOME: CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PREFERENCES_HOME + }) +}; -const BPD_ROUTE_NAMES: ReadonlyArray = [ - BPD_ROUTES.CTA_START_BPD, - BPD_ROUTES.CTA_BPD_IBAN_EDIT -]; +const bpdRoutesToNavigationAction: Record = { + [BPD_ROUTES.CTA_BPD_IBAN_EDIT]: CommonActions.navigate( + ROUTES.WALLET_NAVIGATOR, + { + screen: BPD_ROUTES.CTA_BPD_IBAN_EDIT + } + ) +}; -const CGN_ROUTE_NAMES: ReadonlyArray = [ - CGN_ROUTES.ACTIVATION.CTA_START_CGN, - CGN_ROUTES.DETAILS.DETAILS -]; +const cgnRoutesToNavigationAction: Record = { + [CGN_ROUTES.ACTIVATION.CTA_START_CGN]: CommonActions.navigate( + CGN_ROUTES.ACTIVATION.MAIN, + { + screen: CGN_ROUTES.ACTIVATION.CTA_START_CGN + } + ), + [CGN_ROUTES.DETAILS.DETAILS]: CommonActions.navigate( + CGN_ROUTES.DETAILS.MAIN, + { + screen: CGN_ROUTES.DETAILS.DETAILS + } + ) +}; -const MY_PORTAL_ROUTES: ReadonlyArray = [ROUTES.SERVICE_WEBVIEW]; +const myPortalRoutesToNavigationAction: Record = { + [ROUTES.SERVICE_WEBVIEW]: CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: ROUTES.SERVICE_WEBVIEW + }) +}; -const SV_ROUTE_NAMES: ReadonlyArray = [ - SV_ROUTES.VOUCHER_GENERATION.CHECK_STATUS, - SV_ROUTES.VOUCHER_LIST.LIST -]; +const uaDonationsRoutesToNavigationAction: Record = { + [UADONATION_ROUTES.WEBVIEW]: CommonActions.navigate(UADONATION_ROUTES.WEBVIEW) +}; -const UA_DONATION_ROUTES: ReadonlyArray = uaDonationsEnabled - ? [UADONATION_ROUTES.WEBVIEW] - : []; +const svRoutesToNavigationAction: Record = { + [SV_ROUTES.VOUCHER_GENERATION.CHECK_STATUS]: CommonActions.navigate( + ROUTES.SERVICES_NAVIGATOR, + { + screen: SV_ROUTES.VOUCHER_GENERATION.CHECK_STATUS + } + ), + [SV_ROUTES.VOUCHER_LIST.LIST]: CommonActions.navigate( + ROUTES.SERVICES_NAVIGATOR, + { + screen: SV_ROUTES.VOUCHER_LIST.LIST + } + ) +}; -const ALLOWED_ROUTE_NAMES = ROUTE_NAMES.concat( - myPortalEnabled ? MY_PORTAL_ROUTES : [], - bpdEnabled ? BPD_ROUTE_NAMES : [], - CGN_ROUTE_NAMES, - svEnabled ? SV_ROUTE_NAMES : [], - UA_DONATION_ROUTES -); +const allowedRoutes = { + ...routesToNavigationAction, + ...cgnRoutesToNavigationAction, + ...legacyRoutesToNavigationAction, + ...(myPortalEnabled ? myPortalRoutesToNavigationAction : {}), + ...(bpdEnabled ? bpdRoutesToNavigationAction : {}), + ...(svEnabled ? svRoutesToNavigationAction : {}), + ...(uaDonationsEnabled ? uaDonationsRoutesToNavigationAction : {}) +}; export const testableALLOWED_ROUTE_NAMES = isTestEnv - ? ALLOWED_ROUTE_NAMES + ? allowedRoutes : undefined; -/** - * Used to replace old navigation routes with new one - */ -function replaceOldRoute(routeName: string): string { - switch (routeName) { - case "PREFERENCES_SERVICES": - return ROUTES.SERVICES_HOME; - case "PREFERENCES_HOME": - return ROUTES.PROFILE_PREFERENCES_HOME; - default: - return routeName; - } -} - type InternalRouteParams = Record; export type InternalRoute = { routeName: string; params?: InternalRouteParams; + navigationAction: NavigationAction; }; export function getInternalRoute(href: string): Option { @@ -94,14 +163,13 @@ export function getInternalRoute(href: string): Option { try { const url = new URLParse(href, true); if (url.protocol.toLowerCase() === IO_INTERNAL_LINK_PROTOCOL) { - return fromNullable( - ALLOWED_ROUTE_NAMES.find( - e => e === replaceOldRoute(url.host.toUpperCase()) - ) - ).map(routeName => ({ - routeName, - params: Object.keys(url.query).length === 0 ? undefined : url.query // avoid empty object - })); + return fromNullable(allowedRoutes[url.host.toUpperCase()]).map( + navigationAction => ({ + routeName: url.host.toUpperCase(), + params: Object.keys(url.query).length === 0 ? undefined : url.query, // avoid empty object, + navigationAction + }) + ); } return none; } catch (_) { @@ -129,9 +197,7 @@ export function handleInternalLink( }) ); NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: internalNavigation.routeName - }) + internalNavigation.navigationAction ); }); } diff --git a/ts/components/wallet/__test__/OutcomeCodeMessageComponent.test.tsx b/ts/components/wallet/__test__/OutcomeCodeMessageComponent.test.tsx index 02033feaf32..7003026090d 100644 --- a/ts/components/wallet/__test__/OutcomeCodeMessageComponent.test.tsx +++ b/ts/components/wallet/__test__/OutcomeCodeMessageComponent.test.tsx @@ -1,14 +1,13 @@ import * as React from "react"; import { View } from "react-native"; -import { NavigationParams } from "react-navigation"; import configureMockStore from "redux-mock-store"; import { setLocale } from "../../../i18n"; -import { OutcomeCode } from "../../../types/outcomeCode"; -import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; import ROUTES from "../../../navigation/routes"; -import { GlobalState } from "../../../store/reducers/types"; import { applicationChangeState } from "../../../store/actions/application"; import { appReducer } from "../../../store/reducers"; +import { GlobalState } from "../../../store/reducers/types"; +import { OutcomeCode } from "../../../types/outcomeCode"; +import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; import OutcomeCodeMessageComponent from "../OutcomeCodeMessageComponent"; const ASuccessComponent = () => ; @@ -90,7 +89,7 @@ const renderComponent = ( ...globalState } as GlobalState); - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( () => ( { function renderComponent() { const globalState = appReducer(undefined, applicationChangeState("active")); - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( () => ( NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ELIGIBILITY.CHECK_LOADING + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ELIGIBILITY.CHECK_LOADING + } }) ); @@ -21,8 +25,11 @@ export const navigateToBonusEligibilityLoading = () => */ export const navigateToIseeNotEligible = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ELIGIBILITY.ISEE_NOT_ELIGIBLE + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ELIGIBILITY.ISEE_NOT_ELIGIBLE + } }) ); @@ -32,8 +39,11 @@ export const navigateToIseeNotEligible = () => */ export const navigateToIseeNotAvailable = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ELIGIBILITY.ISEE_NOT_AVAILABLE + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ELIGIBILITY.ISEE_NOT_AVAILABLE + } }) ); @@ -43,8 +53,11 @@ export const navigateToIseeNotAvailable = () => */ export const navigateToEligible = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ELIGIBILITY.ELIGIBLE + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ELIGIBILITY.ELIGIBLE + } }) ); @@ -54,8 +67,11 @@ export const navigateToEligible = () => */ export const navigateToTimeoutEligibilityCheck = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ELIGIBILITY.TIMEOUT + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ELIGIBILITY.TIMEOUT + } }) ); @@ -65,8 +81,11 @@ export const navigateToTimeoutEligibilityCheck = () => */ export const navigateToBonusActivationPending = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ELIGIBILITY.PENDING + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ELIGIBILITY.PENDING + } }) ); @@ -76,8 +95,11 @@ export const navigateToBonusActivationPending = () => */ export const navigateToUnderage = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ELIGIBILITY.UNDERAGE + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ELIGIBILITY.UNDERAGE + } }) ); @@ -87,8 +109,11 @@ export const navigateToUnderage = () => */ export const navigateToAvailableBonusScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.BONUS_AVAILABLE_LIST + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.BONUS_AVAILABLE_LIST + } }) ); @@ -100,9 +125,12 @@ export const navigateToBonusRequestInformation = ( params?: BonusInformationScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.BONUS_REQUEST_INFORMATION, - params + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.BONUS_REQUEST_INFORMATION, + params + } }) ); @@ -114,8 +142,8 @@ export const navigateToBonusActiveDetailScreen = ( params?: ActiveBonusScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.BONUS_ACTIVE_DETAIL_SCREEN, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.BONUS_ACTIVE_DETAIL_SCREEN, params }) ); @@ -126,8 +154,11 @@ export const navigateToBonusActiveDetailScreen = ( */ export const navigateToBonusActivationLoading = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ACTIVATION.LOADING + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ACTIVATION.LOADING + } }) ); @@ -137,8 +168,11 @@ export const navigateToBonusActivationLoading = () => */ export const navigateToBonusActivationTimeout = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ACTIVATION.TIMEOUT + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ACTIVATION.TIMEOUT + } }) ); @@ -148,8 +182,11 @@ export const navigateToBonusActivationTimeout = () => */ export const navigateToBonusAlreadyExists = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ACTIVATION.EXISTS + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ACTIVATION.EXISTS + } }) ); @@ -159,8 +196,11 @@ export const navigateToBonusAlreadyExists = () => */ export const navigateToEligibilityExpired = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ACTIVATION.ELIGIBILITY_EXPIRED + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ACTIVATION.ELIGIBILITY_EXPIRED + } }) ); @@ -170,7 +210,10 @@ export const navigateToEligibilityExpired = () => */ export const navigateToBonusActivationCompleted = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BONUSVACANZE_ROUTES.ACTIVATION.COMPLETED + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BONUSVACANZE_ROUTES.MAIN, + params: { + screen: BONUSVACANZE_ROUTES.ACTIVATION.COMPLETED + } }) ); diff --git a/ts/features/bonus/bonusVacanze/navigation/navigator.ts b/ts/features/bonus/bonusVacanze/navigation/navigator.ts index 1f02911a8d1..0ebf33b2e0c 100644 --- a/ts/features/bonus/bonusVacanze/navigation/navigator.ts +++ b/ts/features/bonus/bonusVacanze/navigation/navigator.ts @@ -1,4 +1,5 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import ActivateBonusCompletedScreen from "../screens/activation/ActivateBonusCompletedScreen"; import BonusAlreadyExists from "../screens/activation/BonusAlreadyExists"; import EligibilityExpired from "../screens/activation/EligibilityExpired"; @@ -16,7 +17,9 @@ import TimeoutEligibilityCheckInfoScreen from "../screens/eligibility/TimeoutEli import UnderageScreen from "../screens/eligibility/UnderageScreen"; import BONUSVACANZE_ROUTES from "./routes"; -const BonusVacanzeNavigator = createStackNavigator( +const BonusVacanzeNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [BONUSVACANZE_ROUTES.BONUS_AVAILABLE_LIST]: { screen: AvailableBonusScreen @@ -68,7 +71,7 @@ const BonusVacanzeNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/bonus/bonusVacanze/screens/ActiveBonusScreen.tsx b/ts/features/bonus/bonusVacanze/screens/ActiveBonusScreen.tsx index 46f8e58c272..9e0eae614fb 100644 --- a/ts/features/bonus/bonusVacanze/screens/ActiveBonusScreen.tsx +++ b/ts/features/bonus/bonusVacanze/screens/ActiveBonusScreen.tsx @@ -1,3 +1,4 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { fromNullable, none, Option } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Millisecond } from "italia-ts-commons/lib/units"; @@ -12,7 +13,6 @@ import { ViewStyle } from "react-native"; import ViewShot, { CaptureOptions } from "react-native-view-shot"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { BonusActivationStatusEnum } from "../../../../../definitions/bonus_vacanze/BonusActivationStatus"; import { BonusActivationWithQrCode } from "../../../../../definitions/bonus_vacanze/BonusActivationWithQrCode"; @@ -29,6 +29,8 @@ import TouchableDefaultOpacity from "../../../../components/TouchableDefaultOpac import IconFont from "../../../../components/ui/IconFont"; import { LightModalContextInterface } from "../../../../components/ui/LightModal"; import I18n from "../../../../i18n"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../navigation/params/WalletParamsList"; import { navigateBack } from "../../../../store/actions/navigation"; import { Dispatch } from "../../../../store/actions/types"; import { GlobalState } from "../../../../store/reducers/types"; @@ -82,7 +84,11 @@ export type ActiveBonusScreenNavigationParams = Readonly<{ const QR_CODE_MIME_TYPE = "image/svg+xml"; const PNG_IMAGE_TYPE = "image/png"; -type OwnProps = NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = OwnProps & ReturnType & diff --git a/ts/features/bonus/bonusVacanze/screens/BonusInformationScreen.tsx b/ts/features/bonus/bonusVacanze/screens/BonusInformationScreen.tsx index d365feca8df..74370c730f3 100644 --- a/ts/features/bonus/bonusVacanze/screens/BonusInformationScreen.tsx +++ b/ts/features/bonus/bonusVacanze/screens/BonusInformationScreen.tsx @@ -1,21 +1,26 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { BonusAvailable } from "../../../../../definitions/content/BonusAvailable"; import { ContextualHelpPropsMarkdown } from "../../../../components/screens/BaseScreenComponent"; import I18n from "../../../../i18n"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; import { navigateBack } from "../../../../store/actions/navigation"; import { GlobalState } from "../../../../store/reducers/types"; import BonusInformationComponent from "../../common/components/BonusInformationComponent"; +import { BonusVacanzeParamsList } from "../navigation/params"; import { ownedActiveOrRedeemedBonus } from "../store/reducers/allActive"; export type BonusInformationScreenNavigationParams = Readonly<{ bonusItem: BonusAvailable; }>; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = OwnProps & ReturnType & diff --git a/ts/features/bonus/bonusVacanze/screens/__tests__/AvailableBonusScreen.test.tsx b/ts/features/bonus/bonusVacanze/screens/__tests__/AvailableBonusScreen.test.tsx index ae17eb02443..b1723a7f1e5 100644 --- a/ts/features/bonus/bonusVacanze/screens/__tests__/AvailableBonusScreen.test.tsx +++ b/ts/features/bonus/bonusVacanze/screens/__tests__/AvailableBonusScreen.test.tsx @@ -1,6 +1,6 @@ import { fireEvent } from "@testing-library/react-native"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore, Store } from "redux"; import { Alert } from "react-native"; import configureMockStore from "redux-mock-store"; @@ -158,7 +158,7 @@ describe("Test AvailableBonusScreen behaviour", () => { }); const renderComponent = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , BONUSVACANZE_ROUTES.BONUS_AVAILABLE_LIST, {}, diff --git a/ts/features/bonus/bpd/components/optInPaymentMethods/__tests__/RetryAfterDeletionFailsComponent.test.ts b/ts/features/bonus/bpd/components/optInPaymentMethods/__tests__/RetryAfterDeletionFailsComponent.test.ts index 4c5e44be9ea..a5eb03605ab 100644 --- a/ts/features/bonus/bpd/components/optInPaymentMethods/__tests__/RetryAfterDeletionFailsComponent.test.ts +++ b/ts/features/bonus/bpd/components/optInPaymentMethods/__tests__/RetryAfterDeletionFailsComponent.test.ts @@ -1,5 +1,5 @@ import { createStore, Store } from "redux"; -import { NavigationParams } from "react-navigation"; + import { fireEvent, RenderAPI } from "@testing-library/react-native"; import { GlobalState } from "../../../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../../../utils/testWrapper"; @@ -43,7 +43,7 @@ describe("the RetryAfterDeletionFailsComponent screen", () => { }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( RetryAfterDeletionFailsComponent, ROUTES.MAIN, {}, diff --git a/ts/features/bonus/bpd/components/optInPaymentMethods/__tests__/ThankYouSuccessComponent.test.ts b/ts/features/bonus/bpd/components/optInPaymentMethods/__tests__/ThankYouSuccessComponent.test.ts index 3a39b951294..3a493fed82d 100644 --- a/ts/features/bonus/bpd/components/optInPaymentMethods/__tests__/ThankYouSuccessComponent.test.ts +++ b/ts/features/bonus/bpd/components/optInPaymentMethods/__tests__/ThankYouSuccessComponent.test.ts @@ -1,5 +1,5 @@ import { createStore, Store } from "redux"; -import { NavigationParams } from "react-navigation"; + import { fireEvent, RenderAPI } from "@testing-library/react-native"; import { GlobalState } from "../../../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../../../utils/testWrapper"; @@ -30,7 +30,7 @@ describe("the ThankYouSuccessComponent screen", () => { }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( ThankYouSuccessComponent, ROUTES.MAIN, {}, diff --git a/ts/features/bonus/bpd/components/paymentMethodActivationToggle/base/PaymentMethodBpdToggle.tsx b/ts/features/bonus/bpd/components/paymentMethodActivationToggle/base/PaymentMethodBpdToggle.tsx index 9499c31be52..a50fc762c56 100644 --- a/ts/features/bonus/bpd/components/paymentMethodActivationToggle/base/PaymentMethodBpdToggle.tsx +++ b/ts/features/bonus/bpd/components/paymentMethodActivationToggle/base/PaymentMethodBpdToggle.tsx @@ -1,4 +1,5 @@ /* eslint-disable functional/immutable-data */ +import { useNavigation } from "@react-navigation/native"; import * as pot from "italia-ts-commons/lib/pot"; import { View } from "native-base"; import * as React from "react"; @@ -8,7 +9,6 @@ import { connect } from "react-redux"; import { Dispatch } from "redux"; import { fetchPaymentManagerLongTimeout } from "../../../../../../config"; import { GlobalState } from "../../../../../../store/reducers/types"; -import { useNavigationContext } from "../../../../../../utils/hooks/useOnFocus"; import { bpdPaymentMethodActivation, BpdPaymentMethodActivation, @@ -68,7 +68,7 @@ const styles = StyleSheet.create({ */ const useInitialValue = (props: Props) => { const timerRetry = useRef(undefined); - const navigation = useNavigationContext(); + const navigation = useNavigation(); const isFocused = navigation.isFocused(); const { bpdPotActivation, hPan, loadActualValue, hasBpdCapability } = props; diff --git a/ts/features/bonus/bpd/navigation/actions.ts b/ts/features/bonus/bpd/navigation/actions.ts index 7c563c06396..dedf66c9d31 100644 --- a/ts/features/bonus/bpd/navigation/actions.ts +++ b/ts/features/bonus/bpd/navigation/actions.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../../navigation/NavigationService"; +import ROUTES from "../../../../navigation/routes"; import { BpdPeriodWithInfo } from "../store/reducers/details/periods"; import BPD_ROUTES from "./routes"; @@ -9,8 +10,11 @@ import BPD_ROUTES from "./routes"; */ export const navigateToBpdOnboardingLoadActivationStatus = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.ONBOARDING.LOAD_CHECK_ACTIVATION_STATUS + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.ONBOARDING.MAIN, + params: { + screen: BPD_ROUTES.ONBOARDING.LOAD_CHECK_ACTIVATION_STATUS + } }) ); @@ -20,8 +24,11 @@ export const navigateToBpdOnboardingLoadActivationStatus = () => */ export const navigateToBpdOnboardingInformationTos = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.ONBOARDING.INFORMATION_TOS + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.ONBOARDING.MAIN, + params: { + screen: BPD_ROUTES.ONBOARDING.INFORMATION_TOS + } }) ); @@ -31,8 +38,11 @@ export const navigateToBpdOnboardingInformationTos = () => */ export const navigateToBpdOnboardingDeclaration = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.ONBOARDING.DECLARATION + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.ONBOARDING.MAIN, + params: { + screen: BPD_ROUTES.ONBOARDING.DECLARATION + } }) ); @@ -42,8 +52,11 @@ export const navigateToBpdOnboardingDeclaration = () => */ export const navigateToBpdOnboardingLoadActivate = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.ONBOARDING.LOAD_ACTIVATE_BPD + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.ONBOARDING.MAIN, + params: { + screen: BPD_ROUTES.ONBOARDING.LOAD_ACTIVATE_BPD + } }) ); @@ -53,8 +66,11 @@ export const navigateToBpdOnboardingLoadActivate = () => */ export const navigateToBpdOnboardingEnrollPaymentMethod = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.ONBOARDING.ENROLL_PAYMENT_METHODS + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.ONBOARDING.MAIN, + params: { + screen: BPD_ROUTES.ONBOARDING.ENROLL_PAYMENT_METHODS + } }) ); @@ -64,8 +80,11 @@ export const navigateToBpdOnboardingEnrollPaymentMethod = () => */ export const navigateToBpdOnboardingNoPaymentMethods = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.ONBOARDING.NO_PAYMENT_METHODS + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.ONBOARDING.MAIN, + params: { + screen: BPD_ROUTES.ONBOARDING.NO_PAYMENT_METHODS + } }) ); @@ -75,8 +94,11 @@ export const navigateToBpdOnboardingNoPaymentMethods = () => */ export const navigateToBpdOnboardingErrorPaymentMethods = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.ONBOARDING.ERROR_PAYMENT_METHODS + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.ONBOARDING.MAIN, + params: { + screen: BPD_ROUTES.ONBOARDING.ERROR_PAYMENT_METHODS + } }) ); @@ -88,8 +110,8 @@ export const navigateToBpdOnboardingErrorPaymentMethods = () => */ export const navigateToBpdIbanInsertion = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.IBAN + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.IBAN }) ); @@ -101,9 +123,12 @@ export const navigateToBpdIbanInsertion = () => */ export const navigateToBpdDetails = (specificPeriod?: BpdPeriodWithInfo) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.DETAILS, - params: { specificPeriod } + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.DETAILS_MAIN, + params: { + screen: BPD_ROUTES.DETAILS, + params: { specificPeriod } + } }) ); @@ -115,23 +140,35 @@ export const navigateToBpdDetails = (specificPeriod?: BpdPeriodWithInfo) => */ export const navigateToBpdTransactions = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: BPD_ROUTES.TRANSACTIONS + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.DETAILS_MAIN, + params: { + screen: BPD_ROUTES.TRANSACTIONS + } }) ); // OPT-IN export const navigateToOptInPaymentMethodsChoiceScreen = () => - NavigationActions.navigate({ - routeName: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.CHOICE + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.MAIN, + params: { + screen: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.CHOICE + } }); export const navigateToOptInPaymentMethodsThankYouDeleteMethodsScreen = () => - NavigationActions.navigate({ - routeName: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.THANK_YOU_DELETE_METHOD + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.MAIN, + params: { + screen: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.THANK_YOU_DELETE_METHOD + } }); export const navigateToOptInPaymentMethodsThankYouKeepMethodsScreen = () => - NavigationActions.navigate({ - routeName: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.THANK_YOU_KEEP_METHOD + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.MAIN, + params: { + screen: BPD_ROUTES.OPT_IN_PAYMENT_METHODS.THANK_YOU_KEEP_METHOD + } }); diff --git a/ts/features/bonus/bpd/navigation/navigator.ts b/ts/features/bonus/bpd/navigation/navigator.ts index dabe8435d34..ff13d0c59f0 100644 --- a/ts/features/bonus/bpd/navigation/navigator.ts +++ b/ts/features/bonus/bpd/navigation/navigator.ts @@ -1,9 +1,9 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import { bpdTransactionsPaging } from "../../../../config"; import BpdDetailsScreen from "../screens/details/BpdDetailsScreen"; import BpdTransactionsScreen from "../screens/details/transaction/BpdTransactionsScreen"; import BpdTransactionsRouterScreen from "../screens/details/transaction/v2/BpdTransactionsRouterScreen"; -import MainIbanScreen from "../screens/iban/MainIbanScreen"; import CtaLandingScreen from "../screens/onboarding/BpdCTAStartOnboardingScreen"; import BpdInformationScreen from "../screens/onboarding/BpdInformationScreen"; import DeclarationScreen from "../screens/onboarding/declaration/DeclarationScreen"; @@ -18,7 +18,9 @@ import OptInPaymentMethodsThankYouDeleteMethodsScreen from "../screens/optInPaym import OptInPaymentMethodsThankYouKeepMethodsScreen from "../screens/optInPaymentMethods/OptInPaymentMethodsThankYouKeepMethodsScreen"; import BPD_ROUTES from "./routes"; -export const BpdOnboardingNavigator = createStackNavigator( +export const BpdOnboardingNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [BPD_ROUTES.ONBOARDING.LOAD_CHECK_ACTIVATION_STATUS]: { screen: LoadBpdActivationStatus @@ -49,12 +51,14 @@ export const BpdOnboardingNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); -export const BpdDetailsNavigator = createStackNavigator( +export const BpdDetailsNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [BPD_ROUTES.DETAILS]: { screen: BpdDetailsScreen @@ -69,27 +73,14 @@ export const BpdDetailsNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); -export const BpdIBANNavigator = createStackNavigator( - { - [BPD_ROUTES.IBAN]: { - screen: MainIbanScreen - } - }, - { - // Let each screen handle the header and navigation - headerMode: "none", - defaultNavigationOptions: { - gesturesEnabled: false - } - } -); - -export const OptInPaymentMethodNavigator = createStackNavigator( +export const OptInPaymentMethodNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [BPD_ROUTES.OPT_IN_PAYMENT_METHODS.CASHBACK_UPDATE]: { screen: OptInPaymentMethodsCashbackUpdateScreen @@ -108,7 +99,7 @@ export const OptInPaymentMethodNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/bonus/bpd/saga/index.ts b/ts/features/bonus/bpd/saga/index.ts index 60a089ca6e8..55df3071da4 100644 --- a/ts/features/bonus/bpd/saga/index.ts +++ b/ts/features/bonus/bpd/saga/index.ts @@ -16,6 +16,11 @@ import { bpdOnboardingStart, bpdUpdateOptInStatusMethod } from "../store/actions/onboarding"; +import { + optInPaymentMethodsDeletionChoice, + optInPaymentMethodsShowChoice, + optInPaymentMethodsStart +} from "../store/actions/optInPaymentMethods"; import { bpdPaymentMethodActivation, bpdUpdatePaymentMethodActivation @@ -28,11 +33,6 @@ import { bpdTransactionsLoadPage, bpdTransactionsLoadRequiredData } from "../store/actions/transactions"; -import { - optInPaymentMethodsDeletionChoice, - optInPaymentMethodsShowChoice, - optInPaymentMethodsStart -} from "../store/actions/optInPaymentMethods"; import { deleteCitizen, getCitizenV2, @@ -54,8 +54,8 @@ import { handleTransactionsPage } from "./networking/winning-transactions/transa import { handleBpdIbanInsertion } from "./orchestration/insertIban"; import { handleBpdEnroll } from "./orchestration/onboarding/enrollToBpd"; import { handleBpdStartOnboardingSaga } from "./orchestration/onboarding/startOnboarding"; -import { optInPaymentMethodsHandler } from "./orchestration/optInPaymentMethods/optInPaymentMethodsHandler"; import { optInDeletionChoiceHandler } from "./orchestration/optInPaymentMethods/optInDeletionChoiceHandler"; +import { optInPaymentMethodsHandler } from "./orchestration/optInPaymentMethods/optInPaymentMethodsHandler"; import { optInShouldShowChoiceHandler } from "./orchestration/optInPaymentMethods/optInShouldShowChoiceHandler"; // watch all events about bpd diff --git a/ts/features/bonus/bpd/saga/orchestration/__tests__/activateBpdOnNewPaymentMethods.test.ts b/ts/features/bonus/bpd/saga/orchestration/__tests__/activateBpdOnNewPaymentMethods.test.tsx similarity index 93% rename from ts/features/bonus/bpd/saga/orchestration/__tests__/activateBpdOnNewPaymentMethods.test.ts rename to ts/features/bonus/bpd/saga/orchestration/__tests__/activateBpdOnNewPaymentMethods.test.tsx index bffbb05fa5f..c6532eb1284 100644 --- a/ts/features/bonus/bpd/saga/orchestration/__tests__/activateBpdOnNewPaymentMethods.test.ts +++ b/ts/features/bonus/bpd/saga/orchestration/__tests__/activateBpdOnNewPaymentMethods.test.tsx @@ -1,4 +1,5 @@ import { left, right } from "fp-ts/lib/Either"; +import { View } from "react-native"; import { createStore } from "redux"; import { expectSaga } from "redux-saga-test-plan"; import * as matchers from "redux-saga-test-plan/matchers"; @@ -8,6 +9,7 @@ import { navigateToWalletHome } from "../../../../../../store/actions/navigation import { appReducer } from "../../../../../../store/reducers"; import { bpdRemoteConfigSelector } from "../../../../../../store/reducers/backendStatus"; import { mockPrivativeCard } from "../../../../../../store/reducers/wallet/__mocks__/wallets"; +import { renderScreenFakeNavRedux } from "../../../../../../utils/testWrapper"; import { navigateToSuggestBpdActivation } from "../../../../../wallet/onboarding/bancomat/navigation/action"; import { navigateToActivateBpdOnNewPrivative } from "../../../../../wallet/onboarding/privative/navigation/action"; import { activateBpdOnNewPaymentMethods } from "../activateBpdOnNewAddedPaymentMethods"; @@ -28,10 +30,20 @@ const enrollAfterAddFalse: BpdConfig = { describe("Test activateBpdOnNewPaymentMethods behaviour", () => { jest.useFakeTimers(); + + beforeEach(() => { + const globalState = appReducer(undefined, applicationChangeState("active")); + const store = createStore(appReducer, globalState as any); + renderScreenFakeNavRedux(View, "DUMMY", {}, store); + }); + it("With default state and no payment methods, should navigate to wallet home", async () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); + // We trigger the initialization of the NavigationService + renderScreenFakeNavRedux(View, "DUMMY", {}, store); + await expectSaga( activateBpdOnNewPaymentMethods, [], diff --git a/ts/features/bonus/bpd/saga/orchestration/insertIban.ts b/ts/features/bonus/bpd/saga/orchestration/insertIban.ts index b09fb623561..5951c85cf39 100644 --- a/ts/features/bonus/bpd/saga/orchestration/insertIban.ts +++ b/ts/features/bonus/bpd/saga/orchestration/insertIban.ts @@ -1,5 +1,5 @@ +import { NavigationActions } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; -import { NavigationActions } from "react-navigation"; import { SagaIterator } from "redux-saga"; import { call, put, select, take } from "typed-redux-saga/macro"; import { ActionType, isActionOf } from "typesafe-actions"; diff --git a/ts/features/bonus/bpd/saga/orchestration/onboarding/enrollToBpd.ts b/ts/features/bonus/bpd/saga/orchestration/onboarding/enrollToBpd.ts index d38ad939354..ab119da25eb 100644 --- a/ts/features/bonus/bpd/saga/orchestration/onboarding/enrollToBpd.ts +++ b/ts/features/bonus/bpd/saga/orchestration/onboarding/enrollToBpd.ts @@ -1,4 +1,4 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import { call, put, race, take } from "typed-redux-saga/macro"; import { ActionType } from "typesafe-actions"; import NavigationService from "../../../../../../navigation/NavigationService"; @@ -50,6 +50,9 @@ export function* handleBpdEnroll() { }); if (cancelAction) { - yield* put(NavigationActions.back()); + yield* call( + NavigationService.dispatchNavigationAction, + CommonActions.goBack() + ); } } diff --git a/ts/features/bonus/bpd/saga/orchestration/onboarding/startOnboarding.ts b/ts/features/bonus/bpd/saga/orchestration/onboarding/startOnboarding.ts index 5d5da1b82f6..49f3c255b90 100644 --- a/ts/features/bonus/bpd/saga/orchestration/onboarding/startOnboarding.ts +++ b/ts/features/bonus/bpd/saga/orchestration/onboarding/startOnboarding.ts @@ -1,6 +1,6 @@ +import { StackActions } from "@react-navigation/compat"; import { Either, right } from "fp-ts/lib/Either"; import * as pot from "italia-ts-commons/lib/pot"; -import { StackActions } from "react-navigation"; import { call, put, select, take, race } from "typed-redux-saga/macro"; import { ActionType } from "typesafe-actions"; import NavigationService from "../../../../../../navigation/NavigationService"; diff --git a/ts/features/bonus/bpd/saga/orchestration/optInPaymentMethods/optInPaymentMethodsHandler.ts b/ts/features/bonus/bpd/saga/orchestration/optInPaymentMethods/optInPaymentMethodsHandler.ts index 479e6c811fa..fbc37f9d6c3 100644 --- a/ts/features/bonus/bpd/saga/orchestration/optInPaymentMethods/optInPaymentMethodsHandler.ts +++ b/ts/features/bonus/bpd/saga/orchestration/optInPaymentMethods/optInPaymentMethodsHandler.ts @@ -1,18 +1,18 @@ +import { NavigationActions } from "@react-navigation/compat"; import { call } from "typed-redux-saga/macro"; -import { NavigationActions } from "react-navigation"; import NavigationService from "../../../../../../navigation/NavigationService"; -import { - optInPaymentMethodsBack, - optInPaymentMethodsCancel, - optInPaymentMethodsCompleted, - optInPaymentMethodsFailure -} from "../../../store/actions/optInPaymentMethods"; import { executeWorkUnit, withFailureHandling, withResetNavigationStack } from "../../../../../../sagas/workUnit"; import BPD_ROUTES from "../../../navigation/routes"; +import { + optInPaymentMethodsBack, + optInPaymentMethodsCancel, + optInPaymentMethodsCompleted, + optInPaymentMethodsFailure +} from "../../../store/actions/optInPaymentMethods"; function* optInPaymentMethodsWorkUnit() { return yield* call(executeWorkUnit, { diff --git a/ts/features/bonus/bpd/screens/details/transaction/__test__/BpdTransactionsScreen.test.tsx b/ts/features/bonus/bpd/screens/details/transaction/__test__/BpdTransactionsScreen.test.tsx index 71427b7aa16..91fe0e65028 100644 --- a/ts/features/bonus/bpd/screens/details/transaction/__test__/BpdTransactionsScreen.test.tsx +++ b/ts/features/bonus/bpd/screens/details/transaction/__test__/BpdTransactionsScreen.test.tsx @@ -1,6 +1,6 @@ import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { Action, createStore } from "redux"; import ROUTES from "../../../../../../../navigation/routes"; import { applicationChangeState } from "../../../../../../../store/actions/application"; @@ -19,8 +19,6 @@ import * as lastUpdateReducer from "../../../../store/reducers/details/lastUpdat import { BpdPeriodWithInfo } from "../../../../store/reducers/details/periods"; import BpdTransactionsScreen from "../BpdTransactionsScreen"; -// Be sure that navigation is unmocked -jest.unmock("react-navigation"); jest.mock("react-native-share", () => ({ open: jest.fn() })); @@ -29,7 +27,7 @@ describe("BpdTransactionsScreen", () => { it("should show the TransactionUnavailable screen if bpdLastUpdate is pot.none", () => { const globalState = appReducer(undefined, applicationChangeState("active")); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -51,7 +49,7 @@ describe("BpdTransactionsScreen", () => { appReducer, sequenceOfActions ); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -80,7 +78,7 @@ describe("BpdTransactionsScreen", () => { } } }; - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -110,7 +108,7 @@ describe("BpdTransactionsScreen", () => { sequenceOfActions ); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -138,7 +136,7 @@ describe("BpdTransactionsScreen", () => { appReducer, sequenceOfActions ); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -168,7 +166,7 @@ describe("BpdTransactionsScreen", () => { appReducer, sequenceOfActions ); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -198,7 +196,7 @@ describe("BpdTransactionsScreen", () => { } } }; - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -223,7 +221,7 @@ describe("BpdTransactionsScreen", () => { appReducer, sequenceOfActions ); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -258,7 +256,7 @@ describe("BpdTransactionsScreen", () => { } } }; - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -295,7 +293,7 @@ describe("BpdTransactionsScreen", () => { appReducer, sequenceOfActions ); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -332,7 +330,7 @@ describe("BpdTransactionsScreen", () => { } } }; - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, @@ -371,7 +369,7 @@ describe("BpdTransactionsScreen", () => { appReducer, sequenceOfActions ); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_BPAY_DETAIL, {}, diff --git a/ts/features/bonus/bpd/screens/details/transaction/__test__/LoadTransactions.test.tsx b/ts/features/bonus/bpd/screens/details/transaction/__test__/LoadTransactions.test.tsx index 65af8ec8008..5481992d438 100644 --- a/ts/features/bonus/bpd/screens/details/transaction/__test__/LoadTransactions.test.tsx +++ b/ts/features/bonus/bpd/screens/details/transaction/__test__/LoadTransactions.test.tsx @@ -1,34 +1,31 @@ -import { render } from "@testing-library/react-native"; -import * as React from "react"; +import { createStore } from "redux"; import I18n from "../../../../../../../i18n"; +import { applicationChangeState } from "../../../../../../../store/actions/application"; +import { appReducer } from "../../../../../../../store/reducers"; +import { renderScreenFakeNavRedux } from "../../../../../../../utils/testWrapper"; import LoadTransactions from "../LoadTransactions"; -jest.mock("react-navigation", () => ({ - NavigationEvents: "mockNavigationEvents", - StackActions: { - push: jest - .fn() - .mockImplementation(x => ({ ...x, type: "Navigation/PUSH" })), - replace: jest - .fn() - .mockImplementation(x => ({ ...x, type: "Navigation/REPLACE" })), - reset: jest.fn() - }, - NavigationActions: { - navigate: jest.fn().mockImplementation(x => x) - }, - createStackNavigator: jest.fn(), - withNavigation: (component: any) => component -})); describe("LoadTransactions component", () => { + const globalState = appReducer(undefined, applicationChangeState("active")); + const store = createStore(appReducer, globalState as any); it("should show the activity indicator", () => { - const component = render(); + const component = renderScreenFakeNavRedux( + LoadTransactions, + "DUMMY", + {}, + store + ); const activityIndicator = component.queryByTestId("activityIndicator"); expect(activityIndicator).not.toBe(null); }); it("should show the right title", () => { - const component = render(); + const component = renderScreenFakeNavRedux( + LoadTransactions, + "DUMMY", + {}, + store + ); const title = component.getByText( I18n.t("bonus.bpd.details.transaction.loading") ); diff --git a/ts/features/bonus/bpd/screens/details/transaction/__test__/TransactionsUnavailable.test.tsx b/ts/features/bonus/bpd/screens/details/transaction/__test__/TransactionsUnavailable.test.tsx index ea9f2a7b901..e7e5a96b4d8 100644 --- a/ts/features/bonus/bpd/screens/details/transaction/__test__/TransactionsUnavailable.test.tsx +++ b/ts/features/bonus/bpd/screens/details/transaction/__test__/TransactionsUnavailable.test.tsx @@ -1,17 +1,21 @@ +import { some } from "fp-ts/lib/Option"; +import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { Store } from "redux"; import configureMockStore from "redux-mock-store"; -import { some } from "fp-ts/lib/Option"; -import * as pot from "italia-ts-commons/lib/pot"; +import { ToolEnum } from "../../../../../../../../definitions/content/AssistanceToolConfig"; +import { BackendStatus } from "../../../../../../../../definitions/content/BackendStatus"; +import { Config } from "../../../../../../../../definitions/content/Config"; import I18n from "../../../../../../../i18n"; import { GlobalState } from "../../../../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../../../../utils/testWrapper"; import BPD_ROUTES from "../../../../navigation/routes"; import TransactionsUnavailable from "../TransactionsUnavailable"; -import { ToolEnum } from "../../../../../../../../definitions/content/AssistanceToolConfig"; -import { Config } from "../../../../../../../../definitions/content/Config"; -import { BackendStatus } from "../../../../../../../../definitions/content/BackendStatus"; + +jest.mock("../../../../../../../store/reducers/navigation", () => ({ + currentRouteSelector: jest.fn() +})); describe("TransactionsUnavailable component", () => { const mockStore = configureMockStore(); @@ -65,7 +69,7 @@ describe("TransactionsUnavailable component", () => { }); }); const getComponent = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , BPD_ROUTES.TRANSACTIONS, {}, diff --git a/ts/features/bonus/bpd/screens/details/transaction/v2/__test__/BpdTransactionsRouterScreen.test.tsx b/ts/features/bonus/bpd/screens/details/transaction/v2/__test__/BpdTransactionsRouterScreen.test.tsx index 2a6387ab753..f96a6858b23 100644 --- a/ts/features/bonus/bpd/screens/details/transaction/v2/__test__/BpdTransactionsRouterScreen.test.tsx +++ b/ts/features/bonus/bpd/screens/details/transaction/v2/__test__/BpdTransactionsRouterScreen.test.tsx @@ -1,7 +1,7 @@ import { fireEvent } from "@testing-library/react-native"; import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore, Store } from "redux"; import I18n from "../../../../../../../../i18n"; import { applicationChangeState } from "../../../../../../../../store/actions/application"; @@ -105,7 +105,7 @@ const getStateWithBpdInitialized = (): Store => { }; const renderComponent = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , BPD_ROUTES.TRANSACTIONS, {}, diff --git a/ts/features/bonus/bpd/screens/details/transaction/v2/__test__/TransactionsSectionList.test.tsx b/ts/features/bonus/bpd/screens/details/transaction/v2/__test__/TransactionsSectionList.test.tsx index 00a57d75508..1e394525031 100644 --- a/ts/features/bonus/bpd/screens/details/transaction/v2/__test__/TransactionsSectionList.test.tsx +++ b/ts/features/bonus/bpd/screens/details/transaction/v2/__test__/TransactionsSectionList.test.tsx @@ -1,6 +1,6 @@ import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore, Store } from "redux"; import { applicationChangeState } from "../../../../../../../../store/actions/application"; import { appReducer } from "../../../../../../../../store/reducers"; @@ -157,7 +157,7 @@ const getStateWithBpdInitialized = (): Store => { }; const renderComponent = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , BPD_ROUTES.TRANSACTIONS, {}, diff --git a/ts/features/bonus/bpd/screens/iban/IbanCTAEditScreen.tsx b/ts/features/bonus/bpd/screens/iban/IbanCTAEditScreen.tsx index 5d8dae1e5c0..44c3eacc1cb 100644 --- a/ts/features/bonus/bpd/screens/iban/IbanCTAEditScreen.tsx +++ b/ts/features/bonus/bpd/screens/iban/IbanCTAEditScreen.tsx @@ -1,3 +1,4 @@ +import { useNavigation } from "@react-navigation/native"; import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; import { Alert } from "react-native"; @@ -8,10 +9,7 @@ import I18n from "../../../../../i18n"; import { navigateBack } from "../../../../../store/actions/navigation"; import { bpdRemoteConfigSelector } from "../../../../../store/reducers/backendStatus"; import { GlobalState } from "../../../../../store/reducers/types"; -import { - useActionOnFocus, - useNavigationContext -} from "../../../../../utils/hooks/useOnFocus"; +import { useActionOnFocus } from "../../../../../utils/hooks/useOnFocus"; import { isStrictSome } from "../../../../../utils/pot"; import { LoadingErrorComponent } from "../../../bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; import { navigateToBpdDetails } from "../../navigation/actions"; @@ -117,7 +115,7 @@ const InnerIbanCTAEditScreen = (props: Props) => { * Landing screen from the CTA message that asks to review user's IBAN insertion */ const IbanCTAEditScreen: React.FC = (props: Props) => { - const navigation = useNavigationContext(); + const navigation = useNavigation(); if (!props.bpdRemoteConfig?.program_active) { Alert.alert( I18n.t("bonus.bpd.title"), diff --git a/ts/features/bonus/bpd/screens/onboarding/BpdCTAStartOnboardingScreen.tsx b/ts/features/bonus/bpd/screens/onboarding/BpdCTAStartOnboardingScreen.tsx index 05473e360b6..55e7e6d99d1 100644 --- a/ts/features/bonus/bpd/screens/onboarding/BpdCTAStartOnboardingScreen.tsx +++ b/ts/features/bonus/bpd/screens/onboarding/BpdCTAStartOnboardingScreen.tsx @@ -1,23 +1,21 @@ -import { useEffect } from "react"; +import { useNavigation } from "@react-navigation/native"; import * as React from "react"; +import { useEffect } from "react"; import { Alert } from "react-native"; -import { Dispatch } from "redux"; import { connect } from "react-redux"; +import { Dispatch } from "redux"; +import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; +import I18n from "../../../../../i18n"; import { bpdRemoteConfigSelector } from "../../../../../store/reducers/backendStatus"; -import { bpdOnboardingStart } from "../../store/actions/onboarding"; +import { GlobalState } from "../../../../../store/reducers/types"; +import { useActionOnFocus } from "../../../../../utils/hooks/useOnFocus"; import { LoadingErrorComponent } from "../../../bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; -import I18n from "../../../../../i18n"; import { loadAvailableBonuses } from "../../../bonusVacanze/store/actions/bonusVacanze"; -import { GlobalState } from "../../../../../store/reducers/types"; import { isAvailableBonusErrorSelector, supportedAvailableBonusSelector } from "../../../bonusVacanze/store/reducers/availableBonusesTypes"; -import { - useActionOnFocus, - useNavigationContext -} from "../../../../../utils/hooks/useOnFocus"; -import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; +import { bpdOnboardingStart } from "../../store/actions/onboarding"; export type Props = ReturnType & ReturnType; @@ -50,7 +48,7 @@ const BaseBpdCTAStartOnboardingComponent = (props: Props) => { * this is a dummy screen reachable only from a message CTA */ const BpdCTAStartOnboardingScreen: React.FC = (props: Props) => { - const navigation = useNavigationContext(); + const navigation = useNavigation(); if (!props.bpdRemoteConfig?.program_active) { Alert.alert( I18n.t("bonus.bpd.title"), diff --git a/ts/features/bonus/bpd/screens/optInPaymentMethods/OptInPaymentMethodsCashbackUpdateScreen.tsx b/ts/features/bonus/bpd/screens/optInPaymentMethods/OptInPaymentMethodsCashbackUpdateScreen.tsx index b2beaa0e123..731ec3a7f49 100644 --- a/ts/features/bonus/bpd/screens/optInPaymentMethods/OptInPaymentMethodsCashbackUpdateScreen.tsx +++ b/ts/features/bonus/bpd/screens/optInPaymentMethods/OptInPaymentMethodsCashbackUpdateScreen.tsx @@ -1,3 +1,5 @@ +import { useNavigation } from "@react-navigation/native"; +import { Text, View } from "native-base"; import React from "react"; import { Image, @@ -6,25 +8,23 @@ import { ScrollView, StyleSheet } from "react-native"; -import { View, Text } from "native-base"; -import I18n from "../../../../../i18n"; -import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; -import { IOStyles } from "../../../../../components/core/variables/IOStyles"; +import dafaultLogo from "../../../../../../img/bonus/bpd/logo_cashback_blue.png"; import ButtonDefaultOpacity from "../../../../../components/ButtonDefaultOpacity"; import { IORenderHtml } from "../../../../../components/core/IORenderHtml"; import { H2 } from "../../../../../components/core/typography/H2"; -import { useIODispatch, useIOSelector } from "../../../../../store/hooks"; -import { availableBonusTypesSelectorFromId } from "../../../bonusVacanze/store/reducers/availableBonusesTypes"; -import { ID_BPD_TYPE } from "../../../bonusVacanze/utils/bonus"; -import dafaultLogo from "../../../../../../img/bonus/bpd/logo_cashback_blue.png"; +import { IOStyles } from "../../../../../components/core/variables/IOStyles"; +import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; import FooterWithButtons from "../../../../../components/ui/FooterWithButtons"; -import { confirmButtonProps } from "../../../bonusVacanze/components/buttons/ButtonConfigurations"; -import { navigateToOptInPaymentMethodsChoiceScreen } from "../../navigation/actions"; -import { useNavigationContext } from "../../../../../utils/hooks/useOnFocus"; +import I18n from "../../../../../i18n"; +import { useIODispatch, useIOSelector } from "../../../../../store/hooks"; import { getBPDMethodsSelector, paymentMethodsSelector } from "../../../../../store/reducers/wallet/wallets"; +import { confirmButtonProps } from "../../../bonusVacanze/components/buttons/ButtonConfigurations"; +import { availableBonusTypesSelectorFromId } from "../../../bonusVacanze/store/reducers/availableBonusesTypes"; +import { ID_BPD_TYPE } from "../../../bonusVacanze/utils/bonus"; +import { navigateToOptInPaymentMethodsChoiceScreen } from "../../navigation/actions"; import { optInPaymentMethodsCompleted, optInPaymentMethodsFailure @@ -42,7 +42,7 @@ const styles = StyleSheet.create({ } }); const OptInPaymentMethodsCashbackUpdateScreen = () => { - const navigation = useNavigationContext(); + const navigation = useNavigation(); const dispatch = useIODispatch(); const bpdPaymentMethods = useIOSelector(getBPDMethodsSelector); const paymentMethods = useIOSelector(paymentMethodsSelector); @@ -58,7 +58,7 @@ const OptInPaymentMethodsCashbackUpdateScreen = () => { const handleOnContinuePress = () => { if (bpdPaymentMethods.length > 0) { - navigation.navigate(navigateToOptInPaymentMethodsChoiceScreen()); + navigation.dispatch(navigateToOptInPaymentMethodsChoiceScreen()); } else { dispatch(optInPaymentMethodsCompleted()); } diff --git a/ts/features/bonus/bpd/screens/optInPaymentMethods/OptInPaymentMethodsChoiceScreen.tsx b/ts/features/bonus/bpd/screens/optInPaymentMethods/OptInPaymentMethodsChoiceScreen.tsx index dd63d595676..33cbeb3c8ef 100644 --- a/ts/features/bonus/bpd/screens/optInPaymentMethods/OptInPaymentMethodsChoiceScreen.tsx +++ b/ts/features/bonus/bpd/screens/optInPaymentMethods/OptInPaymentMethodsChoiceScreen.tsx @@ -1,3 +1,4 @@ +import { useNavigation } from "@react-navigation/native"; import React, { useMemo, useState } from "react"; import { SafeAreaView, ScrollView } from "react-native"; import { View } from "native-base"; @@ -26,7 +27,6 @@ import { navigateToOptInPaymentMethodsThankYouDeleteMethodsScreen, navigateToOptInPaymentMethodsThankYouKeepMethodsScreen } from "../../navigation/actions"; -import { useNavigationContext } from "../../../../../utils/hooks/useOnFocus"; type PaymentMethodsChoiceOptions = | "keepPaymentMethods" @@ -82,11 +82,13 @@ const disabledButtonProps = disablePrimaryButtonProps( const OptInPaymentMethodsChoiceScreen = () => { const [selectedMethod, setSelectedMethod] = useState(null); - const { navigate } = useNavigationContext(); + const navigation = useNavigation(); const { presentBottomSheet, bottomSheet } = useBottomSheetMethodsToDelete({ onDeletePress: () => - navigate(navigateToOptInPaymentMethodsThankYouDeleteMethodsScreen()) + navigation.dispatch( + navigateToOptInPaymentMethodsThankYouDeleteMethodsScreen() + ) }); const bottomButtons: { @@ -95,7 +97,9 @@ const OptInPaymentMethodsChoiceScreen = () => { () => ({ keepPaymentMethods: confirmButtonProps( () => - navigate(navigateToOptInPaymentMethodsThankYouKeepMethodsScreen()), + navigation.dispatch( + navigateToOptInPaymentMethodsThankYouKeepMethodsScreen() + ), I18n.t("global.buttons.continue"), undefined, "continueButton" @@ -107,7 +111,7 @@ const OptInPaymentMethodsChoiceScreen = () => { undefined ) }), - [navigate, presentBottomSheet] + [navigation, presentBottomSheet] ); const computedBottomButtonProps = diff --git a/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsCashbackUpdateScreen.test.tsx b/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsCashbackUpdateScreen.test.tsx index f80b61fc5bb..f9bdc803e16 100644 --- a/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsCashbackUpdateScreen.test.tsx +++ b/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsCashbackUpdateScreen.test.tsx @@ -1,5 +1,5 @@ import { createStore, Store } from "redux"; -import { NavigationParams } from "react-navigation"; + import { fireEvent, RenderAPI } from "@testing-library/react-native"; import { GlobalState } from "../../../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../../../utils/testWrapper"; @@ -145,7 +145,7 @@ describe("the OptInPaymentMethodsCashbackUpdateScreen screen", () => { }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( OptInPaymentMethodsCashbackUpdateScreen, ROUTES.MAIN, {}, diff --git a/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsChoiceScreen.test.tsx b/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsChoiceScreen.test.tsx index 87c6aa84251..e9e2afb650a 100644 --- a/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsChoiceScreen.test.tsx +++ b/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsChoiceScreen.test.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore } from "redux"; import { fireEvent } from "@testing-library/react-native"; import { appReducer } from "../../../../../../store/reducers"; @@ -35,7 +35,7 @@ describe("the OptInPaymentMethodsChoiceScreen screen", () => { }); const renderComponent = () => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , BPD_ROUTES.OPT_IN_PAYMENT_METHODS.CHOICE, {}, diff --git a/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsThankYouDeleteMethodsScreen.test.ts b/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsThankYouDeleteMethodsScreen.test.ts index d0911ad72be..eda0eb6f20f 100644 --- a/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsThankYouDeleteMethodsScreen.test.ts +++ b/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsThankYouDeleteMethodsScreen.test.ts @@ -1,7 +1,7 @@ import { createStore, Store } from "redux"; import * as pot from "italia-ts-commons/lib/pot"; import { RenderAPI } from "@testing-library/react-native"; -import { NavigationParams } from "react-navigation"; + import { GlobalState } from "../../../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../../../utils/testWrapper"; import ROUTES from "../../../../../../navigation/routes"; @@ -169,7 +169,7 @@ describe("the OptInPaymentMethodsThankYouDeleteMethodsScreen screen", () => { }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( OptInPaymentMethodsThankYouDeleteMethodsScreen, ROUTES.MAIN, {}, diff --git a/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsThankYouKeepMethodsScreen.test.ts b/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsThankYouKeepMethodsScreen.test.ts index be2ab5000ed..57dacd552de 100644 --- a/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsThankYouKeepMethodsScreen.test.ts +++ b/ts/features/bonus/bpd/screens/optInPaymentMethods/__tests__/OptInPaymentMethodsThankYouKeepMethodsScreen.test.ts @@ -1,7 +1,7 @@ import { createStore, Store } from "redux"; import * as pot from "italia-ts-commons/lib/pot"; import { RenderAPI } from "@testing-library/react-native"; -import { NavigationParams } from "react-navigation"; + import { GlobalState } from "../../../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../../../utils/testWrapper"; import ROUTES from "../../../../../../navigation/routes"; @@ -91,7 +91,7 @@ describe("the OptInPaymentMethodsThankYouKeepMethodsScreen screen", () => { }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( OptInPaymentMethodsThankYouKeepMethodsScreen, ROUTES.MAIN, {}, diff --git a/ts/features/bonus/cgn/navigation/actions.ts b/ts/features/bonus/cgn/navigation/actions.ts index aa2dec2575b..e37c5e16398 100644 --- a/ts/features/bonus/cgn/navigation/actions.ts +++ b/ts/features/bonus/cgn/navigation/actions.ts @@ -1,4 +1,4 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../../navigation/NavigationService"; import { CgnMerchantDetailScreenNavigationParams } from "../screens/merchants/CgnMerchantDetailScreen"; import { CgnMerchantLandingWebviewNavigationParams } from "../screens/merchants/CgnMerchantLandingWebview"; @@ -10,8 +10,8 @@ import CGN_ROUTES from "./routes"; */ export const navigateToCgnActivationInformationTos = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.ACTIVATION.INFORMATION_TOS + CommonActions.navigate(CGN_ROUTES.ACTIVATION.MAIN, { + screen: CGN_ROUTES.ACTIVATION.INFORMATION_TOS }) ); @@ -21,8 +21,8 @@ export const navigateToCgnActivationInformationTos = () => */ export const navigateToCgnActivationLoading = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.ACTIVATION.LOADING + CommonActions.navigate(CGN_ROUTES.ACTIVATION.MAIN, { + screen: CGN_ROUTES.ACTIVATION.LOADING }) ); @@ -32,8 +32,8 @@ export const navigateToCgnActivationLoading = () => */ export const navigateToEycaActivationLoading = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.EYCA.ACTIVATION.LOADING + CommonActions.navigate(CGN_ROUTES.EYCA.ACTIVATION.MAIN, { + screen: CGN_ROUTES.EYCA.ACTIVATION.LOADING }) ); @@ -43,8 +43,8 @@ export const navigateToEycaActivationLoading = () => */ export const navigateToCgnAlreadyActive = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.ACTIVATION.EXISTS + CommonActions.navigate(CGN_ROUTES.ACTIVATION.MAIN, { + screen: CGN_ROUTES.ACTIVATION.EXISTS }) ); @@ -54,8 +54,8 @@ export const navigateToCgnAlreadyActive = () => */ export const navigateToCgnActivationPending = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.ACTIVATION.PENDING + CommonActions.navigate(CGN_ROUTES.ACTIVATION.MAIN, { + screen: CGN_ROUTES.ACTIVATION.PENDING }) ); @@ -65,8 +65,8 @@ export const navigateToCgnActivationPending = () => */ export const navigateToCgnActivationTimeout = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.ACTIVATION.TIMEOUT + CommonActions.navigate(CGN_ROUTES.ACTIVATION.MAIN, { + screen: CGN_ROUTES.ACTIVATION.TIMEOUT }) ); @@ -76,8 +76,8 @@ export const navigateToCgnActivationTimeout = () => */ export const navigateToCgnActivationIneligible = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.ACTIVATION.INELIGIBLE + CommonActions.navigate(CGN_ROUTES.ACTIVATION.MAIN, { + screen: CGN_ROUTES.ACTIVATION.INELIGIBLE }) ); @@ -87,8 +87,8 @@ export const navigateToCgnActivationIneligible = () => */ export const navigateToCgnActivationCompleted = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.ACTIVATION.COMPLETED + CommonActions.navigate(CGN_ROUTES.ACTIVATION.MAIN, { + screen: CGN_ROUTES.ACTIVATION.COMPLETED }) ); @@ -100,8 +100,8 @@ export const navigateToCgnActivationCompleted = () => */ export const navigateToCgnDetails = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.DETAILS.DETAILS + CommonActions.navigate(CGN_ROUTES.DETAILS.MAIN, { + screen: CGN_ROUTES.DETAILS.DETAILS }) ); @@ -112,8 +112,8 @@ export const navigateToCgnDetails = () => */ export const navigateToCgnMerchantsList = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.DETAILS.MERCHANTS.LIST + CommonActions.navigate(CGN_ROUTES.DETAILS.MAIN, { + screen: CGN_ROUTES.DETAILS.MERCHANTS.LIST }) ); @@ -123,8 +123,8 @@ export const navigateToCgnMerchantsList = () => */ export const navigateToCgnMerchantsTabs = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.DETAILS.MERCHANTS.TABS + CommonActions.navigate(CGN_ROUTES.DETAILS.MAIN, { + screen: CGN_ROUTES.DETAILS.MERCHANTS.TABS }) ); @@ -136,8 +136,8 @@ export const navigateToCgnMerchantDetail = ( params: CgnMerchantDetailScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.DETAILS.MERCHANTS.DETAIL, + CommonActions.navigate(CGN_ROUTES.DETAILS.MAIN, { + screen: CGN_ROUTES.DETAILS.MERCHANTS.DETAIL, params }) ); @@ -150,8 +150,8 @@ export const navigateToCgnMerchantLandingWebview = ( params: CgnMerchantLandingWebviewNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: CGN_ROUTES.DETAILS.MERCHANTS.LANDING_WEBVIEW, + CommonActions.navigate(CGN_ROUTES.DETAILS.MAIN, { + screen: CGN_ROUTES.DETAILS.MERCHANTS.LANDING_WEBVIEW, params }) ); diff --git a/ts/features/bonus/cgn/navigation/navigator.ts b/ts/features/bonus/cgn/navigation/navigator.ts index 96a55715285..58fa25d75ab 100644 --- a/ts/features/bonus/cgn/navigation/navigator.ts +++ b/ts/features/bonus/cgn/navigation/navigator.ts @@ -1,4 +1,5 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import CgnActivationCompletedScreen from "../screens/activation/CgnActivationCompletedScreen"; import CgnActivationIneligibleScreen from "../screens/activation/CgnActivationIneligibleScreen"; import CgnActivationLoadingScreen from "../screens/activation/CgnActivationLoadingScreen"; @@ -18,7 +19,9 @@ import CgnMerchantsTabsScreen from "../screens/merchants/CgnMerchantsTabsScreen" import CGN_ROUTES from "./routes"; -export const CgnActivationNavigator = createStackNavigator( +export const CgnActivationNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [CGN_ROUTES.ACTIVATION.INFORMATION_TOS]: { screen: CgnInformationScreen @@ -49,12 +52,14 @@ export const CgnActivationNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); -export const CgnDetailsNavigator = createStackNavigator( +export const CgnDetailsNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [CGN_ROUTES.DETAILS.DETAILS]: { screen: CgnDetailScreen @@ -82,12 +87,14 @@ export const CgnDetailsNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); -export const CgnEYCAActivationNavigator = createStackNavigator( +export const CgnEYCAActivationNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [CGN_ROUTES.EYCA.ACTIVATION.LOADING]: { screen: EycaActivationLoading @@ -97,7 +104,7 @@ export const CgnEYCAActivationNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/bonus/cgn/navigation/routes.ts b/ts/features/bonus/cgn/navigation/routes.ts index 73410f7cb2b..eacd995f598 100644 --- a/ts/features/bonus/cgn/navigation/routes.ts +++ b/ts/features/bonus/cgn/navigation/routes.ts @@ -14,7 +14,7 @@ const CGN_ROUTES = { ACTIVATION: { MAIN: "CGN_EYCA_MAIN", LOADING: "CGN_EYCA_ACTIVATION_LOADING" - } + } as const }, DETAILS: { MAIN: "CGN_DETAILS_MAIN", @@ -26,8 +26,8 @@ const CGN_ROUTES = { TABS: "CGN_MERCHANTS_TABS", DETAIL: "CGN_MERCHANTS_DETAIL", LANDING_WEBVIEW: "CGN_MERCHANTS_LANDING_WEBVIEW" - } - } + } as const + } as const } as const; export default CGN_ROUTES; diff --git a/ts/features/bonus/cgn/saga/orchestration/activation/activationSaga.ts b/ts/features/bonus/cgn/saga/orchestration/activation/activationSaga.ts index 8827d3f057e..52556386573 100644 --- a/ts/features/bonus/cgn/saga/orchestration/activation/activationSaga.ts +++ b/ts/features/bonus/cgn/saga/orchestration/activation/activationSaga.ts @@ -1,9 +1,14 @@ import { SagaIterator } from "redux-saga"; import { call } from "typed-redux-saga/macro"; +import NavigationService from "../../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../../navigation/routes"; import { executeWorkUnit, withResetNavigationStack } from "../../../../../../sagas/workUnit"; +import { navigateBack } from "../../../../../../store/actions/navigation"; +import { SagaCallReturnType } from "../../../../../../types/utils"; +import BONUSVACANZE_ROUTES from "../../../../bonusVacanze/navigation/routes"; import { navigateToCgnActivationInformationTos, navigateToCgnDetails @@ -15,11 +20,6 @@ import { cgnActivationComplete, cgnActivationFailure } from "../../../store/actions/activation"; -import { SagaCallReturnType } from "../../../../../../types/utils"; -import NavigationService from "../../../../../../navigation/NavigationService"; -import BONUSVACANZE_ROUTES from "../../../../bonusVacanze/navigation/routes"; -import { navigateBack } from "../../../../../../store/actions/navigation"; -import ROUTES from "../../../../../../navigation/routes"; function* cgnActivationWorkUnit() { return yield* call(executeWorkUnit, { @@ -44,11 +44,11 @@ export function* handleCgnStartActivationSaga(): SagaIterator { sagaExecution ); - if (initialScreen?.routeName === CGN_ROUTES.ACTIVATION.CTA_START_CGN) { + if (initialScreen?.name === CGN_ROUTES.ACTIVATION.CTA_START_CGN) { yield* call(NavigationService.navigate, ROUTES.MESSAGES_HOME); } if (result === "completed") { - if (initialScreen?.routeName === BONUSVACANZE_ROUTES.BONUS_AVAILABLE_LIST) { + if (initialScreen?.name === BONUSVACANZE_ROUTES.BONUS_AVAILABLE_LIST) { yield* call(navigateBack); } yield* call(navigateToCgnDetails); diff --git a/ts/features/bonus/cgn/saga/orchestration/activation/handleActivationSaga.ts b/ts/features/bonus/cgn/saga/orchestration/activation/handleActivationSaga.ts index 942f99376c3..7df7cc23e79 100644 --- a/ts/features/bonus/cgn/saga/orchestration/activation/handleActivationSaga.ts +++ b/ts/features/bonus/cgn/saga/orchestration/activation/handleActivationSaga.ts @@ -1,5 +1,5 @@ +import { CommonActions } from "@react-navigation/native"; import { fromNullable } from "fp-ts/lib/Option"; -import { NavigationActions } from "react-navigation"; import { call, put, race, take } from "typed-redux-saga/macro"; import { ActionType, isActionOf } from "typesafe-actions"; import NavigationService from "../../../../../../navigation/NavigationService"; @@ -68,6 +68,9 @@ export function* handleCgnActivationSaga(cgnActivationSaga: CgnActivationType) { cancelAction: take(cgnActivationCancel) }); if (cancelAction) { - yield* put(NavigationActions.back()); + yield* call( + NavigationService.dispatchNavigationAction, + CommonActions.goBack() + ); } } diff --git a/ts/features/bonus/cgn/saga/orchestration/eyca/eycaActivationSaga.ts b/ts/features/bonus/cgn/saga/orchestration/eyca/eycaActivationSaga.ts index 921058f478c..241a79dee98 100644 --- a/ts/features/bonus/cgn/saga/orchestration/eyca/eycaActivationSaga.ts +++ b/ts/features/bonus/cgn/saga/orchestration/eyca/eycaActivationSaga.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import { call, put, race, take } from "typed-redux-saga/macro"; +import NavigationService from "../../../../../../navigation/NavigationService"; import { SagaCallReturnType } from "../../../../../../types/utils"; import { BackendCGN } from "../../../api/backendCgn"; import { @@ -93,6 +94,9 @@ export function* eycaActivationSaga( }); if (cancelAction) { - yield* put(NavigationActions.back()); + yield* call( + NavigationService.dispatchNavigationAction, + CommonActions.goBack() + ); } } diff --git a/ts/features/bonus/cgn/screens/CgnDetailScreen.tsx b/ts/features/bonus/cgn/screens/CgnDetailScreen.tsx index d9d65265221..cc7c7f0d7eb 100644 --- a/ts/features/bonus/cgn/screens/CgnDetailScreen.tsx +++ b/ts/features/bonus/cgn/screens/CgnDetailScreen.tsx @@ -1,4 +1,5 @@ import * as pot from "@pagopa/ts-commons/lib/pot"; +import { useNavigation } from "@react-navigation/native"; import { View } from "native-base"; import React, { useState } from "react"; import { SafeAreaView, ScrollView } from "react-native"; @@ -13,6 +14,7 @@ import SectionStatusComponent from "../../../../components/SectionStatus"; import FocusAwareStatusBar from "../../../../components/ui/FocusAwareStatusBar"; import FooterWithButtons from "../../../../components/ui/FooterWithButtons"; import I18n from "../../../../i18n"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; import { navigateBack } from "../../../../store/actions/navigation"; import { Dispatch } from "../../../../store/actions/types"; import { @@ -22,11 +24,13 @@ import { import { GlobalState } from "../../../../store/reducers/types"; import customVariables from "../../../../theme/variables"; import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; +import { useActionOnFocus } from "../../../../utils/hooks/useOnFocus"; import { confirmButtonProps } from "../../bonusVacanze/components/buttons/ButtonConfigurations"; import { useHardwareBackButton } from "../../bonusVacanze/components/hooks/useHardwareBackButton"; import { availableBonusTypesSelectorFromId } from "../../bonusVacanze/store/reducers/availableBonusesTypes"; import { ID_CGN_TYPE } from "../../bonusVacanze/utils/bonus"; import { isLoading } from "../../bpd/model/RemoteValue"; +import CgnCardComponent from "../components/detail/CgnCardComponent"; import CgnOwnershipInformation from "../components/detail/CgnOwnershipInformation"; import CgnStatusDetail from "../components/detail/CgnStatusDetail"; import CgnUnsubscribe from "../components/detail/CgnUnsubscribe"; @@ -35,11 +39,8 @@ import { navigateToCgnMerchantsList, navigateToCgnMerchantsTabs } from "../navigation/actions"; -import CgnCardComponent from "../components/detail/CgnCardComponent"; -import { - useActionOnFocus, - useNavigationContext -} from "../../../../utils/hooks/useOnFocus"; +import { CgnDetailsParamsList } from "../navigation/params"; +import CGN_ROUTES from "../navigation/routes"; import { cgnDetails } from "../store/actions/details"; import { cgnEycaStatus } from "../store/actions/eyca/details"; import { cgnUnsubscribe } from "../store/actions/unsubscribe"; @@ -50,7 +51,6 @@ import { } from "../store/reducers/details"; import { eycaDetailSelector } from "../store/reducers/eyca/details"; import { cgnUnsubscribeSelector } from "../store/reducers/unsubscribe"; -import CGN_ROUTES from "../navigation/routes"; import { canEycaCardBeShown } from "../utils/eyca"; type Props = ReturnType & @@ -64,7 +64,8 @@ const GRADIENT_END_COLOR = "#5C488F"; */ const CgnDetailScreen = (props: Props): React.ReactElement => { const [cardLoading, setCardLoading] = useState(true); - const navigation = useNavigationContext(); + const navigation = + useNavigation>(); const loadCGN = () => { props.loadCgnDetails(); diff --git a/ts/features/bonus/cgn/screens/activation/CgnCTAStartActivationScreen.tsx b/ts/features/bonus/cgn/screens/activation/CgnCTAStartActivationScreen.tsx index 40178cca324..ccfbedb8526 100644 --- a/ts/features/bonus/cgn/screens/activation/CgnCTAStartActivationScreen.tsx +++ b/ts/features/bonus/cgn/screens/activation/CgnCTAStartActivationScreen.tsx @@ -1,15 +1,14 @@ +import { useNavigation } from "@react-navigation/native"; import * as React from "react"; import { useRef } from "react"; +import { Alert } from "react-native"; import { connect } from "react-redux"; import { Dispatch } from "redux"; -import { Alert } from "react-native"; import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; import I18n from "../../../../../i18n"; +import { isCGNEnabledSelector } from "../../../../../store/reducers/backendStatus"; import { GlobalState } from "../../../../../store/reducers/types"; -import { - useActionOnFocus, - useNavigationContext -} from "../../../../../utils/hooks/useOnFocus"; +import { useActionOnFocus } from "../../../../../utils/hooks/useOnFocus"; import { LoadingErrorComponent } from "../../../bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; import { loadAvailableBonuses } from "../../../bonusVacanze/store/actions/bonusVacanze"; import { @@ -19,7 +18,6 @@ import { } from "../../../bonusVacanze/store/reducers/availableBonusesTypes"; import { ID_CGN_TYPE } from "../../../bonusVacanze/utils/bonus"; import { cgnActivationStart } from "../../store/actions/activation"; -import { isCGNEnabledSelector } from "../../../../../store/reducers/backendStatus"; export type Props = ReturnType & ReturnType; @@ -60,7 +58,7 @@ const CgnCTAStartOnboardingComponent: React.FC = (props: Props) => { * this is a dummy screen reachable only from a message CTA */ const CgnCTAStartOnboardingScreen = (props: Props) => { - const navigation = useNavigationContext(); + const navigation = useNavigation(); if (!props.isCgnEnabled) { Alert.alert( I18n.t("bonus.cgn.name"), diff --git a/ts/features/bonus/cgn/screens/merchants/CgnMerchantDetailScreen.tsx b/ts/features/bonus/cgn/screens/merchants/CgnMerchantDetailScreen.tsx index 35b5847e410..fa613352bec 100644 --- a/ts/features/bonus/cgn/screens/merchants/CgnMerchantDetailScreen.tsx +++ b/ts/features/bonus/cgn/screens/merchants/CgnMerchantDetailScreen.tsx @@ -1,3 +1,4 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { fromNullable } from "fp-ts/lib/Option"; import { View } from "native-base"; import * as React from "react"; @@ -10,7 +11,6 @@ import { ScrollView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Address } from "../../../../../../definitions/cgn/merchants/Address"; import { Discount } from "../../../../../../definitions/cgn/merchants/Discount"; @@ -24,6 +24,7 @@ import BaseScreenComponent from "../../../../../components/screens/BaseScreenCom import TouchableDefaultOpacity from "../../../../../components/TouchableDefaultOpacity"; import IconFont from "../../../../../components/ui/IconFont"; import I18n from "../../../../../i18n"; +import { IOStackNavigationProp } from "../../../../../navigation/params/AppParamsList"; import { Dispatch } from "../../../../../store/actions/types"; import { GlobalState } from "../../../../../store/reducers/types"; import { clipboardSetStringWithFeedback } from "../../../../../utils/clipboard"; @@ -31,6 +32,7 @@ import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; import { LoadingErrorComponent } from "../../../bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; import { isLoading, isReady } from "../../../bpd/model/RemoteValue"; import CgnMerchantDiscountItem from "../../components/merchants/CgnMerchantsDiscountItem"; +import { CgnDetailsParamsList } from "../../navigation/params"; import { cgnSelectedMerchant } from "../../store/actions/merchants"; import { cgnSelectedMerchantSelector } from "../../store/reducers/merchants"; import { openWebUrl } from "../../../../../utils/url"; @@ -42,8 +44,11 @@ export type CgnMerchantDetailScreenNavigationParams = Readonly<{ }>; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; const styles = StyleSheet.create({ merchantImage: { diff --git a/ts/features/bonus/cgn/screens/merchants/CgnMerchantLandingWebview.tsx b/ts/features/bonus/cgn/screens/merchants/CgnMerchantLandingWebview.tsx index 28df8c367fc..c936cc072dd 100644 --- a/ts/features/bonus/cgn/screens/merchants/CgnMerchantLandingWebview.tsx +++ b/ts/features/bonus/cgn/screens/merchants/CgnMerchantLandingWebview.tsx @@ -1,23 +1,28 @@ +import { CompatNavigationProp } from "@react-navigation/compat/src/types"; +import { useNavigation } from "@react-navigation/native"; import * as React from "react"; import { SafeAreaView } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { IOStyles } from "../../../../../components/core/variables/IOStyles"; -import WebviewComponent from "../../../../../components/WebviewComponent"; -import { useNavigationContext } from "../../../../../utils/hooks/useOnFocus"; import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; +import WebviewComponent from "../../../../../components/WebviewComponent"; +import { IOStackNavigationProp } from "../../../../../navigation/params/AppParamsList"; +import { CgnDetailsParamsList } from "../../navigation/params"; export type CgnMerchantLandingWebviewNavigationParams = Readonly<{ landingPageUrl: string; landingPageReferrer: string; }>; -type Props = - NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; const CgnMerchantLandingWebview: React.FunctionComponent = ( props: Props ) => { - const navigation = useNavigationContext(); + const navigation = useNavigation(); const landingPageUrl = props.navigation.getParam("landingPageUrl"); const landingPageReferrer = props.navigation.getParam("landingPageReferrer"); diff --git a/ts/features/bonus/cgn/screens/merchants/CgnMerchantsCategoriesSelectionScreen.tsx b/ts/features/bonus/cgn/screens/merchants/CgnMerchantsCategoriesSelectionScreen.tsx index 541e5d58938..a31a9169146 100644 --- a/ts/features/bonus/cgn/screens/merchants/CgnMerchantsCategoriesSelectionScreen.tsx +++ b/ts/features/bonus/cgn/screens/merchants/CgnMerchantsCategoriesSelectionScreen.tsx @@ -1,4 +1,5 @@ import * as pot from "@pagopa/ts-commons/lib/pot"; +import { useNavigation } from "@react-navigation/native"; import { View } from "native-base"; import * as React from "react"; import { useEffect, useMemo, useRef } from "react"; @@ -10,10 +11,12 @@ import { IOStyles } from "../../../../../components/core/variables/IOStyles"; import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; import { EdgeBorderComponent } from "../../../../../components/screens/EdgeBorderComponent"; import I18n from "../../../../../i18n"; +import { IOStackNavigationProp } from "../../../../../navigation/params/AppParamsList"; import { useIODispatch, useIOSelector } from "../../../../../store/hooks"; import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; -import { useNavigationContext } from "../../../../../utils/hooks/useOnFocus"; +import { showToast } from "../../../../../utils/showToast"; import CgnMerchantCategoryItem from "../../components/merchants/CgnMerchantCategoryItem"; +import { CgnDetailsParamsList } from "../../navigation/params"; import CGN_ROUTES from "../../navigation/routes"; import { cgnCategories, @@ -21,13 +24,15 @@ import { } from "../../store/actions/categories"; import { cgnCategoriesListSelector } from "../../store/reducers/categories"; import { getCategorySpecs } from "../../utils/filters"; -import { showToast } from "../../../../../utils/showToast"; const CgnMerchantsCategoriesSelectionScreen = () => { const isFirstRender = useRef(true); const dispatch = useIODispatch(); const potCategories = useIOSelector(cgnCategoriesListSelector); - const navigation = useNavigationContext(); + const navigation = + useNavigation< + IOStackNavigationProp + >(); const loadCategories = () => { dispatch(cgnCategories.request()); diff --git a/ts/features/bonus/cgn/screens/merchants/CgnMerchantsListByCategory.tsx b/ts/features/bonus/cgn/screens/merchants/CgnMerchantsListByCategory.tsx index a196aab9ed8..d79a79045fc 100644 --- a/ts/features/bonus/cgn/screens/merchants/CgnMerchantsListByCategory.tsx +++ b/ts/features/bonus/cgn/screens/merchants/CgnMerchantsListByCategory.tsx @@ -1,38 +1,40 @@ +import { useNavigation } from "@react-navigation/native"; +import { fromNullable } from "fp-ts/lib/Option"; +import { View } from "native-base"; import * as React from "react"; import { useMemo } from "react"; import { SafeAreaView, StyleSheet } from "react-native"; import LinearGradient from "react-native-linear-gradient"; -import { View } from "native-base"; -import { fromNullable } from "fp-ts/lib/Option"; -import { useIODispatch, useIOSelector } from "../../../../../store/hooks"; -import { - cgnOfflineMerchants, - cgnOnlineMerchants -} from "../../store/actions/merchants"; -import { cgnSelectedCategorySelector } from "../../store/reducers/categories"; +import { Merchant } from "../../../../../../definitions/cgn/merchants/Merchant"; +import { OfflineMerchant } from "../../../../../../definitions/cgn/merchants/OfflineMerchant"; +import { OnlineMerchant } from "../../../../../../definitions/cgn/merchants/OnlineMerchant"; +import { H1 } from "../../../../../components/core/typography/H1"; +import { IOColors } from "../../../../../components/core/variables/IOColors"; +import { IOStyles } from "../../../../../components/core/variables/IOStyles"; import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; -import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; +import GenericErrorComponent from "../../../../../components/screens/GenericErrorComponent"; import I18n from "../../../../../i18n"; -import { IOStyles } from "../../../../../components/core/variables/IOStyles"; -import CgnMerchantsListView from "../../components/merchants/CgnMerchantsListView"; +import { IOStackNavigationProp } from "../../../../../navigation/params/AppParamsList"; +import { useIODispatch, useIOSelector } from "../../../../../store/hooks"; +import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; import { getValueOrElse, isError, isLoading } from "../../../bpd/model/RemoteValue"; -import { OfflineMerchant } from "../../../../../../definitions/cgn/merchants/OfflineMerchant"; -import { OnlineMerchant } from "../../../../../../definitions/cgn/merchants/OnlineMerchant"; +import CgnMerchantsListView from "../../components/merchants/CgnMerchantsListView"; +import { CgnDetailsParamsList } from "../../navigation/params"; +import CGN_ROUTES from "../../navigation/routes"; +import { + cgnOfflineMerchants, + cgnOnlineMerchants +} from "../../store/actions/merchants"; +import { cgnSelectedCategorySelector } from "../../store/reducers/categories"; import { cgnOfflineMerchantsSelector, cgnOnlineMerchantsSelector } from "../../store/reducers/merchants"; -import { Merchant } from "../../../../../../definitions/cgn/merchants/Merchant"; -import { useNavigationContext } from "../../../../../utils/hooks/useOnFocus"; -import CGN_ROUTES from "../../navigation/routes"; import { CATEGORY_GRADIENT_ANGLE, getCategorySpecs } from "../../utils/filters"; -import { H1 } from "../../../../../components/core/typography/H1"; -import { IOColors } from "../../../../../components/core/variables/IOColors"; -import GenericErrorComponent from "../../../../../components/screens/GenericErrorComponent"; import { MerchantsAll } from "./CgnMerchantsListScreen"; const styles = StyleSheet.create({ @@ -56,7 +58,10 @@ const CgnMerchantsListByCategory = () => { [currentCategory] ); - const navigation = useNavigationContext(); + const navigation = + useNavigation< + IOStackNavigationProp + >(); const categoryFilter = useMemo( () => diff --git a/ts/features/bonus/siciliaVola/components/__tests__/CheckResidenceComponent.test.tsx b/ts/features/bonus/siciliaVola/components/__tests__/CheckResidenceComponent.test.tsx index 5813fd084ad..17e0a64a306 100644 --- a/ts/features/bonus/siciliaVola/components/__tests__/CheckResidenceComponent.test.tsx +++ b/ts/features/bonus/siciliaVola/components/__tests__/CheckResidenceComponent.test.tsx @@ -1,5 +1,5 @@ +import { CommonActions } from "@react-navigation/native"; import { fireEvent } from "@testing-library/react-native"; -import { NavigationActions, NavigationParams } from "react-navigation"; import configureMockStore from "redux-mock-store"; import I18n from "../../../../../i18n"; import NavigationService from "../../../../../navigation/NavigationService"; @@ -60,8 +60,8 @@ describe("the CheckResidenceComponent", () => { fireEvent(continueButton, "onPress"); expect(spy).toHaveBeenCalledWith( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.SELECT_BENEFICIARY_CATEGORY + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.SELECT_BENEFICIARY_CATEGORY }) ); }); @@ -79,8 +79,8 @@ describe("the CheckResidenceComponent", () => { ); fireEvent(continueButton, "onPress"); expect(spy).toHaveBeenCalledWith( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.KO_CHECK_RESIDENCE + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.KO_CHECK_RESIDENCE }) ); }); @@ -100,7 +100,7 @@ function renderComponent() { const mockStore = configureMockStore(); const store = mockStore(globalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( CheckResidenceComponent, ROUTES.MAIN, {}, diff --git a/ts/features/bonus/siciliaVola/navigation/actions.ts b/ts/features/bonus/siciliaVola/navigation/actions.ts index bb36395d410..684680fc92b 100644 --- a/ts/features/bonus/siciliaVola/navigation/actions.ts +++ b/ts/features/bonus/siciliaVola/navigation/actions.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../../navigation/NavigationService"; +import ROUTES from "../../../../navigation/routes"; import SV_ROUTES from "./routes"; /** @@ -7,8 +8,8 @@ import SV_ROUTES from "./routes"; */ export const navigateToSvCheckStatusRouterScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.CHECK_STATUS + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.CHECK_STATUS }) ); @@ -17,8 +18,8 @@ export const navigateToSvCheckStatusRouterScreen = () => */ export const navigateToSvSelectBeneficiaryCategoryScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.SELECT_BENEFICIARY_CATEGORY + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.SELECT_BENEFICIARY_CATEGORY }) ); @@ -27,8 +28,8 @@ export const navigateToSvSelectBeneficiaryCategoryScreen = () => */ export const navigateToSvStudentSelectDestinationScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.STUDENT_SELECT_DESTINATION + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.STUDENT_SELECT_DESTINATION }) ); @@ -37,8 +38,8 @@ export const navigateToSvStudentSelectDestinationScreen = () => */ export const navigateToSvDisabledAdditionalInfoScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.DISABLED_ADDITIONAL_INFO + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.DISABLED_ADDITIONAL_INFO }) ); @@ -47,8 +48,8 @@ export const navigateToSvDisabledAdditionalInfoScreen = () => */ export const navigateToSvWorkerCheckIncomeThresholdScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.WORKER_CHECK_INCOME_THRESHOLD + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.WORKER_CHECK_INCOME_THRESHOLD }) ); @@ -57,8 +58,8 @@ export const navigateToSvWorkerCheckIncomeThresholdScreen = () => */ export const navigateToSvWorkerSelectDestinationScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.WORKER_SELECT_DESTINATION + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.WORKER_SELECT_DESTINATION }) ); @@ -67,8 +68,8 @@ export const navigateToSvWorkerSelectDestinationScreen = () => */ export const navigateToSvSickCheckIncomeThresholdScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.SICK_CHECK_INCOME_THRESHOLD + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.SICK_CHECK_INCOME_THRESHOLD }) ); @@ -77,8 +78,8 @@ export const navigateToSvSickCheckIncomeThresholdScreen = () => */ export const navigateToSvSickSelectDestinationScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.SICK_SELECT_DESTINATION + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.SICK_SELECT_DESTINATION }) ); @@ -87,8 +88,8 @@ export const navigateToSvSickSelectDestinationScreen = () => */ export const navigateToSvSelectFlightsDateScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.SELECT_FLIGHTS_DATA + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.SELECT_FLIGHTS_DATA }) ); @@ -97,8 +98,8 @@ export const navigateToSvSelectFlightsDateScreen = () => */ export const navigateToSvSummaryScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.SUMMARY + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.SUMMARY }) ); @@ -107,8 +108,8 @@ export const navigateToSvSummaryScreen = () => */ export const navigateToSvVoucherGeneratedScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.VOUCHER_GENERATED + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.VOUCHER_GENERATED }) ); @@ -117,8 +118,8 @@ export const navigateToSvVoucherGeneratedScreen = () => */ export const navigateToSvKoCheckResidenceScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.KO_CHECK_RESIDENCE + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.KO_CHECK_RESIDENCE }) ); @@ -127,8 +128,8 @@ export const navigateToSvKoCheckResidenceScreen = () => */ export const navigateToSvKoSelectBeneficiaryCategoryScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.KO_SELECT_BENEFICIARY_CATEGORY + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.KO_SELECT_BENEFICIARY_CATEGORY }) ); @@ -137,8 +138,8 @@ export const navigateToSvKoSelectBeneficiaryCategoryScreen = () => */ export const navigateToSvKoCheckIncomeThresholdScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.KO_CHECK_INCOME_THRESHOLD + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.KO_CHECK_INCOME_THRESHOLD }) ); @@ -147,8 +148,8 @@ export const navigateToSvKoCheckIncomeThresholdScreen = () => */ export const navigateToSvTimeoutGeneratedVoucherScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_GENERATION.TIMEOUT_GENERATED_VOUCHER + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_GENERATION.TIMEOUT_GENERATED_VOUCHER }) ); @@ -157,8 +158,8 @@ export const navigateToSvTimeoutGeneratedVoucherScreen = () => */ export const navigateToSvVoucherListScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_LIST.LIST + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_LIST.LIST }) ); @@ -167,7 +168,7 @@ export const navigateToSvVoucherListScreen = () => */ export const navigateToSvVoucherDetailsScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: SV_ROUTES.VOUCHER_LIST.DETAILS + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: SV_ROUTES.VOUCHER_LIST.DETAILS }) ); diff --git a/ts/features/euCovidCert/navigation/actions.ts b/ts/features/euCovidCert/navigation/actions.ts index 9b60c842423..82a8bc84df9 100644 --- a/ts/features/euCovidCert/navigation/actions.ts +++ b/ts/features/euCovidCert/navigation/actions.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../navigation/NavigationService"; +import ROUTES from "../../../navigation/routes"; import { EuCovidCertificateRouterScreenNavigationParams } from "../screens/EuCovidCertificateRouterScreen"; import { EuCovidCertMarkdownDetailsScreenNavigationParams } from "../screens/valid/EuCovidCertMarkdownDetailsScreen"; import { EuCovidCertQrCodeFullScreenNavigationParams } from "../screens/valid/EuCovidCertQrCodeFullScreen"; @@ -13,9 +14,12 @@ export const navigateToEuCovidCertificateDetailScreen = ( params: EuCovidCertificateRouterScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: EUCOVIDCERT_ROUTES.CERTIFICATE, - params + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: EUCOVIDCERT_ROUTES.MAIN, + params: { + screen: EUCOVIDCERT_ROUTES.CERTIFICATE, + params + } }) ); @@ -27,9 +31,12 @@ export const navigateToEuCovidCertificateQrCodeFullScreen = ( params: EuCovidCertQrCodeFullScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: EUCOVIDCERT_ROUTES.QRCODE, - params + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: EUCOVIDCERT_ROUTES.MAIN, + params: { + screen: EUCOVIDCERT_ROUTES.QRCODE, + params + } }) ); @@ -41,8 +48,11 @@ export const navigateToEuCovidCertificateMarkdownDetailsScreen = ( params: EuCovidCertMarkdownDetailsScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: EUCOVIDCERT_ROUTES.MARKDOWN_DETAILS, - params + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: EUCOVIDCERT_ROUTES.MAIN, + params: { + screen: EUCOVIDCERT_ROUTES.MARKDOWN_DETAILS, + params + } }) ); diff --git a/ts/features/euCovidCert/navigation/navigator.ts b/ts/features/euCovidCert/navigation/navigator.ts index b60a0521e36..e6666abe69f 100644 --- a/ts/features/euCovidCert/navigation/navigator.ts +++ b/ts/features/euCovidCert/navigation/navigator.ts @@ -1,10 +1,11 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import EuCovidCertificateRouterScreen from "../screens/EuCovidCertificateRouterScreen"; import { EuCovidCertMarkdownDetailsScreen } from "../screens/valid/EuCovidCertMarkdownDetailsScreen"; import { EuCovidCertQrCodeFullScreen } from "../screens/valid/EuCovidCertQrCodeFullScreen"; import EUCOVIDCERT_ROUTES from "./routes"; -const EuCovidCertNavigator = createStackNavigator( +const EuCovidCertNavigator = createCompatNavigatorFactory(createStackNavigator)( { [EUCOVIDCERT_ROUTES.CERTIFICATE]: { screen: EuCovidCertificateRouterScreen @@ -20,7 +21,7 @@ const EuCovidCertNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/euCovidCert/screens/BaseEuCovidCertificateLayout.tsx b/ts/features/euCovidCert/screens/BaseEuCovidCertificateLayout.tsx index 6208f88ba09..4015ccc2156 100644 --- a/ts/features/euCovidCert/screens/BaseEuCovidCertificateLayout.tsx +++ b/ts/features/euCovidCert/screens/BaseEuCovidCertificateLayout.tsx @@ -1,15 +1,15 @@ +import { NavigationEvents } from "@react-navigation/compat"; +import { View } from "native-base"; import * as React from "react"; import { useRef } from "react"; import { SafeAreaView, ScrollView, StyleSheet } from "react-native"; -import { NavigationEvents } from "react-navigation"; -import { View } from "native-base"; import { heightPercentageToDP } from "react-native-responsive-screen"; import { IOStyles } from "../../../components/core/variables/IOStyles"; import BaseScreenComponent from "../../../components/screens/BaseScreenComponent"; +import SectionStatusComponent from "../../../components/SectionStatus"; import { WithTestID } from "../../../types/WithTestID"; import { setAccessibilityFocus } from "../../../utils/accessibility"; import { emptyContextualHelp } from "../../../utils/emptyContextualHelp"; -import SectionStatusComponent from "../../../components/SectionStatus"; type Props = WithTestID<{ header?: React.ReactElement; @@ -28,7 +28,7 @@ export const BaseEuCovidCertificateLayout = (props: Props) => { const elementRef = useRef(null); return ( - setAccessibilityFocus(elementRef)} /> + setAccessibilityFocus(elementRef)} /> ; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; /** * Return the right screen based on the response value diff --git a/ts/features/euCovidCert/screens/__test__/EUCovidCertExpiredScreen.test.tsx b/ts/features/euCovidCert/screens/__test__/EUCovidCertExpiredScreen.test.tsx index 83417ad8db1..f4befd61579 100644 --- a/ts/features/euCovidCert/screens/__test__/EUCovidCertExpiredScreen.test.tsx +++ b/ts/features/euCovidCert/screens/__test__/EUCovidCertExpiredScreen.test.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { Store } from "redux"; import configureMockStore from "redux-mock-store"; import { applicationChangeState } from "../../../../store/actions/application"; @@ -38,7 +38,7 @@ const renderComponent = ( store: Store, revokedCertificate: ExpiredCertificate ) => ({ - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => ( ), diff --git a/ts/features/euCovidCert/screens/__test__/EUCovidCertRevokedScreen.test.tsx b/ts/features/euCovidCert/screens/__test__/EUCovidCertRevokedScreen.test.tsx index 5dab79bc62d..7d8d53a2512 100644 --- a/ts/features/euCovidCert/screens/__test__/EUCovidCertRevokedScreen.test.tsx +++ b/ts/features/euCovidCert/screens/__test__/EUCovidCertRevokedScreen.test.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { Store } from "redux"; import configureMockStore from "redux-mock-store"; import { applicationChangeState } from "../../../../store/actions/application"; @@ -38,7 +38,7 @@ const renderComponent = ( store: Store, revokedCertificate: RevokedCertificate ) => ({ - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => ( ), diff --git a/ts/features/euCovidCert/screens/__test__/EUCovidCertValidScreen.test.tsx b/ts/features/euCovidCert/screens/__test__/EUCovidCertValidScreen.test.tsx index 678c56efa27..97f54a0f98a 100644 --- a/ts/features/euCovidCert/screens/__test__/EUCovidCertValidScreen.test.tsx +++ b/ts/features/euCovidCert/screens/__test__/EUCovidCertValidScreen.test.tsx @@ -1,10 +1,11 @@ +import { NavigationAction } from "@react-navigation/native"; import { fireEvent } from "@testing-library/react-native"; import * as React from "react"; -import { NavigationAction, NavigationParams } from "react-navigation"; import { Store } from "redux"; import configureMockStore from "redux-mock-store"; import I18n from "../../../../i18n"; import NavigationService from "../../../../navigation/NavigationService"; +import ROUTES from "../../../../navigation/routes"; import { applicationChangeState } from "../../../../store/actions/application"; import { appReducer } from "../../../../store/reducers"; import { GlobalState } from "../../../../store/reducers/types"; @@ -78,9 +79,19 @@ describe("Test EUCovidCertificateValidScreen", () => { if (detailsButton) { fireEvent.press(detailsButton); const detailsPayload: NavigationAction = { - type: "Navigation/NAVIGATE", - routeName: "EUCOVIDCERT_MARKDOWN_DETAILS", - params: { markdownDetails: "markdownDetails" } + type: "NAVIGATE", + payload: { + name: ROUTES.MESSAGES_NAVIGATOR, + params: { + screen: EUCOVIDCERT_ROUTES.MAIN, + params: { + screen: EUCOVIDCERT_ROUTES.MARKDOWN_DETAILS, + params: { + markdownDetails: "markdownDetails" + } + } + } + } }; expect(spy).toHaveBeenCalledWith(detailsPayload); } @@ -88,12 +99,20 @@ describe("Test EUCovidCertificateValidScreen", () => { if (qrCodeTouchable) { fireEvent.press(qrCodeTouchable); const qrCodePayload: NavigationAction = { - params: { - qrCodeContent: - "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQAAAABRBrPYAAAHWElEQVR42u2aPY6kSBSEH8LAgwsgcQ28vBJcAIoLwJXw8hpIXAA8DETuF9Rs1Yyx0q5Eap0etUqoKlqT/X4i4r0sC//m32Y/sB/YD+w/wk6z6mXrfljjqldmVldDKHNLpzkM3iyLAutDtdVnY0syp8NRTUeY9GbZ+8VcFXwUWJNVV12FucxrS8LSOUuO6uXOJPBTJrFgen5l6ZiFaSYa1tXEZ+l9GF08WDXW6VWHYbb2WK96nWYr+HQOe4gFI+CdS0c7u4wyKJts0UNN9tfxj2Q9CeOj1v/Tz+9l+SAsKCZGyVmeKSMNtZdxznWsjUT81oBPwoZQDfNS+Ooyaz3xWUcejrKd0xDSKQrszOslOdbhUHkXgY/KPiyNC7vneSniwPTpwePZzisYs3A561XqS3tUYxYF1s+QxmJ1uDIFJAl0NzEJWxY2t+QuBizss4r8Vac7ccjSwadbprB0mYHZosBOy8TPRbDGSgXBQ85nEeCupQ+RYGHMrHNknziYuXXiAbqGuI4w1uuVRYER6kTBh7gWCnt0qw5ck5o0HDpeBBgcYrlKSwy5wxszH6XSPqPjwsvFgKEIa/CQJOLLG/AziahGW1r6GqUIUWB7SC9HAaQvW4qD8uaVGrB+rq6sCnFgKEKOHFhZzJAkOoj+VlNYd6+qG10U2E66a4NAqLfOzqZG9QjOSVjCQaCiwEZ3s6Un+Og7fJWGeR0C/Amhlb2PATsbZ7kRFhLNIavhgMFgFbmaxsHbUWCEYsuWHJthZ+EpdZhTEo9p3Oyr9c/CEo+7EBUPFLyRC+KTqsXCWRxLEgVGZ1HhSF46HXAIJGm9/KqkAYHYQxRYmBECOvp+h9TLXVQTjvGm68tFgWHCX6ptmogagCcVk7vFKMLqc7ZHYWLL4kDcq+l2qi+XYm9MXbZuZr2PAkPf6aaBds7INUVOUs7ccSr81dmGGLAw+ZK66mpSULYHVUedyyQXdLQvPwbjWdjIkZChwN+OY0xfruRIiS/7uwxaHwUW7uAPB3yFFN6jBw9ZuvOKOGZRYFQ4bipHj6g3d+bYchNz5mJR+i4G7OyP0mSMV5nVoNQXXvzcGVPtl6KfhWFpCopNY/vdvAcjLVYHxib7FgnW+zI5zgRD7kVcY33KvIWbq+07CDwKwz7BUSdWKtdSAp9cIk9MdgVzkMovBkzi3uKNa8Dh0uj6HthpN+p/+XT9szA0lxQ3lmJZC2QIo2hGiNBcy6q/KfphWCdLg+SplxG+nHlWHa2S48wWBcYox6SD6mEamXR4WOkmfosyCLdXjwCTLsCNuTZOJaTBwG523pOXjHqXRYHBhy/HuKqBa9CgtzSmiUC//ts+5FEYAUm3mhRLbZkoKbkAkygL91FdFNjL7uaShyEUDHfrbWY0Zt7aFAOG26dz+RQFTCfNsHjylOxfaGJYpzgwc/AVjVzCGEjSLlap9lkOFjVsfRRYckjmmKCTmYaio0+aC2Jp0NzjyyEPwzwSUCZBfthq6JFXTbJbLeouosDeWq+tCJHpbs29tV4eo/X2p8F4Csb/TiMzaxAZIk8ZMPLwvI41/PltwGdh/WzJvcQb8DMHcdA2jzKYVA/fsz0M8+QadRCNJDMDpt5JJIvyb32IAaPSpICdaZBMVG/VxszumNklvo2LAZMnx7Zh+y9V9fpC8fE5h7Z8PORZFBhUzMG2WoWXv4dleVQkqWzf6/coMFh6fe8i9hmTrIM1VonBqAQXAxZ2htaZ8zC6avaZPOqw7sySmdLRZTFgp9bOjMxak2rkGR0dLXIetEX8LsCfhVFgCrjHUDFEW4/yan6XM7/q79mehSWq82o/sMd4KsrAjMFZio/r+DquZ2FNVvZQVkAIUl0SHZIkSn2/zdvgY8CwNPRUNbo00E1aiTBH0+CaKCHqzkWBDRok6Skk6b5MCUsyL52RHS1hJh8HJmuBjaHC4StqgALQupJB3urwWZs8CjvvnWEFh2zyydgYYoIKk3cthz/19iyMbkLWrV43mUaYmbwwO1MMIszPnPUo7DZRs2aQzpEF+SjeJj7awBz22eY9CpPe4aBy/e2/umzLpPK75j4yEgMWJtiSGjt+lRwC1Gjc0+VgojuOKDCKbZClQXo4JyRGUujrdbPqytYrCgx7TLGh6erol260dYcyanWJdTy/CvgkjFwzBcAYHIOkv69sVl06MAfZ9zb2UZgcKUW132PsJPYom3p5bzKvuvqsmx6FaRmCFR9NE4dJg95jCGSyYNd3HwOmLwkUGqzwjdpracyZmT70i9rshRiw8P7CCbWtzpoXE2GeN3753ak+CtP3agZi7jV6iDF0w6uvCkBlu/9+B+NZmFbfby3IzkJcrXP28gAysW0c2E3LtJXGKxSBiQCnihyM2op/tgTPw166OGa4Iw7vJa3oer+J9JOFp2HKNSPApktVGKwKB2ajui8XPlr/MIwib3WDg9CnA2qryY5XbSzva50oMOrtUjdpqaVFIuV339PpguxIX1kM2M83/X5gP7D/C/YXGO1CDNeFmMoAAAAASUVORK5CYII=" - }, - routeName: "EUCOVIDCERT_QRCODE", - type: "Navigation/NAVIGATE" + type: "NAVIGATE", + payload: { + name: ROUTES.MESSAGES_NAVIGATOR, + params: { + screen: EUCOVIDCERT_ROUTES.MAIN, + params: { + screen: EUCOVIDCERT_ROUTES.QRCODE, + params: { + qrCodeContent: + "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQAAAABRBrPYAAAHWElEQVR42u2aPY6kSBSEH8LAgwsgcQ28vBJcAIoLwJXw8hpIXAA8DETuF9Rs1Yyx0q5Eap0etUqoKlqT/X4i4r0sC//m32Y/sB/YD+w/wk6z6mXrfljjqldmVldDKHNLpzkM3iyLAutDtdVnY0syp8NRTUeY9GbZ+8VcFXwUWJNVV12FucxrS8LSOUuO6uXOJPBTJrFgen5l6ZiFaSYa1tXEZ+l9GF08WDXW6VWHYbb2WK96nWYr+HQOe4gFI+CdS0c7u4wyKJts0UNN9tfxj2Q9CeOj1v/Tz+9l+SAsKCZGyVmeKSMNtZdxznWsjUT81oBPwoZQDfNS+Ooyaz3xWUcejrKd0xDSKQrszOslOdbhUHkXgY/KPiyNC7vneSniwPTpwePZzisYs3A561XqS3tUYxYF1s+QxmJ1uDIFJAl0NzEJWxY2t+QuBizss4r8Vac7ccjSwadbprB0mYHZosBOy8TPRbDGSgXBQ85nEeCupQ+RYGHMrHNknziYuXXiAbqGuI4w1uuVRYER6kTBh7gWCnt0qw5ck5o0HDpeBBgcYrlKSwy5wxszH6XSPqPjwsvFgKEIa/CQJOLLG/AziahGW1r6GqUIUWB7SC9HAaQvW4qD8uaVGrB+rq6sCnFgKEKOHFhZzJAkOoj+VlNYd6+qG10U2E66a4NAqLfOzqZG9QjOSVjCQaCiwEZ3s6Un+Og7fJWGeR0C/Amhlb2PATsbZ7kRFhLNIavhgMFgFbmaxsHbUWCEYsuWHJthZ+EpdZhTEo9p3Oyr9c/CEo+7EBUPFLyRC+KTqsXCWRxLEgVGZ1HhSF46HXAIJGm9/KqkAYHYQxRYmBECOvp+h9TLXVQTjvGm68tFgWHCX6ptmogagCcVk7vFKMLqc7ZHYWLL4kDcq+l2qi+XYm9MXbZuZr2PAkPf6aaBds7INUVOUs7ccSr81dmGGLAw+ZK66mpSULYHVUedyyQXdLQvPwbjWdjIkZChwN+OY0xfruRIiS/7uwxaHwUW7uAPB3yFFN6jBw9ZuvOKOGZRYFQ4bipHj6g3d+bYchNz5mJR+i4G7OyP0mSMV5nVoNQXXvzcGVPtl6KfhWFpCopNY/vdvAcjLVYHxib7FgnW+zI5zgRD7kVcY33KvIWbq+07CDwKwz7BUSdWKtdSAp9cIk9MdgVzkMovBkzi3uKNa8Dh0uj6HthpN+p/+XT9szA0lxQ3lmJZC2QIo2hGiNBcy6q/KfphWCdLg+SplxG+nHlWHa2S48wWBcYox6SD6mEamXR4WOkmfosyCLdXjwCTLsCNuTZOJaTBwG523pOXjHqXRYHBhy/HuKqBa9CgtzSmiUC//ts+5FEYAUm3mhRLbZkoKbkAkygL91FdFNjL7uaShyEUDHfrbWY0Zt7aFAOG26dz+RQFTCfNsHjylOxfaGJYpzgwc/AVjVzCGEjSLlap9lkOFjVsfRRYckjmmKCTmYaio0+aC2Jp0NzjyyEPwzwSUCZBfthq6JFXTbJbLeouosDeWq+tCJHpbs29tV4eo/X2p8F4Csb/TiMzaxAZIk8ZMPLwvI41/PltwGdh/WzJvcQb8DMHcdA2jzKYVA/fsz0M8+QadRCNJDMDpt5JJIvyb32IAaPSpICdaZBMVG/VxszumNklvo2LAZMnx7Zh+y9V9fpC8fE5h7Z8PORZFBhUzMG2WoWXv4dleVQkqWzf6/coMFh6fe8i9hmTrIM1VonBqAQXAxZ2htaZ8zC6avaZPOqw7sySmdLRZTFgp9bOjMxak2rkGR0dLXIetEX8LsCfhVFgCrjHUDFEW4/yan6XM7/q79mehSWq82o/sMd4KsrAjMFZio/r+DquZ2FNVvZQVkAIUl0SHZIkSn2/zdvgY8CwNPRUNbo00E1aiTBH0+CaKCHqzkWBDRok6Skk6b5MCUsyL52RHS1hJh8HJmuBjaHC4StqgALQupJB3urwWZs8CjvvnWEFh2zyydgYYoIKk3cthz/19iyMbkLWrV43mUaYmbwwO1MMIszPnPUo7DZRs2aQzpEF+SjeJj7awBz22eY9CpPe4aBy/e2/umzLpPK75j4yEgMWJtiSGjt+lRwC1Gjc0+VgojuOKDCKbZClQXo4JyRGUujrdbPqytYrCgx7TLGh6erol260dYcyanWJdTy/CvgkjFwzBcAYHIOkv69sVl06MAfZ9zb2UZgcKUW132PsJPYom3p5bzKvuvqsmx6FaRmCFR9NE4dJg95jCGSyYNd3HwOmLwkUGqzwjdpracyZmT70i9rshRiw8P7CCbWtzpoXE2GeN3753ak+CtP3agZi7jV6iDF0w6uvCkBlu/9+B+NZmFbfby3IzkJcrXP28gAysW0c2E3LtJXGKxSBiQCnihyM2op/tgTPw166OGa4Iw7vJa3oer+J9JOFp2HKNSPApktVGKwKB2ajui8XPlr/MIwib3WDg9CnA2qryY5XbSzva50oMOrtUjdpqaVFIuV339PpguxIX1kM2M83/X5gP7D/C/YXGO1CDNeFmMoAAAAASUVORK5CYII=" + } + } + } + } }; expect(spy).toHaveBeenCalledWith(qrCodePayload); } @@ -121,7 +140,7 @@ describe("Test EUCovidCertificateValidScreen", () => { }); const renderComponent = (store: Store, validCertificate: ValidCertificate) => ({ - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => ( { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); + const render = renderComponent(store); + navigateToEuCovidCertificateDetailScreen({ authCode, messageId: "messageId" }); - const render = renderComponent(store); - expect( render.component.queryByTestId("EuCovidCertLoadingScreen") ).not.toBeNull(); @@ -209,7 +208,7 @@ describe("Test EuCovidCertificateRouterScreen", () => { }); const renderComponent = (store: Store) => ({ - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( EuCovidCertificateRouterScreen, EUCOVIDCERT_ROUTES.CERTIFICATE, { authCode, messageId: "messageId" }, diff --git a/ts/features/euCovidCert/screens/ko/__tests__/EuCovidCertNotFoundKoScreen.test.tsx b/ts/features/euCovidCert/screens/ko/__tests__/EuCovidCertNotFoundKoScreen.test.tsx index 2570b56ab67..cf11236b568 100644 --- a/ts/features/euCovidCert/screens/ko/__tests__/EuCovidCertNotFoundKoScreen.test.tsx +++ b/ts/features/euCovidCert/screens/ko/__tests__/EuCovidCertNotFoundKoScreen.test.tsx @@ -1,6 +1,6 @@ import { fireEvent } from "@testing-library/react-native"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore } from "redux"; import i18n from "../../../../../i18n"; import * as mixpanelTrack from "../../../../../mixpanel"; @@ -79,7 +79,7 @@ const renderComponent = (state: GlobalState, withContext: boolean = true) => { ); - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( () => Component, EUCOVIDCERT_ROUTES.CERTIFICATE, {}, diff --git a/ts/features/euCovidCert/screens/ko/__tests__/EuCovidCertWrongFormatKoScreen.test.tsx b/ts/features/euCovidCert/screens/ko/__tests__/EuCovidCertWrongFormatKoScreen.test.tsx index 1ac30a02366..2bed4279c63 100644 --- a/ts/features/euCovidCert/screens/ko/__tests__/EuCovidCertWrongFormatKoScreen.test.tsx +++ b/ts/features/euCovidCert/screens/ko/__tests__/EuCovidCertWrongFormatKoScreen.test.tsx @@ -1,6 +1,6 @@ import { fireEvent } from "@testing-library/react-native"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore } from "redux"; import i18n from "../../../../../i18n"; import * as mixpanelTrack from "../../../../../mixpanel"; @@ -80,7 +80,7 @@ const renderComponent = (state: GlobalState, withContext: boolean = true) => { ); - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( () => Component, EUCOVIDCERT_ROUTES.CERTIFICATE, {}, diff --git a/ts/features/euCovidCert/screens/valid/EuCovidCertMarkdownDetailsScreen.tsx b/ts/features/euCovidCert/screens/valid/EuCovidCertMarkdownDetailsScreen.tsx index 49f0b82f7a8..08832fde323 100644 --- a/ts/features/euCovidCert/screens/valid/EuCovidCertMarkdownDetailsScreen.tsx +++ b/ts/features/euCovidCert/screens/valid/EuCovidCertMarkdownDetailsScreen.tsx @@ -1,8 +1,8 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { View } from "native-base"; import * as React from "react"; import { useState } from "react"; import { SafeAreaView, ScrollView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import ButtonDefaultOpacity from "../../../../components/ButtonDefaultOpacity"; import { Label } from "../../../../components/core/typography/Label"; import { IOStyles } from "../../../../components/core/variables/IOStyles"; @@ -10,6 +10,7 @@ import BaseScreenComponent from "../../../../components/screens/BaseScreenCompon import FooterWithButtons from "../../../../components/ui/FooterWithButtons"; import I18n from "../../../../i18n"; import { mixpanelTrack } from "../../../../mixpanel"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; import { showToast } from "../../../../utils/showToast"; import { cancelButtonProps } from "../../../bonus/bonusVacanze/components/buttons/ButtonConfigurations"; @@ -18,6 +19,7 @@ import { FlashAnimationState } from "../../components/FlashAnimatedComponent"; import { MarkdownHandleCustomLink } from "../../components/MarkdownHandleCustomLink"; +import { EUCovidCertParamsList } from "../../navigation/params"; import { captureScreenshot, screenshotOptions } from "../../utils/screenshot"; export type EuCovidCertMarkdownDetailsScreenNavigationParams = Readonly<{ @@ -37,9 +39,11 @@ const styles = StyleSheet.create({ const showToastError = (error: string = I18n.t("global.genericError")) => showToast(error); -export const EuCovidCertMarkdownDetailsScreen = ( - props: NavigationStackScreenProps -): React.ReactElement => { +export const EuCovidCertMarkdownDetailsScreen = (props: { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}): React.ReactElement => { const [loadMarkdownComplete, setLoadMarkdownComplete] = useState(false); const [isCapturingScreenShoot, setIsCapturingScreenShoot] = useState(false); const [flashAnimationState, setFlashAnimationState] = diff --git a/ts/features/euCovidCert/screens/valid/EuCovidCertQrCodeFullScreen.tsx b/ts/features/euCovidCert/screens/valid/EuCovidCertQrCodeFullScreen.tsx index ed02ca516a7..95d44135ab1 100644 --- a/ts/features/euCovidCert/screens/valid/EuCovidCertQrCodeFullScreen.tsx +++ b/ts/features/euCovidCert/screens/valid/EuCovidCertQrCodeFullScreen.tsx @@ -1,3 +1,4 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { View } from "native-base"; import * as React from "react"; import { @@ -7,14 +8,15 @@ import { ScrollView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { IOStyles } from "../../../../components/core/variables/IOStyles"; import BaseScreenComponent from "../../../../components/screens/BaseScreenComponent"; import FooterWithButtons from "../../../../components/ui/FooterWithButtons"; import I18n from "../../../../i18n"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; import { useMaxBrightness } from "../../../../utils/brightness"; import { withBase64Uri } from "../../../../utils/image"; import { cancelButtonProps } from "../../../bonus/bonusVacanze/components/buttons/ButtonConfigurations"; +import { EUCovidCertParamsList } from "../../navigation/params"; export type EuCovidCertQrCodeFullScreenNavigationParams = Readonly<{ qrCodeContent: string; @@ -29,9 +31,11 @@ const styles = StyleSheet.create({ } }); -export const EuCovidCertQrCodeFullScreen = ( - props: NavigationStackScreenProps -): React.ReactElement => { +export const EuCovidCertQrCodeFullScreen = (props: { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}): React.ReactElement => { useMaxBrightness(); return ( diff --git a/ts/features/mvl/navigation/actions.ts b/ts/features/mvl/navigation/actions.ts index ffce988d72c..2dd7470557b 100644 --- a/ts/features/mvl/navigation/actions.ts +++ b/ts/features/mvl/navigation/actions.ts @@ -1,26 +1,39 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; +import ROUTES from "../../../navigation/routes"; import { MvlRouterScreenNavigationParams } from "../screens/MvlRouterScreen"; import MVL_ROUTES from "./routes"; export const navigateToMvlDetailsScreen = ( params: MvlRouterScreenNavigationParams ) => - NavigationActions.navigate({ - routeName: MVL_ROUTES.DETAILS, - params + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: MVL_ROUTES.MAIN, + params: { + screen: MVL_ROUTES.DETAILS, + params + } }); export const navigateToMvlCertificatesScreen = () => - NavigationActions.navigate({ - routeName: MVL_ROUTES.CERTIFICATES + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: MVL_ROUTES.MAIN, + params: { + screen: MVL_ROUTES.CERTIFICATES + } }); export const navigateToMvlRecipientsScreen = () => - NavigationActions.navigate({ - routeName: MVL_ROUTES.RECIPIENTS + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: MVL_ROUTES.MAIN, + params: { + screen: MVL_ROUTES.RECIPIENTS + } }); export const navigateToMvlSignatureScreen = () => - NavigationActions.navigate({ - routeName: MVL_ROUTES.SIGNATURE + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: MVL_ROUTES.MAIN, + params: { + screen: MVL_ROUTES.SIGNATURE + } }); diff --git a/ts/features/mvl/navigation/navigator.ts b/ts/features/mvl/navigation/navigator.ts index aedcde9fe1f..9c18809b66f 100644 --- a/ts/features/mvl/navigation/navigator.ts +++ b/ts/features/mvl/navigation/navigator.ts @@ -1,11 +1,12 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import { MvlCertificatesScreen } from "../screens/metadata/MvlCertificatesScreen"; import { MvlRecipientsScreen } from "../screens/metadata/MvlRecipientsScreen"; import { MvlSignatureScreen } from "../screens/metadata/MvlSignatureScreen"; import { MvlRouterScreen } from "../screens/MvlRouterScreen"; import MVL_ROUTES from "./routes"; -const MvlNavigator = createStackNavigator( +const MvlNavigator = createCompatNavigatorFactory(createStackNavigator)( { [MVL_ROUTES.DETAILS]: { screen: MvlRouterScreen @@ -24,7 +25,7 @@ const MvlNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/mvl/screens/MvlRouterScreen.tsx b/ts/features/mvl/screens/MvlRouterScreen.tsx index c8bde04c0f1..c4624d741c8 100644 --- a/ts/features/mvl/screens/MvlRouterScreen.tsx +++ b/ts/features/mvl/screens/MvlRouterScreen.tsx @@ -1,12 +1,14 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; +import { usePaginatedMessages } from "../../../config"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; import { DEPRECATED_setMessageReadState } from "../../../store/actions/messages"; import { useIODispatch, useIOSelector } from "../../../store/hooks"; import { isMessageRead } from "../../../store/reducers/entities/messages/messagesStatus"; import { UIMessageId } from "../../../store/reducers/entities/messages/types"; import { useOnFirstRender } from "../../../utils/hooks/useOnFirstRender"; -import { usePaginatedMessages } from "../../../config"; +import { MvlParamsList } from "../navigation/params"; import { mvlDetailsLoad } from "../store/actions"; import { mvlFromIdSelector } from "../store/reducers/byId"; import { Mvl } from "../types/mvlData"; @@ -44,9 +46,11 @@ const renderByPot = ( * @constructor * @param props */ -export const MvlRouterScreen = ( - props: NavigationStackScreenProps -): React.ReactElement => { +export const MvlRouterScreen = (props: { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}): React.ReactElement => { const mvlId = props.navigation.getParam("id"); const mvlPot = useIOSelector(state => mvlFromIdSelector(state, mvlId)); const dispatch = useIODispatch(); diff --git a/ts/features/mvl/screens/__test__/MvlRouterScreen.test.tsx b/ts/features/mvl/screens/__test__/MvlRouterScreen.test.tsx index e00c8caac2e..0460b2c6b53 100644 --- a/ts/features/mvl/screens/__test__/MvlRouterScreen.test.tsx +++ b/ts/features/mvl/screens/__test__/MvlRouterScreen.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import { createStore, Store } from "redux"; import configureMockStore, { MockStore } from "redux-mock-store"; import { applicationChangeState } from "../../../../store/actions/application"; @@ -155,7 +154,7 @@ const dispatchActionAndRenderComponent = (actions: ReadonlyArray) => { }; const renderComponent = (store: MockStore | Store) => ({ - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( MvlRouterScreen, MVL_ROUTES.DETAILS, { id: mvlMockId }, diff --git a/ts/features/mvl/screens/details/components/attachment/__test__/MvlAttachments.test.tsx b/ts/features/mvl/screens/details/components/attachment/__test__/MvlAttachments.test.tsx index 27928bd695c..039778a5b7d 100644 --- a/ts/features/mvl/screens/details/components/attachment/__test__/MvlAttachments.test.tsx +++ b/ts/features/mvl/screens/details/components/attachment/__test__/MvlAttachments.test.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore } from "redux"; import { fireEvent } from "@testing-library/react-native"; import I18n from "../../../../../../../i18n"; @@ -159,7 +159,7 @@ const renderComponent = ( mvl: { ...globalState.features.mvl, preferences: mvlPreferences } } } as any); - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( () => , MVL_ROUTES.DETAILS, {}, diff --git a/ts/features/uaDonations/components/__test__/UaDonationsBanner.test.tsx b/ts/features/uaDonations/components/__test__/UaDonationsBanner.test.tsx index 82e926025d3..f92d629493c 100644 --- a/ts/features/uaDonations/components/__test__/UaDonationsBanner.test.tsx +++ b/ts/features/uaDonations/components/__test__/UaDonationsBanner.test.tsx @@ -1,5 +1,5 @@ // import React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore, Store } from "redux"; import { MockStore } from "redux-mock-store"; import ROUTES from "../../../../navigation/routes"; @@ -138,7 +138,7 @@ describe("UaDonationsBanner", () => { }); const renderComponent = (store: MockStore | Store) => ({ - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( UaDonationsBanner, ROUTES.MESSAGES_HOME, {}, diff --git a/ts/features/uaDonations/navigation/navigator.ts b/ts/features/uaDonations/navigation/navigator.ts deleted file mode 100644 index c9fd40ef748..00000000000 --- a/ts/features/uaDonations/navigation/navigator.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { createStackNavigator } from "react-navigation-stack"; -import { UAWebViewScreen } from "../screens/UAWebViewScreen"; -import UADONATION_ROUTES from "./routes"; - -const UADonationNavigator = createStackNavigator( - { - [UADONATION_ROUTES.WEBVIEW]: { - screen: UAWebViewScreen - } - }, - { - // Let each screen handle the header and navigation - headerMode: "none", - defaultNavigationOptions: { - gesturesEnabled: false - } - } -); - -export default UADonationNavigator; diff --git a/ts/features/uaDonations/screens/UAWebViewScreen.tsx b/ts/features/uaDonations/screens/UAWebViewScreen.tsx index 7165060bcaa..64c4875e657 100644 --- a/ts/features/uaDonations/screens/UAWebViewScreen.tsx +++ b/ts/features/uaDonations/screens/UAWebViewScreen.tsx @@ -1,38 +1,42 @@ -import WebView from "react-native-webview"; -import React, { useEffect, useState } from "react"; -import { SafeAreaView, StyleSheet } from "react-native"; -import { WebViewMessageEvent } from "react-native-webview/lib/WebViewTypes"; -import { View } from "native-base"; -import URLParse from "url-parse"; -import { readableReport } from "@pagopa/ts-commons/lib/reporters"; import { AmountInEuroCents, PaymentNoticeNumber, PaymentNoticeNumberFromString, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { readableReport } from "@pagopa/ts-commons/lib/reporters"; +import { useNavigation } from "@react-navigation/native"; +import { View } from "native-base"; +import React, { useEffect, useState } from "react"; +import { SafeAreaView, StyleSheet } from "react-native"; +import WebView from "react-native-webview"; +import { WebViewMessageEvent } from "react-native-webview/lib/WebViewTypes"; +import URLParse from "url-parse"; +import dataErrorImage from "../../../../img/pictograms/doubt.png"; +import genericErrorImage from "../../../../img/wallet/errors/generic-error-icon.png"; import { IOStyles } from "../../../components/core/variables/IOStyles"; +import { renderInfoRasterImage } from "../../../components/infoScreen/imageRendering"; +import { InfoScreenComponent } from "../../../components/infoScreen/InfoScreenComponent"; import BaseScreenComponent from "../../../components/screens/BaseScreenComponent"; +import { BlockButtonProps } from "../../../components/ui/BlockButtons"; +import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import { RefreshIndicator } from "../../../components/ui/RefreshIndicator"; import I18n from "../../../i18n"; +import { mixpanelTrack } from "../../../mixpanel"; +import { + AppParamsList, + IOStackNavigationProp +} from "../../../navigation/params/AppParamsList"; +import { navigateToPaymentTransactionSummaryScreen } from "../../../store/actions/navigation"; import { paymentInitializeState } from "../../../store/actions/wallet/payment"; import { useIODispatch, useIOSelector } from "../../../store/hooks"; +import { internalRouteNavigationParamsSelector } from "../../../store/reducers/internalRouteNavigation"; +import { emptyContextualHelp } from "../../../utils/emptyContextualHelp"; +import { showToast } from "../../../utils/showToast"; import { isStringNullyOrEmpty } from "../../../utils/strings"; import { isHttp, openWebUrl } from "../../../utils/url"; -import { navigateToPaymentTransactionSummaryScreen } from "../../../store/actions/navigation"; -import { showToast } from "../../../utils/showToast"; -import { InfoScreenComponent } from "../../../components/infoScreen/InfoScreenComponent"; -import { renderInfoRasterImage } from "../../../components/infoScreen/imageRendering"; -import genericErrorImage from "../../../../img/wallet/errors/generic-error-icon.png"; -import dataErrorImage from "../../../../img/pictograms/doubt.png"; -import FooterWithButtons from "../../../components/ui/FooterWithButtons"; -import { BlockButtonProps } from "../../../components/ui/BlockButtons"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; -import { emptyContextualHelp } from "../../../utils/emptyContextualHelp"; -import { UADonationWebViewMessage } from "../types"; -import { mixpanelTrack } from "../../../mixpanel"; import { AVOID_ZOOM_JS, closeInjectedScript } from "../../../utils/webview"; -import { internalRouteNavigationParamsSelector } from "../../../store/reducers/internalRouteNavigation"; +import { UADonationWebViewMessage } from "../types"; const styles = StyleSheet.create({ loading: { @@ -169,7 +173,7 @@ const injectedJavascript = closeInjectedScript(AVOID_ZOOM_JS); */ export const UAWebViewScreen = () => { const navigationParams = useIOSelector(internalRouteNavigationParamsSelector); - const navigation = useNavigationContext(); + const navigation = useNavigation>(); const dispatch = useIODispatch(); const uri = navigationParams?.urlToLoad; const ref = React.createRef(); @@ -201,8 +205,7 @@ export const UAWebViewScreen = () => { navigateToPaymentTransactionSummaryScreen({ rptId, initialAmount, - paymentStartOrigin: "donation", - startRoute: undefined + paymentStartOrigin: "donation" }); }; @@ -238,7 +241,7 @@ export const UAWebViewScreen = () => { )} errorText={I18n.t("wallet.errors.GENERIC_ERROR")} onRetry={() => { - navigation.goBack(null); + navigation.goBack(); }} /> ); diff --git a/ts/features/wallet/bancomat/screen/BancomatDetailScreen.tsx b/ts/features/wallet/bancomat/screen/BancomatDetailScreen.tsx index 76d3de07d28..f3c2888486a 100644 --- a/ts/features/wallet/bancomat/screen/BancomatDetailScreen.tsx +++ b/ts/features/wallet/bancomat/screen/BancomatDetailScreen.tsx @@ -1,11 +1,13 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { View } from "native-base"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import ItemSeparatorComponent from "../../../../components/ItemSeparatorComponent"; import I18n from "../../../../i18n"; import { mixpanelTrack } from "../../../../mixpanel"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../navigation/params/WalletParamsList"; import { GlobalState } from "../../../../store/reducers/types"; import { BancomatPaymentMethod } from "../../../../types/pagopa"; import { showToast } from "../../../../utils/showToast"; @@ -21,8 +23,11 @@ export type BancomatDetailScreenNavigationParams = Readonly<{ }>; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; /** * Start the cobadge onboarding, if the abi is defined diff --git a/ts/features/wallet/bancomatpay/component/__test__/BPayWalletPreview.test.tsx b/ts/features/wallet/bancomatpay/component/__test__/BPayWalletPreview.test.tsx index dfcf82210d1..878543ef540 100644 --- a/ts/features/wallet/bancomatpay/component/__test__/BPayWalletPreview.test.tsx +++ b/ts/features/wallet/bancomatpay/component/__test__/BPayWalletPreview.test.tsx @@ -1,13 +1,13 @@ -import { fireEvent, render } from "@testing-library/react-native"; +import { CommonActions } from "@react-navigation/native"; +import { fireEvent } from "@testing-library/react-native"; import { none, some } from "fp-ts/lib/Option"; import * as React from "react"; -import { NavigationActions } from "react-navigation"; -import { Provider } from "react-redux"; import { Store } from "redux"; import configureMockStore from "redux-mock-store"; import NavigationService from "../../../../../navigation/NavigationService"; import ROUTES from "../../../../../navigation/routes"; import { BPayPaymentMethod } from "../../../../../types/pagopa"; +import { renderScreenFakeNavRedux } from "../../../../../utils/testWrapper"; import * as hooks from "../../../onboarding/bancomat/screens/hooks/useImageResize"; import BPayWalletPreview from "../BPayWalletPreview"; @@ -91,8 +91,8 @@ describe("BPayWalletPreview component", () => { if (cardComponent) { fireEvent.press(cardComponent); expect(spy).toHaveBeenCalledWith( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_BPAY_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_BPAY_DETAIL, params: { bPay: aBPay } }) ); @@ -101,8 +101,9 @@ describe("BPayWalletPreview component", () => { }); const getComponent = (bPay: BPayPaymentMethod, store: Store) => - render( - - - + renderScreenFakeNavRedux( + () => , + "WALLET_HOME", + {}, + store ); diff --git a/ts/features/wallet/bancomatpay/screen/BPayDetailScreen.tsx b/ts/features/wallet/bancomatpay/screen/BPayDetailScreen.tsx index d198b4dd1df..d19a81b5623 100644 --- a/ts/features/wallet/bancomatpay/screen/BPayDetailScreen.tsx +++ b/ts/features/wallet/bancomatpay/screen/BPayDetailScreen.tsx @@ -1,7 +1,9 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../navigation/params/WalletParamsList"; import { GlobalState } from "../../../../store/reducers/types"; import { BPayPaymentMethod } from "../../../../types/pagopa"; import BasePaymentMethodScreen from "../../common/BasePaymentMethodScreen"; @@ -14,8 +16,11 @@ export type BPayDetailScreenNavigationParams = Readonly<{ }>; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; /** * Detail screen for a Bancomat Pay diff --git a/ts/features/wallet/cobadge/component/__tests__/CobadgeWalletPreview.test.tsx b/ts/features/wallet/cobadge/component/__tests__/CobadgeWalletPreview.test.tsx index bcf4390fd53..0dc87683499 100644 --- a/ts/features/wallet/cobadge/component/__tests__/CobadgeWalletPreview.test.tsx +++ b/ts/features/wallet/cobadge/component/__tests__/CobadgeWalletPreview.test.tsx @@ -1,15 +1,15 @@ -import { render, fireEvent } from "@testing-library/react-native"; +import { NavigationAction } from "@react-navigation/native"; +import { fireEvent } from "@testing-library/react-native"; +import { none, some } from "fp-ts/lib/Option"; import * as React from "react"; import { Store } from "redux"; -import { Provider } from "react-redux"; -import { NavigationAction, NavigationActions } from "react-navigation"; import configureMockStore from "redux-mock-store"; -import { none, some } from "fp-ts/lib/Option"; import NavigationService from "../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../navigation/routes"; import { CreditCardPaymentMethod } from "../../../../../types/pagopa"; -import CobadgeWalletPreview from "../CobadgeWalletPreview"; +import { renderScreenFakeNavRedux } from "../../../../../utils/testWrapper"; import * as hooks from "../../../onboarding/bancomat/screens/hooks/useImageResize"; -import ROUTES from "../../../../../navigation/routes"; +import CobadgeWalletPreview from "../CobadgeWalletPreview"; jest.mock("../../../onboarding/bancomat/screens/hooks/useImageResize"); describe("CobadgeWalletPreview component", () => { @@ -136,10 +136,15 @@ describe("CobadgeWalletPreview component", () => { const component = getComponent(aCobadgeCard, store); const cardComponent = component.queryByTestId("cardPreview"); const expectedPayload: NavigationAction = { - type: NavigationActions.NAVIGATE, - routeName: ROUTES.WALLET_COBADGE_DETAIL, - params: { - cobadge: aCobadgeCard + type: "NAVIGATE", + payload: { + name: ROUTES.WALLET_NAVIGATOR, + params: { + screen: ROUTES.WALLET_COBADGE_DETAIL, + params: { + cobadge: aCobadgeCard + } + } } }; if (cardComponent) { @@ -153,8 +158,9 @@ const getComponent = ( cobadge: CreditCardPaymentMethod, store: Store ) => - render( - - - + renderScreenFakeNavRedux( + () => , + "WALLET_HOME", + {}, + store ); diff --git a/ts/features/wallet/cobadge/screen/CobadgeDetailScreen.tsx b/ts/features/wallet/cobadge/screen/CobadgeDetailScreen.tsx index 7977d749e9d..a28ada7b68b 100644 --- a/ts/features/wallet/cobadge/screen/CobadgeDetailScreen.tsx +++ b/ts/features/wallet/cobadge/screen/CobadgeDetailScreen.tsx @@ -1,7 +1,9 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../navigation/params/WalletParamsList"; import { GlobalState } from "../../../../store/reducers/types"; import { CreditCardPaymentMethod } from "../../../../types/pagopa"; import BasePaymentMethodScreen from "../../common/BasePaymentMethodScreen"; @@ -14,8 +16,11 @@ export type CobadgeDetailScreenNavigationParams = Readonly<{ }>; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; /** * Detail screen for a cobadge card diff --git a/ts/features/wallet/component/__test__/PagoPaPaymentCapability.test.tsx b/ts/features/wallet/component/__test__/PagoPaPaymentCapability.test.tsx index 6e32353ff44..ec5105995e0 100644 --- a/ts/features/wallet/component/__test__/PagoPaPaymentCapability.test.tsx +++ b/ts/features/wallet/component/__test__/PagoPaPaymentCapability.test.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore } from "redux"; import { TypeEnum } from "../../../../../definitions/pagopa/walletv2/CardInfo"; import ROUTES from "../../../../navigation/routes"; @@ -49,10 +49,7 @@ describe("PagoPaPaymentCapability", () => { const store = createStore(appReducer, globalState as any); store.dispatch(fetchWalletsSuccess(updatedMethods)); - const testComponent = renderScreenFakeNavRedux< - GlobalState, - NavigationParams - >( + const testComponent = renderScreenFakeNavRedux( () => , ROUTES.WALLET_HOME, {}, @@ -73,7 +70,7 @@ describe("PagoPaPaymentCapability", () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_HOME, {}, @@ -93,7 +90,7 @@ describe("PagoPaPaymentCapability", () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_HOME, {}, @@ -114,7 +111,7 @@ describe("PagoPaPaymentCapability", () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_HOME, {}, @@ -141,7 +138,7 @@ describe("PagoPaPaymentCapability", () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_HOME, {}, @@ -167,7 +164,7 @@ describe("PagoPaPaymentCapability", () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); - const component = renderScreenFakeNavRedux( + const component = renderScreenFakeNavRedux( () => , ROUTES.WALLET_HOME, {}, diff --git a/ts/features/wallet/component/__test__/PaymentMethodCapability.test.tsx b/ts/features/wallet/component/__test__/PaymentMethodCapability.test.tsx index 159a1ce0ae4..8996ab33ad0 100644 --- a/ts/features/wallet/component/__test__/PaymentMethodCapability.test.tsx +++ b/ts/features/wallet/component/__test__/PaymentMethodCapability.test.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore } from "redux"; import { BackendStatus } from "../../../../../definitions/content/BackendStatus"; import ROUTES from "../../../../navigation/routes"; @@ -68,7 +68,7 @@ describe("Test for PaymentMethodCapabilities", () => { const renderComponent = (state: GlobalState, paymentMethod: PaymentMethod) => { const store = createStore(appReducer, state as any); - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( () => , ROUTES.WALLET_BANCOMAT_DETAIL, {}, diff --git a/ts/features/wallet/creditCard/screen/CreditCardDetailScreen.tsx b/ts/features/wallet/creditCard/screen/CreditCardDetailScreen.tsx index 714f6dca91f..1a6016eb876 100644 --- a/ts/features/wallet/creditCard/screen/CreditCardDetailScreen.tsx +++ b/ts/features/wallet/creditCard/screen/CreditCardDetailScreen.tsx @@ -1,8 +1,10 @@ +import { CompatNavigationProp } from "@react-navigation/compat/src/types"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import WorkunitGenericFailure from "../../../../components/error/WorkunitGenericFailure"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../navigation/params/WalletParamsList"; import { GlobalState } from "../../../../store/reducers/types"; import { creditCardByIdSelector } from "../../../../store/reducers/wallet/wallets"; import { CreditCardPaymentMethod } from "../../../../types/pagopa"; @@ -16,8 +18,11 @@ export type CreditCardDetailScreenNavigationParams = Readonly<{ }>; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; /** * Detail screen for a credit card diff --git a/ts/features/wallet/creditCard/screen/__tests__/CreditCardDetailScreen.test.tsx b/ts/features/wallet/creditCard/screen/__tests__/CreditCardDetailScreen.test.tsx index 3acdf864142..56540440fa4 100644 --- a/ts/features/wallet/creditCard/screen/__tests__/CreditCardDetailScreen.test.tsx +++ b/ts/features/wallet/creditCard/screen/__tests__/CreditCardDetailScreen.test.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { createStore, Store } from "redux"; import { TypeEnum } from "../../../../../../definitions/pagopa/walletv2/CardInfo"; import { WalletTypeEnum } from "../../../../../../definitions/pagopa/WalletV2"; @@ -119,7 +119,7 @@ const renderDetailScreen = ( store: Store, creditCard: CreditCardPaymentMethod ) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( CreditCardWrapper, ROUTES.WALLET_CREDIT_CARD_DETAIL, { creditCard }, diff --git a/ts/features/wallet/onboarding/bancomat/navigation/action.ts b/ts/features/wallet/onboarding/bancomat/navigation/action.ts index 56cdf61ecc1..e076f86b709 100644 --- a/ts/features/wallet/onboarding/bancomat/navigation/action.ts +++ b/ts/features/wallet/onboarding/bancomat/navigation/action.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../navigation/routes"; import { ActivateBpdOnNewCreditCardScreenNavigationParams } from "../../common/screens/bpd/ActivateBpdOnNewCreditCardScreen"; import WALLET_ONBOARDING_BANCOMAT_ROUTES from "./routes"; @@ -8,8 +9,11 @@ import WALLET_ONBOARDING_BANCOMAT_ROUTES from "./routes"; */ export const navigateToOnboardingBancomatSearchStartScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BANCOMAT_ROUTES.BANCOMAT_START + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.BANCOMAT_START + } }) ); @@ -18,8 +22,11 @@ export const navigateToOnboardingBancomatSearchStartScreen = () => */ export const navigateToOnboardingBancomatChooseBank = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BANCOMAT_ROUTES.CHOOSE_BANK + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.CHOOSE_BANK + } }) ); @@ -28,9 +35,11 @@ export const navigateToOnboardingBancomatChooseBank = () => */ export const navigateToOnboardingBancomatSearchAvailableUserBancomat = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: - WALLET_ONBOARDING_BANCOMAT_ROUTES.SEARCH_AVAILABLE_USER_BANCOMAT + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.SEARCH_AVAILABLE_USER_BANCOMAT + } }) ); @@ -39,8 +48,11 @@ export const navigateToOnboardingBancomatSearchAvailableUserBancomat = () => */ export const navigateToSuggestBpdActivation = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BANCOMAT_ROUTES.SUGGEST_BPD_ACTIVATION + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.SUGGEST_BPD_ACTIVATION + } }) ); @@ -49,8 +61,11 @@ export const navigateToSuggestBpdActivation = () => */ export const navigateToActivateBpdOnNewBancomat = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BANCOMAT_ROUTES.ACTIVATE_BPD_NEW_BANCOMAT + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.ACTIVATE_BPD_NEW_BANCOMAT + } }) ); @@ -61,8 +76,11 @@ export const navigateToActivateBpdOnNewCreditCard = ( params: ActivateBpdOnNewCreditCardScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BANCOMAT_ROUTES.ACTIVATE_BPD_NEW_CREDIT_CARD, - params + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BANCOMAT_ROUTES.ACTIVATE_BPD_NEW_CREDIT_CARD, + params + } }) ); diff --git a/ts/features/wallet/onboarding/bancomat/navigation/navigator.ts b/ts/features/wallet/onboarding/bancomat/navigation/navigator.ts index f7c9861e5a3..0684c9c7960 100644 --- a/ts/features/wallet/onboarding/bancomat/navigation/navigator.ts +++ b/ts/features/wallet/onboarding/bancomat/navigation/navigator.ts @@ -1,11 +1,14 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import SuggestBpdActivationScreen from "../../common/screens/bpd/SuggestBpdActivationScreen"; import BancomatSearchBankScreen from "../screens/search/BancomatSearchBankScreen"; import BancomatSearchStartScreen from "../screens/search/BancomatSearchStartScreen"; import SearchAvailableUserBancomatScreen from "../screens/searchBancomat/SearchAvailableUserBancomatScreen"; import WALLET_ONBOARDING_BANCOMAT_ROUTES from "./routes"; -const PaymentMethodOnboardingBancomatNavigator = createStackNavigator( +const PaymentMethodOnboardingBancomatNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [WALLET_ONBOARDING_BANCOMAT_ROUTES.BANCOMAT_START]: { screen: BancomatSearchStartScreen @@ -24,7 +27,7 @@ const PaymentMethodOnboardingBancomatNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/wallet/onboarding/bancomatPay/navigation/action.ts b/ts/features/wallet/onboarding/bancomatPay/navigation/action.ts index 88ffd3501cb..ea272d96f02 100644 --- a/ts/features/wallet/onboarding/bancomatPay/navigation/action.ts +++ b/ts/features/wallet/onboarding/bancomatPay/navigation/action.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../navigation/routes"; import WALLET_ONBOARDING_BPAY_ROUTES from "./routes"; /** @@ -8,8 +9,11 @@ import WALLET_ONBOARDING_BPAY_ROUTES from "./routes"; */ export const navigateToOnboardingBPaySearchStartScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BPAY_ROUTES.START + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BPAY_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BPAY_ROUTES.START + } }) ); @@ -19,8 +23,11 @@ export const navigateToOnboardingBPaySearchStartScreen = () => */ export const navigateToOnboardingBPayChooseBank = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BPAY_ROUTES.CHOOSE_BANK + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BPAY_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BPAY_ROUTES.CHOOSE_BANK + } }) ); @@ -30,8 +37,11 @@ export const navigateToOnboardingBPayChooseBank = () => */ export const navigateToOnboardingBPaySearchAvailableUserAccount = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BPAY_ROUTES.SEARCH_AVAILABLE_USER_ACCOUNT + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BPAY_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BPAY_ROUTES.SEARCH_AVAILABLE_USER_ACCOUNT + } }) ); @@ -41,7 +51,10 @@ export const navigateToOnboardingBPaySearchAvailableUserAccount = () => */ export const navigateToActivateBpdOnNewBPay = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_BPAY_ROUTES.ACTIVATE_BPD_NEW + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_BPAY_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_BPAY_ROUTES.ACTIVATE_BPD_NEW + } }) ); diff --git a/ts/features/wallet/onboarding/bancomatPay/navigation/navigator.ts b/ts/features/wallet/onboarding/bancomatPay/navigation/navigator.ts index 4da80ca1970..0c81afb9a55 100644 --- a/ts/features/wallet/onboarding/bancomatPay/navigation/navigator.ts +++ b/ts/features/wallet/onboarding/bancomatPay/navigation/navigator.ts @@ -1,10 +1,13 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import BPaySearchBankScreen from "../screens/search/BPaySearchBankScreen"; import BPaySearchStartScreen from "../screens/search/BPaySearchStartScreen"; import SearchAvailableUserBPayScreen from "../screens/searchBPay/SearchAvailableUserBPayScreen"; import WALLET_ONBOARDING_BPAY_ROUTES from "./routes"; -const PaymentMethodOnboardingBPayNavigator = createStackNavigator( +const PaymentMethodOnboardingBPayNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [WALLET_ONBOARDING_BPAY_ROUTES.START]: { screen: BPaySearchStartScreen @@ -20,7 +23,7 @@ const PaymentMethodOnboardingBPayNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/wallet/onboarding/cobadge/navigation/action.ts b/ts/features/wallet/onboarding/cobadge/navigation/action.ts index fa1000e0774..b656a6aa6b6 100644 --- a/ts/features/wallet/onboarding/cobadge/navigation/action.ts +++ b/ts/features/wallet/onboarding/cobadge/navigation/action.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../navigation/routes"; import { CoBadgeChooseTypeNavigationProps } from "../screens/CoBadgeChooseType"; import WALLET_ONBOARDING_COBADGE_ROUTES from "./routes"; @@ -11,9 +12,12 @@ export const navigateToOnboardingCoBadgeChooseTypeStartScreen = ( navigationParams: CoBadgeChooseTypeNavigationProps ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_COBADGE_ROUTES.CHOOSE_TYPE, - params: navigationParams + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_COBADGE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_COBADGE_ROUTES.CHOOSE_TYPE, + params: navigationParams + } }) ); @@ -23,8 +27,11 @@ export const navigateToOnboardingCoBadgeChooseTypeStartScreen = ( */ export const navigateToOnboardingCoBadgeSearchStartScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_COBADGE_ROUTES.START + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_COBADGE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_COBADGE_ROUTES.START + } }) ); @@ -34,8 +41,11 @@ export const navigateToOnboardingCoBadgeSearchStartScreen = () => */ export const navigateToOnboardingCoBadgeSearchAvailable = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_COBADGE_ROUTES.SEARCH_AVAILABLE + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_COBADGE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_COBADGE_ROUTES.SEARCH_AVAILABLE + } }) ); @@ -45,7 +55,10 @@ export const navigateToOnboardingCoBadgeSearchAvailable = () => */ export const navigateToActivateBpdOnNewCoBadge = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_COBADGE_ROUTES.ACTIVATE_BPD_NEW + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_COBADGE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_COBADGE_ROUTES.ACTIVATE_BPD_NEW + } }) ); diff --git a/ts/features/wallet/onboarding/cobadge/navigation/navigator.ts b/ts/features/wallet/onboarding/cobadge/navigation/navigator.ts index 0d2e45d054e..0e0e73b1fd2 100644 --- a/ts/features/wallet/onboarding/cobadge/navigation/navigator.ts +++ b/ts/features/wallet/onboarding/cobadge/navigation/navigator.ts @@ -1,10 +1,13 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import CoBadgeChooseType from "../screens/CoBadgeChooseType"; import SearchAvailableCoBadgeScreen from "../screens/search/SearchAvailableCoBadgeScreen"; import CoBadgeStartScreen from "../screens/start/CoBadgeStartScreen"; import WALLET_ONBOARDING_COBADGE_ROUTES from "./routes"; -const PaymentMethodOnboardingCoBadgeNavigator = createStackNavigator( +const PaymentMethodOnboardingCoBadgeNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [WALLET_ONBOARDING_COBADGE_ROUTES.CHOOSE_TYPE]: { screen: CoBadgeChooseType @@ -20,7 +23,7 @@ const PaymentMethodOnboardingCoBadgeNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/wallet/onboarding/cobadge/screens/CoBadgeChooseType.tsx b/ts/features/wallet/onboarding/cobadge/screens/CoBadgeChooseType.tsx index e875ed28087..549c71c6ce9 100644 --- a/ts/features/wallet/onboarding/cobadge/screens/CoBadgeChooseType.tsx +++ b/ts/features/wallet/onboarding/cobadge/screens/CoBadgeChooseType.tsx @@ -1,3 +1,4 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { none } from "fp-ts/lib/Option"; import { Content, ListItem, View } from "native-base"; import * as React from "react"; @@ -7,7 +8,6 @@ import { SafeAreaView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { H1 } from "../../../../../components/core/typography/H1"; @@ -20,6 +20,7 @@ import BaseScreenComponent from "../../../../../components/screens/BaseScreenCom import FooterWithButtons from "../../../../../components/ui/FooterWithButtons"; import IconFont from "../../../../../components/ui/IconFont"; import I18n from "../../../../../i18n"; +import { IOStackNavigationProp } from "../../../../../navigation/params/AppParamsList"; import { navigateBack as legacyNavigateBack, navigateToWalletAddCreditCard @@ -27,11 +28,18 @@ import { import { GlobalState } from "../../../../../store/reducers/types"; import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; import { cancelButtonProps } from "../../../../bonus/bonusVacanze/components/buttons/ButtonConfigurations"; +import { PaymentMethodOnboardingCoBadgeParamsList } from "../navigation/params"; import { walletAddCoBadgeStart } from "../store/actions"; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp< + PaymentMethodOnboardingCoBadgeParamsList, + "WALLET_ONBOARDING_COBADGE_CHOOSE_TYPE" + > + >; + }; export type CoBadgeChooseTypeNavigationProps = { abi?: string; diff --git a/ts/features/wallet/onboarding/cobadge/screens/__tests__/CoBadgeChooseType.test.tsx b/ts/features/wallet/onboarding/cobadge/screens/__tests__/CoBadgeChooseType.test.tsx index 1e92d23f132..c9c38b0ec25 100644 --- a/ts/features/wallet/onboarding/cobadge/screens/__tests__/CoBadgeChooseType.test.tsx +++ b/ts/features/wallet/onboarding/cobadge/screens/__tests__/CoBadgeChooseType.test.tsx @@ -1,6 +1,6 @@ +import { CommonActions } from "@react-navigation/native"; import { fireEvent } from "@testing-library/react-native"; import { none } from "fp-ts/lib/Option"; -import { NavigationActions, NavigationParams } from "react-navigation"; import configureMockStore from "redux-mock-store"; import NavigationService from "../../../../../../navigation/NavigationService"; import ROUTES from "../../../../../../navigation/routes"; @@ -33,12 +33,15 @@ describe("CoBadgeChooseType component", () => { if (enabledItem) { fireEvent.press(enabledItem); expect(spyBack).toHaveBeenCalledTimes(1); - expect(spyService).toHaveBeenCalledWith( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_ADD_CARD, - params: { inPayment: none } - }) - ); + expect(spyService.mock.calls).toEqual([ + [CommonActions.goBack()], + [ + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_ADD_CARD, + params: { inPayment: none } + }) + ] + ]); } }); it("should dispatch walletAddCoBadgeStart action if press disabled or unknown item", () => { @@ -74,7 +77,7 @@ const getComponent = (abi?: string, legacyAddCreditCardBack?: number) => { } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( CoBadgeChooseType, ROUTES.WALLET_BPAY_DETAIL, { abi, legacyAddCreditCardBack }, diff --git a/ts/features/wallet/onboarding/cobadge/screens/search/__test__/SearchAvailableCoBadgeScreen.test.tsx b/ts/features/wallet/onboarding/cobadge/screens/search/__test__/SearchAvailableCoBadgeScreen.test.tsx index e6fcac755a0..61b480e1e88 100644 --- a/ts/features/wallet/onboarding/cobadge/screens/search/__test__/SearchAvailableCoBadgeScreen.test.tsx +++ b/ts/features/wallet/onboarding/cobadge/screens/search/__test__/SearchAvailableCoBadgeScreen.test.tsx @@ -1,6 +1,6 @@ import { fireEvent, RenderAPI } from "@testing-library/react-native"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { Action, createStore, Store } from "redux"; import { CobadgeResponse } from "../../../../../../../../definitions/pagopa/walletv2/CobadgeResponse"; import { @@ -261,7 +261,7 @@ const getSearchAvailableCoBadgeScreen = (abi?: string) => { const renderSearchAvailableCoBadgeScreen = ( store: Store ) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , WALLET_ONBOARDING_COBADGE_ROUTES.SEARCH_AVAILABLE, {}, diff --git a/ts/features/wallet/onboarding/cobadge/screens/start/__test__/CoBadgeStartScreen.test.tsx b/ts/features/wallet/onboarding/cobadge/screens/start/__test__/CoBadgeStartScreen.test.tsx index cdf8bb332cd..85372f43ec5 100644 --- a/ts/features/wallet/onboarding/cobadge/screens/start/__test__/CoBadgeStartScreen.test.tsx +++ b/ts/features/wallet/onboarding/cobadge/screens/start/__test__/CoBadgeStartScreen.test.tsx @@ -1,7 +1,7 @@ import { fireEvent, RenderAPI } from "@testing-library/react-native"; import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { Action, createStore, Store } from "redux"; import { StatusEnum } from "../../../../../../../../definitions/pagopa/cobadge/configuration/CoBadgeService"; import { CoBadgeServices } from "../../../../../../../../definitions/pagopa/cobadge/configuration/CoBadgeServices"; @@ -252,7 +252,7 @@ const getInitCoBadgeStartScreen = (abi: string) => { }; const renderCoBadgeScreen = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , WALLET_ONBOARDING_COBADGE_ROUTES.CHOOSE_TYPE, {}, diff --git a/ts/features/wallet/onboarding/common/screens/bpd/ActivateBpdOnNewCreditCardScreen.tsx b/ts/features/wallet/onboarding/common/screens/bpd/ActivateBpdOnNewCreditCardScreen.tsx index a968d707717..99f3d693c1f 100644 --- a/ts/features/wallet/onboarding/common/screens/bpd/ActivateBpdOnNewCreditCardScreen.tsx +++ b/ts/features/wallet/onboarding/common/screens/bpd/ActivateBpdOnNewCreditCardScreen.tsx @@ -1,6 +1,8 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import I18n from "../../../../../../i18n"; +import { IOStackNavigationProp } from "../../../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../../../navigation/params/WalletParamsList"; import { PaymentMethod } from "../../../../../../types/pagopa"; import { emptyContextualHelp } from "../../../../../../utils/emptyContextualHelp"; import ActivateBpdOnNewPaymentMethodScreen from "./ActivateBpdOnNewPaymentMethodScreen"; @@ -8,8 +10,14 @@ import ActivateBpdOnNewPaymentMethodScreen from "./ActivateBpdOnNewPaymentMethod export type ActivateBpdOnNewCreditCardScreenNavigationParams = { creditCards: ReadonlyArray; }; -type Props = - NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp< + WalletParamsList, + "WALLET_ONBOARDING_CREDIT_CARD_ACTIVATE_BPD_NEW" + > + >; +}; export const ActivateBpdOnNewCreditCardScreen: React.FC = ( props: Props diff --git a/ts/features/wallet/onboarding/common/searchBank/SearchBankScreen.tsx b/ts/features/wallet/onboarding/common/searchBank/SearchBankScreen.tsx index 89e8cd767f0..78fe0554611 100644 --- a/ts/features/wallet/onboarding/common/searchBank/SearchBankScreen.tsx +++ b/ts/features/wallet/onboarding/common/searchBank/SearchBankScreen.tsx @@ -1,8 +1,8 @@ +import { NavigationEvents } from "@react-navigation/compat"; import { Content } from "native-base"; import * as React from "react"; import { useRef } from "react"; import { SafeAreaView } from "react-native"; -import { NavigationEvents } from "react-navigation"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { IOStyles } from "../../../../../components/core/variables/IOStyles"; diff --git a/ts/features/wallet/onboarding/paypal/navigation/navigator.ts b/ts/features/wallet/onboarding/paypal/navigation/navigator.ts index 4c206d5aea3..2bed5c09ee3 100644 --- a/ts/features/wallet/onboarding/paypal/navigation/navigator.ts +++ b/ts/features/wallet/onboarding/paypal/navigation/navigator.ts @@ -1,4 +1,5 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import PayPalOnboardingCheckoutCompletedScreen from "../screen/PayPalOnboardingCheckoutCompletedScreen"; import PayPalOnboardingCheckoutScreen from "../screen/PayPalOnboardingCheckoutScreen"; import PayPalPspSelectionScreen from "../screen/PayPalPspSelectionScreen"; @@ -6,7 +7,7 @@ import PayPalStartOnboardingScreen from "../screen/PayPalStartOnboardingScreen"; import PAYPAL_ROUTES from "./routes"; export const PaymentMethodOnboardingPayPalOnboardingNavigator = - createStackNavigator( + createCompatNavigatorFactory(createStackNavigator)( { [PAYPAL_ROUTES.ONBOARDING.START]: { screen: PayPalStartOnboardingScreen @@ -25,7 +26,7 @@ export const PaymentMethodOnboardingPayPalOnboardingNavigator = // Let each screen handles the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/wallet/onboarding/paypal/saga/orchestration/index.ts b/ts/features/wallet/onboarding/paypal/saga/orchestration/index.ts index 719fac46086..f83e8b0153d 100644 --- a/ts/features/wallet/onboarding/paypal/saga/orchestration/index.ts +++ b/ts/features/wallet/onboarding/paypal/saga/orchestration/index.ts @@ -1,13 +1,16 @@ +import { StackActions } from "@react-navigation/compat"; +import { CommonActions } from "@react-navigation/native"; import { call } from "typed-redux-saga/macro"; -import { NavigationActions, StackActions } from "react-navigation"; import { ActionType } from "typesafe-actions"; +import NavigationService from "../../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../../navigation/routes"; import { executeWorkUnit, withResetNavigationStack, WorkUnitHandler } from "../../../../../../sagas/workUnit"; +import { navigateToPayPalDetailScreen } from "../../../../../../store/actions/navigation"; import PAYPAL_ROUTES from "../../navigation/routes"; -import NavigationService from "../../../../../../navigation/NavigationService"; import { walletAddPaypalBack, walletAddPaypalCancel, @@ -15,15 +18,17 @@ import { walletAddPaypalFailure, walletAddPaypalStart } from "../../store/actions"; -import { navigateToPayPalDetailScreen } from "../../../../../../store/actions/navigation"; // handle the flow of paypal onboarding function* paypalWorkOnboaringUnit() { return yield* call(executeWorkUnit, { startScreenNavigation: () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: PAYPAL_ROUTES.ONBOARDING.START + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: PAYPAL_ROUTES.ONBOARDING.MAIN, + params: { + screen: PAYPAL_ROUTES.ONBOARDING.START + } }) ), startScreenName: PAYPAL_ROUTES.ONBOARDING.START, diff --git a/ts/features/wallet/onboarding/paypal/screen/PayPalOnboardingCheckoutScreen.tsx b/ts/features/wallet/onboarding/paypal/screen/PayPalOnboardingCheckoutScreen.tsx index 72ff44cc731..aab5e1fbe3e 100644 --- a/ts/features/wallet/onboarding/paypal/screen/PayPalOnboardingCheckoutScreen.tsx +++ b/ts/features/wallet/onboarding/paypal/screen/PayPalOnboardingCheckoutScreen.tsx @@ -1,32 +1,32 @@ -import React, { useContext, useEffect, useState } from "react"; -import { connect } from "react-redux"; -import { Dispatch } from "redux"; +import { useNavigation } from "@react-navigation/native"; import { Option } from "fp-ts/lib/Option"; -import { NavigationContext } from "react-navigation"; +import React, { useEffect, useState } from "react"; import { Alert } from "react-native"; +import { connect } from "react-redux"; +import { Dispatch } from "redux"; +import WorkunitGenericFailure from "../../../../../components/error/WorkunitGenericFailure"; import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; -import I18n from "../../../../../i18n"; -import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; -import { - walletAddPaypalOutcome, - walletAddPaypalBack, - walletAddPaypalRefreshPMToken -} from "../store/actions"; -import { GlobalState } from "../../../../../store/reducers/types"; -import { pmSessionTokenSelector } from "../../../../../store/reducers/wallet/payment"; -import { fold } from "../../../../bonus/bpd/model/RemoteValue"; -import { LoadingErrorComponent } from "../../../../bonus/bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; import { PayWebViewModal } from "../../../../../components/wallet/PayWebViewModal"; import { pagoPaApiUrlPrefix, pagoPaApiUrlPrefixTest } from "../../../../../config"; +import I18n from "../../../../../i18n"; import { isPagoPATestEnabledSelector } from "../../../../../store/reducers/persistedPreferences"; -import { paypalOnboardingSelectedPsp } from "../store/reducers/selectedPsp"; +import { GlobalState } from "../../../../../store/reducers/types"; +import { pmSessionTokenSelector } from "../../../../../store/reducers/wallet/payment"; +import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; import { getLocalePrimaryWithFallback } from "../../../../../utils/locale"; import { getLookUpIdPO } from "../../../../../utils/pmLookUpId"; -import WorkunitGenericFailure from "../../../../../components/error/WorkunitGenericFailure"; +import { LoadingErrorComponent } from "../../../../bonus/bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; +import { fold } from "../../../../bonus/bpd/model/RemoteValue"; +import { + walletAddPaypalBack, + walletAddPaypalOutcome, + walletAddPaypalRefreshPMToken +} from "../store/actions"; import { navigateToPayPalCheckoutCompleted } from "../store/actions/navigation"; +import { paypalOnboardingSelectedPsp } from "../store/reducers/selectedPsp"; type Props = ReturnType & ReturnType; @@ -104,7 +104,7 @@ const CheckoutContent = ( * 4. navigate to the checkout completed screen */ const PayPalOnboardingCheckoutScreen = (props: Props) => { - const navigation = useContext(NavigationContext); + const navigation = useNavigation(); const { refreshPMtoken } = props; // refresh the PM at the startup useEffect(() => { diff --git a/ts/features/wallet/onboarding/paypal/screen/PayPalPspSelectionScreen.tsx b/ts/features/wallet/onboarding/paypal/screen/PayPalPspSelectionScreen.tsx index 83ff1780fc5..27a2291331d 100644 --- a/ts/features/wallet/onboarding/paypal/screen/PayPalPspSelectionScreen.tsx +++ b/ts/features/wallet/onboarding/paypal/screen/PayPalPspSelectionScreen.tsx @@ -1,40 +1,40 @@ +import { useNavigation } from "@react-navigation/native"; +import { View } from "native-base"; import React, { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, StyleSheet } from "react-native"; -import { View } from "native-base"; import { connect, useDispatch } from "react-redux"; import { Dispatch } from "redux"; -import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; -import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; -import I18n from "../../../../../i18n"; -import { IOStyles } from "../../../../../components/core/variables/IOStyles"; -import { H1 } from "../../../../../components/core/typography/H1"; -import { Body } from "../../../../../components/core/typography/Body"; -import { Link } from "../../../../../components/core/typography/Link"; -import FooterWithButtons from "../../../../../components/ui/FooterWithButtons"; import { RadioButtonList, RadioItem } from "../../../../../components/core/selection/RadioButtonList"; +import { Body } from "../../../../../components/core/typography/Body"; +import { H1 } from "../../../../../components/core/typography/H1"; +import { H4 } from "../../../../../components/core/typography/H4"; +import { Link } from "../../../../../components/core/typography/Link"; +import { IOStyles } from "../../../../../components/core/variables/IOStyles"; +import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; +import FooterWithButtons from "../../../../../components/ui/FooterWithButtons"; +import I18n from "../../../../../i18n"; +import { GlobalState } from "../../../../../store/reducers/types"; +import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; +import { useIOBottomSheetModal } from "../../../../../utils/hooks/bottomSheet"; +import { LoadingErrorComponent } from "../../../../bonus/bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; import { getValueOrElse, isError, isReady } from "../../../../bonus/bpd/model/RemoteValue"; -import { H4 } from "../../../../../components/core/typography/H4"; -import { GlobalState } from "../../../../../store/reducers/types"; -import { LoadingErrorComponent } from "../../../../bonus/bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; import { PspRadioItem } from "../components/PspRadioItem"; -import { useIOBottomSheetModal } from "../../../../../utils/hooks/bottomSheet"; -import { IOPayPalPsp } from "../types"; import { searchPaypalPsp as searchPaypalPspAction, walletAddPaypalBack, walletAddPaypalCancel, walletAddPaypalPspSelected } from "../store/actions"; -import { payPalPspSelector } from "../store/reducers/searchPsp"; -import { useNavigationContext } from "../../../../../utils/hooks/useOnFocus"; import { navigateToPayPalCheckout } from "../store/actions/navigation"; +import { payPalPspSelector } from "../store/reducers/searchPsp"; +import { IOPayPalPsp } from "../types"; type Props = ReturnType & ReturnType; @@ -108,7 +108,7 @@ const PayPalPspSelectionScreen = (props: Props): React.ReactElement | null => { const pspList = getValueOrElse(props.pspList, []); const [selectedPsp, setSelectedPsp] = useState(); const dispatch = useDispatch(); - const navigation = useNavigationContext(); + const navigation = useNavigation(); const searchPaypalPsp = () => { dispatch(searchPaypalPspAction.request()); }; @@ -132,7 +132,7 @@ const PayPalPspSelectionScreen = (props: Props): React.ReactElement | null => { onPress: () => { if (selectedPsp) { props.setPspSelected(selectedPsp); - navigation.navigate(navigateToPayPalCheckout()); + navigation.dispatch(navigateToPayPalCheckout()); } }, title: I18n.t("global.buttons.continue") diff --git a/ts/features/wallet/onboarding/paypal/screen/PayPalStartOnboardingScreen.tsx b/ts/features/wallet/onboarding/paypal/screen/PayPalStartOnboardingScreen.tsx index deb4aa30f3d..6b1546f2fee 100644 --- a/ts/features/wallet/onboarding/paypal/screen/PayPalStartOnboardingScreen.tsx +++ b/ts/features/wallet/onboarding/paypal/screen/PayPalStartOnboardingScreen.tsx @@ -1,21 +1,21 @@ +import { useNavigation } from "@react-navigation/native"; import React from "react"; import { Dimensions, SafeAreaView, View } from "react-native"; -import { Dispatch } from "redux"; import { connect } from "react-redux"; -import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; -import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; -import I18n from "../../../../../i18n"; -import { IOStyles } from "../../../../../components/core/variables/IOStyles"; -import FooterWithButtons from "../../../../../components/ui/FooterWithButtons"; +import { Dispatch } from "redux"; +import Oval from "../../../../../../img/wallet/payment-methods/paypal/oval.svg"; +import PPLogo from "../../../../../../img/wallet/payment-methods/paypal/paypal_logo.svg"; import { Body } from "../../../../../components/core/typography/Body"; +import { IOStyles } from "../../../../../components/core/variables/IOStyles"; import { InfoScreenComponent } from "../../../../../components/infoScreen/InfoScreenComponent"; -import PPLogo from "../../../../../../img/wallet/payment-methods/paypal/paypal_logo.svg"; -import Oval from "../../../../../../img/wallet/payment-methods/paypal/oval.svg"; +import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; +import SectionStatusComponent from "../../../../../components/SectionStatus"; +import FooterWithButtons from "../../../../../components/ui/FooterWithButtons"; +import I18n from "../../../../../i18n"; import { GlobalState } from "../../../../../store/reducers/types"; +import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; import { walletAddPaypalBack, walletAddPaypalCancel } from "../store/actions"; -import { useNavigationContext } from "../../../../../utils/hooks/useOnFocus"; import { navigateToPaypalSearchPsp } from "../store/actions/navigation"; -import SectionStatusComponent from "../../../../../components/SectionStatus"; type Props = ReturnType & ReturnType; @@ -50,9 +50,9 @@ const PayPalLogo = () => ( const PayPalStartOnboardingScreen = ( props: Props ): React.ReactElement | null => { - const navigationContext = useNavigationContext(); + const navigationContext = useNavigation(); const navigateToSearchPsp = () => - navigationContext.navigate(navigateToPaypalSearchPsp()); + navigationContext.dispatch(navigateToPaypalSearchPsp()); const cancelButtonProps = { testID: "cancelButtonId", diff --git a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalOnboardingCheckoutScreen.test.tsx b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalOnboardingCheckoutScreen.test.tsx index f4c81ad6899..ca1c5185279 100644 --- a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalOnboardingCheckoutScreen.test.tsx +++ b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalOnboardingCheckoutScreen.test.tsx @@ -1,5 +1,5 @@ import { createStore, Store } from "redux"; -import { NavigationParams } from "react-navigation"; + import { Alert } from "react-native"; import { fireEvent } from "@testing-library/react-native"; import { appReducer } from "../../../../../../store/reducers"; @@ -150,7 +150,7 @@ describe("PayPalOnboardingCheckoutScreen", () => { }); const renderComponent = (store: Store) => ({ - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( PayPalOnboardingCheckoutScreen, PAYPAL_ROUTES.ONBOARDING.CHECKOUT, {}, diff --git a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalOnboardingCompletedSuccessComponent.test.tsx b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalOnboardingCompletedSuccessComponent.test.tsx index c524e8aeb93..162c5c1694a 100644 --- a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalOnboardingCompletedSuccessComponent.test.tsx +++ b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalOnboardingCompletedSuccessComponent.test.tsx @@ -1,5 +1,5 @@ import { createStore } from "redux"; -import { NavigationParams } from "react-navigation"; + import { appReducer } from "../../../../../../store/reducers"; import { applicationChangeState } from "../../../../../../store/actions/application"; import { renderScreenFakeNavRedux } from "../../../../../../utils/testWrapper"; @@ -86,7 +86,7 @@ const renderComponent = () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); const render = { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( PayPalOnboardingCompletedSuccessComponent, "N/A", {}, diff --git a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalPpsSelectionScreen.test.tsx b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalPpsSelectionScreen.test.tsx index caf8ddcdb17..c9e5f05f167 100644 --- a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalPpsSelectionScreen.test.tsx +++ b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalPpsSelectionScreen.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import { createStore } from "redux"; import { fireEvent } from "@testing-library/react-native"; import { appReducer } from "../../../../../../store/reducers"; @@ -88,7 +87,7 @@ const renderComponent = () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( PayPalPpsSelectionScreen, "N/A", {}, diff --git a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalPspUpdateScreen.test.tsx b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalPspUpdateScreen.test.tsx index 3d7a6046cde..4ba1c819c0f 100644 --- a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalPspUpdateScreen.test.tsx +++ b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalPspUpdateScreen.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import { createStore } from "redux"; import { appReducer } from "../../../../../../store/reducers"; import { applicationChangeState } from "../../../../../../store/actions/application"; @@ -90,7 +89,7 @@ const renderComponent = () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( PayPalPspUpdateScreen, "N/A", {}, diff --git a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalStartOnboardingScreen.test.tsx b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalStartOnboardingScreen.test.tsx index 72cb089bb89..d2ab5d2fed4 100644 --- a/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalStartOnboardingScreen.test.tsx +++ b/ts/features/wallet/onboarding/paypal/screen/__tests__/PayPalStartOnboardingScreen.test.tsx @@ -1,5 +1,5 @@ import { createStore, Store } from "redux"; -import { NavigationParams } from "react-navigation"; + import PayPalStartOnboardingScreen from "../PayPalStartOnboardingScreen"; import { renderScreenFakeNavRedux } from "../../../../../../utils/testWrapper"; import { GlobalState } from "../../../../../../store/reducers/types"; @@ -30,7 +30,7 @@ describe("PayPalStartOnboardingScreen", () => { }); const renderComponent = (store: Store) => ({ - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( PayPalStartOnboardingScreen, "N/A", {}, diff --git a/ts/features/wallet/onboarding/paypal/screen/__tests__/__snapshots__/PayPalOnboardingCompletedSuccessComponent.test.tsx.snap b/ts/features/wallet/onboarding/paypal/screen/__tests__/__snapshots__/PayPalOnboardingCompletedSuccessComponent.test.tsx.snap index b6b4502329a..9ce6c52f641 100644 --- a/ts/features/wallet/onboarding/paypal/screen/__tests__/__snapshots__/PayPalOnboardingCompletedSuccessComponent.test.tsx.snap +++ b/ts/features/wallet/onboarding/paypal/screen/__tests__/__snapshots__/PayPalOnboardingCompletedSuccessComponent.test.tsx.snap @@ -2,28 +2,131 @@ exports[`PayPalOnboardingCompletedSuccessComponent should match the snapshot 1`] = ` - + + + + + + + + + + N/A + + + + + + + - - - - - - Fatto! - - - - Ora puoi continuare con il pagamento. - - - - + "shadowOpacity": 0.3, + "shadowRadius": 5, + "top": 0, + "width": 3, + } + } + /> - - Continua - + + + + + + + + + + + + + + + + Fatto! + + + + Ora puoi continuare con il pagamento. + + + + + + + + Continua + + + + + + + + + + + + + + + @@ -320,6 +693,6 @@ exports[`PayPalOnboardingCompletedSuccessComponent should match the snapshot 1`] - + `; diff --git a/ts/features/wallet/onboarding/paypal/store/actions/navigation.ts b/ts/features/wallet/onboarding/paypal/store/actions/navigation.ts index b48c3187d77..db5ac3b2a84 100644 --- a/ts/features/wallet/onboarding/paypal/store/actions/navigation.ts +++ b/ts/features/wallet/onboarding/paypal/store/actions/navigation.ts @@ -1,4 +1,4 @@ -import { NavigationActions } from "react-navigation"; +import { NavigationActions } from "@react-navigation/compat"; import PAYPAL_ROUTES from "../../navigation/routes"; export const navigateToPaypalSearchPsp = () => diff --git a/ts/features/wallet/onboarding/privative/navigation/action.ts b/ts/features/wallet/onboarding/privative/navigation/action.ts index 903fb6197a5..6beb21396d6 100644 --- a/ts/features/wallet/onboarding/privative/navigation/action.ts +++ b/ts/features/wallet/onboarding/privative/navigation/action.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../navigation/routes"; import WALLET_ONBOARDING_PRIVATIVE_ROUTES from "./routes"; /** @@ -8,8 +9,11 @@ import WALLET_ONBOARDING_PRIVATIVE_ROUTES from "./routes"; */ export const navigateToOnboardingPrivativeChooseIssuerScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_PRIVATIVE_ROUTES.CHOOSE_ISSUER + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.CHOOSE_ISSUER + } }) ); @@ -19,8 +23,11 @@ export const navigateToOnboardingPrivativeChooseIssuerScreen = () => */ export const navigateToOnboardingPrivativeInsertCardNumberScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_PRIVATIVE_ROUTES.INSERT_CARD_NUMBER + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.INSERT_CARD_NUMBER + } }) ); @@ -30,8 +37,11 @@ export const navigateToOnboardingPrivativeInsertCardNumberScreen = () => */ export const navigateToOnboardingPrivativeKoDisabledScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_PRIVATIVE_ROUTES.DISABLED_ISSUER + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.DISABLED_ISSUER + } }) ); @@ -41,8 +51,11 @@ export const navigateToOnboardingPrivativeKoDisabledScreen = () => */ export const navigateToOnboardingPrivativeKoUnavailableScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_PRIVATIVE_ROUTES.UNAVAILABLE_ISSUER + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.UNAVAILABLE_ISSUER + } }) ); @@ -52,8 +65,11 @@ export const navigateToOnboardingPrivativeKoUnavailableScreen = () => */ export const navigateToOnboardingPrivativeSearchAvailable = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_PRIVATIVE_ROUTES.SEARCH_AVAILABLE + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.SEARCH_AVAILABLE + } }) ); @@ -63,7 +79,10 @@ export const navigateToOnboardingPrivativeSearchAvailable = () => */ export const navigateToActivateBpdOnNewPrivative = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_PRIVATIVE_ROUTES.ACTIVATE_BPD_NEW + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.ACTIVATE_BPD_NEW + } }) ); diff --git a/ts/features/wallet/onboarding/privative/navigation/navigator.ts b/ts/features/wallet/onboarding/privative/navigation/navigator.ts index b8df3c0eb1a..4210dc9db06 100644 --- a/ts/features/wallet/onboarding/privative/navigation/navigator.ts +++ b/ts/features/wallet/onboarding/privative/navigation/navigator.ts @@ -1,4 +1,5 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import AddPrivativeCardNumberScreen from "../screens/AddPrivativeCardNumberScreen"; import ChoosePrivativeIssuerScreen from "../screens/choosePrivativeIssuer/ChoosePrivativeIssuerScreen"; import PrivativeIssuerKoDisabled from "../screens/choosePrivativeIssuer/ko/PrivativeIssuerKoDisabled"; @@ -6,7 +7,9 @@ import PrivativeIssuerKoUnavailable from "../screens/choosePrivativeIssuer/ko/Pr import SearchPrivativeCardScreen from "../screens/search/SearchPrivativeCardScreen"; import WALLET_ONBOARDING_PRIVATIVE_ROUTES from "./routes"; -const PaymentMethodOnboardingPrivativeNavigator = createStackNavigator( +const PaymentMethodOnboardingPrivativeNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [WALLET_ONBOARDING_PRIVATIVE_ROUTES.CHOOSE_ISSUER]: { screen: ChoosePrivativeIssuerScreen @@ -28,7 +31,7 @@ const PaymentMethodOnboardingPrivativeNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/wallet/onboarding/privative/screens/__tests__/AddPrivativeCardNumberScreen.test.tsx b/ts/features/wallet/onboarding/privative/screens/__tests__/AddPrivativeCardNumberScreen.test.tsx index ec9931dcc4e..f1e47cf0402 100644 --- a/ts/features/wallet/onboarding/privative/screens/__tests__/AddPrivativeCardNumberScreen.test.tsx +++ b/ts/features/wallet/onboarding/privative/screens/__tests__/AddPrivativeCardNumberScreen.test.tsx @@ -1,9 +1,10 @@ +import { NavigationActions } from "@react-navigation/compat"; import { fireEvent } from "@testing-library/react-native"; import * as React from "react"; -import { NavigationActions, NavigationParams } from "react-navigation"; import configureMockStore from "redux-mock-store"; import I18n from "../../../../../../i18n"; import NavigationService from "../../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../../navigation/routes"; import { applicationChangeState } from "../../../../../../store/actions/application"; import { appReducer } from "../../../../../../store/reducers"; import { GlobalState } from "../../../../../../store/reducers/types"; @@ -72,7 +73,13 @@ describe("AddPrivativeCardNumberScreen", () => { ]); expect(spy).toHaveBeenCalledWith( NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_PRIVATIVE_ROUTES.SEARCH_AVAILABLE + routeName: ROUTES.WALLET_NAVIGATOR, + params: { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_PRIVATIVE_ROUTES.SEARCH_AVAILABLE + } + } }) ); @@ -107,7 +114,7 @@ const renderComponent = () => { } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , WALLET_ONBOARDING_PRIVATIVE_ROUTES.INSERT_CARD_NUMBER, {}, diff --git a/ts/features/wallet/onboarding/privative/screens/add/__tests__/AddPrivativeCardScreen.test.tsx b/ts/features/wallet/onboarding/privative/screens/add/__tests__/AddPrivativeCardScreen.test.tsx index 08947bd0d50..24046c7cfc6 100644 --- a/ts/features/wallet/onboarding/privative/screens/add/__tests__/AddPrivativeCardScreen.test.tsx +++ b/ts/features/wallet/onboarding/privative/screens/add/__tests__/AddPrivativeCardScreen.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import * as React from "react"; import { Action, createStore, Store } from "redux"; import { fireEvent, RenderAPI } from "@testing-library/react-native"; @@ -111,7 +110,7 @@ const getAddPrivativeCardScreen = () => { }; const renderAddPrivativeCardScreen = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , WALLET_ONBOARDING_PRIVATIVE_ROUTES.SEARCH_AVAILABLE, {}, diff --git a/ts/features/wallet/onboarding/privative/screens/choosePrivativeIssuer/__tests__/ChoosePrivativeIssuers.test.tsx b/ts/features/wallet/onboarding/privative/screens/choosePrivativeIssuer/__tests__/ChoosePrivativeIssuers.test.tsx index 0c4d48d8428..14bae2e745c 100644 --- a/ts/features/wallet/onboarding/privative/screens/choosePrivativeIssuer/__tests__/ChoosePrivativeIssuers.test.tsx +++ b/ts/features/wallet/onboarding/privative/screens/choosePrivativeIssuer/__tests__/ChoosePrivativeIssuers.test.tsx @@ -1,6 +1,6 @@ import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { Action, createStore, Store } from "redux"; import { PrivativeServices } from "../../../../../../../../definitions/pagopa/privative/configuration/PrivativeServices"; import { PrivativeServiceStatusEnum } from "../../../../../../../../definitions/pagopa/privative/configuration/PrivativeServiceStatus"; @@ -97,7 +97,7 @@ const getInitChoosePrivativeIssuersScreen = () => { }; const renderPrivativeIssuersScreen = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , WALLET_ONBOARDING_PRIVATIVE_ROUTES.CHOOSE_ISSUER, {}, diff --git a/ts/features/wallet/onboarding/privative/screens/search/__tests__/SearchPrivativeCardScreen.test.tsx b/ts/features/wallet/onboarding/privative/screens/search/__tests__/SearchPrivativeCardScreen.test.tsx index 213e98e5457..ba09ccd0e63 100644 --- a/ts/features/wallet/onboarding/privative/screens/search/__tests__/SearchPrivativeCardScreen.test.tsx +++ b/ts/features/wallet/onboarding/privative/screens/search/__tests__/SearchPrivativeCardScreen.test.tsx @@ -1,6 +1,6 @@ import { fireEvent, RenderAPI } from "@testing-library/react-native"; import * as React from "react"; -import { NavigationParams } from "react-navigation"; + import { Action, createStore, Store } from "redux"; import configureMockStore from "redux-mock-store"; import { @@ -169,7 +169,7 @@ const getSearchPrivativeCardScreen = () => { }; const renderSearchPrivativeCardScreen = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( () => , WALLET_ONBOARDING_PRIVATIVE_ROUTES.SEARCH_AVAILABLE, {}, diff --git a/ts/features/wallet/onboarding/satispay/navigation/action.ts b/ts/features/wallet/onboarding/satispay/navigation/action.ts index 1cc4893e9c8..765297f4f25 100644 --- a/ts/features/wallet/onboarding/satispay/navigation/action.ts +++ b/ts/features/wallet/onboarding/satispay/navigation/action.ts @@ -1,5 +1,6 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import NavigationService from "../../../../../navigation/NavigationService"; +import ROUTES from "../../../../../navigation/routes"; import WALLET_ONBOARDING_SATISPAY_ROUTES from "./routes"; /** @@ -8,8 +9,11 @@ import WALLET_ONBOARDING_SATISPAY_ROUTES from "./routes"; */ export const navigateToOnboardingSatispayStart = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_SATISPAY_ROUTES.START + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_SATISPAY_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_SATISPAY_ROUTES.START + } }) ); @@ -19,9 +23,11 @@ export const navigateToOnboardingSatispayStart = () => */ export const navigateToOnboardingSatispaySearchAvailableUserAccount = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: - WALLET_ONBOARDING_SATISPAY_ROUTES.SEARCH_AVAILABLE_USER_SATISPAY + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_SATISPAY_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_SATISPAY_ROUTES.SEARCH_AVAILABLE_USER_SATISPAY + } }) ); @@ -31,8 +37,11 @@ export const navigateToOnboardingSatispaySearchAvailableUserAccount = () => */ export const navigateToSuggestBpdActivation = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_SATISPAY_ROUTES.SUGGEST_BPD_ACTIVATION + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_SATISPAY_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_SATISPAY_ROUTES.SUGGEST_BPD_ACTIVATION + } }) ); @@ -42,7 +51,10 @@ export const navigateToSuggestBpdActivation = () => */ export const navigateToActivateBpdOnNewSatispay = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: WALLET_ONBOARDING_SATISPAY_ROUTES.ACTIVATE_BPD_NEW_SATISPAY + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: WALLET_ONBOARDING_SATISPAY_ROUTES.MAIN, + params: { + screen: WALLET_ONBOARDING_SATISPAY_ROUTES.ACTIVATE_BPD_NEW_SATISPAY + } }) ); diff --git a/ts/features/wallet/onboarding/satispay/navigation/navigator.ts b/ts/features/wallet/onboarding/satispay/navigation/navigator.ts index e2cbf3655af..f9220a3f253 100644 --- a/ts/features/wallet/onboarding/satispay/navigation/navigator.ts +++ b/ts/features/wallet/onboarding/satispay/navigation/navigator.ts @@ -1,10 +1,13 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import SuggestBpdActivationScreen from "../../common/screens/bpd/SuggestBpdActivationScreen"; import SearchSatispayManagerScreen from "../screens/search/SearchSatispayManagerScreen"; import StartSatispaySearchScreen from "../screens/StartSatispaySearchScreen"; import WALLET_ONBOARDING_SATISPAY_ROUTES from "./routes"; -const PaymentMethodOnboardingSatispayNavigator = createStackNavigator( +const PaymentMethodOnboardingSatispayNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [WALLET_ONBOARDING_SATISPAY_ROUTES.START]: { screen: StartSatispaySearchScreen @@ -20,7 +23,7 @@ const PaymentMethodOnboardingSatispayNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/wallet/paypal/PayPalWalletPreview.tsx b/ts/features/wallet/paypal/PayPalWalletPreview.tsx index 8a4a2f833d9..c081050afbd 100644 --- a/ts/features/wallet/paypal/PayPalWalletPreview.tsx +++ b/ts/features/wallet/paypal/PayPalWalletPreview.tsx @@ -1,13 +1,16 @@ +import { useNavigation } from "@react-navigation/native"; import * as React from "react"; import payPalCard from "../../../../img/wallet/cards-icons/paypal_card.png"; import { Body } from "../../../components/core/typography/Body"; import { IOStyles } from "../../../components/core/variables/IOStyles"; import I18n from "../../../i18n"; -import { CardLogoPreview } from "../component/card/CardLogoPreview"; +import { + AppParamsList, + IOStackNavigationProp +} from "../../../navigation/params/AppParamsList"; import { PayPalPaymentMethod } from "../../../types/pagopa"; -import { navigateToPayPalDetailScreen } from "../../../store/actions/navigation"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; import { getPaypalAccountEmail } from "../../../utils/paypal"; +import { CardLogoPreview } from "../component/card/CardLogoPreview"; type OwnProps = { paypal: PayPalPaymentMethod; @@ -27,9 +30,7 @@ const getAccessibilityRepresentation = () => { * @constructor */ const PayPalWalletPreview: React.FunctionComponent = props => { - const navigation = useNavigationContext(); - const navigateToDetailScreen = () => - navigation.navigate(navigateToPayPalDetailScreen()); + const navigation = useNavigation>(); return ( = props => { } image={payPalCard} - onPress={navigateToDetailScreen} + onPress={() => + navigation.navigate("WALLET_NAVIGATOR", { + screen: "WALLET_PAYPAL_DETAIL" + }) + } /> ); }; diff --git a/ts/features/wallet/paypal/screen/PayPalPspUpdateScreen.tsx b/ts/features/wallet/paypal/screen/PayPalPspUpdateScreen.tsx index 66466be6cdd..42a7b25a58f 100644 --- a/ts/features/wallet/paypal/screen/PayPalPspUpdateScreen.tsx +++ b/ts/features/wallet/paypal/screen/PayPalPspUpdateScreen.tsx @@ -1,36 +1,38 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; +import { useNavigation } from "@react-navigation/native"; +import { ListItem, View } from "native-base"; import React, { useEffect } from "react"; import { Image, SafeAreaView, ScrollView, StyleSheet } from "react-native"; -import { ListItem, View } from "native-base"; import { useDispatch } from "react-redux"; -import { NavigationInjectedProps } from "react-navigation"; -import BaseScreenComponent from "../../../../components/screens/BaseScreenComponent"; -import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; -import I18n from "../../../../i18n"; -import { IOStyles } from "../../../../components/core/variables/IOStyles"; -import { H1 } from "../../../../components/core/typography/H1"; import { Body } from "../../../../components/core/typography/Body"; -import FooterWithButtons from "../../../../components/ui/FooterWithButtons"; -import { isError, isReady } from "../../../bonus/bpd/model/RemoteValue"; +import { H1 } from "../../../../components/core/typography/H1"; import { H4 } from "../../../../components/core/typography/H4"; -import { LoadingErrorComponent } from "../../../bonus/bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; -import { IOPayPalPsp } from "../../onboarding/paypal/types"; -import { useNavigationContext } from "../../../../utils/hooks/useOnFocus"; -import customVariables from "../../../../theme/variables"; +import { Label } from "../../../../components/core/typography/Label"; +import { IOStyles } from "../../../../components/core/variables/IOStyles"; +import BaseScreenComponent from "../../../../components/screens/BaseScreenComponent"; +import FooterWithButtons from "../../../../components/ui/FooterWithButtons"; import IconFont from "../../../../components/ui/IconFont"; +import I18n from "../../../../i18n"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../navigation/params/WalletParamsList"; +import { + pspForPaymentV2, + pspSelectedForPaymentV2 +} from "../../../../store/actions/wallet/payment"; +import { useIOSelector } from "../../../../store/hooks"; +import { pspV2ListSelector } from "../../../../store/reducers/wallet/payment"; +import customVariables from "../../../../theme/variables"; +import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; import { formatNumberCentsToAmount } from "../../../../utils/stringBuilder"; -import { Label } from "../../../../components/core/typography/Label"; +import { LoadingErrorComponent } from "../../../bonus/bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; +import { isError, isReady } from "../../../bonus/bpd/model/RemoteValue"; import { useImageResize } from "../../onboarding/bancomat/screens/hooks/useImageResize"; import { PSP_LOGO_MAX_HEIGHT, PSP_LOGO_MAX_WIDTH } from "../../onboarding/paypal/components/PspRadioItem"; -import { useIOSelector } from "../../../../store/hooks"; -import { pspV2ListSelector } from "../../../../store/reducers/wallet/payment"; -import { - pspForPaymentV2, - pspSelectedForPaymentV2 -} from "../../../../store/actions/wallet/payment"; import { convertPspData } from "../../onboarding/paypal/store/transformers"; +import { IOPayPalPsp } from "../../onboarding/paypal/types"; const styles = StyleSheet.create({ radioListHeaderRightColumn: { @@ -141,7 +143,12 @@ export type PayPalPspUpdateScreenNavigationParams = { idPayment: string; idWallet: number; }; -type Props = NavigationInjectedProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; + /** * This screen is where the user updates the PSP that will be used for the payment * Only 1 psp can be selected @@ -150,7 +157,7 @@ const PayPalPspUpdateScreen: React.FunctionComponent = ( props: Props ) => { const locales = getLocales(); - const navigation = useNavigationContext(); + const navigation = useNavigation(); const dispatch = useDispatch(); const pspList = useIOSelector(pspV2ListSelector); const idPayment = props.navigation.getParam("idPayment"); diff --git a/ts/features/wallet/privative/component/__tests__/PrivativeWalletPreview.test.tsx b/ts/features/wallet/privative/component/__tests__/PrivativeWalletPreview.test.tsx index f912dbdd0e3..1ad185f921f 100644 --- a/ts/features/wallet/privative/component/__tests__/PrivativeWalletPreview.test.tsx +++ b/ts/features/wallet/privative/component/__tests__/PrivativeWalletPreview.test.tsx @@ -1,14 +1,14 @@ -import { fireEvent, render } from "@testing-library/react-native"; +import { CommonActions } from "@react-navigation/native"; +import { fireEvent } from "@testing-library/react-native"; import { none, some } from "fp-ts/lib/Option"; import * as React from "react"; -import { NavigationActions } from "react-navigation"; -import { Provider } from "react-redux"; import configureMockStore from "redux-mock-store"; import I18n from "../../../../../i18n"; import NavigationService from "../../../../../navigation/NavigationService"; import ROUTES from "../../../../../navigation/routes"; import { mockPrivativeCard } from "../../../../../store/reducers/wallet/__mocks__/wallets"; import { PrivativePaymentMethod } from "../../../../../types/pagopa"; +import { renderScreenFakeNavRedux } from "../../../../../utils/testWrapper"; import * as hooks from "../../../onboarding/bancomat/screens/hooks/useImageResize"; import PrivativeWalletPreview from "../PrivativeWalletPreview"; @@ -65,8 +65,8 @@ describe("PrivativeWalletPreview", () => { if (cardComponent) { fireEvent.press(cardComponent); expect(spy).toHaveBeenCalledWith( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_PRIVATIVE_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_PRIVATIVE_DETAIL, params: { privative: mockPrivativeCard } }) ); @@ -77,10 +77,11 @@ const getComponent = (privative: PrivativePaymentMethod) => { const mockStore = configureMockStore(); const store = mockStore(); return { - component: render( - - - + component: renderScreenFakeNavRedux( + () => , + "WALLET_HOME", + {}, + store ), store }; diff --git a/ts/features/wallet/privative/screen/PrivativeDetailScreen.tsx b/ts/features/wallet/privative/screen/PrivativeDetailScreen.tsx index 0916969a5ba..d807ab79c74 100644 --- a/ts/features/wallet/privative/screen/PrivativeDetailScreen.tsx +++ b/ts/features/wallet/privative/screen/PrivativeDetailScreen.tsx @@ -1,7 +1,9 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../navigation/params/WalletParamsList"; import { GlobalState } from "../../../../store/reducers/types"; import { PrivativePaymentMethod } from "../../../../types/pagopa"; import BasePaymentMethodScreen from "../../common/BasePaymentMethodScreen"; @@ -14,8 +16,11 @@ export type PrivativeDetailScreenNavigationParams = Readonly<{ }>; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; /** * Detail screen for a privative card diff --git a/ts/features/wallet/satispay/screen/SatispayDetailScreen.tsx b/ts/features/wallet/satispay/screen/SatispayDetailScreen.tsx index a6d85dd13c4..d2c21957e87 100644 --- a/ts/features/wallet/satispay/screen/SatispayDetailScreen.tsx +++ b/ts/features/wallet/satispay/screen/SatispayDetailScreen.tsx @@ -1,7 +1,9 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; +import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../../navigation/params/WalletParamsList"; import { GlobalState } from "../../../../store/reducers/types"; import { SatispayPaymentMethod } from "../../../../types/pagopa"; import BasePaymentMethodScreen from "../../common/BasePaymentMethodScreen"; @@ -14,8 +16,11 @@ export type SatispayDetailScreenNavigationParams = Readonly<{ }>; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; /** * Detail screen for a satispay diff --git a/ts/features/zendesk/components/ZendeskSupportComponent.tsx b/ts/features/zendesk/components/ZendeskSupportComponent.tsx index b182eddb314..db8986a2136 100644 --- a/ts/features/zendesk/components/ZendeskSupportComponent.tsx +++ b/ts/features/zendesk/components/ZendeskSupportComponent.tsx @@ -1,10 +1,25 @@ +import { useNavigation } from "@react-navigation/native"; +import { fromNullable, Option } from "fp-ts/lib/Option"; +import * as pot from "italia-ts-commons/lib/pot"; +import { View } from "native-base"; import * as React from "react"; import { useEffect } from "react"; -import * as pot from "italia-ts-commons/lib/pot"; -import { fromNullable, Option } from "fp-ts/lib/Option"; import { useDispatch } from "react-redux"; -import { View } from "native-base"; +import { InitializedProfile } from "../../../../definitions/backend/InitializedProfile"; +import AdviceComponent from "../../../components/AdviceComponent"; +import ButtonDefaultOpacity from "../../../components/ButtonDefaultOpacity"; +import { H3 } from "../../../components/core/typography/H3"; +import { H4 } from "../../../components/core/typography/H4"; +import { Label } from "../../../components/core/typography/Label"; +import I18n from "../../../i18n"; +import { mixpanelTrack } from "../../../mixpanel"; +import { + AppParamsList, + IOStackNavigationProp +} from "../../../navigation/params/AppParamsList"; +import { useIOSelector } from "../../../store/hooks"; import { zendeskTokenSelector } from "../../../store/reducers/authentication"; +import { profileSelector } from "../../../store/reducers/profile"; import { AnonymousIdentity, initSupportAssistance, @@ -16,31 +31,15 @@ import { zendeskDefaultAnonymousConfig, zendeskDefaultJwtConfig } from "../../../utils/supportAssistance"; -import { profileSelector } from "../../../store/reducers/profile"; -import { InitializedProfile } from "../../../../definitions/backend/InitializedProfile"; -import { useIOSelector } from "../../../store/hooks"; -import { - navigateToZendeskAskPermissions, - navigateToZendeskChooseCategory, - navigateToZendeskPanicMode -} from "../store/actions/navigation"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; +import { getValueOrElse, isReady } from "../../bonus/bpd/model/RemoteValue"; import { zendeskRequestTicketNumber, zendeskSupportCompleted } from "../store/actions"; -import I18n from "../../../i18n"; -import ButtonDefaultOpacity from "../../../components/ButtonDefaultOpacity"; -import { Label } from "../../../components/core/typography/Label"; -import AdviceComponent from "../../../components/AdviceComponent"; -import { H4 } from "../../../components/core/typography/H4"; import { zendeskConfigSelector, zendeskTicketNumberSelector } from "../store/reducers"; -import { getValueOrElse, isReady } from "../../bonus/bpd/model/RemoteValue"; -import { H3 } from "../../../components/core/typography/H3"; -import { mixpanelTrack } from "../../../mixpanel"; type Props = { assistanceForPayment: boolean; @@ -58,7 +57,7 @@ const ZendeskSupportComponent = (props: Props) => { const zendeskToken = useIOSelector(zendeskTokenSelector); const profile = useIOSelector(profileSelector); const zendeskRemoteConfig = useIOSelector(zendeskConfigSelector); - const navigation = useNavigationContext(); + const navigation = useNavigation>(); const dispatch = useDispatch(); const ticketsNumber = useIOSelector(zendeskTicketNumberSelector); const workUnitCompleted = () => dispatch(zendeskSupportCompleted()); @@ -113,14 +112,23 @@ const ZendeskSupportComponent = (props: Props) => { if (isPanicModeActive(zendeskRemoteConfig)) { // Go to panic mode screen - navigation.navigate(navigateToZendeskPanicMode()); + navigation.navigate("ZENDESK_MAIN", { + screen: "ZENDESK_PANIC_MODE" + }); return; } - const navigationAction = canSkipCategoryChoice - ? navigateToZendeskAskPermissions - : navigateToZendeskChooseCategory; - navigation.navigate(navigationAction({ assistanceForPayment })); + if (canSkipCategoryChoice) { + navigation.navigate("ZENDESK_MAIN", { + screen: "ZENDESK_ASK_PERMISSIONS", + params: { assistanceForPayment } + }); + } else { + navigation.navigate("ZENDESK_MAIN", { + screen: "ZENDESK_CHOOSE_CATEGORY", + params: { assistanceForPayment } + }); + } }; // If the user opened at least at ticket show the "Show tickets" button diff --git a/ts/features/zendesk/components/__tests__/ZendeskSupportComponent.test.tsx b/ts/features/zendesk/components/__tests__/ZendeskSupportComponent.test.tsx index 8af87799824..9745c56cc27 100644 --- a/ts/features/zendesk/components/__tests__/ZendeskSupportComponent.test.tsx +++ b/ts/features/zendesk/components/__tests__/ZendeskSupportComponent.test.tsx @@ -1,29 +1,28 @@ -import { NavigationParams } from "react-navigation"; -import { createStore, Store } from "redux"; import { fireEvent } from "@testing-library/react-native"; -import { appReducer } from "../../../../store/reducers"; -import { applicationChangeState } from "../../../../store/actions/application"; -import { GlobalState } from "../../../../store/reducers/types"; -import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; +import { createStore, Store } from "redux"; +import { PublicSession } from "../../../../../definitions/backend/PublicSession"; +import { SpidLevelEnum } from "../../../../../definitions/backend/SpidLevel"; +import { SpidIdp } from "../../../../../definitions/content/SpidIdp"; +import { Zendesk } from "../../../../../definitions/content/Zendesk"; +import MockZendesk from "../../../../__mocks__/io-react-native-zendesk"; import ROUTES from "../../../../navigation/routes"; -import ZendeskSupportComponent from "../ZendeskSupportComponent"; +import { applicationChangeState } from "../../../../store/actions/application"; import { idpSelected, loginSuccess, sessionInformationLoadSuccess } from "../../../../store/actions/authentication"; +import { appReducer } from "../../../../store/reducers"; +import { GlobalState } from "../../../../store/reducers/types"; import { SessionToken } from "../../../../types/SessionToken"; -import { PublicSession } from "../../../../../definitions/backend/PublicSession"; -import { SpidLevelEnum } from "../../../../../definitions/backend/SpidLevel"; -import MockZendesk from "../../../../__mocks__/io-react-native-zendesk"; -import { SpidIdp } from "../../../../../definitions/content/SpidIdp"; +import { getNetworkError } from "../../../../utils/errors"; +import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; +import ZENDESK_ROUTES from "../../navigation/routes"; import { getZendeskConfig, zendeskRequestTicketNumber } from "../../store/actions"; -import * as zendeskNavigation from "../../store/actions/navigation"; -import { Zendesk } from "../../../../../definitions/content/Zendesk"; -import { getNetworkError } from "../../../../utils/errors"; +import ZendeskSupportComponent from "../ZendeskSupportComponent"; const mockPublicSession: PublicSession = { bpdToken: "bpdToken", @@ -38,6 +37,20 @@ const mockZendeskConfig: Zendesk = { const mockZendeskPanicModeConfig: Zendesk = { panicMode: true }; + +const mockedNavigation = jest.fn(); + +jest.mock("@react-navigation/native", () => { + const actualNav = jest.requireActual("@react-navigation/native"); + return { + ...actualNav, + useNavigation: () => ({ + navigate: mockedNavigation, + dispatch: jest.fn() + }) + }; +}); + jest.useFakeTimers(); describe("the ZendeskSupportComponent", () => { @@ -74,20 +87,8 @@ describe("the ZendeskSupportComponent", () => { }); describe("when the user press the zendesk open ticket button", () => { - const navigateToZendeskAskPermissionsSpy = jest.spyOn( - zendeskNavigation, - "navigateToZendeskAskPermissions" - ); - const navigateToZendeskPanicModeSpy = jest.spyOn( - zendeskNavigation, - "navigateToZendeskPanicMode" - ); - const navigateToZendeskChooseCategorySpy = jest.spyOn( - zendeskNavigation, - "navigateToZendeskChooseCategory" - ); - afterEach(() => { - jest.clearAllMocks(); + beforeEach(() => { + mockedNavigation.mockClear(); }); describe("if panic mode is false", () => { it("if the assistanceForPayment is true should navigate to the ZendeskAskPermissions screen", () => { @@ -95,30 +96,38 @@ describe("the ZendeskSupportComponent", () => { const component = renderComponent(store, true); const zendeskButton = component.getByTestId("contactSupportButton"); fireEvent(zendeskButton, "onPress"); - expect(navigateToZendeskAskPermissionsSpy).toBeCalled(); - expect(navigateToZendeskPanicModeSpy).not.toBeCalled(); - expect(navigateToZendeskChooseCategorySpy).not.toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledTimes(1); + expect(mockedNavigation).toHaveBeenCalledWith("ZENDESK_MAIN", { + params: { assistanceForPayment: undefined }, + screen: ZENDESK_ROUTES.ASK_PERMISSIONS + }); }); it("if the zendeskRemoteConfig is not remoteReady should navigate to the ZendeskAskPermissions screen", () => { const store = createStore(appReducer, globalState as any); const component = renderComponent(store, false); const zendeskButton = component.getByTestId("contactSupportButton"); fireEvent(zendeskButton, "onPress"); - expect(navigateToZendeskAskPermissionsSpy).toBeCalled(); - expect(navigateToZendeskPanicModeSpy).not.toBeCalled(); - expect(navigateToZendeskChooseCategorySpy).not.toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledTimes(1); + expect(mockedNavigation).toHaveBeenCalledWith(ZENDESK_ROUTES.MAIN, { + params: { assistanceForPayment: undefined }, + screen: ZENDESK_ROUTES.ASK_PERMISSIONS + }); store.dispatch(getZendeskConfig.request()); fireEvent(zendeskButton, "onPress"); - expect(navigateToZendeskAskPermissionsSpy).toBeCalledTimes(2); - expect(navigateToZendeskPanicModeSpy).not.toBeCalled(); - expect(navigateToZendeskChooseCategorySpy).not.toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledTimes(2); + expect(mockedNavigation).toHaveBeenCalledWith(ZENDESK_ROUTES.MAIN, { + params: { assistanceForPayment: undefined }, + screen: ZENDESK_ROUTES.ASK_PERMISSIONS + }); store.dispatch( getZendeskConfig.failure(getNetworkError("mockedError")) ); fireEvent(zendeskButton, "onPress"); - expect(navigateToZendeskAskPermissionsSpy).toBeCalledTimes(3); - expect(navigateToZendeskPanicModeSpy).not.toBeCalled(); - expect(navigateToZendeskChooseCategorySpy).not.toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledTimes(3); + expect(mockedNavigation).toHaveBeenCalledWith(ZENDESK_ROUTES.MAIN, { + params: { assistanceForPayment: undefined }, + screen: ZENDESK_ROUTES.ASK_PERMISSIONS + }); }); it("if the assistanceForPayment is false and the zendeskRemoteConfig is remoteReady should navigate to the navigateToZendeskChooseCategory screen", () => { const store = createStore(appReducer, globalState as any); @@ -126,29 +135,24 @@ describe("the ZendeskSupportComponent", () => { store.dispatch(getZendeskConfig.success(mockZendeskConfig)); const zendeskButton = component.getByTestId("contactSupportButton"); fireEvent(zendeskButton, "onPress"); - expect(navigateToZendeskChooseCategorySpy).toBeCalled(); - expect(navigateToZendeskAskPermissionsSpy).not.toBeCalled(); - expect(navigateToZendeskPanicModeSpy).not.toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledTimes(1); + expect(mockedNavigation).toHaveBeenCalledWith(ZENDESK_ROUTES.MAIN, { + params: { assistanceForPayment: undefined }, + screen: ZENDESK_ROUTES.CHOOSE_CATEGORY + }); }); }); it("if panic mode is true, should navigate to the ZendeskAskPermissions screen", () => { - const navigateToZendeskAskPermissionsSpy = jest.spyOn( - zendeskNavigation, - "navigateToZendeskAskPermissions" - ); - const navigateToZendeskPanicModeSpy = jest.spyOn( - zendeskNavigation, - "navigateToZendeskPanicMode" - ); const store = createStore(appReducer, globalState as any); const component = renderComponent(store, false); store.dispatch(getZendeskConfig.success(mockZendeskPanicModeConfig)); const zendeskButton = component.getByTestId("contactSupportButton"); fireEvent(zendeskButton, "onPress"); - expect(navigateToZendeskPanicModeSpy).toBeCalled(); - expect(navigateToZendeskAskPermissionsSpy).not.toBeCalled(); - expect(navigateToZendeskChooseCategorySpy).not.toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledTimes(1); + expect(mockedNavigation).toHaveBeenCalledWith(ZENDESK_ROUTES.MAIN, { + screen: ZENDESK_ROUTES.PANIC_MODE + }); }); }); describe("when the user press the zendesk show tickets button", () => { @@ -169,7 +173,7 @@ function renderComponent( store: Store, assistanceForPayment: boolean ) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( ZendeskSupportComponent, ROUTES.MAIN, { assistanceForPayment }, diff --git a/ts/features/zendesk/navigation/navigator.tsx b/ts/features/zendesk/navigation/navigator.tsx index d8687f6c89f..1eafddbb7cb 100644 --- a/ts/features/zendesk/navigation/navigator.tsx +++ b/ts/features/zendesk/navigation/navigator.tsx @@ -1,4 +1,5 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import ZendeskSupportHelpCenter from "../screens/ZendeskSupportHelpCenter"; import ZendeskAskPermissions from "../screens/ZendeskAskPermissions"; import ZendeskChooseCategory from "../screens/ZendeskChooseCategory"; @@ -6,7 +7,9 @@ import ZendeskChooseSubCategory from "../screens/ZendeskChooseSubCategory"; import ZendeskPanicMode from "../screens/ZendeskPanicMode"; import ZENDESK_ROUTES from "./routes"; -export const zendeskSupportNavigator = createStackNavigator( +export const zendeskSupportNavigator = createCompatNavigatorFactory( + createStackNavigator +)( { [ZENDESK_ROUTES.HELP_CENTER]: { screen: ZendeskSupportHelpCenter }, [ZENDESK_ROUTES.PANIC_MODE]: { screen: ZendeskPanicMode }, @@ -18,7 +21,7 @@ export const zendeskSupportNavigator = createStackNavigator( // Let each screen handles the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/features/zendesk/navigation/params.ts b/ts/features/zendesk/navigation/params.ts index d8f543689a7..1c452a07de2 100644 --- a/ts/features/zendesk/navigation/params.ts +++ b/ts/features/zendesk/navigation/params.ts @@ -1,10 +1,11 @@ import { ZendeskAskPermissionsNavigationParams } from "../screens/ZendeskAskPermissions"; import { ZendeskChooseCategoryNavigationParams } from "../screens/ZendeskChooseCategory"; import { ZendeskChooseSubCategoryNavigationParams } from "../screens/ZendeskChooseSubCategory"; +import { ZendeskSupportHelpCenterNavigationParams } from "../screens/ZendeskSupportHelpCenter"; import ZENDESK_ROUTES from "./routes"; export type ZendeskParamsList = { - [ZENDESK_ROUTES.HELP_CENTER]: undefined; + [ZENDESK_ROUTES.HELP_CENTER]: ZendeskSupportHelpCenterNavigationParams; [ZENDESK_ROUTES.PANIC_MODE]: undefined; [ZENDESK_ROUTES.ASK_PERMISSIONS]: ZendeskAskPermissionsNavigationParams; [ZENDESK_ROUTES.CHOOSE_CATEGORY]: ZendeskChooseCategoryNavigationParams; diff --git a/ts/features/zendesk/saga/orchestration/index.ts b/ts/features/zendesk/saga/orchestration/index.ts index 0553e6b5553..885576a7fa4 100644 --- a/ts/features/zendesk/saga/orchestration/index.ts +++ b/ts/features/zendesk/saga/orchestration/index.ts @@ -1,11 +1,13 @@ import { call } from "typed-redux-saga/macro"; -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import { ActionType } from "typesafe-actions"; +import NavigationService from "../../../../navigation/NavigationService"; import { executeWorkUnit, withFailureHandling, withResetNavigationStack } from "../../../../sagas/workUnit"; +import ZENDESK_ROUTES from "../../navigation/routes"; import { zendeskSupportBack, zendeskSupportCancel, @@ -13,8 +15,6 @@ import { zendeskSupportFailure, zendeskSupportStart } from "../../store/actions"; -import ZENDESK_ROUTES from "../../navigation/routes"; -import NavigationService from "../../../../navigation/NavigationService"; function* zendeskSupportWorkUnit( zendeskStart: ActionType @@ -22,8 +22,8 @@ function* zendeskSupportWorkUnit( return yield* call(executeWorkUnit, { startScreenNavigation: () => { NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ZENDESK_ROUTES.HELP_CENTER, + CommonActions.navigate(ZENDESK_ROUTES.MAIN, { + screen: ZENDESK_ROUTES.HELP_CENTER, params: zendeskStart.payload }) ); diff --git a/ts/features/zendesk/screens/ZendeskAskPermissions.tsx b/ts/features/zendesk/screens/ZendeskAskPermissions.tsx index 7acb30e38c5..fd3040f43af 100644 --- a/ts/features/zendesk/screens/ZendeskAskPermissions.tsx +++ b/ts/features/zendesk/screens/ZendeskAskPermissions.tsx @@ -1,8 +1,8 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { constNull } from "fp-ts/lib/function"; import { ListItem, View } from "native-base"; import React, { ReactNode } from "react"; import { SafeAreaView, ScrollView } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { useDispatch } from "react-redux"; import BatteryIcon from "../../../../img/assistance/battery.svg"; import EmailIcon from "../../../../img/assistance/email.svg"; @@ -24,6 +24,7 @@ import BaseScreenComponent from "../../../components/screens/BaseScreenComponent import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import I18n from "../../../i18n"; import { mixpanelTrack } from "../../../mixpanel"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; import { useIOSelector } from "../../../store/hooks"; import { idpSelector, @@ -37,7 +38,9 @@ import { } from "../../../store/reducers/profile"; import { getAppVersion } from "../../../utils/appVersion"; import { getModel, getSystemVersion } from "../../../utils/device"; +import { getFullLocale } from "../../../utils/locale"; import { isIos } from "../../../utils/platform"; +import { showToast } from "../../../utils/showToast"; import { addTicketCustomField, addTicketTag, @@ -49,6 +52,8 @@ import { zendeskidentityProviderId, zendeskVersionsHistoryId } from "../../../utils/supportAssistance"; +import { handleItemOnPress } from "../../../utils/url"; +import { ZendeskParamsList } from "../navigation/params"; import { zendeskSupportCompleted, zendeskSupportFailure @@ -57,9 +62,6 @@ import { zendeskSelectedCategorySelector, zendeskSelectedSubcategorySelector } from "../store/reducers"; -import { getFullLocale } from "../../../utils/locale"; -import { showToast } from "../../../utils/showToast"; -import { handleItemOnPress } from "../../../utils/url"; /** * Transform an array of string into a Zendesk @@ -188,7 +190,11 @@ export type ZendeskAskPermissionsNavigationParams = { assistanceForPayment: boolean; }; -type Props = NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; /** * this screen shows the kinds of data the app could collect when a user is asking for assistance * @constructor diff --git a/ts/features/zendesk/screens/ZendeskChooseCategory.tsx b/ts/features/zendesk/screens/ZendeskChooseCategory.tsx index 800be2b2e4b..f59b711e90a 100644 --- a/ts/features/zendesk/screens/ZendeskChooseCategory.tsx +++ b/ts/features/zendesk/screens/ZendeskChooseCategory.tsx @@ -1,3 +1,6 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; +import { useNavigation } from "@react-navigation/native"; +import { ListItem } from "native-base"; import React from "react"; import { FlatList, @@ -6,48 +9,51 @@ import { ScrollView } from "react-native"; import { useDispatch } from "react-redux"; -import { ListItem } from "native-base"; -import { NavigationStackScreenProps } from "react-navigation-stack"; -import BaseScreenComponent from "../../../components/screens/BaseScreenComponent"; -import { IOStyles } from "../../../components/core/variables/IOStyles"; +import { ZendeskCategory } from "../../../../definitions/content/ZendeskCategory"; import { H1 } from "../../../components/core/typography/H1"; +import { H4 } from "../../../components/core/typography/H4"; +import { IOStyles } from "../../../components/core/variables/IOStyles"; +import BaseScreenComponent from "../../../components/screens/BaseScreenComponent"; +import IconFont from "../../../components/ui/IconFont"; import View from "../../../components/ui/TextWithIcon"; import I18n from "../../../i18n"; -import { useIOSelector } from "../../../store/hooks"; -import { zendeskConfigSelector } from "../store/reducers"; -import { isReady } from "../../bonus/bpd/model/RemoteValue"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; import { toArray } from "../../../store/helpers/indexer"; -import { H4 } from "../../../components/core/typography/H4"; +import { useIOSelector } from "../../../store/hooks"; import customVariables from "../../../theme/variables"; -import IconFont from "../../../components/ui/IconFont"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; +import { getFullLocale } from "../../../utils/locale"; import { - navigateToZendeskAskPermissions, - navigateToZendeskChooseSubCategory -} from "../store/actions/navigation"; + addTicketCustomField, + hasSubCategories +} from "../../../utils/supportAssistance"; +import { isReady } from "../../bonus/bpd/model/RemoteValue"; +import { ZendeskParamsList } from "../navigation/params"; +import ZENDESK_ROUTES from "../navigation/routes"; import { zendeskSelectedCategory, zendeskSupportFailure } from "../store/actions"; -import { ZendeskCategory } from "../../../../definitions/content/ZendeskCategory"; -import { - addTicketCustomField, - hasSubCategories -} from "../../../utils/supportAssistance"; -import { getFullLocale } from "../../../utils/locale"; +import { zendeskConfigSelector } from "../store/reducers"; export type ZendeskChooseCategoryNavigationParams = { assistanceForPayment: boolean; }; -type Props = NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; /** * this screen shows the categories for which the user can ask support with the assistance */ const ZendeskChooseCategory = (props: Props) => { const dispatch = useDispatch(); - const navigation = useNavigationContext(); + const navigation = + useNavigation< + IOStackNavigationProp + >(); const assistanceForPayment = props.navigation.getParam( "assistanceForPayment" ); @@ -87,13 +93,13 @@ const ZendeskChooseCategory = (props: Props) => { // Set category as custom field addTicketCustomField(categoriesId, category.value); if (hasSubCategories(category)) { - navigation.navigate( - navigateToZendeskChooseSubCategory({ assistanceForPayment }) - ); + navigation.navigate(ZENDESK_ROUTES.CHOOSE_SUB_CATEGORY, { + assistanceForPayment + }); } else { - navigation.navigate( - navigateToZendeskAskPermissions({ assistanceForPayment }) - ); + navigation.navigate(ZENDESK_ROUTES.ASK_PERMISSIONS, { + assistanceForPayment + }); } }} first={listItem.index === 0} diff --git a/ts/features/zendesk/screens/ZendeskChooseSubCategory.tsx b/ts/features/zendesk/screens/ZendeskChooseSubCategory.tsx index 12c3ca34838..481f6b401b4 100644 --- a/ts/features/zendesk/screens/ZendeskChooseSubCategory.tsx +++ b/ts/features/zendesk/screens/ZendeskChooseSubCategory.tsx @@ -1,3 +1,6 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; +import { useNavigation } from "@react-navigation/native"; +import { ListItem } from "native-base"; import React from "react"; import { FlatList, @@ -6,37 +9,38 @@ import { ScrollView } from "react-native"; import { useDispatch } from "react-redux"; -import { ListItem } from "native-base"; -import { NavigationStackScreenProps } from "react-navigation-stack"; -import BaseScreenComponent from "../../../components/screens/BaseScreenComponent"; -import { IOStyles } from "../../../components/core/variables/IOStyles"; +import { ZendeskSubCategory } from "../../../../definitions/content/ZendeskSubCategory"; import { H1 } from "../../../components/core/typography/H1"; +import { H4 } from "../../../components/core/typography/H4"; +import { IOStyles } from "../../../components/core/variables/IOStyles"; +import BaseScreenComponent from "../../../components/screens/BaseScreenComponent"; +import IconFont from "../../../components/ui/IconFont"; import View from "../../../components/ui/TextWithIcon"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; import { useIOSelector } from "../../../store/hooks"; -import { zendeskSelectedCategorySelector } from "../store/reducers"; -import { H4 } from "../../../components/core/typography/H4"; import customVariables from "../../../theme/variables"; -import IconFont from "../../../components/ui/IconFont"; +import { getFullLocale } from "../../../utils/locale"; import { addTicketCustomField, hasSubCategories } from "../../../utils/supportAssistance"; +import { ZendeskParamsList } from "../navigation/params"; import { zendeskSelectedSubcategory, zendeskSupportFailure } from "../store/actions"; -import { getFullLocale } from "../../../utils/locale"; -import { ZendeskSubCategory } from "../../../../definitions/content/ZendeskSubCategory"; -import { navigateToZendeskAskPermissions } from "../store/actions/navigation"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; +import { zendeskSelectedCategorySelector } from "../store/reducers"; export type ZendeskChooseSubCategoryNavigationParams = { assistanceForPayment: boolean; }; -type Props = - NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; /** * this screen shows the sub-categories for which the user can ask support with the assistance @@ -45,7 +49,7 @@ type Props = const ZendeskChooseSubCategory = (props: Props) => { const selectedCategory = useIOSelector(zendeskSelectedCategorySelector); const dispatch = useDispatch(); - const navigation = useNavigationContext(); + const navigation = useNavigation>(); const assistanceForPayment = props.navigation.getParam( "assistanceForPayment" ); @@ -82,9 +86,9 @@ const ZendeskChooseSubCategory = (props: Props) => { selectedSubcategory(subCategory); // Set sub-category as custom field addTicketCustomField(subCategoriesId, subCategory.value); - navigation.navigate( - navigateToZendeskAskPermissions({ assistanceForPayment }) - ); + navigation.navigate("ZENDESK_ASK_PERMISSIONS", { + assistanceForPayment + }); }} first={listItem.index === 0} style={{ paddingRight: 0 }} diff --git a/ts/features/zendesk/screens/ZendeskSupportHelpCenter.tsx b/ts/features/zendesk/screens/ZendeskSupportHelpCenter.tsx index f1b8be61d92..70d14afdda9 100644 --- a/ts/features/zendesk/screens/ZendeskSupportHelpCenter.tsx +++ b/ts/features/zendesk/screens/ZendeskSupportHelpCenter.tsx @@ -1,9 +1,9 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { constNull } from "fp-ts/lib/function"; import { fromNullable, none } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import React, { useEffect, useState } from "react"; import { SafeAreaView, ScrollView } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { useDispatch } from "react-redux"; import { H3 } from "../../../components/core/typography/H3"; import { IOStyles } from "../../../components/core/variables/IOStyles"; @@ -19,6 +19,7 @@ import { import ActivityIndicator from "../../../components/ui/ActivityIndicator"; import View from "../../../components/ui/TextWithIcon"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; import { loadContextualHelpData } from "../../../store/actions/content"; import { useIOSelector } from "../../../store/hooks"; import { getContextualHelpDataFromRouteSelector } from "../../../store/reducers/content"; @@ -26,6 +27,7 @@ import themeVariables from "../../../theme/variables"; import { FAQType, getFAQsFromCategories } from "../../../utils/faq"; import { isStringNullyOrEmpty } from "../../../utils/strings"; import ZendeskSupportComponent from "../components/ZendeskSupportComponent"; +import { ZendeskParamsList } from "../navigation/params"; import { getZendeskConfig, ZendeskStartPayload, @@ -47,6 +49,8 @@ export type ContextualHelpData = { faqs?: ReadonlyArray; }; +export type ZendeskSupportHelpCenterNavigationParams = ZendeskStartPayload; + /** * This component must be used only here. * Make the {@link ZendeskSupportHelpCenter} compatible with {@link BaseScreenComponent} and substitute the {@link ContextualHelp} @@ -149,7 +153,11 @@ const FaqManager = (props: FaqManagerProps) => { ); }; -type Props = NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; /** * Ingress screen to access the Zendesk assistance tool * the user can choose to open a new ticket, follow previous conversations or read the faqs diff --git a/ts/features/zendesk/screens/__tests__/ZendeskAskPermissions.test.tsx b/ts/features/zendesk/screens/__tests__/ZendeskAskPermissions.test.tsx index 3ff51df2ded..c7cce6ed7bd 100644 --- a/ts/features/zendesk/screens/__tests__/ZendeskAskPermissions.test.tsx +++ b/ts/features/zendesk/screens/__tests__/ZendeskAskPermissions.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import { createStore, Store } from "redux"; import { fireEvent, RenderAPI } from "@testing-library/react-native"; import { ReactTestInstance } from "react-test-renderer"; @@ -236,7 +235,7 @@ function renderComponent( store: Store, assistanceForPayment: boolean ) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( ZendeskAskPermissions, ROUTES.MAIN, { assistanceForPayment }, diff --git a/ts/features/zendesk/screens/__tests__/ZendeskChooseCategory.test.tsx b/ts/features/zendesk/screens/__tests__/ZendeskChooseCategory.test.tsx index 870714e49b3..bc49d0b58db 100644 --- a/ts/features/zendesk/screens/__tests__/ZendeskChooseCategory.test.tsx +++ b/ts/features/zendesk/screens/__tests__/ZendeskChooseCategory.test.tsx @@ -1,24 +1,37 @@ -import { NavigationParams } from "react-navigation"; -import { createStore, Store } from "redux"; import { fireEvent, RenderAPI } from "@testing-library/react-native"; import { ReactTestInstance } from "react-test-renderer"; -import { appReducer } from "../../../../store/reducers"; +import { createStore, Store } from "redux"; +import { Zendesk } from "../../../../../definitions/content/Zendesk"; +import { ZendeskCategories } from "../../../../../definitions/content/ZendeskCategories"; +import { ZendeskCategory } from "../../../../../definitions/content/ZendeskCategory"; +import { ZendeskSubCategories } from "../../../../../definitions/content/ZendeskSubCategories"; +import MockZendesk from "../../../../__mocks__/io-react-native-zendesk"; +import ROUTES from "../../../../navigation/routes"; import { applicationChangeState } from "../../../../store/actions/application"; +import { appReducer } from "../../../../store/reducers"; import { GlobalState } from "../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; -import ROUTES from "../../../../navigation/routes"; +import ZENDESK_ROUTES from "../../navigation/routes"; import * as zendeskAction from "../../store/actions"; import { getZendeskConfig } from "../../store/actions"; -import { Zendesk } from "../../../../../definitions/content/Zendesk"; import ZendeskChooseCategory from "../ZendeskChooseCategory"; -import { ZendeskCategories } from "../../../../../definitions/content/ZendeskCategories"; -import { ZendeskSubCategories } from "../../../../../definitions/content/ZendeskSubCategories"; -import { ZendeskCategory } from "../../../../../definitions/content/ZendeskCategory"; -import MockZendesk from "../../../../__mocks__/io-react-native-zendesk"; -import * as navigationAction from "../../store/actions/navigation"; jest.useFakeTimers(); +const mockedNavigation = jest.fn(); + +jest.mock("@react-navigation/native", () => { + const actualNav = jest.requireActual("@react-navigation/native"); + return { + ...actualNav, + useNavigation: () => ({ + addListener: () => jest.fn(), + navigate: mockedNavigation, + dispatch: jest.fn() + }) + }; +}); + const mockedZendeskConfig: Zendesk = { panicMode: false, zendeskCategories: { @@ -100,6 +113,9 @@ describe("the ZendeskChooseCategory screen", () => { }); describe("if the Zendesk config is ready and there is at least a category", () => { + beforeEach(() => { + mockedNavigation.mockClear(); + }); it("should render the received categories", () => { const store: Store = createStore( appReducer, @@ -133,10 +149,6 @@ describe("the ZendeskChooseCategory screen", () => { ).toBeNull(); }); it("should call the addTicketCustomField and the navigateToZendeskChooseSubCategory functions when press the category if it has sub-categories", () => { - const navigateToZendeskChooseSubCategorySpy = jest.spyOn( - navigationAction, - "navigateToZendeskChooseSubCategory" - ); const store: Store = createStore( appReducer, globalState as any @@ -161,13 +173,15 @@ describe("the ZendeskChooseCategory screen", () => { ); fireEvent(categoryItem, "onPress"); expect(MockZendesk.addTicketCustomField).toBeCalled(); - expect(navigateToZendeskChooseSubCategorySpy).toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledTimes(1); + expect(mockedNavigation).toHaveBeenCalledWith( + ZENDESK_ROUTES.CHOOSE_SUB_CATEGORY, + { + assistanceForPayment: undefined + } + ); }); it("should call the navigateToZendeskAskPermissions action when press the category if it has not sub-categories", () => { - const navigateToZendeskAskPermissionsSpy = jest.spyOn( - navigationAction, - "navigateToZendeskAskPermissions" - ); const store: Store = createStore( appReducer, globalState as any @@ -178,13 +192,19 @@ describe("the ZendeskChooseCategory screen", () => { mockedZendeskConfig.zendeskCategories?.categories[0].value as string ); fireEvent(categoryItem, "onPress"); - expect(navigateToZendeskAskPermissionsSpy).toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledTimes(1); + expect(mockedNavigation).toHaveBeenCalledWith( + ZENDESK_ROUTES.ASK_PERMISSIONS, + { + assistanceForPayment: undefined + } + ); }); }); }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( ZendeskChooseCategory, ROUTES.MAIN, {}, diff --git a/ts/features/zendesk/screens/__tests__/ZendeskChooseSubCategory.test.tsx b/ts/features/zendesk/screens/__tests__/ZendeskChooseSubCategory.test.tsx index e04d93fafb0..b4879248c42 100644 --- a/ts/features/zendesk/screens/__tests__/ZendeskChooseSubCategory.test.tsx +++ b/ts/features/zendesk/screens/__tests__/ZendeskChooseSubCategory.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import { createStore, Store } from "redux"; import { fireEvent, RenderAPI } from "@testing-library/react-native"; import { ReactTestInstance } from "react-test-renderer"; @@ -7,16 +6,30 @@ import { applicationChangeState } from "../../../../store/actions/application"; import { GlobalState } from "../../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; import ROUTES from "../../../../navigation/routes"; +import ZENDESK_ROUTES from "../../navigation/routes"; import * as zendeskAction from "../../store/actions"; import { zendeskSelectedCategory } from "../../store/actions"; import { ZendeskSubCategories } from "../../../../../definitions/content/ZendeskSubCategories"; import { ZendeskCategory } from "../../../../../definitions/content/ZendeskCategory"; import MockZendesk from "../../../../__mocks__/io-react-native-zendesk"; import ZendeskChooseSubCategory from "../ZendeskChooseSubCategory"; -import * as navigationAction from "../../store/actions/navigation"; jest.useFakeTimers(); +const mockedNavigation = jest.fn(); + +jest.mock("@react-navigation/native", () => { + const actualNav = jest.requireActual("@react-navigation/native"); + return { + ...actualNav, + useNavigation: () => ({ + navigate: mockedNavigation, + dispatch: jest.fn(), + addListener: () => jest.fn() + }) + }; +}); + const mockedCategory: ZendeskCategory = { value: "mockedValue", description: { @@ -78,6 +91,9 @@ describe("the ZendeskChooseSubCategory screen", () => { }); describe("if the selected category is defined and has at least a subcategory", () => { + beforeEach(() => { + mockedNavigation.mockClear(); + }); it("should render the subcategory", () => { const store: Store = createStore( appReducer, @@ -92,10 +108,6 @@ describe("the ZendeskChooseSubCategory screen", () => { ).toBeDefined(); }); it("should call the addTicketCustomField and the navigateToZendeskAskPermissions functions when is pressed", () => { - const navigateToZendeskAskPermissionsSpy = jest.spyOn( - navigationAction, - "navigateToZendeskAskPermissions" - ); const store: Store = createStore( appReducer, globalState as any @@ -107,13 +119,18 @@ describe("the ZendeskChooseSubCategory screen", () => { ); fireEvent(subCategoryItem, "onPress"); expect(MockZendesk.addTicketCustomField).toBeCalled(); - expect(navigateToZendeskAskPermissionsSpy).toBeCalled(); + expect(mockedNavigation).toHaveBeenCalledWith( + ZENDESK_ROUTES.ASK_PERMISSIONS, + { + assistanceForPayment: undefined + } + ); }); }); }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( ZendeskChooseSubCategory, ROUTES.MAIN, {}, diff --git a/ts/features/zendesk/screens/__tests__/ZendeskPanicMode.test.tsx b/ts/features/zendesk/screens/__tests__/ZendeskPanicMode.test.tsx index dce21b5ad41..f0e80f6da29 100644 --- a/ts/features/zendesk/screens/__tests__/ZendeskPanicMode.test.tsx +++ b/ts/features/zendesk/screens/__tests__/ZendeskPanicMode.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import { createStore, Store } from "redux"; import { fireEvent, RenderAPI } from "@testing-library/react-native"; import { ReactTestInstance } from "react-test-renderer"; @@ -40,7 +39,7 @@ describe("the ZendeskPanicMode screen", () => { }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( ZendeskPanicMode, ROUTES.MAIN, {}, diff --git a/ts/features/zendesk/screens/__tests__/ZendeskSupportHelpCenter.test.tsx b/ts/features/zendesk/screens/__tests__/ZendeskSupportHelpCenter.test.tsx index 4241bc119ca..bc2af7a18d2 100644 --- a/ts/features/zendesk/screens/__tests__/ZendeskSupportHelpCenter.test.tsx +++ b/ts/features/zendesk/screens/__tests__/ZendeskSupportHelpCenter.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import { createStore, Store } from "redux"; import { RenderAPI } from "@testing-library/react-native"; import { appReducer } from "../../../../store/reducers"; @@ -38,7 +37,7 @@ describe("the ZendeskSupportHelpCenter screen", () => { }); function renderComponent(store: Store) { - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( ZendeskSupportHelpCenter, ROUTES.MAIN, {}, diff --git a/ts/features/zendesk/store/actions/navigation.ts b/ts/features/zendesk/store/actions/navigation.ts deleted file mode 100644 index 509c322345b..00000000000 --- a/ts/features/zendesk/store/actions/navigation.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { NavigationActions } from "react-navigation"; -import ZENDESK_ROUTES from "../../navigation/routes"; -import { ZendeskAskPermissionsNavigationParams } from "../../screens/ZendeskAskPermissions"; -import { ZendeskChooseSubCategoryNavigationParams } from "../../screens/ZendeskChooseSubCategory"; -import { ZendeskChooseCategoryNavigationParams } from "../../screens/ZendeskChooseCategory"; - -export const navigateToZendeskAskPermissions = ( - params: ZendeskAskPermissionsNavigationParams -) => - NavigationActions.navigate({ - routeName: ZENDESK_ROUTES.ASK_PERMISSIONS, - params - }); -export const navigateToZendeskPanicMode = () => - NavigationActions.navigate({ - routeName: ZENDESK_ROUTES.PANIC_MODE - }); -export const navigateToZendeskChooseCategory = ( - params: ZendeskChooseCategoryNavigationParams -) => - NavigationActions.navigate({ - routeName: ZENDESK_ROUTES.CHOOSE_CATEGORY, - params - }); -export const navigateToZendeskChooseSubCategory = ( - params: ZendeskChooseSubCategoryNavigationParams -) => - NavigationActions.navigate({ - routeName: ZENDESK_ROUTES.CHOOSE_SUB_CATEGORY, - params - }); diff --git a/ts/navigation/AppNavigator.ts b/ts/navigation/AppNavigator.ts deleted file mode 100644 index 1092d1b05b8..00000000000 --- a/ts/navigation/AppNavigator.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { createStackNavigator } from "react-navigation-stack"; -import WorkunitGenericFailure from "../components/error/WorkunitGenericFailure"; -import { uaDonationsEnabled, zendeskEnabled } from "../config"; -import { - CgnActivationNavigator, - CgnDetailsNavigator, - CgnEYCAActivationNavigator -} from "../features/bonus/cgn/navigation/navigator"; -import CGN_ROUTES from "../features/bonus/cgn/navigation/routes"; -import { zendeskSupportNavigator } from "../features/zendesk/navigation/navigator"; -import ZENDESK_ROUTES from "../features/zendesk/navigation/routes"; - -import BackgroundScreen from "../screens/BackgroundScreen"; -import IngressScreen from "../screens/ingress/IngressScreen"; -import UADONATION_ROUTES from "../features/uaDonations/navigation/routes"; -import { UAWebViewScreen } from "../features/uaDonations/screens/UAWebViewScreen"; -import AuthenticationNavigator from "./AuthenticationNavigator"; -import MainNavigator from "./MainNavigator"; -import OnboardingNavigator from "./OnboardingNavigator"; -import ROUTES from "./routes"; - -/** - * The main stack of screens of the Application. - */ -// eslint-disable-next-line functional/no-let -let configMap = { - [ROUTES.INGRESS]: { - // This is the first screen that gets loaded by the app navigator - // On component mount, the screen will dispatch an - // APPLICATION_INITIALIZED action that gets handled by the startup saga. - screen: IngressScreen - }, - [ROUTES.BACKGROUND]: { - screen: BackgroundScreen - }, - [ROUTES.AUTHENTICATION]: { - // The navigator used during authentication - screen: AuthenticationNavigator - }, - [ROUTES.ONBOARDING]: { - // The navigator user during onboarding for authenticated users - screen: OnboardingNavigator - }, - [ROUTES.MAIN]: { - // The navigator used for authenticated users on onboarding completed - screen: MainNavigator - }, - [ROUTES.WORKUNIT_GENERIC_FAILURE]: { - screen: WorkunitGenericFailure - } -}; - -const cgnConfigMap = { - [CGN_ROUTES.ACTIVATION.MAIN]: { - screen: CgnActivationNavigator - }, - [CGN_ROUTES.DETAILS.MAIN]: { - screen: CgnDetailsNavigator - }, - [CGN_ROUTES.EYCA.ACTIVATION.MAIN]: { - screen: CgnEYCAActivationNavigator - } -}; -configMap = { ...configMap, ...cgnConfigMap }; - -// The addition of the screen to the stack is only protected by local FF -if (zendeskEnabled) { - const zendeskMap = { - [ZENDESK_ROUTES.MAIN]: { - screen: zendeskSupportNavigator - } - }; - configMap = { ...configMap, ...zendeskMap }; -} - -if (uaDonationsEnabled) { - const uaConfigMap = { - [UADONATION_ROUTES.WEBVIEW]: { - screen: UAWebViewScreen - } - }; - configMap = { ...configMap, ...uaConfigMap }; -} - -const navigator = createStackNavigator(configMap, { - // Let each screen handle the header and navigation - headerMode: "none", - defaultNavigationOptions: { - gesturesEnabled: false - } -}); - -export default navigator; diff --git a/ts/navigation/AppStackNavigator.tsx b/ts/navigation/AppStackNavigator.tsx new file mode 100644 index 00000000000..0fe31df4286 --- /dev/null +++ b/ts/navigation/AppStackNavigator.tsx @@ -0,0 +1,143 @@ +/* eslint-disable functional/immutable-data */ +import { DefaultTheme, NavigationContainer } from "@react-navigation/native"; +import { createStackNavigator } from "@react-navigation/stack"; +import { View } from "native-base"; +import * as React from "react"; +import { useRef } from "react"; +import { IOColors } from "../components/core/variables/IOColors"; +import workunitGenericFailure from "../components/error/WorkunitGenericFailure"; +import { + CgnActivationNavigator, + CgnDetailsNavigator, + CgnEYCAActivationNavigator +} from "../features/bonus/cgn/navigation/navigator"; +import CGN_ROUTES from "../features/bonus/cgn/navigation/routes"; +import UADONATION_ROUTES from "../features/uaDonations/navigation/routes"; +import { UAWebViewScreen } from "../features/uaDonations/screens/UAWebViewScreen"; +import { zendeskSupportNavigator } from "../features/zendesk/navigation/navigator"; +import ZENDESK_ROUTES from "../features/zendesk/navigation/routes"; +import IngressScreen from "../screens/ingress/IngressScreen"; +import { setDebugCurrentRouteName } from "../store/actions/debug"; +import { useIODispatch } from "../store/hooks"; +import { trackScreen } from "../store/middlewares/navigation"; +import { isTestEnv } from "../utils/environment"; +import authenticationNavigator from "./AuthenticationNavigator"; +import messagesNavigator from "./MessagesNavigator"; +import NavigationService, { navigationRef } from "./NavigationService"; +import onboardingNavigator from "./OnboardingNavigator"; +import { AppParamsList } from "./params/AppParamsList"; +import profileNavigator from "./ProfileNavigator"; +import ROUTES from "./routes"; +import servicesNavigator from "./ServicesNavigator"; +import { MainTabNavigator } from "./TabNavigator"; +import walletNavigator from "./WalletNavigator"; + +const Stack = createStackNavigator(); + +export const AppStackNavigator = () => ( + + + + + + + + + + + + + + + + + + + + + +); + +const IOTheme = { + ...DefaultTheme, + colors: { + ...DefaultTheme.colors, + background: IOColors.white + } +}; + +const InnerNavigationContainer = (props: { children: React.ReactElement }) => { + const routeNameRef = useRef(); + const dispatch = useIODispatch(); + + return ( + { + NavigationService.setNavigationReady(); + routeNameRef.current = navigationRef.current?.getCurrentRoute()?.name; + }} + onStateChange={async () => { + const previousRouteName = routeNameRef.current; + const currentRouteName = navigationRef.current?.getCurrentRoute()?.name; + + if (currentRouteName !== undefined) { + dispatch(setDebugCurrentRouteName(currentRouteName)); + trackScreen(previousRouteName, currentRouteName); + } + routeNameRef.current = currentRouteName; + }} + > + {props.children} + + ); +}; + +/** + * Wraps the NavigationContainer with the AppStackNavigator (Root navigator of the app) + * @constructor + */ +export const IONavigationContainer = () => ( + + + +); + +export const TestInnerNavigationContainer = isTestEnv + ? InnerNavigationContainer + : View; diff --git a/ts/navigation/AuthenticationNavigator.ts b/ts/navigation/AuthenticationNavigator.ts index 7453d1f9f73..603a701947f 100644 --- a/ts/navigation/AuthenticationNavigator.ts +++ b/ts/navigation/AuthenticationNavigator.ts @@ -1,9 +1,5 @@ -import { NavigationRoute, NavigationRouteConfigMap } from "react-navigation"; -import { createStackNavigator } from "react-navigation-stack"; -import { - NavigationStackOptions, - NavigationStackProp -} from "react-navigation-stack/src/types"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import { environment } from "../config"; import CardSelectionScreen from "../screens/authentication/CardSelectionScreen"; import CieAuthorizeDataUsageScreen from "../screens/authentication/cie/CieAuthorizeDataUsageScreen"; @@ -23,10 +19,7 @@ import MarkdownScreen from "../screens/development/MarkdownScreen"; import ROUTES from "./routes"; // Routes loaded in production mode -const productionRouteConfigMap: NavigationRouteConfigMap< - NavigationStackOptions, - NavigationStackProp -> = { +const productionRouteConfigMap = { [ROUTES.AUTHENTICATION_LANDING]: { screen: LandingScreen }, @@ -76,10 +69,7 @@ const productionRouteConfigMap: NavigationRouteConfigMap< }; // Routes loaded on development mode -const developmentRouteConfigMap: NavigationRouteConfigMap< - NavigationStackOptions, - NavigationStackProp -> = { +const developmentRouteConfigMap = { ...productionRouteConfigMap, [ROUTES.MARKDOWN]: { screen: MarkdownScreen @@ -89,13 +79,13 @@ const developmentRouteConfigMap: NavigationRouteConfigMap< /** * The authentication related stack of screens of the application. */ -const navigator = createStackNavigator( +const navigator = createCompatNavigatorFactory(createStackNavigator)( environment === "DEV" ? developmentRouteConfigMap : productionRouteConfigMap, { // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/navigation/MainNavigator.tsx b/ts/navigation/MainNavigator.tsx deleted file mode 100644 index fc951a6c4bb..00000000000 --- a/ts/navigation/MainNavigator.tsx +++ /dev/null @@ -1,179 +0,0 @@ -/** - * Main navigator, handling the navigation within - * the app *after* the login and onboarding have - * occurred. This takes care of displaying a tab - * navigator with the appropriate icons - */ - -import * as React from "react"; -import { StyleSheet } from "react-native"; -import deviceInfoModule from "react-native-device-info"; -import { - NavigationRoute, - NavigationScreenProp, - NavigationState -} from "react-navigation"; -import { createBottomTabNavigator } from "react-navigation-tabs"; -import MessagesTabIcon from "../components/MessagesTabIcon"; -import NavBarLabel from "../components/NavBarLabel"; -import ProfileTabIcon from "../components/ProfileTabIcon"; -import ServiceTabIcon from "../components/ServiceTabIcon"; -import IconFont from "../components/ui/IconFont"; -import WalletTabIcon from "../components/WalletTabIcon"; -import variables from "../theme/variables"; -import MessageNavigator from "./MessagesNavigator"; -import ProfileNavigator from "./ProfileNavigator"; -import ROUTES from "./routes"; -import ServicesNavigator from "./ServicesNavigator"; -import WalletNavigator from "./WalletNavigator"; - -type Routes = keyof typeof ROUTES; - -type RouteIconMap = { [key in Routes]?: string }; -const ROUTE_ICON: RouteIconMap = { - MESSAGES_NAVIGATOR: "io-messaggi", - WALLET_HOME: "io-portafoglio", - SERVICES_NAVIGATOR: "io-servizi", - PROFILE_NAVIGATOR: "io-profilo" -}; - -const getIcon = (routeName: string): string => { - const fallbackIcon = "io-question"; // fallback icon: question mark - const route = ROUTE_ICON[routeName as Routes]; // same as for getLabel - return route === undefined ? fallbackIcon : route; -}; - -const tabBarStyleFactory = () => { - const defaultStyle = { - backgroundColor: variables.colorWhite, - paddingLeft: 3, - paddingRight: 3, - borderTopWidth: 0, - paddingTop: 8, - height: 64 - }; - - return deviceInfoModule.hasNotch() - ? defaultStyle - : { ...defaultStyle, paddingBottom: 10 }; -}; - -const styles = StyleSheet.create({ - tabBarStyle: tabBarStyleFactory(), - upsideShadow: { - // iOS shadow - shadowColor: variables.footerShadowColor, - shadowOffset: { - width: variables.footerShadowOffsetWidth, - height: variables.footerShadowOffsetHeight - }, - zIndex: 999, - shadowOpacity: variables.footerShadowOpacity, - shadowRadius: variables.footerShadowRadius, - // Android shadow - elevation: variables.footerElevation - } -}); - -const TabFirstLevelRoutes: Array = [ - ROUTES.WALLET_HOME, - ROUTES.MESSAGES_HOME, - ROUTES.SERVICES_HOME, - ROUTES.PROFILE_MAIN -]; - -const getTabBarVisibility = ( - nav: NavigationScreenProp -): boolean => { - const state = nav.state as NavigationState; - - const { routeName } = state.routes[state.index]; - - return TabFirstLevelRoutes.indexOf(routeName) !== -1; -}; - -/** - * A navigator for all the screens used when the user is authenticated. - */ -const navigation = createBottomTabNavigator( - { - [ROUTES.MESSAGES_NAVIGATOR]: { - screen: MessageNavigator - }, - [ROUTES.WALLET_HOME]: { - screen: WalletNavigator - }, - [ROUTES.SERVICES_NAVIGATOR]: { - screen: ServicesNavigator - }, - [ROUTES.PROFILE_NAVIGATOR]: { - screen: ProfileNavigator - } - }, - { - defaultNavigationOptions: ({ navigation: nav }) => ({ - tabBarVisible: getTabBarVisibility(nav), - tabBarLabel: (options: { - tintColor: string | null; - focused: boolean; - }) => { - const { routeName } = nav.state; - // adding `color` as a separate style property since it depends on tintColor - return ; - }, - tabBarIcon: (options: { tintColor: string | null; focused: boolean }) => { - const { routeName } = nav.state; - const iconName: string = getIcon(routeName); - if (routeName === ROUTES.MESSAGES_NAVIGATOR) { - return ( - - ); - } - if (iconName === ROUTE_ICON.WALLET_HOME) { - return ( - - ); - } - if (iconName === ROUTE_ICON.PROFILE_NAVIGATOR) { - return ( - - ); - } - if (iconName === ROUTE_ICON.SERVICES_NAVIGATOR) { - return ( - - ); - } else { - return ( - - ); - } - } - }), - tabBarOptions: { - /** - * Add the hidden on keyboard show option when https://www.pivotaltracker.com/story/show/172715822 - * see https://github.com/react-navigation/react-navigation/issues/7415#issuecomment-485027123 - */ - activeTintColor: variables.brandPrimary, - inactiveTintColor: variables.brandDarkGray, - style: [styles.tabBarStyle, styles.upsideShadow] - }, - initialRouteName: ROUTES.MESSAGES_NAVIGATOR - } -); - -export default navigation; diff --git a/ts/navigation/MessagesNavigator.ts b/ts/navigation/MessagesNavigator.ts index 858e586faff..52393d9a2d9 100644 --- a/ts/navigation/MessagesNavigator.ts +++ b/ts/navigation/MessagesNavigator.ts @@ -1,37 +1,18 @@ -import { NavigationRoute, NavigationRouteConfigMap } from "react-navigation"; -import { createStackNavigator } from "react-navigation-stack"; -import { - NavigationStackOptions, - NavigationStackProp -} from "react-navigation-stack/src/types"; - -import { - euCovidCertificateEnabled, - mvlEnabled, - usePaginatedMessages -} from "../config"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; +import { euCovidCertificateEnabled, mvlEnabled } from "../config"; import EuCovidCertNavigator from "../features/euCovidCert/navigation/navigator"; import EUCOVIDCERT_ROUTES from "../features/euCovidCert/navigation/routes"; import MvlNavigator from "../features/mvl/navigation/navigator"; import MVL_ROUTES from "../features/mvl/navigation/routes"; import MessageDetailScreen from "../screens/messages/MessageDetailScreen"; import MessageRouterScreen from "../screens/messages/MessageRouterScreen"; -import MessagesHomeScreen from "../screens/messages/MessagesHomeScreen"; import PaginatedMessageDetailScreen from "../screens/messages/paginated/MessageDetailScreen"; import PaginatedMessageRouterScreen from "../screens/messages/paginated/MessageRouterScreen"; -import PaginatedMessagesHomeScreen from "../screens/messages/paginated/MessagesHomeScreen"; import ROUTES from "./routes"; -const baseMessageRouteConfig: NavigationRouteConfigMap< - NavigationStackOptions, - NavigationStackProp -> = { - [ROUTES.MESSAGES_HOME]: { - screen: usePaginatedMessages - ? PaginatedMessagesHomeScreen - : MessagesHomeScreen - }, +const baseMessageRouteConfig = { [ROUTES.MESSAGE_ROUTER]: { screen: MessageRouterScreen }, @@ -46,43 +27,32 @@ const baseMessageRouteConfig: NavigationRouteConfigMap< } }; -const euCovidCertificateRouteConfig: NavigationRouteConfigMap< - NavigationStackOptions, - NavigationStackProp -> = euCovidCertificateEnabled - ? { - [EUCOVIDCERT_ROUTES.MAIN]: { - screen: EuCovidCertNavigator - } - } - : {}; - -const mvlRouteConfig: NavigationRouteConfigMap< - NavigationStackOptions, - NavigationStackProp -> = mvlEnabled - ? { - [MVL_ROUTES.MAIN]: { - screen: MvlNavigator - } - } - : {}; +const euCovidCertificateRouteConfig = { + [EUCOVIDCERT_ROUTES.MAIN]: { + screen: EuCovidCertNavigator + } +}; -const messageRouteConfig: NavigationRouteConfigMap< - NavigationStackOptions, - NavigationStackProp -> = { +const mvlRouteConfig = { + [MVL_ROUTES.MAIN]: { + screen: MvlNavigator + } +}; +const messageRouteConfig = { ...baseMessageRouteConfig, - ...euCovidCertificateRouteConfig, - ...mvlRouteConfig + ...(euCovidCertificateEnabled ? euCovidCertificateRouteConfig : {}), + ...(mvlEnabled ? mvlRouteConfig : {}) }; -const MessagesNavigator = createStackNavigator(messageRouteConfig, { - // Let each screen handle the header and navigation - headerMode: "none", - defaultNavigationOptions: { - gesturesEnabled: false +const MessagesNavigator = createCompatNavigatorFactory(createStackNavigator)( + messageRouteConfig, + { + // Let each screen handle the header and navigation + headerMode: "none", + defaultNavigationOptions: { + gestureEnabled: false + } } -}); +); export default MessagesNavigator; diff --git a/ts/navigation/NavigationService.ts b/ts/navigation/NavigationService.ts index 8c361753031..31b2bc4d218 100644 --- a/ts/navigation/NavigationService.ts +++ b/ts/navigation/NavigationService.ts @@ -1,27 +1,27 @@ import { NavigationAction, - NavigationActions, - NavigationContainerComponent, - NavigationLeafRoute, - NavigationParams, - NavigationState -} from "react-navigation"; + NavigationContainerRef +} from "@react-navigation/native"; +import { Route } from "@react-navigation/routers"; +import React from "react"; import { mixpanelTrack } from "../mixpanel"; -import { - getCurrentRoute as utilsGetCurrentRoute, - getCurrentRouteKey as utilsGetCurrentRouteKey, - getCurrentRouteName as utilsGetCurrentRouteName -} from "../utils/navigation"; +export const navigationRef = React.createRef(); // eslint-disable-next-line functional/no-let -let navigator: NavigationContainerComponent | null | undefined; -// eslint-disable-next-line functional/no-let -let currentRouteState: NavigationState | null = null; +let isNavigationReady: boolean = false; + +export const setNavigationReady = () => { + // eslint-disable-next-line functional/immutable-data + isNavigationReady = true; +}; + +export const getIsNavigationReady = () => + isNavigationReady && navigationRef.current !== null; const withLogging = , R>(f: (...a: A) => R) => (...args: A): R => { - if (navigator === null || navigator === undefined) { + if (navigationRef.current === null || !isNavigationReady) { void mixpanelTrack("NAVIGATION_SERVICE_NAVIGATOR_UNDEFINED", { method: f.name }); @@ -29,48 +29,42 @@ const withLogging = return f(...args); }; -const setTopLevelNavigator = ( - navigatorRef: NavigationContainerComponent | null | undefined -) => { - navigator = navigatorRef; -}; - -const getNavigator = (): NavigationContainerComponent | null | undefined => - navigator; - -const setCurrentState = (state: NavigationState) => { - // This is a security check since sometime the onNavigationStateChange could return an undefined state ignoring the type - currentRouteState = state ?? null; -}; +// NavigationContainerComponent +const getNavigator = (): React.RefObject => + navigationRef; -const navigate = (routeName: string, params?: NavigationParams) => { - navigator?.dispatch(NavigationActions.navigate({ routeName, params })); +// NavigationParams +const navigate = (routeName: string, params?: any) => { + if (isNavigationReady) { + navigationRef.current?.navigate(routeName, params); + } }; const dispatchNavigationAction = (action: NavigationAction) => { - navigator?.dispatch(action); + navigationRef.current?.dispatch(action); }; const getCurrentRouteName = (): string | undefined => - currentRouteState ? utilsGetCurrentRouteName(currentRouteState) : undefined; + navigationRef.current?.getCurrentRoute()?.name; const getCurrentRouteKey = (): string | undefined => - currentRouteState ? utilsGetCurrentRouteKey(currentRouteState) : undefined; + navigationRef.current?.getCurrentRoute()?.key; -const getCurrentRoute = (): NavigationLeafRoute | undefined => - currentRouteState ? utilsGetCurrentRoute(currentRouteState) : undefined; +// NavigationLeafRoute +const getCurrentRoute = (): Route | undefined => + navigationRef.current?.getCurrentRoute(); -const getCurrentState = (): NavigationState | null => currentRouteState; +const getCurrentState = () => navigationRef?.current?.getState(); // add other navigation functions that you need and export them export default { navigate: withLogging(navigate), getNavigator, - setTopLevelNavigator, dispatchNavigationAction: withLogging(dispatchNavigationAction), - setCurrentState, getCurrentRouteName, getCurrentRouteKey, getCurrentRoute, - getCurrentState + getCurrentState, + getIsNavigationReady, + setNavigationReady }; diff --git a/ts/navigation/OnboardingNavigator.ts b/ts/navigation/OnboardingNavigator.ts index d7e5f3c7a87..4db2650f8d5 100644 --- a/ts/navigation/OnboardingNavigator.ts +++ b/ts/navigation/OnboardingNavigator.ts @@ -1,39 +1,20 @@ -import { - createStackNavigator, - NavigationStackOptions, - NavigationStackProp -} from "react-navigation-stack"; -import { NavigationRoute, NavigationRouteConfigMap } from "react-navigation"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import EmailInsertScreen from "../screens/onboarding/EmailInsertScreen"; import EmailReadScreen from "../screens/onboarding/EmailReadScreen"; import FingerprintScreen from "../screens/onboarding/FingerprintScreen"; +import OnboardingServicesPreferenceScreen from "../screens/onboarding/OnboardingServicesPreferenceScreen"; import OnboardingShareDataScreen from "../screens/onboarding/OnboardingShareDataScreen"; import PinScreen from "../screens/onboarding/PinScreen"; -import TosScreen from "../screens/onboarding/TosScreen"; -import OnboardingServicesPreferenceScreen from "../screens/onboarding/OnboardingServicesPreferenceScreen"; -import ServicePreferenceCompleteScreen from "../screens/onboarding/ServicePreferenceCompleteScreen"; import { PremiumMessagesOptInOutScreen } from "../screens/onboarding/premiumMessages/PremiumMessagesOptInOutScreen"; -import { premiumMessagesOptInEnabled } from "../config"; +import ServicePreferenceCompleteScreen from "../screens/onboarding/ServicePreferenceCompleteScreen"; +import TosScreen from "../screens/onboarding/TosScreen"; import ROUTES from "./routes"; -/** - * The routes used for the premium messages feature. - */ -const premiumMessagesRoutes: NavigationRouteConfigMap< - NavigationStackOptions, - NavigationStackProp -> = premiumMessagesOptInEnabled - ? { - [ROUTES.ONBOARDING_PREMIUM_MESSAGES_OPT_IN_OUT]: { - screen: PremiumMessagesOptInOutScreen - } - } - : {}; - /** * The onboarding related stack of screens of the application. */ -const navigator = createStackNavigator( +const navigator = createCompatNavigatorFactory(createStackNavigator)( { [ROUTES.ONBOARDING_SHARE_DATA]: { screen: OnboardingShareDataScreen @@ -59,13 +40,15 @@ const navigator = createStackNavigator( [ROUTES.READ_EMAIL_SCREEN]: { screen: EmailReadScreen }, - ...premiumMessagesRoutes + [ROUTES.ONBOARDING_PREMIUM_MESSAGES_OPT_IN_OUT]: { + screen: PremiumMessagesOptInOutScreen + } }, { // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/navigation/ProfileNavigator.ts b/ts/navigation/ProfileNavigator.ts index 370cc980b0a..ce2760ae0d7 100644 --- a/ts/navigation/ProfileNavigator.ts +++ b/ts/navigation/ProfileNavigator.ts @@ -1,9 +1,11 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import LogoutScreen from "../components/screens/LogoutScreen"; import EmailInsertScreen from "../screens/onboarding/EmailInsertScreen"; import EmailReadScreen from "../screens/onboarding/EmailReadScreen"; import TosScreen from "../screens/onboarding/TosScreen"; import CalendarsPreferencesScreen from "../screens/profile/CalendarsPreferencesScreen"; +import CgnLandingPlayground from "../screens/profile/CgnLandingPlayground"; import DownloadProfileDataScreen from "../screens/profile/DownloadProfileDataScreen"; import EmailForwardingScreen from "../screens/profile/EmailForwardingScreen"; import FiscalCodeScreen from "../screens/profile/FiscalCodeScreen"; @@ -11,27 +13,22 @@ import LanguagesPreferencesScreen from "../screens/profile/LanguagesPreferencesS import MarkdownPlayground from "../screens/profile/playgrounds/MarkdownPlayground"; import PreferencesScreen from "../screens/profile/PreferencesScreen"; import PrivacyMainScreen from "../screens/profile/PrivacyMainScreen"; -import ProfileMainScreen from "../screens/profile/ProfileMainScreen"; +import ProfileDataScreen from "../screens/profile/ProfileDataScreen"; import RemoveAccountDetails from "../screens/profile/RemoveAccountDetailsScreen"; import RemoveAccountInfo from "../screens/profile/RemoveAccountInfoScreen"; import RemoveAccountSuccess from "../screens/profile/RemoveAccountSuccessScreen"; +import SecurityScreen from "../screens/profile/SecurityScreen"; +import ServicesPreferenceScreen from "../screens/profile/ServicesPreferenceScreen"; import ShareDataScreen from "../screens/profile/ShareDataScreen"; import WebPlayground from "../screens/profile/WebPlayground"; import { Showroom } from "../screens/showroom/Showroom"; -import ServicesPreferenceScreen from "../screens/profile/ServicesPreferenceScreen"; -import ProfileDataScreen from "../screens/profile/ProfileDataScreen"; -import SecurityScreen from "../screens/profile/SecurityScreen"; -import CgnLandingPlayground from "../screens/profile/CgnLandingPlayground"; import ROUTES from "./routes"; /** * A navigator for all the screens of the Profile section */ -const ProfileNavigator = createStackNavigator( +const ProfileNavigator = createCompatNavigatorFactory(createStackNavigator)( { - [ROUTES.PROFILE_MAIN]: { - screen: ProfileMainScreen - }, [ROUTES.PROFILE_PRIVACY_MAIN]: { screen: PrivacyMainScreen }, @@ -103,7 +100,7 @@ const ProfileNavigator = createStackNavigator( // Let each screen handle the header and navigation headerMode: "none", defaultNavigationOptions: { - gesturesEnabled: false + gestureEnabled: false } } ); diff --git a/ts/navigation/ServicesNavigator.ts b/ts/navigation/ServicesNavigator.ts index 2ae7219507b..3bf53342ad9 100644 --- a/ts/navigation/ServicesNavigator.ts +++ b/ts/navigation/ServicesNavigator.ts @@ -1,16 +1,13 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import { myPortalEnabled, svEnabled } from "../config"; +import SvNavigator from "../features/bonus/siciliaVola/navigation/navigator"; import ServiceDetailsScreen from "../screens/services/ServiceDetailsScreen"; -import ServicesHomeScreen from "../screens/services/ServicesHomeScreen"; import ServicesWebviewScreen from "../screens/services/ServicesWebviewScreen"; -import SvNavigator from "../features/bonus/siciliaVola/navigation/navigator"; import ROUTES from "./routes"; const servicesRoutes = { - [ROUTES.SERVICES_HOME]: { - screen: ServicesHomeScreen - }, [ROUTES.SERVICE_DETAIL]: { screen: ServiceDetailsScreen } @@ -28,12 +25,15 @@ const routeConfig = myPortalEnabled ? { ...servicesRoutes, ...myPortalRoutes, ...svConfigMap } : { ...servicesRoutes, ...svConfigMap }; -const ServicesNavigator = createStackNavigator(routeConfig, { - // Let each screen handle the header and navigation - headerMode: "none", - defaultNavigationOptions: { - gesturesEnabled: false +const ServicesNavigator = createCompatNavigatorFactory(createStackNavigator)( + routeConfig, + { + // Let each screen handle the header and navigation + headerMode: "none", + defaultNavigationOptions: { + gestureEnabled: false + } } -}); +); export default ServicesNavigator; diff --git a/ts/navigation/TabNavigator.tsx b/ts/navigation/TabNavigator.tsx new file mode 100644 index 00000000000..cdd752811e2 --- /dev/null +++ b/ts/navigation/TabNavigator.tsx @@ -0,0 +1,96 @@ +import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; +import * as React from "react"; +import { StyleSheet } from "react-native"; +import deviceInfoModule from "react-native-device-info"; +import { makeFontStyleObject } from "../components/core/fonts"; +import { IOColors } from "../components/core/variables/IOColors"; +import MessagesTabIcon from "../components/MessagesTabIcon"; +import ProfileTabIcon from "../components/ProfileTabIcon"; +import ServiceTabIcon from "../components/ServiceTabIcon"; +import WalletTabIcon from "../components/WalletTabIcon"; +import { usePaginatedMessages } from "../config"; +import I18n from "../i18n"; +import MessagesHomeScreen from "../screens/messages/MessagesHomeScreen"; +import PaginatedMessagesHomeScreen from "../screens/messages/paginated/MessagesHomeScreen"; +import ProfileMainScreen from "../screens/profile/ProfileMainScreen"; +import ServicesHomeScreen from "../screens/services/ServicesHomeScreen"; +import WalletHomeScreen from "../screens/wallet/WalletHomeScreen"; +import variables from "../theme/variables"; +import { MainTabParamsList } from "./params/MainTabParamsList"; +import ROUTES from "./routes"; + +const Tab = createBottomTabNavigator(); + +const styles = StyleSheet.create({ + tabBarStyle: { + backgroundColor: variables.colorWhite, + paddingLeft: 3, + paddingRight: 3, + borderTopWidth: 0, + paddingTop: 8, + height: 64 + (deviceInfoModule.hasNotch() ? 24 : 0), + // iOS shadow + shadowColor: variables.footerShadowColor, + shadowOffset: { + width: variables.footerShadowOffsetWidth, + height: variables.footerShadowOffsetHeight + }, + zIndex: 999, + shadowOpacity: variables.footerShadowOpacity, + shadowRadius: variables.footerShadowRadius, + // Android shadow + elevation: variables.footerElevation + }, + notchPadding: deviceInfoModule.hasNotch() ? {} : { paddingBottom: 10 } +}); + +export const MainTabNavigator = () => ( + + + }} + /> + + }} + /> + + }} + /> + + }} + /> + +); diff --git a/ts/navigation/WalletNavigator.ts b/ts/navigation/WalletNavigator.ts index 3776da78d20..89422511b29 100644 --- a/ts/navigation/WalletNavigator.ts +++ b/ts/navigation/WalletNavigator.ts @@ -1,4 +1,5 @@ -import { createStackNavigator } from "react-navigation-stack"; +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import { bonusVacanzeEnabled, bpdEnabled, @@ -9,12 +10,12 @@ import BONUSVACANZE_ROUTES from "../features/bonus/bonusVacanze/navigation/route import ActiveBonusScreen from "../features/bonus/bonusVacanze/screens/ActiveBonusScreen"; import { BpdDetailsNavigator, - BpdIBANNavigator, BpdOnboardingNavigator, OptInPaymentMethodNavigator } from "../features/bonus/bpd/navigation/navigator"; import BPD_ROUTES from "../features/bonus/bpd/navigation/routes"; import IbanCTAEditScreen from "../features/bonus/bpd/screens/iban/IbanCTAEditScreen"; +import MainIbanScreen from "../features/bonus/bpd/screens/iban/MainIbanScreen"; import BancomatDetailScreen from "../features/wallet/bancomat/screen/BancomatDetailScreen"; import BPayDetailScreen from "../features/wallet/bancomatpay/screen/BPayDetailScreen"; import CobadgeDetailScreen from "../features/wallet/cobadge/screen/CobadgeDetailScreen"; @@ -30,12 +31,15 @@ import WALLET_ONBOARDING_COBADGE_ROUTES from "../features/wallet/onboarding/coba import ActivateBpdOnNewCoBadgeScreen from "../features/wallet/onboarding/cobadge/screens/ActivateBpdOnNewCoBadgeScreen"; import { ActivateBpdOnNewCreditCardScreen } from "../features/wallet/onboarding/common/screens/bpd/ActivateBpdOnNewCreditCardScreen"; import { PaymentMethodOnboardingPayPalOnboardingNavigator } from "../features/wallet/onboarding/paypal/navigation/navigator"; +import PAYPAL_ROUTES from "../features/wallet/onboarding/paypal/navigation/routes"; import PaymentMethodOnboardingPrivativeNavigator from "../features/wallet/onboarding/privative/navigation/navigator"; import WALLET_ONBOARDING_PRIVATIVE_ROUTES from "../features/wallet/onboarding/privative/navigation/routes"; import ActivateBpdOnNewPrivativeScreen from "../features/wallet/onboarding/privative/screens/ActivateBpdOnNewPrivativeScreen"; import PaymentMethodOnboardingSatispayNavigator from "../features/wallet/onboarding/satispay/navigation/navigator"; import WALLET_ONBOARDING_SATISPAY_ROUTES from "../features/wallet/onboarding/satispay/navigation/routes"; import ActivateBpdOnNewSatispayScreen from "../features/wallet/onboarding/satispay/screens/ActivateBpdOnNewSatispayScreen"; +import PaypalDetailScreen from "../features/wallet/paypal/screen/PaypalDetailScreen"; +import PayPalPspUpdateScreen from "../features/wallet/paypal/screen/PayPalPspUpdateScreen"; import PrivativeDetailScreen from "../features/wallet/privative/screen/PrivativeDetailScreen"; import SatispayDetailScreen from "../features/wallet/satispay/screen/SatispayDetailScreen"; import AddCardScreen from "../screens/wallet/AddCardScreen"; @@ -55,16 +59,9 @@ import TransactionSummaryScreen from "../screens/wallet/payment/TransactionSumma import PaymentHistoryDetailsScreen from "../screens/wallet/PaymentHistoryDetailsScreen"; import PaymentsHistoryScreen from "../screens/wallet/PaymentsHistoryScreen"; import TransactionDetailsScreen from "../screens/wallet/TransactionDetailsScreen"; -import WalletHomeScreen from "../screens/wallet/WalletHomeScreen"; -import PaypalDetailScreen from "../features/wallet/paypal/screen/PaypalDetailScreen"; -import PAYPAL_ROUTES from "../features/wallet/onboarding/paypal/navigation/routes"; -import PayPalPspUpdateScreen from "../features/wallet/paypal/screen/PayPalPspUpdateScreen"; import ROUTES from "./routes"; const baseRouteConfigMap = { - [ROUTES.WALLET_HOME]: { - screen: WalletHomeScreen - }, [ROUTES.WALLET_ADD_PAYMENT_METHOD]: { screen: AddPaymentMethodScreen }, @@ -155,8 +152,8 @@ const bpdConfigMap = { [BPD_ROUTES.ONBOARDING.MAIN]: { screen: BpdOnboardingNavigator }, - [BPD_ROUTES.IBAN_MAIN]: { - screen: BpdIBANNavigator + [BPD_ROUTES.IBAN]: { + screen: MainIbanScreen }, [BPD_ROUTES.DETAILS_MAIN]: { screen: BpdDetailsNavigator @@ -219,12 +216,15 @@ const routeConfig = { ...(bpdOptInPaymentMethodsEnabled ? optInPaymentMethodsConfigMap : {}) }; -const WalletNavigator = createStackNavigator(routeConfig, { - // Let each screen handle the header and navigation - headerMode: "none", - defaultNavigationOptions: { - gesturesEnabled: false +const WalletNavigator = createCompatNavigatorFactory(createStackNavigator)( + routeConfig, + { + // Let each screen handle the header and navigation + headerMode: "none", + defaultNavigationOptions: { + gestureEnabled: false + } } -}); +); export default WalletNavigator; diff --git a/ts/navigation/params/AppParamsList.ts b/ts/navigation/params/AppParamsList.ts index f66e51e4c95..69f5690f896 100644 --- a/ts/navigation/params/AppParamsList.ts +++ b/ts/navigation/params/AppParamsList.ts @@ -1,17 +1,63 @@ -import ROUTES from "../routes"; +import { + NavigatorScreenParams, + ParamListBase, + RouteProp +} from "@react-navigation/native"; +import { StackNavigationProp } from "@react-navigation/stack"; +import { + CgnActivationParamsList, + CgnDetailsParamsList, + CgnEYCAActivationParamsList +} from "../../features/bonus/cgn/navigation/params"; +import CGN_ROUTES from "../../features/bonus/cgn/navigation/routes"; import UADONATION_ROUTES from "../../features/uaDonations/navigation/routes"; +import { ZendeskParamsList } from "../../features/zendesk/navigation/params"; +import ZENDESK_ROUTES from "../../features/zendesk/navigation/routes"; +import ROUTES from "../routes"; +import { AuthenticationParamsList } from "./AuthenticationParamsList"; +import { MainTabParamsList } from "./MainTabParamsList"; +import { MessagesParamsList } from "./MessagesParamsList"; +import { OnboardingParamsList } from "./OnboardingParamsList"; +import { ProfileParamsList } from "./ProfileParamsList"; +import { ServicesParamsList } from "./ServicesParamsList"; +import { WalletParamsList } from "./WalletParamsList"; export type AppParamsList = { [ROUTES.INGRESS]: undefined; [ROUTES.BACKGROUND]: undefined; - // TODO: [ROUTES.AUTHENTICATION]: NavigatorScreenParams - // TODO: [ROUTES.ONBOARDING]: NavigatorScreenParams - // TODO: [ROUTES.MAIN]: NavigatorScreenParams - // TODO: [CGN_ROUTES.ACTIVATION.MAIN]: NavigatorScreenParams - // TODO: [CGN_ROUTES.DETAILS.MAIN]: NavigatorScreenParams - // TODO: [CGN_ROUTES.EYCA.ACTIVATION.MAIN]: NavigatorScreenParams + [ROUTES.AUTHENTICATION]: NavigatorScreenParams; + [ROUTES.ONBOARDING]: NavigatorScreenParams; + [ROUTES.MAIN]: NavigatorScreenParams; + + [ROUTES.MESSAGES_NAVIGATOR]: NavigatorScreenParams; + [ROUTES.WALLET_NAVIGATOR]: NavigatorScreenParams; + [ROUTES.SERVICES_NAVIGATOR]: NavigatorScreenParams; + [ROUTES.PROFILE_NAVIGATOR]: NavigatorScreenParams; + + [CGN_ROUTES.ACTIVATION.MAIN]: NavigatorScreenParams; + [CGN_ROUTES.DETAILS.MAIN]: NavigatorScreenParams; + [CGN_ROUTES.EYCA.ACTIVATION + .MAIN]: NavigatorScreenParams; [ROUTES.WORKUNIT_GENERIC_FAILURE]: undefined; - // TODO: [ZENDESK_ROUTES.MAIN]: NavigatorScreenParams + [ZENDESK_ROUTES.MAIN]: NavigatorScreenParams; [UADONATION_ROUTES.WEBVIEW]: undefined; }; + +/** + * Merge the navigation of the ParamList stack with AppParamsList, in order to allow + * the navigation in the same stack and the global stack. + * This should be used in the new react-navigation v5 navigator + */ +export type IOStackNavigationRouteProps< + ParamList extends ParamListBase, + RouteName extends keyof ParamList = string +> = { + navigation: IOStackNavigationProp; + route: RouteProp; +}; + +export type IOStackNavigationProp< + ParamList extends ParamListBase, + RouteName extends keyof ParamList = string +> = StackNavigationProp; diff --git a/ts/navigation/params/MainParamsList.ts b/ts/navigation/params/MainParamsList.ts deleted file mode 100644 index bced4acf1f2..00000000000 --- a/ts/navigation/params/MainParamsList.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type MainParamsList = { - // TODO: [ROUTES.MESSAGES_NAVIGATOR]: NavigatorScreenParams - // TODO: [ROUTES.WALLET_HOME]: NavigatorScreenParams - // TODO: [ROUTES.SERVICES_NAVIGATOR]: NavigatorScreenParams - // TODO: [ROUTES.PROFILE_NAVIGATOR]: NavigatorScreenParams -}; diff --git a/ts/navigation/params/MainTabParamsList.ts b/ts/navigation/params/MainTabParamsList.ts new file mode 100644 index 00000000000..5e1729a577d --- /dev/null +++ b/ts/navigation/params/MainTabParamsList.ts @@ -0,0 +1,9 @@ +import { WalletHomeNavigationParams } from "../../screens/wallet/WalletHomeScreen"; +import ROUTES from "../routes"; + +export type MainTabParamsList = { + [ROUTES.MESSAGES_HOME]: undefined; + [ROUTES.WALLET_HOME]: WalletHomeNavigationParams; + [ROUTES.SERVICES_HOME]: undefined; + [ROUTES.PROFILE_MAIN]: undefined; +}; diff --git a/ts/navigation/params/MessagesParamsList.ts b/ts/navigation/params/MessagesParamsList.ts index f6205d93a6e..ff803fc4039 100644 --- a/ts/navigation/params/MessagesParamsList.ts +++ b/ts/navigation/params/MessagesParamsList.ts @@ -1,3 +1,8 @@ +import { NavigatorScreenParams } from "@react-navigation/native"; +import { EUCovidCertParamsList } from "../../features/euCovidCert/navigation/params"; +import EUCOVIDCERT_ROUTES from "../../features/euCovidCert/navigation/routes"; +import { MvlParamsList } from "../../features/mvl/navigation/params"; +import MVL_ROUTES from "../../features/mvl/navigation/routes"; import { MessageDetailScreenNavigationParams } from "../../screens/messages/MessageDetailScreen"; import { MessageRouterScreenNavigationParams } from "../../screens/messages/MessageRouterScreen"; import { MessageDetailScreenPaginatedNavigationParams } from "../../screens/messages/paginated/MessageDetailScreen"; @@ -5,11 +10,10 @@ import { MessageRouterScreenPaginatedNavigationParams } from "../../screens/mess import ROUTES from "../routes"; export type MessagesParamsList = { - [ROUTES.MESSAGES_HOME]: undefined; [ROUTES.MESSAGE_ROUTER]: MessageRouterScreenNavigationParams; [ROUTES.MESSAGE_DETAIL]: MessageDetailScreenNavigationParams; [ROUTES.MESSAGE_ROUTER_PAGINATED]: MessageRouterScreenPaginatedNavigationParams; [ROUTES.MESSAGE_DETAIL_PAGINATED]: MessageDetailScreenPaginatedNavigationParams; - // TODO: [EUCOVIDCERT_ROUTES.MAIN]: NavigatorScreenParams - // TODO: [MVL_ROUTES.MAIN]: NavigatorScreenParams + [EUCOVIDCERT_ROUTES.MAIN]: NavigatorScreenParams; + [MVL_ROUTES.MAIN]: NavigatorScreenParams; }; diff --git a/ts/navigation/params/OnboardingParamsList.ts b/ts/navigation/params/OnboardingParamsList.ts index e8d6d4ce1e6..24c9db895bb 100644 --- a/ts/navigation/params/OnboardingParamsList.ts +++ b/ts/navigation/params/OnboardingParamsList.ts @@ -11,4 +11,5 @@ export type OnboardingParamsList = { [ROUTES.ONBOARDING_FINGERPRINT]: FingerprintScreenNavigationParams; [ROUTES.INSERT_EMAIL_SCREEN]: undefined; [ROUTES.READ_EMAIL_SCREEN]: undefined; + [ROUTES.ONBOARDING_PREMIUM_MESSAGES_OPT_IN_OUT]: undefined; }; diff --git a/ts/navigation/params/ProfileParamsList.ts b/ts/navigation/params/ProfileParamsList.ts index 4bdbde0de6a..ecc1df04482 100644 --- a/ts/navigation/params/ProfileParamsList.ts +++ b/ts/navigation/params/ProfileParamsList.ts @@ -1,7 +1,6 @@ import ROUTES from "../routes"; export type ProfileParamsList = { - [ROUTES.PROFILE_MAIN]: undefined; [ROUTES.PROFILE_PRIVACY_MAIN]: undefined; [ROUTES.PROFILE_PRIVACY]: undefined; [ROUTES.PROFILE_PRIVACY_SHARE_DATA]: undefined; @@ -23,4 +22,5 @@ export type ProfileParamsList = { [ROUTES.PROFILE_REMOVE_ACCOUNT_INFO]: undefined; [ROUTES.PROFILE_REMOVE_ACCOUNT_DETAILS]: undefined; [ROUTES.PROFILE_REMOVE_ACCOUNT_SUCCESS]: undefined; + [ROUTES.CGN_LANDING_PLAYGROUND]: undefined; }; diff --git a/ts/navigation/params/ServicesParamsList.ts b/ts/navigation/params/ServicesParamsList.ts index e2a2a17772f..124f2320925 100644 --- a/ts/navigation/params/ServicesParamsList.ts +++ b/ts/navigation/params/ServicesParamsList.ts @@ -1,8 +1,12 @@ +import { + SvVoucherGenerationNavigatorParamsList, + SvVoucherListNavigatorParamsList +} from "../../features/bonus/siciliaVola/navigation/params"; import { ServiceDetailsScreenNavigationParams } from "../../screens/services/ServiceDetailsScreen"; import ROUTES from "../routes"; export type ServicesParamsList = { - [ROUTES.SERVICES_HOME]: undefined; [ROUTES.SERVICE_DETAIL]: ServiceDetailsScreenNavigationParams; [ROUTES.SERVICE_WEBVIEW]: undefined; -}; +} & SvVoucherGenerationNavigatorParamsList & + SvVoucherListNavigatorParamsList; diff --git a/ts/navigation/params/WalletParamsList.ts b/ts/navigation/params/WalletParamsList.ts index 8d4147f3be7..27ccc962d92 100644 --- a/ts/navigation/params/WalletParamsList.ts +++ b/ts/navigation/params/WalletParamsList.ts @@ -1,16 +1,31 @@ +import { NavigatorScreenParams } from "@react-navigation/native"; +import { BonusVacanzeParamsList } from "../../features/bonus/bonusVacanze/navigation/params"; import BONUSVACANZE_ROUTES from "../../features/bonus/bonusVacanze/navigation/routes"; import { ActiveBonusScreenNavigationParams } from "../../features/bonus/bonusVacanze/screens/ActiveBonusScreen"; +import { + BpdDetailsParamsList, + BpdOnboardingParamsList, + BpdOptInParamsList +} from "../../features/bonus/bpd/navigation/params"; import BPD_ROUTES from "../../features/bonus/bpd/navigation/routes"; import { BancomatDetailScreenNavigationParams } from "../../features/wallet/bancomat/screen/BancomatDetailScreen"; import { BPayDetailScreenNavigationParams } from "../../features/wallet/bancomatpay/screen/BPayDetailScreen"; import { CobadgeDetailScreenNavigationParams } from "../../features/wallet/cobadge/screen/CobadgeDetailScreen"; import { CreditCardDetailScreenNavigationParams } from "../../features/wallet/creditCard/screen/CreditCardDetailScreen"; +import { PaymentMethodOnboardingBancomatParamsList } from "../../features/wallet/onboarding/bancomat/navigation/params"; import WALLET_ONBOARDING_BANCOMAT_ROUTES from "../../features/wallet/onboarding/bancomat/navigation/routes"; +import { PaymentMethodOnboardingBPayParamsList } from "../../features/wallet/onboarding/bancomatPay/navigation/params"; import WALLET_ONBOARDING_BPAY_ROUTES from "../../features/wallet/onboarding/bancomatPay/navigation/routes"; +import { PaymentMethodOnboardingCoBadgeParamsList } from "../../features/wallet/onboarding/cobadge/navigation/params"; import WALLET_ONBOARDING_COBADGE_ROUTES from "../../features/wallet/onboarding/cobadge/navigation/routes"; import { ActivateBpdOnNewCreditCardScreenNavigationParams } from "../../features/wallet/onboarding/common/screens/bpd/ActivateBpdOnNewCreditCardScreen"; +import { PaymentMethodOnboardingPayPalParamsList } from "../../features/wallet/onboarding/paypal/navigation/params"; +import PAYPAL_ROUTES from "../../features/wallet/onboarding/paypal/navigation/routes"; +import { PaymentMethodOnboardingPrivativeParamsList } from "../../features/wallet/onboarding/privative/navigation/params"; import WALLET_ONBOARDING_PRIVATIVE_ROUTES from "../../features/wallet/onboarding/privative/navigation/routes"; +import { PaymentMethodOnboardingSatispayParamsList } from "../../features/wallet/onboarding/satispay/navigation/params"; import WALLET_ONBOARDING_SATISPAY_ROUTES from "../../features/wallet/onboarding/satispay/navigation/routes"; +import { PayPalPspUpdateScreenNavigationParams } from "../../features/wallet/paypal/screen/PayPalPspUpdateScreen"; import { PrivativeDetailScreenNavigationParams } from "../../features/wallet/privative/screen/PrivativeDetailScreen"; import { SatispayDetailScreenNavigationParams } from "../../features/wallet/satispay/screen/SatispayDetailScreen"; import { AddCardScreenNavigationParams } from "../../screens/wallet/AddCardScreen"; @@ -27,17 +42,16 @@ import { TransactionErrorScreenNavigationParams } from "../../screens/wallet/pay import { TransactionSummaryScreenNavigationParams } from "../../screens/wallet/payment/TransactionSummaryScreen"; import { PaymentHistoryDetailsScreenNavigationParams } from "../../screens/wallet/PaymentHistoryDetailsScreen"; import { TransactionDetailsScreenNavigationParams } from "../../screens/wallet/TransactionDetailsScreen"; -import { WalletHomeNavigationParams } from "../../screens/wallet/WalletHomeScreen"; import ROUTES from "../routes"; export type WalletParamsList = { - [ROUTES.WALLET_HOME]: WalletHomeNavigationParams; [ROUTES.WALLET_ADD_PAYMENT_METHOD]: AddPaymentMethodScreenNavigationParams; [ROUTES.WALLET_TRANSACTION_DETAILS]: TransactionDetailsScreenNavigationParams; [ROUTES.WALLET_CREDIT_CARD_DETAIL]: CreditCardDetailScreenNavigationParams; [ROUTES.WALLET_BANCOMAT_DETAIL]: BancomatDetailScreenNavigationParams; [ROUTES.WALLET_SATISPAY_DETAIL]: SatispayDetailScreenNavigationParams; [ROUTES.WALLET_PAYPAL_DETAIL]: undefined; + [ROUTES.WALLET_PAYPAL_UPDATE_PAYMENT_PSP]: PayPalPspUpdateScreenNavigationParams; [ROUTES.WALLET_BPAY_DETAIL]: BPayDetailScreenNavigationParams; [ROUTES.WALLET_COBADGE_DETAIL]: CobadgeDetailScreenNavigationParams; [ROUTES.WALLET_PRIVATIVE_DETAIL]: PrivativeDetailScreenNavigationParams; @@ -57,18 +71,24 @@ export type WalletParamsList = { [ROUTES.ADD_CREDIT_CARD_OUTCOMECODE_MESSAGE]: AddCreditCardOutcomeCodeMessageNavigationParams; [ROUTES.PAYMENT_OUTCOMECODE_MESSAGE]: PaymentOutcomeCodeMessageNavigationParams; - // TODO: [ROUTES.MAIN]: NavigatorScreenParams + [BONUSVACANZE_ROUTES.MAIN]: NavigatorScreenParams; [BONUSVACANZE_ROUTES.BONUS_ACTIVE_DETAIL_SCREEN]: ActiveBonusScreenNavigationParams; - // TODO: [BPD_ROUTES.ONBOARDING.MAIN]: NavigatorScreenParams - // TODO: [BPD_ROUTES.DETAILS_MAIN.MAIN]: NavigatorScreenParams + [BPD_ROUTES.ONBOARDING.MAIN]: NavigatorScreenParams; + [BPD_ROUTES.DETAILS_MAIN]: NavigatorScreenParams; [BPD_ROUTES.CTA_BPD_IBAN_EDIT]: undefined; + [BPD_ROUTES.IBAN]: undefined; - // TODO: [WALLET_ONBOARDING_BANCOMAT_ROUTES.MAIN]: NavigatorScreenParams - // TODO: [WALLET_ONBOARDING_SATISPAY_ROUTES.MAIN]: NavigatorScreenParams - // TODO: [WALLET_ONBOARDING_BPAY_ROUTES.MAIN]: NavigatorScreenParams - // TODO: [WALLET_ONBOARDING_COBADGE_ROUTES.MAIN]: NavigatorScreenParams - // TODO: [WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN]: NavigatorScreenParams + [BPD_ROUTES.OPT_IN_PAYMENT_METHODS + .MAIN]: NavigatorScreenParams; + + [WALLET_ONBOARDING_BANCOMAT_ROUTES.MAIN]: NavigatorScreenParams; + [WALLET_ONBOARDING_SATISPAY_ROUTES.MAIN]: NavigatorScreenParams; + [WALLET_ONBOARDING_BPAY_ROUTES.MAIN]: NavigatorScreenParams; + [WALLET_ONBOARDING_COBADGE_ROUTES.MAIN]: NavigatorScreenParams; + [WALLET_ONBOARDING_PRIVATIVE_ROUTES.MAIN]: NavigatorScreenParams; + [PAYPAL_ROUTES.ONBOARDING + .MAIN]: NavigatorScreenParams; [WALLET_ONBOARDING_BANCOMAT_ROUTES.ACTIVATE_BPD_NEW_CREDIT_CARD]: ActivateBpdOnNewCreditCardScreenNavigationParams; [WALLET_ONBOARDING_BANCOMAT_ROUTES.ACTIVATE_BPD_NEW_BANCOMAT]: undefined; diff --git a/ts/navigation/routes.ts b/ts/navigation/routes.ts index 67d574fc371..595972255f6 100644 --- a/ts/navigation/routes.ts +++ b/ts/navigation/routes.ts @@ -35,6 +35,7 @@ const ROUTES = { "ONBOARDING_PREMIUM_MESSAGES_OPT_IN_OUT", // Wallet + WALLET_NAVIGATOR: "WALLET_NAVIGATOR", WALLET_HOME: "WALLET_HOME", WALLET_TRANSACTION_DETAILS: "WALLET_TRANSACTION_DETAILS", WALLET_CREDIT_CARD_DETAIL: "WALLET_CREDIT_CARD_DETAIL", diff --git a/ts/sagas/__tests__/premiumMessages.test.ts b/ts/sagas/__tests__/premiumMessages.test.ts index ca83b880f6c..d9763323a5e 100644 --- a/ts/sagas/__tests__/premiumMessages.test.ts +++ b/ts/sagas/__tests__/premiumMessages.test.ts @@ -1,4 +1,4 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import { testSaga } from "redux-saga-test-plan"; import NavigationService from "../../navigation/NavigationService"; import ROUTES from "../../navigation/routes"; @@ -41,8 +41,8 @@ describe("Premium messages sagas", () => { .next(null) .call( NavigationService.dispatchNavigationAction, - NavigationActions.navigate({ - routeName: ROUTES.ONBOARDING_PREMIUM_MESSAGES_OPT_IN_OUT + CommonActions.navigate(ROUTES.ONBOARDING, { + screen: ROUTES.ONBOARDING_PREMIUM_MESSAGES_OPT_IN_OUT }) ) .next() diff --git a/ts/sagas/index.ts b/ts/sagas/index.ts index fdb5e15f44b..8423f70430e 100644 --- a/ts/sagas/index.ts +++ b/ts/sagas/index.ts @@ -12,14 +12,12 @@ import { watchBackToEntrypointPaymentSaga, watchPaymentInitializeSaga } from "./wallet"; -import { watchNavigateToDeepLinkSaga } from "./watchNavigateToDeepLinkSaga"; export default function* root() { yield* all([ call(startupSaga), call(backendStatusSaga), call(versionInfoSaga), - call(watchNavigateToDeepLinkSaga), call(loadSystemPreferencesSaga), call(watchContentSaga), call(watchPaymentInitializeSaga), diff --git a/ts/sagas/mixpanel.ts b/ts/sagas/mixpanel.ts index fadabf6ac6f..d64953f753e 100644 --- a/ts/sagas/mixpanel.ts +++ b/ts/sagas/mixpanel.ts @@ -1,5 +1,5 @@ -import { NavigationActions } from "react-navigation"; import { call, select, take } from "typed-redux-saga/macro"; +import { CommonActions } from "@react-navigation/native"; import { ActionType } from "typesafe-actions"; import { initializeMixPanel, terminateMixpanel } from "../mixpanel"; import NavigationService from "../navigation/NavigationService"; @@ -43,8 +43,11 @@ export function* askMixpanelOptIn() { // wait until he/she done a choice yield* call( NavigationService.dispatchNavigationAction, - NavigationActions.navigate({ - routeName: ROUTES.ONBOARDING_SHARE_DATA + CommonActions.navigate({ + name: ROUTES.ONBOARDING, + params: { + screen: ROUTES.ONBOARDING_SHARE_DATA + } }) ); yield* take(setMixpanelEnabled); diff --git a/ts/sagas/premiumMessages.ts b/ts/sagas/premiumMessages.ts index 2ddd1e2cc1e..c952c4a57f3 100644 --- a/ts/sagas/premiumMessages.ts +++ b/ts/sagas/premiumMessages.ts @@ -1,5 +1,5 @@ +import { CommonActions } from "@react-navigation/native"; import { select, call, take } from "typed-redux-saga/macro"; -import { NavigationActions } from "react-navigation"; import { createStandardAction } from "typesafe-actions"; import NavigationService from "../navigation/NavigationService"; import ROUTES from "../navigation/routes"; @@ -48,8 +48,8 @@ export function* askPremiumMessagesOptInOut() { // wait until he/she done a choice. yield* call( NavigationService.dispatchNavigationAction, - NavigationActions.navigate({ - routeName: ROUTES.ONBOARDING_PREMIUM_MESSAGES_OPT_IN_OUT + CommonActions.navigate(ROUTES.ONBOARDING, { + screen: ROUTES.ONBOARDING_PREMIUM_MESSAGES_OPT_IN_OUT }) ); diff --git a/ts/sagas/startup.ts b/ts/sagas/startup.ts index 58475691620..0db0dc63a5d 100644 --- a/ts/sagas/startup.ts +++ b/ts/sagas/startup.ts @@ -80,15 +80,16 @@ import { previousInstallationDataDeleteSaga } from "./installation"; import watchLoadMessageDetails from "./messages/watchLoadMessageDetails"; import watchLoadNextPageMessages from "./messages/watchLoadNextPageMessages"; import watchLoadPreviousPageMessages from "./messages/watchLoadPreviousPageMessages"; +import watchMigrateToPagination from "./messages/watchMigrateToPagination"; import watchReloadAllMessages from "./messages/watchReloadAllMessages"; import watchUpsertMessageStatusAttribues from "./messages/watchUpsertMessageStatusAttribues"; -import watchMigrateToPagination from "./messages/watchMigrateToPagination"; import { askMixpanelOptIn, handleSetMixpanelEnabled, initMixpanel } from "./mixpanel"; import { updateInstallationSaga } from "./notifications"; +import { askPremiumMessagesOptInOut } from "./premiumMessages"; import { loadProfile, watchProfile, @@ -97,6 +98,7 @@ import { } from "./profile"; import { askServicesPreferencesModeOptin } from "./services/servicesOptinSaga"; import { watchLoadServicesSaga } from "./services/watchLoadServicesSaga"; +import { checkAppHistoryVersionSaga } from "./startup/appVersionHistorySaga"; import { authenticationSaga } from "./startup/authenticationSaga"; import { checkAcceptedTosSaga } from "./startup/checkAcceptedTosSaga"; import { checkAcknowledgedEmailSaga } from "./startup/checkAcknowledgedEmailSaga"; @@ -124,8 +126,6 @@ import { } from "./user/userMetadata"; import { watchWalletSaga } from "./wallet"; import { watchProfileEmailValidationChangedSaga } from "./watchProfileEmailValidationChangedSaga"; -import { checkAppHistoryVersionSaga } from "./startup/appVersionHistorySaga"; -import { askPremiumMessagesOptInOut } from "./premiumMessages"; const WAIT_INITIALIZE_SAGA = 5000 as Millisecond; const navigatorPollingTime = 125 as Millisecond; @@ -536,6 +536,8 @@ export function* initializeApplicationSaga(): Generator< // Remove the pending message from the notification state yield* put(clearNotificationPendingMessage()); + + yield* call(navigateToMainNavigatorAction); // Navigate to message router screen if (usePaginatedMessages) { NavigationService.dispatchNavigationAction( @@ -558,8 +560,9 @@ export function* initializeApplicationSaga(): Generator< */ function* waitForNavigatorServiceInitialization() { // eslint-disable-next-line functional/no-let - let navigator: ReturnType = - yield* call(NavigationService.getNavigator); + let isNavigatorReady: ReturnType< + typeof NavigationService.getIsNavigationReady + > = yield* call(NavigationService.getIsNavigationReady); // eslint-disable-next-line functional/no-let let timeoutLogged = false; @@ -567,7 +570,7 @@ function* waitForNavigatorServiceInitialization() { const startTime = performance.now(); // before continuing we must wait for the navigatorService to be ready - while (navigator === null || navigator === undefined) { + while (!isNavigatorReady) { const elapsedTime = performance.now() - startTime; if (!timeoutLogged && elapsedTime >= warningWaitNavigatorTime) { timeoutLogged = true; @@ -575,7 +578,7 @@ function* waitForNavigatorServiceInitialization() { yield* call(mixpanelTrack, "NAVIGATION_SERVICE_INITIALIZATION_TIMEOUT"); } yield* delay(navigatorPollingTime); - navigator = yield* call(NavigationService.getNavigator); + isNavigatorReady = yield* call(NavigationService.getIsNavigationReady); } const initTime = performance.now() - startTime; diff --git a/ts/sagas/startup/__tests__/checkAcceptedTosSaga.test.ts b/ts/sagas/startup/__tests__/checkAcceptedTosSaga.test.tsx similarity index 83% rename from ts/sagas/startup/__tests__/checkAcceptedTosSaga.test.ts rename to ts/sagas/startup/__tests__/checkAcceptedTosSaga.test.tsx index c7ce9bea31d..c88e0325fc5 100644 --- a/ts/sagas/startup/__tests__/checkAcceptedTosSaga.test.ts +++ b/ts/sagas/startup/__tests__/checkAcceptedTosSaga.test.tsx @@ -1,14 +1,19 @@ +import { createStore } from "redux"; import { expectSaga } from "redux-saga-test-plan"; import { NonNegativeInteger, NonNegativeNumber } from "italia-ts-commons/lib/numbers"; +import { View } from "react-native"; import { tosVersion } from "../../../config"; +import { applicationChangeState } from "../../../store/actions/application"; import { navigateToTosScreen } from "../../../store/actions/navigation"; import { tosAccepted } from "../../../store/actions/onboarding"; +import { appReducer } from "../../../store/reducers"; import { isProfileFirstOnBoarding } from "../../../store/reducers/profile"; import mockedProfile from "../../../__mocks__/initializedProfile"; +import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; import { checkAcceptedTosSaga } from "../checkAcceptedTosSaga"; describe("checkAcceptedTosSaga", () => { @@ -40,6 +45,13 @@ describe("checkAcceptedTosSaga", () => { accepted_tos_version: tosVersion }; + beforeEach(() => { + const globalState = appReducer(undefined, applicationChangeState("active")); + const store = createStore(appReducer, globalState as any); + renderScreenFakeNavRedux(View, "DUMMY", {}, store); + jest.useRealTimers(); + }); + describe("when a profile is first time onboarded", () => { it("should be true", () => { expect(isProfileFirstOnBoarding(firstOnboardingProfile)).toBeTruthy(); diff --git a/ts/sagas/startup/__tests__/checkProfileEmailSaga.test.ts b/ts/sagas/startup/__tests__/checkProfileEmailSaga.test.tsx similarity index 51% rename from ts/sagas/startup/__tests__/checkProfileEmailSaga.test.ts rename to ts/sagas/startup/__tests__/checkProfileEmailSaga.test.tsx index c2429907261..917cce5e38c 100644 --- a/ts/sagas/startup/__tests__/checkProfileEmailSaga.test.ts +++ b/ts/sagas/startup/__tests__/checkProfileEmailSaga.test.tsx @@ -1,17 +1,28 @@ +import { View } from "react-native"; +import { createStore } from "redux"; import { expectSaga } from "redux-saga-test-plan"; +import mockedProfile from "../../../__mocks__/initializedProfile"; +import NavigationService from "../../../navigation/NavigationService"; +import ROUTES from "../../../navigation/routes"; +import { applicationChangeState } from "../../../store/actions/application"; -import { - navigateToEmailInsertScreen, - navigateToEmailReadScreen -} from "../../../store/actions/navigation"; +import { navigateToEmailReadScreen } from "../../../store/actions/navigation"; import { emailAcknowledged, emailInsert } from "../../../store/actions/onboarding"; -import mockedProfile from "../../../__mocks__/initializedProfile"; +import { appReducer } from "../../../store/reducers"; +import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; import { checkAcknowledgedEmailSaga } from "../checkAcknowledgedEmailSaga"; describe("checkAcceptedTosSaga", () => { + beforeEach(() => { + const globalState = appReducer(undefined, applicationChangeState("active")); + const store = createStore(appReducer, globalState as any); + renderScreenFakeNavRedux(View, "DUMMY", {}, store); + jest.useRealTimers(); + }); + describe("when user has an email and it is validated", () => { it("should do nothing", () => expectSaga(checkAcknowledgedEmailSaga, mockedProfile) @@ -24,13 +35,16 @@ describe("checkAcceptedTosSaga", () => { ...mockedProfile, version: 0 }; - it("should show email read screen", () => - expectSaga( + it("should show email read screen", async () => { + await expectSaga( checkAcknowledgedEmailSaga, profileEmailValidatedFirstOnboarding ) - .call(navigateToEmailReadScreen) - .run()); + .call(NavigationService.navigate, ROUTES.ONBOARDING, { + screen: ROUTES.READ_EMAIL_SCREEN + }) + .run(); + }); }); describe("when user has an email and it not is validated", () => { @@ -42,7 +56,9 @@ describe("checkAcceptedTosSaga", () => { expectSaga(checkAcknowledgedEmailSaga, profileWithEmailNotValidated) // read screen is wrapped in a HOC where if email is validate show ReadScreen // otherwise a screen that remembers to validate it - .call(navigateToEmailReadScreen) + .call(NavigationService.navigate, ROUTES.ONBOARDING, { + screen: ROUTES.READ_EMAIL_SCREEN + }) .dispatch(emailAcknowledged()) .run()); }); @@ -53,11 +69,20 @@ describe("checkAcceptedTosSaga", () => { is_email_validated: false, email: undefined }; - it("should prompt the screen to insert it", () => - expectSaga(checkAcknowledgedEmailSaga, profileWithNoEmail) - .call(navigateToEmailInsertScreen) // go to email insert screen + it("should prompt the screen to insert it", async () => { + const globalState = appReducer( + undefined, + applicationChangeState("active") + ); + const store = createStore(appReducer, globalState as any); + renderScreenFakeNavRedux(View, "DUMMY", {}, store); + await expectSaga(checkAcknowledgedEmailSaga, profileWithNoEmail) + .call(NavigationService.navigate, ROUTES.ONBOARDING, { + screen: ROUTES.INSERT_EMAIL_SCREEN + }) // go to email insert screen .dispatch(emailInsert()) // dispatch email insert .dispatch(emailAcknowledged()) // press continue - .run()); + .run(); + }); }); }); diff --git a/ts/sagas/startup/__tests__/checkProfileEnabledSaga.test.ts b/ts/sagas/startup/__tests__/checkProfileEnabledSaga.test.ts index d0ba4920324..caa194ce565 100644 --- a/ts/sagas/startup/__tests__/checkProfileEnabledSaga.test.ts +++ b/ts/sagas/startup/__tests__/checkProfileEnabledSaga.test.ts @@ -28,10 +28,12 @@ describe("checkProfileEnabledSaga", () => { version: 1 as NonNegativeInteger }; - it("should enable inbox if tos version is not defined or 0", () => - expectSaga(checkProfileEnabledSaga, updatedProfile) + it("should enable inbox if tos version is not defined or 0", async () => { + jest.useRealTimers(); + await expectSaga(checkProfileEnabledSaga, updatedProfile) .put.like({ action: { type: getType(profileUpsert.request) } }) - .run()); + .run(); + }); it("should enable inbox if it's disabled and tos version > 1", () => expectSaga(checkProfileEnabledSaga, { diff --git a/ts/sagas/startup/__tests__/saveNavigationStateSaga.test.ts b/ts/sagas/startup/__tests__/saveNavigationStateSaga.test.ts deleted file mode 100644 index 101c90a56c8..00000000000 --- a/ts/sagas/startup/__tests__/saveNavigationStateSaga.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { expectSaga } from "redux-saga-test-plan"; -import * as matchers from "redux-saga-test-plan/matchers"; -import { getType } from "typesafe-actions"; -import NavigationService from "../../../navigation/NavigationService"; - -import { saveNavigationStateSaga } from "../saveNavigationStateSaga"; - -import { setDeepLink } from "../../../store/actions/deepLink"; - -import ROUTES from "../../../navigation/routes"; - -jest.mock("react-native-share", () => ({ - open: jest.fn() -})); - -describe("saveNavigationStateSaga", () => { - it("should not set a deep link when not in main navigator", () => - expectSaga(saveNavigationStateSaga) - .provide([ - [ - matchers.call(NavigationService.getCurrentRoute), - { - index: 0, - routes: [{}] - } - ] - ]) - .not.put.like({ action: { type: getType(setDeepLink) } }) - .run()); - it("should set a deep link when in main navigator", () => { - const subRoute = { - routeName: "Test", - params: { myparam: true }, - key: "test" - }; - return expectSaga(saveNavigationStateSaga) - .provide([ - [ - matchers.call(NavigationService.getCurrentRoute), - { - index: 0, - routes: [ - { - routeName: ROUTES.MAIN, - index: 0, - routes: [subRoute] - } - ] - } - ] - ]) - .put(setDeepLink(subRoute)) - .run(); - }); -}); diff --git a/ts/sagas/startup/checkAcknowledgedEmailSaga.ts b/ts/sagas/startup/checkAcknowledgedEmailSaga.ts index 7aa086c6cf9..216230c9f84 100644 --- a/ts/sagas/startup/checkAcknowledgedEmailSaga.ts +++ b/ts/sagas/startup/checkAcknowledgedEmailSaga.ts @@ -1,9 +1,7 @@ import { call, take } from "typed-redux-saga/macro"; import { InitializedProfile } from "../../../definitions/backend/InitializedProfile"; -import { - navigateToEmailInsertScreen, - navigateToEmailReadScreen -} from "../../store/actions/navigation"; +import NavigationService from "../../navigation/NavigationService"; +import ROUTES from "../../navigation/routes"; import { emailAcknowledged } from "../../store/actions/onboarding"; import { hasProfileEmail, @@ -33,7 +31,9 @@ export function* checkAcknowledgedEmailSaga( // OR // An email exists on the user's profile but it is not validated, the conditional // view shows the component that reminds to validate the email address or allows the navigation to edit it. - yield* call(navigateToEmailReadScreen); + yield* call(NavigationService.navigate, ROUTES.ONBOARDING, { + screen: ROUTES.READ_EMAIL_SCREEN + }); } else { // we can go on, no need to wait return; @@ -43,7 +43,9 @@ export function* checkAcknowledgedEmailSaga( // EmailInsertScreen knows if the user comes from onboarding or not // if he comes from onboarding, on email inserted the navigation will focus EmailReadScreen to remember the user // to validate it - yield* call(navigateToEmailInsertScreen); + yield* call(NavigationService.navigate, ROUTES.ONBOARDING, { + screen: ROUTES.INSERT_EMAIL_SCREEN + }); } // Wait for the user to press "Continue" button after having checked out diff --git a/ts/sagas/startup/saveNavigationStateSaga.ts b/ts/sagas/startup/saveNavigationStateSaga.ts deleted file mode 100644 index b1a8fe1706f..00000000000 --- a/ts/sagas/startup/saveNavigationStateSaga.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { NavigationParams, NavigationStateRoute } from "react-navigation"; -import { call, put } from "typed-redux-saga/macro"; -import NavigationService from "../../navigation/NavigationService"; - -import ROUTES from "../../navigation/routes"; - -import { setDeepLink } from "../../store/actions/deepLink"; -import { ReduxSagaEffect } from "../../types/utils"; - -/** - * Saves the navigation state in the deep link state so that when the app - * goes through the initialization saga, the user gets sent back to the saved - * navigation route. - * Saving and restoring routes relies on the deep link mechanism. - */ -export function* saveNavigationStateSaga(): Generator< - ReduxSagaEffect, - void, - ReturnType -> { - const currentScreen: ReturnType = - yield* call(NavigationService.getCurrentRoute); - - if (currentScreen) { - const currentRoute = currentScreen.routes[ - currentScreen.index - ] as NavigationStateRoute; - if (currentRoute.routes && currentRoute.routeName === ROUTES.MAIN) { - // only save state when in Main navigator - const mainSubRoute = currentRoute.routes[currentRoute.index]; - yield* put( - setDeepLink({ - routeName: mainSubRoute.routeName, - params: mainSubRoute.params, - key: mainSubRoute.key - }) - ); - } - } -} diff --git a/ts/sagas/wallet.ts b/ts/sagas/wallet.ts index 3b56bd20edc..16dfbb2f67e 100644 --- a/ts/sagas/wallet.ts +++ b/ts/sagas/wallet.ts @@ -1,5 +1,6 @@ /* eslint-disable */ +import { NavigationActions, StackActions } from "@react-navigation/compat"; /** * A saga that manages the Wallet. */ @@ -9,7 +10,6 @@ import * as pot from "italia-ts-commons/lib/pot"; import { DeferredPromise } from "italia-ts-commons/lib/promises"; import { Millisecond } from "italia-ts-commons/lib/units"; import _ from "lodash"; -import { NavigationActions, StackActions } from "react-navigation"; import { call, delay, @@ -73,6 +73,7 @@ import { searchUserCoBadge, walletAddCoBadgeStart } from "../features/wallet/onboarding/cobadge/store/actions"; +import { watchPaypalOnboardingSaga } from "../features/wallet/onboarding/paypal/saga"; import { handleAddPrivativeToWallet } from "../features/wallet/onboarding/privative/saga/networking/handleAddPrivativeToWallet"; import { handleSearchUserPrivative } from "../features/wallet/onboarding/privative/saga/networking/handleSearchUserPrivative"; import { handleLoadPrivativeConfiguration } from "../features/wallet/onboarding/privative/saga/networking/loadPrivativeConfiguration"; @@ -164,6 +165,7 @@ import { PaymentManagerToken } from "../types/pagopa"; import { SessionToken } from "../types/SessionToken"; +import { ReduxSagaEffect } from "../types/utils"; import { waitBackoffError } from "../utils/backoffError"; import { isTestEnv } from "../utils/environment"; @@ -196,8 +198,6 @@ import { updatePaymentStatusSaga, updateWalletPspRequestHandler } from "./wallet/pagopaApis"; -import { watchPaypalOnboardingSaga } from "../features/wallet/onboarding/paypal/saga"; -import { ReduxSagaEffect } from "../types/utils"; const successScreenDelay = 2000 as Millisecond; diff --git a/ts/sagas/watchNavigateToDeepLinkSaga.ts b/ts/sagas/watchNavigateToDeepLinkSaga.ts deleted file mode 100644 index 2801e0ce2a4..00000000000 --- a/ts/sagas/watchNavigateToDeepLinkSaga.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { NavigationActions, StackActions } from "react-navigation"; -import { all, call, put, takeLatest } from "typed-redux-saga/macro"; -import { ActionType, getType } from "typesafe-actions"; -import NavigationService from "../navigation/NavigationService"; - -import { clearDeepLink, navigateToDeepLink } from "../store/actions/deepLink"; -import { ReduxSagaEffect } from "../types/utils"; - -export function* watchNavigateToDeepLinkSaga(): IterableIterator { - yield* takeLatest( - getType(navigateToDeepLink), - function* ( - action: ActionType, - replace: boolean = false - ) { - const payload = action.payload; - const navigationAction = - replace && payload.key !== undefined - ? StackActions.replace({ - routeName: payload.routeName, - params: payload.params, - action: payload.action, - key: payload.key - }) - : NavigationActions.navigate(action.payload); - - yield* all([ - call(NavigationService.dispatchNavigationAction, navigationAction), - put(clearDeepLink()) - ]); - } - ); -} diff --git a/ts/sagas/workUnit/index.ts b/ts/sagas/workUnit/index.ts index b9cf2545d7c..d35318c3307 100644 --- a/ts/sagas/workUnit/index.ts +++ b/ts/sagas/workUnit/index.ts @@ -1,4 +1,4 @@ -import { NavigationActions } from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import { call, take } from "typed-redux-saga/macro"; import { ActionCreator, @@ -12,6 +12,7 @@ import { ReduxSagaEffect } from "../../types/utils"; /** * The data model needed to run the workunit + * @deprecated */ export type WorkUnit = { // The navigation action that will be used if the current screen isn't the `startScreenName` @@ -30,11 +31,12 @@ export type WorkUnit = { /** * The result of the WorkUnit + * @deprecated */ export type SagaResult = "cancel" | "completed" | "back" | "failure"; /** - * + * @deprecated */ export type WorkUnitHandler = ( g: (...args: Array) => Generator @@ -44,6 +46,7 @@ export type WorkUnitHandler = ( * Ensure that the `startScreen` is the current screen or navigate to `startScreen` using `navigateTo` * @param navigateTo * @param startScreen + * @deprecated */ function* ensureScreen(navigateTo: () => void, startScreen: string) { const currentRoute: ReturnType = @@ -58,21 +61,19 @@ function* ensureScreen(navigateTo: () => void, startScreen: string) { * Ensure that after the execution of the saga `g`, * the navigation stack return to the screen from which the saga was invoked * @param g + * @deprecated */ export function* withResetNavigationStack( g: (...args: Array) => Generator -) { - const initialScreen: ReturnType = - yield* call(NavigationService.getCurrentRoute); +): Generator { + const navigator = yield* call(NavigationService.getNavigator); + const initialState = navigator.current?.getRootState(); + const res: T = yield* call(g); - if (initialScreen?.routeName !== undefined) { + if (initialState !== undefined) { yield* call( NavigationService.dispatchNavigationAction, - NavigationActions.navigate({ - routeName: initialScreen.routeName, - params: initialScreen?.params, - key: initialScreen?.key - }) + CommonActions.reset(initialState) ); } return res; @@ -81,6 +82,7 @@ export function* withResetNavigationStack( /** * TODO: Generic handling for the failure of a workunit, navigate to GenericFailureScren * @param g + * @deprecated */ export function* withFailureHandling( g: (...args: Array) => Generator @@ -95,6 +97,7 @@ export function* withFailureHandling( /** * Execute the work unit, and wait for an action to complete * @param wu + * @deprecated */ export function* executeWorkUnit( wu: WorkUnit diff --git a/ts/screens/authentication/CardSelectionScreen.tsx b/ts/screens/authentication/CardSelectionScreen.tsx index 4fcf3232c9e..29c6042c1d8 100644 --- a/ts/screens/authentication/CardSelectionScreen.tsx +++ b/ts/screens/authentication/CardSelectionScreen.tsx @@ -1,19 +1,21 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { Millisecond } from "italia-ts-commons/lib/units"; import { Button, Content, H2, Text, View } from "native-base"; import * as React from "react"; import { Image, StyleSheet } from "react-native"; -import { NavigationScreenProp, NavigationState } from "react-navigation"; import AnimatedRing from "../../components/animations/AnimatedRing"; import ScreenHeader from "../../components/ScreenHeader"; import BaseScreenComponent from "../../components/screens/BaseScreenComponent"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../navigation/params/AuthenticationParamsList"; import customVariables from "../../theme/variables"; -interface OwnProps { - navigation: NavigationScreenProp; -} - -type Props = OwnProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; // Image dimension const imgDimension = 180; const boxDimension = 245; diff --git a/ts/screens/authentication/IdpLoginScreen.tsx b/ts/screens/authentication/IdpLoginScreen.tsx index 657eb427fd1..76ba406eb70 100644 --- a/ts/screens/authentication/IdpLoginScreen.tsx +++ b/ts/screens/authentication/IdpLoginScreen.tsx @@ -1,3 +1,4 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { fromNullable, none } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Text, View } from "native-base"; @@ -8,7 +9,6 @@ import { WebViewErrorEvent, WebViewNavigation } from "react-native-webview/lib/WebViewTypes"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import brokenLinkImage from "../../../img/broken-link.png"; import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity"; @@ -20,6 +20,8 @@ import Markdown from "../../components/ui/Markdown"; import { RefreshIndicator } from "../../components/ui/RefreshIndicator"; import I18n from "../../i18n"; import { mixpanelTrack } from "../../mixpanel"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../navigation/params/AuthenticationParamsList"; import { idpLoginUrlChanged, loginFailure, @@ -31,6 +33,7 @@ import { isLoggedOutWithIdp, selectedIdentityProviderSelector } from "../../store/reducers/authentication"; +import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; import { idpContextualHelpDataFromIdSelector } from "../../store/reducers/content"; import { GlobalState } from "../../store/reducers/types"; import { SessionToken } from "../../types/SessionToken"; @@ -40,16 +43,18 @@ import { onLoginUriChanged } from "../../utils/login"; import { getSpidErrorCodeDescription } from "../../utils/spidErrorCode"; -import { getUrlBasepath } from "../../utils/url"; -import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; import { assistanceToolRemoteConfig, handleSendAssistanceLog } from "../../utils/supportAssistance"; +import { getUrlBasepath } from "../../utils/url"; import { originSchemasWhiteList } from "./originSchemasWhiteList"; -type Props = NavigationStackScreenProps & - ReturnType & +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType & ReturnType; enum ErrorType { diff --git a/ts/screens/authentication/InvalidNfcConnectionScreen.tsx b/ts/screens/authentication/InvalidNfcConnectionScreen.tsx index 5f31e23301e..b8de7b723ee 100644 --- a/ts/screens/authentication/InvalidNfcConnectionScreen.tsx +++ b/ts/screens/authentication/InvalidNfcConnectionScreen.tsx @@ -6,14 +6,17 @@ import { Container, H2, Text, View } from "native-base"; import * as React from "react"; import { StyleSheet } from "react-native"; -import { NavigationScreenProp, NavigationState } from "react-navigation"; import BaseScreenComponent from "../../components/screens/BaseScreenComponent"; import FooterWithButtons from "../../components/ui/FooterWithButtons"; import I18n from "../../i18n"; +import { + AppParamsList, + IOStackNavigationProp +} from "../../navigation/params/AppParamsList"; type OwnProps = { - navigation: NavigationScreenProp; + navigation: IOStackNavigationProp; }; type Props = OwnProps; @@ -35,7 +38,7 @@ class InvalidNfcConnectionScreen extends React.Component { const cancelButtonProps = { cancel: true, block: true, - onPress: (): boolean => this.props.navigation.goBack(), + onPress: (): void => this.props.navigation.goBack(), title: I18n.t("global.buttons.cancel") }; const retryButtonProps = { diff --git a/ts/screens/authentication/LandingScreen.tsx b/ts/screens/authentication/LandingScreen.tsx index 0c62d3c0210..22d5d3d4460 100644 --- a/ts/screens/authentication/LandingScreen.tsx +++ b/ts/screens/authentication/LandingScreen.tsx @@ -2,6 +2,7 @@ * A screen where the user can choose to login with SPID or get more informations. * It includes a carousel with highlights on the app functionalities */ +import { CompatNavigationProp } from "@react-navigation/compat"; import { none, Option, some } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import JailMonkey from "jail-monkey"; @@ -9,7 +10,6 @@ import { Content, Text, View } from "native-base"; import * as React from "react"; import { Alert, StyleSheet } from "react-native"; import DeviceInfo from "react-native-device-info"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import sessionExpiredImg from "../../../img/landing/session_expired.png"; import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity"; @@ -31,6 +31,10 @@ import IconFont from "../../components/ui/IconFont"; import { LightModalContextInterface } from "../../components/ui/LightModal"; import I18n from "../../i18n"; import { IdentityProvider } from "../../models/IdentityProvider"; +import { + AppParamsList, + IOStackNavigationProp +} from "../../navigation/params/AppParamsList"; import ROUTES from "../../navigation/routes"; import { idpSelected, @@ -51,8 +55,11 @@ import { ComponentProps } from "../../types/react"; import { isDevEnv } from "../../utils/environment"; import RootedDeviceModal from "../modal/RootedDeviceModal"; -type Props = NavigationStackScreenProps & - LightModalContextInterface & +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & LightModalContextInterface & ReturnType & ReturnType; @@ -185,26 +192,32 @@ class LandingScreen extends React.PureComponent { }; private navigateToMarkdown = () => - this.props.navigation.navigate(ROUTES.MARKDOWN); + this.props.navigation.navigate({ + routeName: ROUTES.MARKDOWN + }); private navigateToIdpSelection = () => - this.props.navigation.navigate(ROUTES.AUTHENTICATION_IDP_SELECTION); + this.props.navigation.navigate({ + routeName: ROUTES.AUTHENTICATION_IDP_SELECTION + }); private navigateToCiePinScreen = () => { if (this.isCieSupported()) { this.props.dispatchIdpCieSelected(); - this.props.navigation.navigate(ROUTES.CIE_PIN_SCREEN); + this.props.navigation.navigate({ + routeName: ROUTES.CIE_PIN_SCREEN + }); } else { this.openUnsupportedCIEModal(); } }; private navigateToSpidCieInformationRequest = () => - this.props.navigation.navigate( - this.isCieSupported() + this.props.navigation.navigate({ + routeName: this.isCieSupported() ? ROUTES.AUTHENTICATION_SPID_CIE_INFORMATION : ROUTES.AUTHENTICATION_SPID_INFORMATION - ); + }); private renderCardComponents = () => { const cardProps = getCards(this.isCieSupported()); diff --git a/ts/screens/authentication/SpidCIEInformationScreen.tsx b/ts/screens/authentication/SpidCIEInformationScreen.tsx index d39cffe99ca..f2d8105d0a0 100644 --- a/ts/screens/authentication/SpidCIEInformationScreen.tsx +++ b/ts/screens/authentication/SpidCIEInformationScreen.tsx @@ -1,6 +1,7 @@ /** * A screen where the user can know more about SPID, CIE and access to spid.gov.it */ +import { CompatNavigationProp } from "@react-navigation/compat"; import { Col, Content, @@ -14,16 +15,24 @@ import { } from "native-base"; import * as React from "react"; import { StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import BaseScreenComponent from "../../components/screens/BaseScreenComponent"; import { ScreenContentHeader } from "../../components/screens/ScreenContentHeader"; import FooterWithButtons from "../../components/ui/FooterWithButtons"; import Markdown from "../../components/ui/Markdown"; import { openLink } from "../../components/ui/Markdown/handlers/link"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../navigation/params/AuthenticationParamsList"; import customVariables from "../../theme/variables"; -type Props = NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp< + AuthenticationParamsList, + "AUTHENTICATION_SPID_CIE_INFORMATION" + > + >; +}; type State = { currentTab: number; diff --git a/ts/screens/authentication/SpidInformationScreen.tsx b/ts/screens/authentication/SpidInformationScreen.tsx index cf101d1cb81..5695ce32759 100644 --- a/ts/screens/authentication/SpidInformationScreen.tsx +++ b/ts/screens/authentication/SpidInformationScreen.tsx @@ -1,18 +1,27 @@ /** * A screen where the user can know more about spid and access to spid.gov.it */ +import { CompatNavigationProp } from "@react-navigation/compat"; import { Col, Content, Grid, H1, H2, Row, Text, View } from "native-base"; import * as React from "react"; import { StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity"; import BaseScreenComponent from "../../components/screens/BaseScreenComponent"; import { openLink } from "../../components/ui/Markdown/handlers/link"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../navigation/params/AuthenticationParamsList"; import variables from "../../theme/variables"; -type Props = NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp< + AuthenticationParamsList, + "AUTHENTICATION_SPID_INFORMATION" + > + >; +}; const styles = StyleSheet.create({ value: { diff --git a/ts/screens/authentication/TestAuthenticationScreen.tsx b/ts/screens/authentication/TestAuthenticationScreen.tsx index 5453712e9d7..1f4e2667e95 100644 --- a/ts/screens/authentication/TestAuthenticationScreen.tsx +++ b/ts/screens/authentication/TestAuthenticationScreen.tsx @@ -1,7 +1,7 @@ import { FiscalCode } from "italia-ts-commons/lib/strings"; import { Content, View } from "native-base"; import * as React from "react"; -import { SafeAreaView } from "react-navigation"; +import { SafeAreaView } from "react-native"; import { connect } from "react-redux"; import { PasswordLogin } from "../../../definitions/backend/PasswordLogin"; import { LabelledItem } from "../../components/LabelledItem"; diff --git a/ts/screens/authentication/cie/CieAuthorizeDataUsageScreen.tsx b/ts/screens/authentication/cie/CieAuthorizeDataUsageScreen.tsx index 04cd7c21206..15051260a91 100644 --- a/ts/screens/authentication/cie/CieAuthorizeDataUsageScreen.tsx +++ b/ts/screens/authentication/cie/CieAuthorizeDataUsageScreen.tsx @@ -1,17 +1,26 @@ /** * A screen displayed while the backend manage the opening of the session for the CIE authentication */ +import { CompatNavigationProp } from "@react-navigation/compat"; import { Content, H2, View } from "native-base"; import * as React from "react"; import { Alert, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import TopScreenComponent from "../../../components/screens/TopScreenComponent"; import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import Markdown from "../../../components/ui/Markdown"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../../navigation/params/AuthenticationParamsList"; import variables from "../../../theme/variables"; -type Props = NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp< + AuthenticationParamsList, + "CIE_AUTHORIZE_USAGE_SCREEN" + > + >; +}; type State = { isLoadingCompleted: boolean; diff --git a/ts/screens/authentication/cie/CieCardReaderScreen.tsx b/ts/screens/authentication/cie/CieCardReaderScreen.tsx index fffa11a0496..d3a9c9f4a10 100644 --- a/ts/screens/authentication/cie/CieCardReaderScreen.tsx +++ b/ts/screens/authentication/cie/CieCardReaderScreen.tsx @@ -4,6 +4,8 @@ * TODO: when 100% is reached, the animation end */ import cieManager, { Event as CEvent } from "@pagopa/react-native-cie"; +import { CompatNavigationProp } from "@react-navigation/compat"; +import { fromNullable } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Millisecond } from "italia-ts-commons/lib/units"; import { Content, Text, View } from "native-base"; @@ -14,9 +16,7 @@ import { StyleSheet, Vibration } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; -import { fromNullable } from "fp-ts/lib/Option"; import CieNfcOverlay from "../../../components/cie/CieNfcOverlay"; import CieReadingCardAnimation, { ReadingState @@ -26,7 +26,17 @@ import { ScreenContentHeader } from "../../../components/screens/ScreenContentHe import TopScreenComponent from "../../../components/screens/TopScreenComponent"; import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../../navigation/params/AuthenticationParamsList"; import ROUTES from "../../../navigation/routes"; +import { + cieAuthenticationError, + CieAuthenticationErrorPayload, + CieAuthenticationErrorReason +} from "../../../store/actions/cie"; +import { resetToAuthenticationRoute } from "../../../store/actions/navigation"; +import { ReduxProps } from "../../../store/actions/types"; +import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; import { isNfcEnabledSelector } from "../../../store/reducers/cie"; import { GlobalState } from "../../../store/reducers/types"; import customVariables from "../../../theme/variables"; @@ -34,15 +44,7 @@ import { isScreenReaderEnabled, setAccessibilityFocus } from "../../../utils/accessibility"; -import { - cieAuthenticationError, - CieAuthenticationErrorPayload, - CieAuthenticationErrorReason -} from "../../../store/actions/cie"; -import { ReduxProps } from "../../../store/actions/types"; import { isIos } from "../../../utils/platform"; -import { resetToAuthenticationRoute } from "../../../store/actions/navigation"; -import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; import { assistanceToolRemoteConfig, handleSendAssistanceLog @@ -53,8 +55,11 @@ export type CieCardReaderScreenNavigationParams = { authorizationUri: string; }; -type Props = NavigationStackScreenProps & - ReduxProps & +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReduxProps & ReturnType; const styles = StyleSheet.create({ @@ -76,8 +81,7 @@ type State = { type setErrorParameter = { eventReason: CieAuthenticationErrorReason; errorDescription?: string; - navigationRoute?: string; - navigationParams?: Record; + navigation?: () => void; }; // A subset of Cie Events (errors) which is of interest to analytics @@ -202,8 +206,7 @@ class CieCardReaderScreen extends React.PureComponent { private setError = ({ eventReason, errorDescription, - navigationRoute, - navigationParams = {} + navigation }: setErrorParameter) => { const cieDescription = errorDescription ?? @@ -221,9 +224,7 @@ class CieCardReaderScreen extends React.PureComponent { }, () => { Vibration.vibrate(VIBRATION); - if (navigationRoute !== undefined) { - this.props.navigation.navigate(navigationRoute, navigationParams); - } + navigation?.(); } ); }; @@ -258,7 +259,10 @@ class CieCardReaderScreen extends React.PureComponent { case "ON_CARD_PIN_LOCKED": this.setError({ eventReason: event.event, - navigationRoute: ROUTES.CIE_PIN_TEMP_LOCKED_SCREEN + navigation: () => + this.props.navigation.navigate({ + routeName: ROUTES.CIE_PIN_TEMP_LOCKED_SCREEN + }) }); break; @@ -266,10 +270,13 @@ class CieCardReaderScreen extends React.PureComponent { case "ON_PIN_ERROR": this.setError({ eventReason: event.event, - navigationRoute: ROUTES.CIE_WRONG_PIN_SCREEN, - navigationParams: { - remainingCount: event.attemptsLeft - } + navigation: () => + this.props.navigation.navigate({ + routeName: ROUTES.CIE_WRONG_PIN_SCREEN, + params: { + remainingCount: event.attemptsLeft + } + }) }); break; @@ -278,7 +285,10 @@ class CieCardReaderScreen extends React.PureComponent { case "CERTIFICATE_REVOKED": this.setError({ eventReason: event.event, - navigationRoute: ROUTES.CIE_EXPIRED_SCREEN + navigation: () => + this.props.navigation.navigate({ + routeName: ROUTES.CIE_EXPIRED_SCREEN + }) }); break; @@ -349,8 +359,11 @@ class CieCardReaderScreen extends React.PureComponent { this.updateContent(); setTimeout( async () => { - this.props.navigation.navigate(ROUTES.CIE_CONSENT_DATA_USAGE, { - cieConsentUri + this.props.navigation.navigate({ + routeName: ROUTES.CIE_CONSENT_DATA_USAGE, + params: { + cieConsentUri + } }); // if screen reader is enabled, give more time to read the success message }, diff --git a/ts/screens/authentication/cie/CieConsentDataUsageScreen.tsx b/ts/screens/authentication/cie/CieConsentDataUsageScreen.tsx index 939db8db251..c70b78a5b80 100644 --- a/ts/screens/authentication/cie/CieConsentDataUsageScreen.tsx +++ b/ts/screens/authentication/cie/CieConsentDataUsageScreen.tsx @@ -2,6 +2,7 @@ * A screen to display, by a webview, the consent to send user sensitive data * to backend and proceed with the onboarding process */ +import { CompatNavigationProp } from "@react-navigation/compat"; import { View } from "native-base"; import * as React from "react"; import { Alert, BackHandler } from "react-native"; @@ -10,13 +11,13 @@ import { WebViewHttpErrorEvent, WebViewNavigation } from "react-native-webview/lib/WebViewTypes"; -import { NavigationScreenProp, NavigationState } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import LoadingSpinnerOverlay from "../../../components/LoadingSpinnerOverlay"; import GenericErrorComponent from "../../../components/screens/GenericErrorComponent"; import TopScreenComponent from "../../../components/screens/TopScreenComponent"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../../navigation/params/AuthenticationParamsList"; import { loginFailure, loginSuccess @@ -41,10 +42,11 @@ type State = { isLoginSuccess?: boolean; }; -type Props = NavigationScreenProp & - OwnProps & - NavigationStackScreenProps & - ReturnType; +type Props = OwnProps & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType; const loaderComponent = ( diff --git a/ts/screens/authentication/cie/CieExpiredOrInvalidScreen.tsx b/ts/screens/authentication/cie/CieExpiredOrInvalidScreen.tsx index a644857a05b..0df1e2840f2 100644 --- a/ts/screens/authentication/cie/CieExpiredOrInvalidScreen.tsx +++ b/ts/screens/authentication/cie/CieExpiredOrInvalidScreen.tsx @@ -1,6 +1,6 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { Content, Text, View } from "native-base"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Link } from "../../../components/core/typography/Link"; import { ScreenContentHeader } from "../../../components/screens/ScreenContentHeader"; @@ -8,10 +8,16 @@ import TopScreenComponent from "../../../components/screens/TopScreenComponent"; import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import { openLink } from "../../../components/ui/Markdown/handlers/link"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../../navigation/params/AuthenticationParamsList"; import { resetToAuthenticationRoute } from "../../../store/actions/navigation"; import { ReduxProps } from "../../../store/actions/types"; -type Props = NavigationStackScreenProps & ReduxProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReduxProps; const bookingUrl = I18n.t("cie.booking_url"); const browseToLink = () => openLink(bookingUrl); diff --git a/ts/screens/authentication/cie/CiePinLockedTemporarilyScreen.tsx b/ts/screens/authentication/cie/CiePinLockedTemporarilyScreen.tsx index d281ba1076a..133fe27ea29 100644 --- a/ts/screens/authentication/cie/CiePinLockedTemporarilyScreen.tsx +++ b/ts/screens/authentication/cie/CiePinLockedTemporarilyScreen.tsx @@ -1,22 +1,31 @@ /** * A screen to alert the user about the number of attempts remains */ +import { CompatNavigationProp } from "@react-navigation/compat"; +import { constNull } from "fp-ts/lib/function"; import { Content } from "native-base"; import * as React from "react"; import { Linking, Platform } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; -import { constNull } from "fp-ts/lib/function"; import { ScreenContentHeader } from "../../../components/screens/ScreenContentHeader"; import TopScreenComponent from "../../../components/screens/TopScreenComponent"; import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import Markdown from "../../../components/ui/Markdown"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../../navigation/params/AuthenticationParamsList"; import { resetToAuthenticationRoute } from "../../../store/actions/navigation"; import { ReduxProps } from "../../../store/actions/types"; import variables from "../../../theme/variables"; -type Props = NavigationStackScreenProps & ReduxProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp< + AuthenticationParamsList, + "CIE_PIN_TEMP_LOCKED_SCREEN" + > + >; +} & ReduxProps; type State = Readonly<{ isLoadingCompleted: boolean; diff --git a/ts/screens/authentication/cie/CiePinScreen.tsx b/ts/screens/authentication/cie/CiePinScreen.tsx index 41c926340dc..c396418ec1a 100644 --- a/ts/screens/authentication/cie/CiePinScreen.tsx +++ b/ts/screens/authentication/cie/CiePinScreen.tsx @@ -1,3 +1,5 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; +import { useNavigation } from "@react-navigation/native"; import { Millisecond } from "italia-ts-commons/lib/units"; import { View } from "native-base"; import React, { @@ -14,8 +16,6 @@ import { ScrollView, StyleSheet } from "react-native"; -import { NavigationContext } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import AdviceComponent from "../../../components/AdviceComponent"; import ButtonDefaultOpacity from "../../../components/ButtonDefaultOpacity"; @@ -32,6 +32,8 @@ import { } from "../../../components/ui/LightModal"; import Markdown from "../../../components/ui/Markdown"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../../navigation/params/AuthenticationParamsList"; import ROUTES from "../../../navigation/routes"; import { nfcIsEnabled } from "../../../store/actions/cie"; import { Dispatch, ReduxProps } from "../../../store/actions/types"; @@ -45,8 +47,11 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ }); type Props = ReduxProps & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; const styles = StyleSheet.create({ container: { @@ -74,7 +79,7 @@ const onOpenForgotPinPage = () => openWebUrl(FORGOT_PIN_PAGE_URL); const CiePinScreen: React.FC = props => { const { showAnimatedModal, hideModal } = useContext(LightModalContext); - const { navigate } = useContext(NavigationContext); + const navigation = useNavigation(); const [pin, setPin] = useState(""); const continueButtonRef = useRef(null); const pinPadViewRef = useRef(null); @@ -113,12 +118,9 @@ const CiePinScreen: React.FC = props => { useEffect(() => { if (authUrlGenerated !== undefined) { - navigate({ - routeName: ROUTES.CIE_CARD_READER_SCREEN, - params: { - ciePin: pin, - authorizationUri: authUrlGenerated - } + navigation.navigate(ROUTES.CIE_CARD_READER_SCREEN, { + ciePin: pin, + authorizationUri: authUrlGenerated }); handleAuthenticationOverlayOnClose(); } @@ -126,7 +128,7 @@ const CiePinScreen: React.FC = props => { handleAuthenticationOverlayOnClose, authUrlGenerated, hideModal, - navigate, + navigation, pin ]); diff --git a/ts/screens/authentication/cie/CieWrongCiePinScreen.tsx b/ts/screens/authentication/cie/CieWrongCiePinScreen.tsx index c51e05b6f96..98571d49f1c 100644 --- a/ts/screens/authentication/cie/CieWrongCiePinScreen.tsx +++ b/ts/screens/authentication/cie/CieWrongCiePinScreen.tsx @@ -1,15 +1,17 @@ /** * A screen to alert the user about the number of attempts remains */ +import { CompatNavigationProp } from "@react-navigation/compat"; import { Content, Text, View } from "native-base"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { ScreenContentHeader } from "../../../components/screens/ScreenContentHeader"; import TopScreenComponent from "../../../components/screens/TopScreenComponent"; import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { AuthenticationParamsList } from "../../../navigation/params/AuthenticationParamsList"; import ROUTES from "../../../navigation/routes"; import { resetToAuthenticationRoute } from "../../../store/actions/navigation"; @@ -17,13 +19,16 @@ export type CieWrongCiePinScreenNavigationParams = { remainingCount: number; }; -type Props = NavigationStackScreenProps & - ReturnType; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType; class CieWrongCiePinScreen extends React.PureComponent { // TODO: use redux to handle control? private navigateToCiePinScreen = async () => { - this.props.navigation.navigate(ROUTES.CIE_PIN_SCREEN); + this.props.navigation.navigate({ routeName: ROUTES.CIE_PIN_SCREEN }); }; get ciePinRemainingCount() { diff --git a/ts/screens/messages/MessageDetailScreen/index.tsx b/ts/screens/messages/MessageDetailScreen/index.tsx index f23f75e7344..35869eb200e 100644 --- a/ts/screens/messages/MessageDetailScreen/index.tsx +++ b/ts/screens/messages/MessageDetailScreen/index.tsx @@ -1,7 +1,7 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { fromNullable, none } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { CreatedMessageWithoutContent } from "../../../../definitions/backend/CreatedMessageWithoutContent"; import { TagEnum } from "../../../../definitions/backend/MessageCategoryPayment"; @@ -10,6 +10,8 @@ import BaseScreenComponent, { ContextualHelpPropsMarkdown } from "../../../components/screens/BaseScreenComponent"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { MessagesParamsList } from "../../../navigation/params/MessagesParamsList"; import { loadMessageWithRelations, MessageReadType, @@ -35,7 +37,11 @@ export type MessageDetailScreenNavigationParams = { messageId: string; }; -type OwnProps = NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = OwnProps & ReturnType & diff --git a/ts/screens/messages/MessageRouterScreen.tsx b/ts/screens/messages/MessageRouterScreen.tsx index 2f4d8122083..227b40db632 100644 --- a/ts/screens/messages/MessageRouterScreen.tsx +++ b/ts/screens/messages/MessageRouterScreen.tsx @@ -1,7 +1,7 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import * as React from "react"; import { useEffect, useRef } from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { CreatedMessageWithContentAndAttachments } from "../../../definitions/backend/CreatedMessageWithContentAndAttachments"; @@ -11,6 +11,8 @@ import { navigateToEuCovidCertificateDetailScreen } from "../../features/euCovid import { EUCovidCertificateAuthCode } from "../../features/euCovidCert/types/EUCovidCertificate"; import I18n from "../../i18n"; import { mixpanelTrack } from "../../mixpanel"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { MessagesParamsList } from "../../navigation/params/MessagesParamsList"; import { DEPRECATED_loadMessages as loadMessages } from "../../store/actions/messages"; import { navigateBack, @@ -26,8 +28,11 @@ export type MessageRouterScreenNavigationParams = MessageDetailScreenNavigationParams; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; /** * In order to have the final CreatedMessageWithContentAndAttachments, these conditions should be verified: diff --git a/ts/screens/messages/MessagesHomeScreen.tsx b/ts/screens/messages/MessagesHomeScreen.tsx index e544d8d5394..224eff3d01e 100644 --- a/ts/screens/messages/MessagesHomeScreen.tsx +++ b/ts/screens/messages/MessagesHomeScreen.tsx @@ -1,13 +1,13 @@ /** * A screen that contains all the Tabs related to messages. */ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; +import { Millisecond } from "italia-ts-commons/lib/units"; import { Tab, Tabs } from "native-base"; import * as React from "react"; import { Animated, Platform, StyleSheet, View } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; -import { Millisecond } from "italia-ts-commons/lib/units"; import { IOStyles } from "../../components/core/variables/IOStyles"; import MessagesArchive from "../../components/messages/MessagesArchive"; import MessagesDeadlines from "../../components/messages/MessagesDeadlines"; @@ -19,7 +19,10 @@ import TopScreenComponent from "../../components/screens/TopScreenComponent"; import { MIN_CHARACTER_SEARCH_TEXT } from "../../components/search/SearchButton"; import { SearchNoResultMessage } from "../../components/search/SearchNoResultMessage"; import SectionStatusComponent from "../../components/SectionStatus"; +import FocusAwareStatusBar from "../../components/ui/FocusAwareStatusBar"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { MainTabParamsList } from "../../navigation/params/MainTabParamsList"; import { DEPRECATED_loadMessages as loadMessages, DEPRECATED_setMessagesArchivedState @@ -27,6 +30,7 @@ import { import { navigateToMessageRouterScreen } from "../../store/actions/navigation"; import { loadServiceDetail } from "../../store/actions/services"; import { Dispatch } from "../../store/actions/types"; +import { sectionStatusSelector } from "../../store/reducers/backendStatus"; import { lexicallyOrderedMessagesStateSelector } from "../../store/reducers/entities/messages"; import { paymentsByRptIdSelector } from "../../store/reducers/entities/payments"; import { @@ -40,16 +44,17 @@ import { import { GlobalState } from "../../store/reducers/types"; import { makeFontStyleObject } from "../../theme/fonts"; import customVariables from "../../theme/variables"; -import { HEADER_HEIGHT, MESSAGE_ICON_HEIGHT } from "../../utils/constants"; -import { sectionStatusSelector } from "../../store/reducers/backendStatus"; import { isScreenReaderEnabled, setAccessibilityFocus } from "../../utils/accessibility"; -import FocusAwareStatusBar from "../../components/ui/FocusAwareStatusBar"; +import { HEADER_HEIGHT, MESSAGE_ICON_HEIGHT } from "../../utils/constants"; -type Props = NavigationStackScreenProps & - ReturnType & +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType & ReturnType; type State = { diff --git a/ts/screens/messages/__test__/MessageRouterScreen.test.tsx b/ts/screens/messages/__test__/MessageRouterScreen.test.tsx index f077baa7a1f..ae4d23332a3 100644 --- a/ts/screens/messages/__test__/MessageRouterScreen.test.tsx +++ b/ts/screens/messages/__test__/MessageRouterScreen.test.tsx @@ -1,3 +1,5 @@ +import { OrganizationFiscalCode } from "@pagopa/ts-commons/lib/strings"; +import { CommonActions } from "@react-navigation/native"; import * as pot from "italia-ts-commons/lib/pot"; import { FiscalCode, @@ -5,14 +7,13 @@ import { NonEmptyString, WithinRangeString } from "italia-ts-commons/lib/strings"; -import { NavigationActions, NavigationParams } from "react-navigation"; import { createStore } from "redux"; import configureMockStore from "redux-mock-store"; -import { OrganizationFiscalCode } from "@pagopa/ts-commons/lib/strings"; import { CreatedMessageWithContentAndAttachments } from "../../../../definitions/backend/CreatedMessageWithContentAndAttachments"; import { CreatedMessageWithoutContent } from "../../../../definitions/backend/CreatedMessageWithoutContent"; import { PaymentAmount } from "../../../../definitions/backend/PaymentAmount"; import { TimeToLiveSeconds } from "../../../../definitions/backend/TimeToLiveSeconds"; +import EUCOVIDCERT_ROUTES from "../../../features/euCovidCert/navigation/routes"; import NavigationService from "../../../navigation/NavigationService"; import ROUTES from "../../../navigation/routes"; import { applicationChangeState } from "../../../store/actions/application"; @@ -102,6 +103,14 @@ const mockEUCovidMessage: pot.Pot< jest.mock("../../../config", () => ({ euCovidCertificateEnabled: true })); +jest.mock("../../../navigation/NavigationService", () => ({ + dispatchNavigationAction: jest.fn(), + setNavigationReady: jest.fn(), + navigationRef: { + current: jest.fn() + } +})); + describe("Test MessageRouterScreen", () => { jest.useFakeTimers(); it("With the default state, the screen should be loading", () => { @@ -118,6 +127,7 @@ describe("Test MessageRouterScreen", () => { it("With the messages allIds pot.some and byId some, default message, the navigation to MESSAGE_DETAIL should be dispatched", () => { const globalState = appReducer(undefined, applicationChangeState("active")); const spy = jest.spyOn(NavigationService, "dispatchNavigationAction"); + spy.mockClear(); const routerScreen = renderComponentMockStore({ ...globalState, @@ -138,19 +148,22 @@ describe("Test MessageRouterScreen", () => { expect(routerScreen).not.toBeNull(); - expect(spy).toHaveBeenCalledWith(NavigationActions.back()); - expect(spy).toHaveBeenCalledWith( - NavigationActions.navigate({ - params: { - messageId: "01DQQGBXWSCNNY44CH2QZ95PIO" - }, - routeName: "MESSAGE_DETAIL" - }) - ); + expect(spy.mock.calls).toEqual([ + [CommonActions.goBack()], + [ + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: ROUTES.MESSAGE_DETAIL, + params: { + messageId: "01DQQGBXWSCNNY44CH2QZ95PIO" + } + }) + ] + ]); }); it("With the euCovidCertificate feature flag enabled, messages allIds pot.some and byId some, EU Covid message, the navigation to EUCOVIDCERT_DETAILS should be dispatched", () => { const globalState = appReducer(undefined, applicationChangeState("active")); const spy = jest.spyOn(NavigationService, "dispatchNavigationAction"); + spy.mockClear(); const routerScreen = renderComponentMockStore({ ...globalState, @@ -170,16 +183,21 @@ describe("Test MessageRouterScreen", () => { }); expect(routerScreen).not.toBeNull(); - expect(spy).toHaveBeenCalledWith(NavigationActions.back()); - expect(spy).toHaveBeenCalledWith( - NavigationActions.navigate({ - routeName: "EUCOVIDCERT_CERTIFICATE", - params: { - authCode: "eu_covid_cert", - messageId: "01DQQGBXWSCNNY44CH2QZ95PIO" - } - }) - ); + expect(spy.mock.calls).toEqual([ + [CommonActions.goBack()], + [ + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: EUCOVIDCERT_ROUTES.MAIN, + params: { + screen: EUCOVIDCERT_ROUTES.CERTIFICATE, + params: { + authCode: "eu_covid_cert", + messageId: "01DQQGBXWSCNNY44CH2QZ95PIO" + } + } + }) + ] + ]); }); it("With the messages allIds pot.noneLoading, the screen should be loading", () => { const globalState = appReducer(undefined, applicationChangeState("active")); @@ -348,7 +366,7 @@ const renderComponentMockStore = (state: GlobalState) => { } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( MessageRouterScreen, ROUTES.MESSAGE_ROUTER, { messageId: "messageId" }, @@ -362,7 +380,7 @@ const renderComponent = (state: GlobalState) => { const store = createStore(appReducer, state as any); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( MessageRouterScreen, ROUTES.MESSAGE_ROUTER, { messageId: "messageId" }, diff --git a/ts/screens/messages/paginated/MessageDetailScreen.tsx b/ts/screens/messages/paginated/MessageDetailScreen.tsx index b140462cd87..9623ce2637f 100644 --- a/ts/screens/messages/paginated/MessageDetailScreen.tsx +++ b/ts/screens/messages/paginated/MessageDetailScreen.tsx @@ -1,8 +1,8 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { Text, View } from "native-base"; import React from "react"; import { ActivityIndicator, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import MessageDetailComponent from "../../../components/messages/paginated/MessageDetail"; @@ -10,6 +10,8 @@ import BaseScreenComponent, { ContextualHelpPropsMarkdown } from "../../../components/screens/BaseScreenComponent"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { MessagesParamsList } from "../../../navigation/params/MessagesParamsList"; import { loadMessageDetails } from "../../../store/actions/messages"; import { navigateToServiceDetailsScreen } from "../../../store/actions/navigation"; import { loadServiceDetail } from "../../../store/actions/services"; @@ -45,8 +47,11 @@ export type MessageDetailScreenPaginatedNavigationParams = { message: UIMessage; }; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = OwnProps & ReturnType & diff --git a/ts/screens/messages/paginated/MessageRouterScreen.tsx b/ts/screens/messages/paginated/MessageRouterScreen.tsx index 6d3d58516d5..c70dad35830 100644 --- a/ts/screens/messages/paginated/MessageRouterScreen.tsx +++ b/ts/screens/messages/paginated/MessageRouterScreen.tsx @@ -1,6 +1,7 @@ import * as pot from "@pagopa/ts-commons/lib/pot"; +import { CompatNavigationProp } from "@react-navigation/compat/src/types"; +import { useNavigation } from "@react-navigation/native"; import React, { useCallback, useEffect, useRef } from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import * as O from "fp-ts/lib/Option"; @@ -20,6 +21,8 @@ import { EUCovidCertificateAuthCode } from "../../../features/euCovidCert/types/ import { navigateToMvlDetailsScreen } from "../../../features/mvl/navigation/actions"; import I18n from "../../../i18n"; import NavigationService from "../../../navigation/NavigationService"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { MessagesParamsList } from "../../../navigation/params/MessagesParamsList"; import { loadMessageDetails, loadPreviousPageMessages, @@ -45,7 +48,6 @@ import { import { serviceByIdSelector } from "../../../store/reducers/entities/services/servicesById"; import { GlobalState } from "../../../store/reducers/types"; import { emptyContextualHelp } from "../../../utils/emptyContextualHelp"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; import { isStrictSome } from "../../../utils/pot"; import { useOnFirstRender } from "../../../utils/hooks/useOnFirstRender"; @@ -54,8 +56,11 @@ export type MessageRouterScreenPaginatedNavigationParams = { isArchived: boolean; }; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = OwnProps & ReturnType & ReturnType; @@ -108,7 +113,7 @@ const MessageRouterScreen = ({ messageId, setMessageReadState }: Props): React.ReactElement => { - const navigation = useNavigationContext(); + const navigation = useNavigation(); // used to automatically dispatch loadMessages if the pot is not some at the first rendering // (avoid displaying error at the first frame) const firstRendering = useRef(true); diff --git a/ts/screens/messages/paginated/MessagesHomeScreen.tsx b/ts/screens/messages/paginated/MessagesHomeScreen.tsx index 4477f9fc041..417c96f21cd 100644 --- a/ts/screens/messages/paginated/MessagesHomeScreen.tsx +++ b/ts/screens/messages/paginated/MessagesHomeScreen.tsx @@ -1,14 +1,18 @@ -import React, { useContext, useEffect } from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; -import { NavigationContext } from "react-navigation"; -import { connect, useDispatch } from "react-redux"; -import { Animated, Platform, StyleSheet, View } from "react-native"; -import { Tab, Tabs } from "native-base"; +import { CompatNavigationProp } from "@react-navigation/compat"; +import { useNavigation } from "@react-navigation/native"; +import { pipe } from "fp-ts/lib/function"; import { Millisecond } from "italia-ts-commons/lib/units"; -import { createSelector } from "reselect"; +import { Tab, Tabs } from "native-base"; +import React, { useEffect } from "react"; +import { Animated, Platform, StyleSheet, View } from "react-native"; +import { connect, useDispatch } from "react-redux"; +import { Dispatch } from "redux"; -import { pipe } from "fp-ts/lib/function"; -import { Dispatch } from "../../../store/actions/types"; +import { createSelector } from "reselect"; +import { IOStyles } from "../../../components/core/variables/IOStyles"; +import MessageList from "../../../components/messages/paginated/MessageList"; +import MessagesArchive from "../../../components/messages/paginated/MessagesArchive"; +import MessagesInbox from "../../../components/messages/paginated/MessagesInbox"; import MessagesSearch from "../../../components/messages/paginated/MessagesSearch"; import { ContextualHelpPropsMarkdown } from "../../../components/screens/BaseScreenComponent"; import { ScreenContentHeader } from "../../../components/screens/ScreenContentHeader"; @@ -16,48 +20,49 @@ import TopScreenComponent from "../../../components/screens/TopScreenComponent"; import { MIN_CHARACTER_SEARCH_TEXT } from "../../../components/search/SearchButton"; import { SearchNoResultMessage } from "../../../components/search/SearchNoResultMessage"; import SectionStatusComponent from "../../../components/SectionStatus"; +import FocusAwareStatusBar from "../../../components/ui/FocusAwareStatusBar"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { MainTabParamsList } from "../../../navigation/params/MainTabParamsList"; +import ROUTES from "../../../navigation/routes"; import { - isSearchMessagesEnabledSelector, - searchTextSelector -} from "../../../store/reducers/search"; -import { GlobalState } from "../../../store/reducers/types"; -import { MESSAGE_ICON_HEIGHT } from "../../../utils/constants"; + migrateToPaginatedMessages, + resetMigrationStatus, + upsertMessageStatusAttributes +} from "../../../store/actions/messages"; import { sectionStatusSelector } from "../../../store/reducers/backendStatus"; -import { - setAccessibilityFocus, - useScreenReaderEnabled -} from "../../../utils/accessibility"; -import MessageList from "../../../components/messages/paginated/MessageList"; -import MessagesInbox from "../../../components/messages/paginated/MessagesInbox"; -import { navigateToPaginatedMessageRouterAction } from "../../../store/actions/navigation"; -import { UIMessage } from "../../../store/reducers/entities/messages/types"; -import customVariables from "../../../theme/variables"; -import FocusAwareStatusBar from "../../../components/ui/FocusAwareStatusBar"; -import { IOStyles } from "../../../components/core/variables/IOStyles"; -import { makeFontStyleObject } from "../../../theme/fonts"; -import MessagesArchive from "../../../components/messages/paginated/MessagesArchive"; import { allArchiveMessagesSelector, allInboxMessagesSelector, allPaginatedSelector, MessageOperation } from "../../../store/reducers/entities/messages/allPaginated"; -import { useOnFirstRender } from "../../../utils/hooks/useOnFirstRender"; -import { - migrateToPaginatedMessages, - resetMigrationStatus, - upsertMessageStatusAttributes -} from "../../../store/actions/messages"; import { MessagesStatus, messagesStatusSelector } from "../../../store/reducers/entities/messages/messagesStatus"; +import { UIMessage } from "../../../store/reducers/entities/messages/types"; +import { + isSearchMessagesEnabledSelector, + searchTextSelector +} from "../../../store/reducers/search"; +import { GlobalState } from "../../../store/reducers/types"; +import { makeFontStyleObject } from "../../../theme/fonts"; +import customVariables from "../../../theme/variables"; +import { + setAccessibilityFocus, + useScreenReaderEnabled +} from "../../../utils/accessibility"; +import { MESSAGE_ICON_HEIGHT } from "../../../utils/constants"; +import { useOnFirstRender } from "../../../utils/hooks/useOnFirstRender"; import { showToast } from "../../../utils/showToast"; import MigratingMessage from "./MigratingMessage"; -type Props = NavigationStackScreenProps & - ReturnType & +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType & ReturnType; const contextualHelpMarkdown: ContextualHelpPropsMarkdown = { @@ -160,7 +165,7 @@ const MessagesHomeScreen = ({ resetMigrationStatus, latestMessageOperation }: Props) => { - const navigation = useContext(NavigationContext); + const navigation = useNavigation(); const needsMigration = Object.keys(messagesStatus).length > 0; useOnFirstRender(() => { @@ -201,12 +206,13 @@ const MessagesHomeScreen = ({ }, [latestMessageOperation]); const navigateToMessageDetail = (message: UIMessage) => { - navigation.dispatch( - navigateToPaginatedMessageRouterAction({ + navigation.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: ROUTES.MESSAGE_ROUTER_PAGINATED, + params: { messageId: message.id, isArchived: message.isArchived - }) - ); + } + }); }; const dispatch = useDispatch(); diff --git a/ts/screens/messages/paginated/__tests__/MessageRouterScreen.test.tsx b/ts/screens/messages/paginated/__tests__/MessageRouterScreen.test.tsx index 32a0e0f4bf4..b509def1bae 100644 --- a/ts/screens/messages/paginated/__tests__/MessageRouterScreen.test.tsx +++ b/ts/screens/messages/paginated/__tests__/MessageRouterScreen.test.tsx @@ -1,7 +1,5 @@ import { none } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; -import React from "react"; -import { NavigationParams } from "react-navigation"; import configureMockStore from "redux-mock-store"; import { successLoadMessageDetails } from "../../../../__mocks__/message"; import { @@ -35,11 +33,25 @@ jest.mock("../../../../config", () => ({ pageSize: 8, maximumItemsFromAPI: 8 })); -jest.mock("../../../../utils/hooks/useOnFocus", () => ({ - useNavigationContext: () => ({ - dispatch: mockNavDispatch, - state: { routeName: "test-route" } - }) + +jest.mock("@react-navigation/native", () => { + const actualNav = jest.requireActual("@react-navigation/native"); + return { + ...actualNav, + useNavigation: () => ({ + navigate: jest.fn(), + dispatch: mockNavDispatch, + addListener: () => jest.fn() + }) + }; +}); + +jest.mock("../../../../navigation/NavigationService", () => ({ + dispatchNavigationAction: jest.fn(), + setNavigationReady: jest.fn(), + navigationRef: { + current: jest.fn() + } })); describe("MessageRouterScreen", () => { @@ -225,21 +237,9 @@ const renderComponent = (messageId: string, state: InputState = {}) => { } } as GlobalState); const spyStoreDispatch = spyOn(store, "dispatch"); - const navParams = { messageId } as any; - const navigation = { - state: {}, - dispatch: jest.fn(), - getParam: (key: string) => navParams[key] - } as any; - - const component = renderScreenFakeNavRedux( - () => ( - - ), + + const component = renderScreenFakeNavRedux( + MessageRouterScreen, ROUTES.MESSAGE_ROUTER, { messageId }, store @@ -248,7 +248,6 @@ const renderComponent = (messageId: string, state: InputState = {}) => { return { component, store, - spyStoreDispatch, - navigation + spyStoreDispatch }; }; diff --git a/ts/screens/modal/__test__/RootModal.test.tsx b/ts/screens/modal/__test__/RootModal.test.tsx index 33d3d3bca30..92211c0d695 100644 --- a/ts/screens/modal/__test__/RootModal.test.tsx +++ b/ts/screens/modal/__test__/RootModal.test.tsx @@ -1,5 +1,5 @@ import DeviceInfo from "react-native-device-info"; -import { NavigationParams } from "react-navigation"; + import { createStore } from "redux"; import { versionInfoLoadFailure, @@ -15,11 +15,6 @@ import { GlobalState } from "../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; import RootModal from "../RootModal"; -jest.mock("react-native-device-info", () => ({ - getVersion: jest.fn(), - getReadableVersion: jest.fn() -})); - describe("RootModal", () => { describe("When the store is in initial state", () => { it("Shouldn't render the UpdateAppModal", () => { @@ -32,10 +27,12 @@ describe("RootModal", () => { const store = createStore(appReducer, globalState as any); expect(store.getState().versionInfo).toStrictEqual(null); - const testComponent = renderScreenFakeNavRedux< - GlobalState, - NavigationParams - >(RootModal, ROUTES.INGRESS, {}, store); + const testComponent = renderScreenFakeNavRedux( + RootModal, + ROUTES.INGRESS, + {}, + store + ); expect(testComponent).not.toBeNull(); expect(testComponent.queryByText(I18n.t("titleUpdateApp"))).toBeNull(); @@ -53,10 +50,12 @@ describe("RootModal", () => { expect(store.getState().versionInfo).toStrictEqual(null); store.dispatch(versionInfoLoadFailure(new Error())); - const testComponent = renderScreenFakeNavRedux< - GlobalState, - NavigationParams - >(RootModal, ROUTES.INGRESS, {}, store); + const testComponent = renderScreenFakeNavRedux( + RootModal, + ROUTES.INGRESS, + {}, + store + ); expect(testComponent).not.toBeNull(); expect(testComponent.queryByText(I18n.t("titleUpdateApp"))).toBeNull(); @@ -73,10 +72,12 @@ describe("RootModal", () => { expect(store.getState().versionInfo).toStrictEqual(null); store.dispatch(versionInfoLoadFailure(new Error())); - const testComponent = renderScreenFakeNavRedux< - GlobalState, - NavigationParams - >(RootModal, ROUTES.INGRESS, {}, store); + const testComponent = renderScreenFakeNavRedux( + RootModal, + ROUTES.INGRESS, + {}, + store + ); expect(testComponent).not.toBeNull(); expect(testComponent.queryByText(I18n.t("titleUpdateApp"))).toBeNull(); @@ -130,7 +131,7 @@ const testRootModal = ( android: minVersion }); - const testComponent = renderScreenFakeNavRedux( + const testComponent = renderScreenFakeNavRedux( RootModal, ROUTES.INGRESS, {}, diff --git a/ts/screens/onboarding/EmailInsertScreen.tsx b/ts/screens/onboarding/EmailInsertScreen.tsx index 5fd4bcba724..49f61962ae2 100644 --- a/ts/screens/onboarding/EmailInsertScreen.tsx +++ b/ts/screens/onboarding/EmailInsertScreen.tsx @@ -2,6 +2,7 @@ * A screen where user after login (with CIE) can set email address if it is * not present in the profile. */ +import { CompatNavigationProp, StackActions } from "@react-navigation/compat"; import { none, Option, some } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { EmailString } from "italia-ts-commons/lib/strings"; @@ -14,9 +15,8 @@ import { SafeAreaView, StyleSheet } from "react-native"; -import { StackActions } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; +import { H1 } from "../../components/core/typography/H1"; import { withLoadingSpinner } from "../../components/helpers/withLoadingSpinner"; import { LabelledItem } from "../../components/LabelledItem"; import BaseScreenComponent, { @@ -24,6 +24,8 @@ import BaseScreenComponent, { } from "../../components/screens/BaseScreenComponent"; import FooterWithButtons from "../../components/ui/FooterWithButtons"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { OnboardingParamsList } from "../../navigation/params/OnboardingParamsList"; import { navigateToEmailReadScreen } from "../../store/actions/navigation"; import { abortOnboarding, @@ -39,16 +41,18 @@ import { } from "../../store/reducers/profile"; import { GlobalState } from "../../store/reducers/types"; import customVariables from "../../theme/variables"; +import { withKeyboard } from "../../utils/keyboard"; import { isOnboardingCompleted } from "../../utils/navigation"; import { areStringsEqual } from "../../utils/options"; import { showToast } from "../../utils/showToast"; -import { withKeyboard } from "../../utils/keyboard"; -import { H1 } from "../../components/core/typography/H1"; type Props = ReduxProps & ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; const styles = StyleSheet.create({ flex: { diff --git a/ts/screens/onboarding/EmailReadScreen.tsx b/ts/screens/onboarding/EmailReadScreen.tsx index 1928be6da0b..36f885152e2 100644 --- a/ts/screens/onboarding/EmailReadScreen.tsx +++ b/ts/screens/onboarding/EmailReadScreen.tsx @@ -5,12 +5,11 @@ * - it is displayed during the user onboarding * - it is displayed after the onboarding (navigation from the profile section) */ +import { CompatNavigationProp, StackActions } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { Text, View } from "native-base"; import * as React from "react"; import { Alert, Platform, SafeAreaView, StyleSheet } from "react-native"; -import { StackActions } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { withLoadingSpinner } from "../../components/helpers/withLoadingSpinner"; import { withValidatedEmail } from "../../components/helpers/withValidatedEmail"; @@ -25,6 +24,8 @@ import { import FooterWithButtons from "../../components/ui/FooterWithButtons"; import IconFont from "../../components/ui/IconFont"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { OnboardingParamsList } from "../../navigation/params/OnboardingParamsList"; import { navigateBack, navigateToEmailInsertScreen @@ -45,8 +46,11 @@ import { isOnboardingCompleted } from "../../utils/navigation"; type Props = ReduxProps & ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; + }; const styles = StyleSheet.create({ flex: { diff --git a/ts/screens/onboarding/FingerprintScreen.tsx b/ts/screens/onboarding/FingerprintScreen.tsx index 4b0298a3765..4c21c5ebf50 100644 --- a/ts/screens/onboarding/FingerprintScreen.tsx +++ b/ts/screens/onboarding/FingerprintScreen.tsx @@ -1,13 +1,15 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { Content, Text } from "native-base"; import * as React from "react"; import { Alert } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { ContextualHelpPropsMarkdown } from "../../components/screens/BaseScreenComponent"; import { ScreenContentHeader } from "../../components/screens/ScreenContentHeader"; import TopScreenComponent from "../../components/screens/TopScreenComponent"; import FooterWithButtons from "../../components/ui/FooterWithButtons"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { OnboardingParamsList } from "../../navigation/params/OnboardingParamsList"; import { abortOnboarding, fingerprintAcknowledge @@ -48,8 +50,11 @@ function getBiometryIconName(biometryType: BiometricsValidType): string { } } -type Props = NavigationStackScreenProps & - ReturnType; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType; const contextualHelpMarkdown: ContextualHelpPropsMarkdown = { title: "onboarding.contextualHelpTitle", diff --git a/ts/screens/onboarding/OnboardingServicesPreferenceScreen.tsx b/ts/screens/onboarding/OnboardingServicesPreferenceScreen.tsx index 9c2215428b6..8b33f40d2c0 100644 --- a/ts/screens/onboarding/OnboardingServicesPreferenceScreen.tsx +++ b/ts/screens/onboarding/OnboardingServicesPreferenceScreen.tsx @@ -1,8 +1,8 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { View } from "native-base"; import * as React from "react"; import { SafeAreaView, ScrollView } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { ServicesPreferencesModeEnum } from "../../../definitions/backend/ServicesPreferencesMode"; import { InfoBox } from "../../components/box/InfoBox"; @@ -14,6 +14,8 @@ import BaseScreenComponent from "../../components/screens/BaseScreenComponent"; import FooterWithButtons from "../../components/ui/FooterWithButtons"; import { confirmButtonProps } from "../../features/bonus/bonusVacanze/components/buttons/ButtonConfigurations"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { OnboardingParamsList } from "../../navigation/params/OnboardingParamsList"; import { navigateToOnboardingServicePreferenceCompleteAction } from "../../store/actions/navigation"; import { servicesOptinCompleted } from "../../store/actions/onboarding"; import { profileUpsert } from "../../store/actions/profile"; @@ -33,8 +35,14 @@ export type OnboardingServicesPreferenceScreenNavigationParams = { isFirstOnboarding: boolean; }; type Props = ReturnType & - ReturnType & - NavigationStackScreenProps; + ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp< + OnboardingParamsList, + "ONBOARDING_SERVICES_PREFERENCE" + > + >; + }; const OnboardingServicesPreferenceScreen = ( props: Props diff --git a/ts/screens/onboarding/PinScreen.tsx b/ts/screens/onboarding/PinScreen.tsx index d8d2aecd147..9e36122ff4a 100644 --- a/ts/screens/onboarding/PinScreen.tsx +++ b/ts/screens/onboarding/PinScreen.tsx @@ -3,34 +3,37 @@ import { Millisecond } from "italia-ts-commons/lib/units"; import { Content, Text, View } from "native-base"; import * as React from "react"; import { Alert, SafeAreaView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity"; +import { withLightModalContext } from "../../components/helpers/withLightModalContext"; import Pinpad from "../../components/Pinpad"; import BaseScreenComponent, { ContextualHelpPropsMarkdown } from "../../components/screens/BaseScreenComponent"; +import { AlertModal } from "../../components/ui/AlertModal"; +import { LightModalContextInterface } from "../../components/ui/LightModal"; import I18n from "../../i18n"; +import { + AppParamsList, + IOStackNavigationRouteProps +} from "../../navigation/params/AppParamsList"; import { abortOnboarding } from "../../store/actions/onboarding"; import { createPinSuccess } from "../../store/actions/pinset"; +import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; +import { GlobalState } from "../../store/reducers/types"; import variables from "../../theme/variables"; import { PinString } from "../../types/PinString"; import { setAccessibilityFocus } from "../../utils/accessibility"; import { setPin } from "../../utils/keychain"; import { isOnboardingCompleted } from "../../utils/navigation"; import { maybeNotNullyString } from "../../utils/strings"; -import { GlobalState } from "../../store/reducers/types"; -import { AlertModal } from "../../components/ui/AlertModal"; -import { withLightModalContext } from "../../components/helpers/withLightModalContext"; -import { LightModalContextInterface } from "../../components/ui/LightModal"; -import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; import { assistanceToolRemoteConfig, handleSendAssistanceLog } from "../../utils/supportAssistance"; -type Props = NavigationStackScreenProps & +type Props = IOStackNavigationRouteProps & LightModalContextInterface & ReturnType & ReturnType; @@ -370,7 +373,7 @@ class PinScreen extends React.PureComponent { private handleGoBack = () => { if (isOnboardingCompleted()) { - this.props.navigation.goBack(null); + this.props.navigation.goBack(); return; } Alert.alert( diff --git a/ts/screens/onboarding/TosScreen.tsx b/ts/screens/onboarding/TosScreen.tsx index 085e796ed92..46aed862e54 100644 --- a/ts/screens/onboarding/TosScreen.tsx +++ b/ts/screens/onboarding/TosScreen.tsx @@ -4,13 +4,14 @@ * has to accept the new version of ToS. * This screen is used also as Privacy screen From Profile section. */ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { Text, View } from "native-base"; import * as React from "react"; -import { Alert, Image, StyleSheet, SafeAreaView } from "react-native"; +import { Alert, Image, SafeAreaView, StyleSheet } from "react-native"; import { WebViewMessageEvent } from "react-native-webview/lib/WebViewTypes"; -import { NavigationScreenProp, NavigationState } from "react-navigation"; import { connect } from "react-redux"; +import brokenLinkImage from "../../../img/broken-link.png"; import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity"; import { withLoadingSpinner } from "../../components/helpers/withLoadingSpinner"; import BaseScreenComponent, { @@ -20,6 +21,8 @@ import TosWebviewComponent from "../../components/TosWebviewComponent"; import { WebViewMessage } from "../../components/ui/Markdown/types"; import { privacyUrl, tosVersion } from "../../config"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { OnboardingParamsList } from "../../navigation/params/OnboardingParamsList"; import { abortOnboarding, tosAccepted } from "../../store/actions/onboarding"; import { ReduxProps } from "../../store/actions/types"; import { @@ -30,9 +33,12 @@ import { GlobalState } from "../../store/reducers/types"; import customVariables from "../../theme/variables"; import { isOnboardingCompleted } from "../../utils/navigation"; import { showToast } from "../../utils/showToast"; +import { openWebUrl } from "../../utils/url"; type OwnProps = { - navigation: NavigationScreenProp; + navigation: CompatNavigationProp< + IOStackNavigationProp + >; }; type Props = ReduxProps & OwnProps & ReturnType; @@ -41,9 +47,6 @@ type State = { hasError: boolean; }; -import brokenLinkImage from "../../../img/broken-link.png"; -import { openWebUrl } from "../../utils/url"; - const styles = StyleSheet.create({ alert: { backgroundColor: customVariables.toastColor, diff --git a/ts/screens/profile/CalendarsPreferencesScreen.tsx b/ts/screens/profile/CalendarsPreferencesScreen.tsx index d181a34ee76..af56d00b003 100644 --- a/ts/screens/profile/CalendarsPreferencesScreen.tsx +++ b/ts/screens/profile/CalendarsPreferencesScreen.tsx @@ -1,6 +1,6 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as React from "react"; import { Calendar } from "react-native-calendar-events"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import CalendarsListContainer from "../../components/CalendarsListContainer"; import LoadingSpinnerOverlay from "../../components/LoadingSpinnerOverlay"; @@ -8,13 +8,19 @@ import { ContextualHelpPropsMarkdown } from "../../components/screens/BaseScreen import ScreenContent from "../../components/screens/ScreenContent"; import TopScreenComponent from "../../components/screens/TopScreenComponent"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { ProfileParamsList } from "../../navigation/params/ProfileParamsList"; import { preferredCalendarRemoveSuccess, preferredCalendarSaveSuccess } from "../../store/actions/persistedPreferences"; import { Dispatch } from "../../store/actions/types"; -type OwnProps = NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & OwnProps; diff --git a/ts/screens/profile/DownloadProfileDataScreen.tsx b/ts/screens/profile/DownloadProfileDataScreen.tsx index c3214a4ee18..77b0d31fd81 100644 --- a/ts/screens/profile/DownloadProfileDataScreen.tsx +++ b/ts/screens/profile/DownloadProfileDataScreen.tsx @@ -1,9 +1,9 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { View } from "native-base"; import * as React from "react"; import { Alert, StyleSheet } from "react-native"; -import { NavigationScreenProp, NavigationState } from "react-navigation"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { UserDataProcessingChoiceEnum } from "../../../definitions/backend/UserDataProcessingChoice"; @@ -14,6 +14,8 @@ import ScreenContent from "../../components/screens/ScreenContent"; import FooterWithButtons from "../../components/ui/FooterWithButtons"; import Markdown from "../../components/ui/Markdown"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { ProfileParamsList } from "../../navigation/params/ProfileParamsList"; import { ReduxProps } from "../../store/actions/types"; import { resetUserDataProcessingRequest, @@ -25,7 +27,9 @@ import themeVariables from "../../theme/variables"; import { showToast } from "../../utils/showToast"; type OwnProps = { - navigation: NavigationScreenProp; + navigation: CompatNavigationProp< + IOStackNavigationProp + >; }; type Props = ReduxProps & diff --git a/ts/screens/profile/EmailForwardingScreen.tsx b/ts/screens/profile/EmailForwardingScreen.tsx index 826df74f41d..915ef762d1e 100644 --- a/ts/screens/profile/EmailForwardingScreen.tsx +++ b/ts/screens/profile/EmailForwardingScreen.tsx @@ -2,10 +2,10 @@ * A screens to express the preferences related to email forwarding. * //TODO: magage errors (check toast etc.) + avoid useless updates */ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { List, Text } from "native-base"; import * as React from "react"; -import { NavigationScreenProp, NavigationState } from "react-navigation"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { withLoadingSpinner } from "../../components/helpers/withLoadingSpinner"; @@ -16,6 +16,8 @@ import ListItemComponent from "../../components/screens/ListItemComponent"; import ScreenContent from "../../components/screens/ScreenContent"; import TopScreenComponent from "../../components/screens/TopScreenComponent"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { ProfileParamsList } from "../../navigation/params/ProfileParamsList"; import { customEmailChannelSetEnabled } from "../../store/actions/persistedPreferences"; import { profileUpsert } from "../../store/actions/profile"; import { ReduxProps } from "../../store/actions/types"; @@ -34,9 +36,14 @@ import customVariables from "../../theme/variables"; import { getProfileChannelsforServicesList } from "../../utils/profile"; import { showToast } from "../../utils/showToast"; -type OwnProps = Readonly<{ - navigation: NavigationScreenProp; -}>; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp< + ProfileParamsList, + "PROFILE_PREFERENCES_EMAIL_FORWARDING" + > + >; +}; type State = { isCustomChannelEnabledChoice?: boolean; diff --git a/ts/screens/profile/FiscalCodeScreen.tsx b/ts/screens/profile/FiscalCodeScreen.tsx index 42ce890c8d4..abbb2a3b00a 100644 --- a/ts/screens/profile/FiscalCodeScreen.tsx +++ b/ts/screens/profile/FiscalCodeScreen.tsx @@ -1,9 +1,9 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { Text, View } from "native-base"; import * as React from "react"; import { ReactElement, useEffect } from "react"; import { ScrollView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { H2 } from "../../components/core/typography/H2"; @@ -19,6 +19,8 @@ import { LightModalContextInterface } from "../../components/ui/LightModal"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { ProfileParamsList } from "../../navigation/params/ProfileParamsList"; import { contentMunicipalityLoad } from "../../store/actions/content"; import { municipalitySelector } from "../../store/reducers/content"; import { profileSelector } from "../../store/reducers/profile"; @@ -26,9 +28,11 @@ import { GlobalState } from "../../store/reducers/types"; import customVariables from "../../theme/variables"; import { CodiceCatastale } from "../../types/MunicipalityCodiceCatastale"; -type Props = ReturnType & - NavigationStackScreenProps & - ReturnType & +type Props = ReturnType & { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType & LightModalContextInterface; const styles = StyleSheet.create({ diff --git a/ts/screens/profile/PreferencesScreen.tsx b/ts/screens/profile/PreferencesScreen.tsx index d9849d36806..acf05bc90c9 100644 --- a/ts/screens/profile/PreferencesScreen.tsx +++ b/ts/screens/profile/PreferencesScreen.tsx @@ -6,14 +6,19 @@ import * as pot from "italia-ts-commons/lib/pot"; import { List } from "native-base"; import * as React from "react"; import { Alert, PermissionsAndroid } from "react-native"; -import { NavigationScreenProp, NavigationState } from "react-navigation"; import { connect } from "react-redux"; +import { ServicesPreferencesModeEnum } from "../../../definitions/backend/ServicesPreferencesMode"; import { withLightModalContext } from "../../components/helpers/withLightModalContext"; import { ContextualHelpPropsMarkdown } from "../../components/screens/BaseScreenComponent"; import ListItemComponent from "../../components/screens/ListItemComponent"; +import ScreenContent from "../../components/screens/ScreenContent"; import TopScreenComponent from "../../components/screens/TopScreenComponent"; import { LightModalContextInterface } from "../../components/ui/LightModal"; import I18n from "../../i18n"; +import { + AppParamsList, + IOStackNavigationRouteProps +} from "../../navigation/params/AppParamsList"; import { navigateToCalendarPreferenceScreen, navigateToEmailForwardingPreferenceScreen, @@ -32,6 +37,7 @@ import { } from "../../store/reducers/profile"; import { GlobalState } from "../../store/reducers/types"; import { openAppSettings } from "../../utils/appSettings"; +import { AsyncAlert } from "../../utils/asyncAlert"; import { checkAndRequestPermission, convertLocalCalendarName @@ -40,14 +46,9 @@ import { getLocalePrimary, getLocalePrimaryWithFallback } from "../../utils/locale"; -import { ServicesPreferencesModeEnum } from "../../../definitions/backend/ServicesPreferencesMode"; -import ScreenContent from "../../components/screens/ScreenContent"; import { checkIOAndroidPermission } from "../../utils/permission"; -import { AsyncAlert } from "../../utils/asyncAlert"; -type OwnProps = Readonly<{ - navigation: NavigationScreenProp; -}>; +type OwnProps = IOStackNavigationRouteProps; type Props = OwnProps & ReturnType & diff --git a/ts/screens/profile/PrivacyMainScreen.tsx b/ts/screens/profile/PrivacyMainScreen.tsx index aba297857dd..1bde655cdd4 100644 --- a/ts/screens/profile/PrivacyMainScreen.tsx +++ b/ts/screens/profile/PrivacyMainScreen.tsx @@ -5,19 +5,22 @@ * - send a request to delete his profile * - send a request to export all his data (receiving them by email) */ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { List } from "native-base"; import * as React from "react"; import { Alert, AlertButton } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { UserDataProcessingChoiceEnum } from "../../../definitions/backend/UserDataProcessingChoice"; import { UserDataProcessingStatusEnum } from "../../../definitions/backend/UserDataProcessingStatus"; import { withLoadingSpinner } from "../../components/helpers/withLoadingSpinner"; import { ContextualHelpPropsMarkdown } from "../../components/screens/BaseScreenComponent"; import ListItemComponent from "../../components/screens/ListItemComponent"; +import ScreenContent from "../../components/screens/ScreenContent"; import TopScreenComponent from "../../components/screens/TopScreenComponent"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { ProfileParamsList } from "../../navigation/params/ProfileParamsList"; import ROUTES from "../../navigation/routes"; import { Dispatch } from "../../store/actions/types"; import { @@ -30,10 +33,12 @@ import { isProfileEmailValidatedSelector } from "../../store/reducers/profile"; import { GlobalState } from "../../store/reducers/types"; import { userDataProcessingSelector } from "../../store/reducers/userDataProcessing"; import { showToast } from "../../utils/showToast"; -import ScreenContent from "../../components/screens/ScreenContent"; -type Props = NavigationStackScreenProps & - ReturnType & +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType & ReturnType; type State = { @@ -197,8 +202,8 @@ class PrivacyMainScreen extends React.Component { "profile.main.privacy.privacyPolicy.description" )} onPress={() => - this.props.navigation.navigate(ROUTES.PROFILE_PRIVACY, { - isProfile: true + this.props.navigation.navigate({ + routeName: ROUTES.PROFILE_PRIVACY }) } useExtendedSubTitle={true} @@ -210,9 +215,9 @@ class PrivacyMainScreen extends React.Component { "profile.main.privacy.shareData.listItem.description" )} onPress={() => - this.props.navigation.navigate( - ROUTES.PROFILE_PRIVACY_SHARE_DATA - ) + this.props.navigation.navigate({ + routeName: ROUTES.PROFILE_PRIVACY_SHARE_DATA + }) } useExtendedSubTitle={true} /> @@ -249,9 +254,9 @@ class PrivacyMainScreen extends React.Component { UserDataProcessingChoiceEnum.DELETE ); } else { - this.props.navigation.navigate( - ROUTES.PROFILE_REMOVE_ACCOUNT_INFO - ); + this.props.navigation.navigate({ + routeName: ROUTES.PROFILE_REMOVE_ACCOUNT_INFO + }); } }} useExtendedSubTitle={true} diff --git a/ts/screens/profile/ProfileMainScreen.tsx b/ts/screens/profile/ProfileMainScreen.tsx index 15fd03782e2..58bbcd5630b 100644 --- a/ts/screens/profile/ProfileMainScreen.tsx +++ b/ts/screens/profile/ProfileMainScreen.tsx @@ -1,13 +1,9 @@ import AsyncStorage from "@react-native-community/async-storage"; +import { NavigationEvents } from "@react-navigation/compat"; import { Millisecond } from "italia-ts-commons/lib/units"; import { List, ListItem, Text, Toast, View } from "native-base"; import * as React from "react"; import { Alert, ScrollView, StyleSheet } from "react-native"; -import { - NavigationEvents, - NavigationScreenProp, - NavigationState -} from "react-navigation"; import { connect } from "react-redux"; import { TranslationKeys } from "../../../locales/locales"; import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity"; @@ -26,6 +22,8 @@ import Markdown from "../../components/ui/Markdown"; import Switch from "../../components/ui/Switch"; import { isPlaygroundsEnabled } from "../../config"; import I18n from "../../i18n"; +import { IOStackNavigationRouteProps } from "../../navigation/params/AppParamsList"; +import { MainTabParamsList } from "../../navigation/params/MainTabParamsList"; import ROUTES from "../../navigation/routes"; import { sessionExpired } from "../../store/actions/authentication"; import { setDebugModeEnabled } from "../../store/actions/debug"; @@ -47,11 +45,7 @@ import { clipboardSetStringWithFeedback } from "../../utils/clipboard"; import { getDeviceId } from "../../utils/device"; import { isDevEnv } from "../../utils/environment"; -type OwnProps = Readonly<{ - navigation: NavigationScreenProp; -}>; - -type Props = OwnProps & +type Props = IOStackNavigationRouteProps & LightModalContextInterface & ReturnType & ReturnType; @@ -305,15 +299,27 @@ class ProfileMainScreen extends React.PureComponent { <> navigation.navigate(ROUTES.WEB_PLAYGROUND)} + onPress={() => + navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.WEB_PLAYGROUND + }) + } /> navigation.navigate(ROUTES.MARKDOWN_PLAYGROUND)} + onPress={() => + navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.MARKDOWN_PLAYGROUND + }) + } /> navigation.navigate(ROUTES.CGN_LANDING_PLAYGROUND)} + onPress={() => + navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.CGN_LANDING_PLAYGROUND + }) + } /> )} @@ -321,7 +327,11 @@ class ProfileMainScreen extends React.PureComponent { {/* Showroom */} navigation.navigate(ROUTES.SHOWROOM)} + onPress={() => + navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.SHOWROOM + }) + } isFirstItem={true} /> @@ -448,7 +458,11 @@ class ProfileMainScreen extends React.PureComponent { navigation.navigate(ROUTES.PROFILE_DATA)} + onPress={() => + navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_DATA + }) + } isFirstItem /> @@ -456,21 +470,33 @@ class ProfileMainScreen extends React.PureComponent { navigation.navigate(ROUTES.PROFILE_PREFERENCES_HOME)} + onPress={() => + navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PREFERENCES_HOME + }) + } /> {/* Security */} navigation.navigate(ROUTES.PROFILE_SECURITY)} + onPress={() => + navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_SECURITY + }) + } /> {/* Privacy */} navigation.navigate(ROUTES.PROFILE_PRIVACY_MAIN)} + onPress={() => + navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PRIVACY_MAIN + }) + } /> {/* APP IO */} @@ -520,7 +546,9 @@ class ProfileMainScreen extends React.PureComponent { - this.props.navigation.navigate(ROUTES.PROFILE_FISCAL_CODE) + this.props.navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_FISCAL_CODE + }) } > diff --git a/ts/screens/profile/RemoveAccountDetailsScreen.tsx b/ts/screens/profile/RemoveAccountDetailsScreen.tsx index 8d229eac513..da31b852b8a 100644 --- a/ts/screens/profile/RemoveAccountDetailsScreen.tsx +++ b/ts/screens/profile/RemoveAccountDetailsScreen.tsx @@ -1,8 +1,8 @@ +import { StackActions } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { Content, View } from "native-base"; import * as React from "react"; import { Alert, SafeAreaView } from "react-native"; -import { StackActions } from "react-navigation"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { diff --git a/ts/screens/profile/RemoveAccountSuccessScreen.tsx b/ts/screens/profile/RemoveAccountSuccessScreen.tsx index fda813bd430..3b52f5f6836 100644 --- a/ts/screens/profile/RemoveAccountSuccessScreen.tsx +++ b/ts/screens/profile/RemoveAccountSuccessScreen.tsx @@ -2,19 +2,23 @@ import { Content, View } from "native-base"; import * as React from "react"; import { Image, SafeAreaView, StyleSheet } from "react-native"; import { connect } from "react-redux"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { IOStyles } from "../../components/core/variables/IOStyles"; import BaseScreenComponent from "../../components/screens/BaseScreenComponent"; import FooterWithButtons from "../../components/ui/FooterWithButtons"; import I18n from "../../i18n"; import { H4 } from "../../components/core/typography/H4"; import { H2 } from "../../components/core/typography/H2"; +import { + AppParamsList, + IOStackNavigationRouteProps +} from "../../navigation/params/AppParamsList"; import { Dispatch } from "../../store/actions/types"; import { logoutRequest } from "../../store/actions/authentication"; import expiredIcon from "../../../img/wallet/errors/payment-expired-icon.png"; import { useHardwareBackButton } from "../../features/bonus/bonusVacanze/components/hooks/useHardwareBackButton"; -type Props = NavigationStackScreenProps & ReturnType; +type Props = IOStackNavigationRouteProps & + ReturnType; const styles = StyleSheet.create({ content: { flex: 1, diff --git a/ts/screens/profile/__test__/ProfileDataScreen.test.tsx b/ts/screens/profile/__test__/ProfileDataScreen.test.tsx index 685564c42c5..dec302c7f36 100644 --- a/ts/screens/profile/__test__/ProfileDataScreen.test.tsx +++ b/ts/screens/profile/__test__/ProfileDataScreen.test.tsx @@ -1,6 +1,6 @@ import React from "react"; import configureMockStore from "redux-mock-store"; -import { NavigationParams } from "react-navigation"; + import { fireEvent } from "@testing-library/react-native"; import { appReducer } from "../../../store/reducers"; import { applicationChangeState } from "../../../store/actions/application"; @@ -92,7 +92,7 @@ const renderComponent = () => { } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , ROUTES.PROFILE_DATA, {}, diff --git a/ts/screens/profile/__test__/SecurityScreen.test.tsx b/ts/screens/profile/__test__/SecurityScreen.test.tsx index 4cfcb509119..f7497263293 100644 --- a/ts/screens/profile/__test__/SecurityScreen.test.tsx +++ b/ts/screens/profile/__test__/SecurityScreen.test.tsx @@ -1,6 +1,6 @@ import React from "react"; import configureMockStore from "redux-mock-store"; -import { NavigationParams } from "react-navigation"; + import { fireEvent } from "@testing-library/react-native"; import SecurityScreen from "../SecurityScreen"; import I18n from "../../../i18n"; @@ -74,7 +74,7 @@ const renderComponent = () => { } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( () => , ROUTES.PROFILE_SECURITY, {}, diff --git a/ts/screens/services/ServiceDetailsScreen.tsx b/ts/screens/services/ServiceDetailsScreen.tsx index a795ea11146..655e2013cfa 100644 --- a/ts/screens/services/ServiceDetailsScreen.tsx +++ b/ts/screens/services/ServiceDetailsScreen.tsx @@ -1,10 +1,10 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { fromNullable } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Content, Grid, View } from "native-base"; import * as React from "react"; import { useEffect, useState } from "react"; import { SafeAreaView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { ServiceId } from "../../../definitions/backend/ServiceId"; import { ServicePublic } from "../../../definitions/backend/ServicePublic"; @@ -23,6 +23,8 @@ import TosAndPrivacyBox from "../../components/services/TosAndPrivacyBox"; import Markdown from "../../components/ui/Markdown"; import { FooterTopShadow } from "../../features/bonus/bonusVacanze/components/FooterTopShadow"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { ServicesParamsList } from "../../navigation/params/ServicesParamsList"; import { loadServiceDetail } from "../../store/actions/services"; import { Dispatch } from "../../store/actions/types"; import { contentSelector } from "../../store/reducers/content"; @@ -44,8 +46,11 @@ export type ServiceDetailsScreenNavigationParams = Readonly<{ service: ServicePublic; }>; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & ReturnType & diff --git a/ts/screens/services/ServicesHomeScreen.tsx b/ts/screens/services/ServicesHomeScreen.tsx index 772bcd9f35a..493ff418f79 100644 --- a/ts/screens/services/ServicesHomeScreen.tsx +++ b/ts/screens/services/ServicesHomeScreen.tsx @@ -32,7 +32,6 @@ import { Platform, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { ServicePublic } from "../../../definitions/backend/ServicePublic"; import { Label } from "../../components/core/typography/Label"; @@ -54,6 +53,10 @@ import FocusAwareStatusBar from "../../components/ui/FocusAwareStatusBar"; import IconFont from "../../components/ui/IconFont"; import { LightModalContextInterface } from "../../components/ui/LightModal"; import I18n from "../../i18n"; +import { + AppParamsList, + IOStackNavigationRouteProps +} from "../../navigation/params/AppParamsList"; import { navigateToServiceDetailsScreen, navigateToServicePreferenceScreen @@ -100,7 +103,7 @@ import { import { showToast } from "../../utils/showToast"; import { ServiceDetailsScreenNavigationParams } from "./ServiceDetailsScreen"; -type OwnProps = NavigationStackScreenProps; +type OwnProps = IOStackNavigationRouteProps; type ReduxMergedProps = Readonly<{ updateOrganizationsOfInterestMetadata: ( diff --git a/ts/screens/services/__tests__/ServiceDetailsScreen.test.tsx b/ts/screens/services/__tests__/ServiceDetailsScreen.test.tsx index a12ac2f0628..7626ad4bb44 100644 --- a/ts/screens/services/__tests__/ServiceDetailsScreen.test.tsx +++ b/ts/screens/services/__tests__/ServiceDetailsScreen.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import configureMockStore from "redux-mock-store"; import { OrganizationFiscalCode } from "@pagopa/ts-commons/lib/strings"; import * as pot from "@pagopa/ts-commons/lib/pot"; @@ -72,7 +71,7 @@ const renderComponent = () => { } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( ServiceDetailsScreen, ROUTES.SERVICE_DETAIL, { service }, diff --git a/ts/screens/wallet/AddCardScreen.tsx b/ts/screens/wallet/AddCardScreen.tsx index 97e880a305d..79360d4c7da 100644 --- a/ts/screens/wallet/AddCardScreen.tsx +++ b/ts/screens/wallet/AddCardScreen.tsx @@ -4,6 +4,7 @@ */ import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { CompatNavigationProp } from "@react-navigation/compat"; import { fromEither, fromPredicate, @@ -17,7 +18,6 @@ import { Content, View } from "native-base"; import React, { useState } from "react"; import { Keyboard, SafeAreaView, ScrollView, StyleSheet } from "react-native"; import { Col, Grid } from "react-native-easy-grid"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { PaymentRequestsGetResponse } from "../../../definitions/backend/PaymentRequestsGetResponse"; import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity"; @@ -34,6 +34,8 @@ import { BlockButtonProps } from "../../components/ui/BlockButtons"; import FooterWithButtons from "../../components/ui/FooterWithButtons"; import { walletAddCoBadgeStart } from "../../features/wallet/onboarding/cobadge/store/actions"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../navigation/params/WalletParamsList"; import { navigateBack, navigateToWalletConfirmCardDetails @@ -75,7 +77,11 @@ export type AddCardScreenNavigationParams = Readonly<{ keyFrom?: string; }>; -type OwnProps = NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & ReturnType & diff --git a/ts/screens/wallet/AddCreditCardOutcomeCodeMessage.tsx b/ts/screens/wallet/AddCreditCardOutcomeCodeMessage.tsx index 4e210f7682b..343e3e8a9ae 100644 --- a/ts/screens/wallet/AddCreditCardOutcomeCodeMessage.tsx +++ b/ts/screens/wallet/AddCreditCardOutcomeCodeMessage.tsx @@ -1,5 +1,5 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import paymentCompleted from "../../../img/pictograms/payment-completed.png"; @@ -7,6 +7,8 @@ import { renderInfoRasterImage } from "../../components/infoScreen/imageRenderin import { InfoScreenComponent } from "../../components/infoScreen/InfoScreenComponent"; import OutcomeCodeMessageComponent from "../../components/wallet/OutcomeCodeMessageComponent"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../navigation/params/WalletParamsList"; import { navigateToWalletHome } from "../../store/actions/navigation"; import { GlobalState } from "../../store/reducers/types"; import { lastPaymentOutcomeCodeSelector } from "../../store/reducers/wallet/outcomeCode"; @@ -16,8 +18,14 @@ export type AddCreditCardOutcomeCodeMessageNavigationParams = Readonly<{ selectedWallet: Wallet; }>; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp< + WalletParamsList, + "ADD_CREDIT_CARD_OUTCOMECODE_MESSAGE" + > + >; +}; type Props = OwnProps & ReturnType & ReturnType; diff --git a/ts/screens/wallet/AddPaymentMethodScreen.tsx b/ts/screens/wallet/AddPaymentMethodScreen.tsx index 7aae0acc536..2d13352b681 100644 --- a/ts/screens/wallet/AddPaymentMethodScreen.tsx +++ b/ts/screens/wallet/AddPaymentMethodScreen.tsx @@ -1,10 +1,10 @@ import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { CompatNavigationProp } from "@react-navigation/compat"; import { Option } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Content, View } from "native-base"; import * as React from "react"; import { SafeAreaView } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { PaymentRequestsGetResponse } from "../../../definitions/backend/PaymentRequestsGetResponse"; import BpayLogo from "../../../img/wallet/payment-methods/bancomat_pay.svg"; @@ -32,6 +32,8 @@ import { import { walletAddPrivativeStart } from "../../features/wallet/onboarding/privative/store/actions"; import { walletAddSatispayStart } from "../../features/wallet/onboarding/satispay/store/actions"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../navigation/params/WalletParamsList"; import { navigateBack, navigateToWalletAddCreditCard @@ -58,11 +60,15 @@ export type AddPaymentMethodScreenNavigationParams = Readonly<{ keyFrom?: string; }>; -type OwnProps = - NavigationStackScreenProps; -type ReduxProps = ReturnType & +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; + +type Props = OwnProps & + ReturnType & ReturnType; -type Props = ReduxProps & OwnProps; const contextualHelpMarkdown: ContextualHelpPropsMarkdown = { title: "wallet.newPaymentMethod.contextualHelpTitle", @@ -70,7 +76,7 @@ const contextualHelpMarkdown: ContextualHelpPropsMarkdown = { }; const getPaymentMethods = ( - props: ReduxProps, + props: Props, options: { onlyPaymentMethodCanPay: boolean; isPaymentOnGoing: boolean; diff --git a/ts/screens/wallet/ConfirmCardDetailsScreen.tsx b/ts/screens/wallet/ConfirmCardDetailsScreen.tsx index 4b64355f74c..2386174b92b 100644 --- a/ts/screens/wallet/ConfirmCardDetailsScreen.tsx +++ b/ts/screens/wallet/ConfirmCardDetailsScreen.tsx @@ -3,13 +3,13 @@ * inserted the data required to save a new card */ import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { CompatNavigationProp } from "@react-navigation/compat"; import { constNull } from "fp-ts/lib/function"; import { fromNullable, none, Option, some } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Content, View } from "native-base"; import * as React from "react"; import { Alert, SafeAreaView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { PaymentRequestsGetResponse } from "../../../definitions/backend/PaymentRequestsGetResponse"; @@ -41,6 +41,8 @@ import { isReady } from "../../features/bonus/bpd/model/RemoteValue"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../navigation/params/WalletParamsList"; import { navigateToAddCreditCardOutcomeCode, navigateToPaymentPickPaymentMethodScreen, @@ -82,8 +84,11 @@ type ReduxMergedProps = Readonly<{ onRetry?: () => void; }>; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & ReturnType & @@ -384,10 +389,7 @@ const mapStateToProps = (state: GlobalState) => { }; }; -const mapDispatchToProps = ( - dispatch: Dispatch, - props: NavigationStackScreenProps -) => { +const mapDispatchToProps = (dispatch: Dispatch, props: OwnProps) => { const navigateToNextScreen = (maybeWallet: Option) => { const inPayment = props.navigation.getParam("inPayment"); if (inPayment.isSome()) { diff --git a/ts/screens/wallet/PaymentHistoryDetailsScreen.tsx b/ts/screens/wallet/PaymentHistoryDetailsScreen.tsx index d6348ea2e27..2608fe4a907 100644 --- a/ts/screens/wallet/PaymentHistoryDetailsScreen.tsx +++ b/ts/screens/wallet/PaymentHistoryDetailsScreen.tsx @@ -1,8 +1,8 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { fromNullable } from "fp-ts/lib/Option"; import { Text, View } from "native-base"; import * as React from "react"; import { StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { RptIdFromString } from "@pagopa/io-pagopa-commons/lib/pagopa"; import { EnteBeneficiario } from "../../../definitions/backend/EnteBeneficiario"; @@ -24,6 +24,8 @@ import { zendeskSupportStart } from "../../features/zendesk/store/actions"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../navigation/params/WalletParamsList"; import { Dispatch } from "../../store/actions/types"; import { canShowHelpSelector } from "../../store/reducers/assistanceTools"; import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; @@ -59,10 +61,12 @@ export type PaymentHistoryDetailsScreenNavigationParams = Readonly<{ payment: PaymentHistory; }>; -type Props = - NavigationStackScreenProps & - ReturnType & - ReturnType; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +} & ReturnType & + ReturnType; const styles = StyleSheet.create({ flex: { diff --git a/ts/screens/wallet/PaymentsHistoryScreen.tsx b/ts/screens/wallet/PaymentsHistoryScreen.tsx index 47ddec6d8e3..8d2f67b9cbd 100644 --- a/ts/screens/wallet/PaymentsHistoryScreen.tsx +++ b/ts/screens/wallet/PaymentsHistoryScreen.tsx @@ -2,7 +2,6 @@ import { reverse } from "fp-ts/lib/Array"; import { Content, Text, View } from "native-base"; import * as React from "react"; import { StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { H2 } from "../../components/core/typography/H2"; import { withValidatedEmail } from "../../components/helpers/withValidatedEmail"; @@ -11,6 +10,10 @@ import BaseScreenComponent from "../../components/screens/BaseScreenComponent"; import { EdgeBorderComponent } from "../../components/screens/EdgeBorderComponent"; import PaymentHistoryList from "../../components/wallet/PaymentsHistoryList"; import I18n from "../../i18n"; +import { + AppParamsList, + IOStackNavigationRouteProps +} from "../../navigation/params/AppParamsList"; import { navigateToPaymentHistoryDetail } from "../../store/actions/navigation"; import { Dispatch } from "../../store/actions/types"; import { @@ -22,7 +25,7 @@ import variables from "../../theme/variables"; type Props = ReturnType & ReturnType & - NavigationStackScreenProps; + IOStackNavigationRouteProps; const styles = StyleSheet.create({ noBottomPadding: { diff --git a/ts/screens/wallet/TransactionDetailsScreen.tsx b/ts/screens/wallet/TransactionDetailsScreen.tsx index c25d5983391..5b86737ef78 100644 --- a/ts/screens/wallet/TransactionDetailsScreen.tsx +++ b/ts/screens/wallet/TransactionDetailsScreen.tsx @@ -1,10 +1,12 @@ +import { + CompatNavigationProp, + NavigationEvents +} from "@react-navigation/compat"; import { fromNullable } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Text, View } from "native-base"; import * as React from "react"; import { BackHandler, Image, StyleSheet } from "react-native"; -import { NavigationEvents } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity"; import CopyButtonComponent from "../../components/CopyButtonComponent"; @@ -20,6 +22,8 @@ import { LightModalContextInterface } from "../../components/ui/LightModal"; import { PaymentSummaryComponent } from "../../components/wallet/PaymentSummaryComponent"; import { SlidedContentComponent } from "../../components/wallet/SlidedContentComponent"; import I18n from "../../i18n"; +import { IOStackNavigationProp } from "../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../navigation/params/WalletParamsList"; import { Dispatch } from "../../store/actions/types"; import { backToEntrypointPayment } from "../../store/actions/wallet/payment"; import { fetchPsp } from "../../store/actions/wallet/transactions"; @@ -42,8 +46,11 @@ export type TransactionDetailsScreenNavigationParams = Readonly<{ transaction: Transaction; }>; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & ReturnType & @@ -115,7 +122,10 @@ class TransactionDetailsScreen extends React.Component { BackHandler.removeEventListener("hardwareBackPress", this.handleBackPress); } - private handleBackPress = () => this.props.navigation.goBack(); + private handleBackPress = () => { + this.props.navigation.goBack(); + return true; + }; private handleWillFocus = () => { const transaction = this.props.navigation.getParam("transaction"); diff --git a/ts/screens/wallet/WalletHomeScreen.tsx b/ts/screens/wallet/WalletHomeScreen.tsx index d7266f33573..c8aaa888cb8 100644 --- a/ts/screens/wallet/WalletHomeScreen.tsx +++ b/ts/screens/wallet/WalletHomeScreen.tsx @@ -1,10 +1,9 @@ +import { NavigationEvents } from "@react-navigation/compat"; import { none } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Content, Text, View } from "native-base"; import * as React from "react"; import { BackHandler, Image, StyleSheet } from "react-native"; -import { NavigationEvents } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { BonusActivationWithQrCode } from "../../../definitions/bonus_vacanze/BonusActivationWithQrCode"; import { TypeEnum } from "../../../definitions/pagopa/Wallet"; @@ -55,6 +54,8 @@ import FeaturedCardCarousel from "../../features/wallet/component/card/FeaturedC import WalletV2PreviewCards from "../../features/wallet/component/card/WalletV2PreviewCards"; import NewPaymentMethodAddedNotifier from "../../features/wallet/component/NewMethodAddedNotifier"; import I18n from "../../i18n"; +import { IOStackNavigationRouteProps } from "../../navigation/params/AppParamsList"; +import { MainTabParamsList } from "../../navigation/params/MainTabParamsList"; import { navigateBack, navigateToPaymentScanQrCode, @@ -107,7 +108,7 @@ type State = { type Props = ReturnType & ReturnType & - NavigationStackScreenProps & + IOStackNavigationRouteProps & LightModalContextInterface; const styles = StyleSheet.create({ @@ -188,20 +189,13 @@ class WalletHomeScreen extends React.PureComponent { this.state = { hasFocus: false }; } - get newMethodAdded() { - return this.props.navigation.getParam("newMethodAdded"); - } - - get navigationKeyFrom() { - return this.props.navigation.getParam("keyFrom"); - } - private handleBackPress = () => { + const keyFrom = this.props.route.params?.keyFrom; const shouldPop = - this.newMethodAdded && this.navigationKeyFrom !== undefined; + this.props.route.params?.newMethodAdded && keyFrom !== undefined; if (shouldPop) { - this.props.navigateBack(this.navigationKeyFrom); + this.props.navigateBack(); return true; } return false; @@ -629,7 +623,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ validTo?: Date ) => navigateToBonusActiveDetailScreen({ bonus, validFrom, validTo }), navigateToBonusList: () => navigateToAvailableBonusScreen(), - navigateBack: (keyFrom?: string) => navigateBack({ key: keyFrom }), + navigateBack: () => navigateBack(), loadTransactions: (start: number) => dispatch(fetchTransactionsRequestWithExpBackoff({ start })), loadWallets: () => dispatch(fetchWalletsRequestWithExpBackoff()), diff --git a/ts/screens/wallet/__tests__/AddCardScreen.test.tsx b/ts/screens/wallet/__tests__/AddCardScreen.test.tsx index 76b01c75468..82fcf80b6b4 100644 --- a/ts/screens/wallet/__tests__/AddCardScreen.test.tsx +++ b/ts/screens/wallet/__tests__/AddCardScreen.test.tsx @@ -2,6 +2,7 @@ import { fireEvent } from "@testing-library/react-native"; import { none, some } from "fp-ts/lib/Option"; import * as React from "react"; import { createStore } from "redux"; +import { IPaymentMethod } from "../../../components/wallet/PaymentMethodsList"; import I18n from "../../../i18n"; import ROUTES from "../../../navigation/routes"; import { applicationChangeState } from "../../../store/actions/application"; @@ -11,9 +12,7 @@ import { isValidCardHolder } from "../../../utils/input"; import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; import AddCardScreen, { AddCardScreenNavigationParams } from "../AddCardScreen"; import { testableFunctions } from "../AddPaymentMethodScreen"; -import { IPaymentMethod } from "../../../components/wallet/PaymentMethodsList"; -jest.unmock("react-navigation"); jest.mock("react-native-share", () => ({ open: jest.fn() })); @@ -149,7 +148,8 @@ describe("getPaymentMethods", () => { isPaypalEnabled: true, canOnboardBPay: false }; - const methods = testableFunctions.getPaymentMethods!(props, { + // TODO: ⚠️ cast to any only to complete the merge, should be removed! + const methods = testableFunctions.getPaymentMethods!(props as any, { onlyPaymentMethodCanPay: true, isPaymentOnGoing: true, isPaypalEnabled: true, @@ -175,7 +175,8 @@ describe("getPaymentMethods", () => { }); it("paypal should be always notImplemented when the FF is OFF", () => { - const methods = testableFunctions.getPaymentMethods!(props, { + // TODO: ⚠️ cast to any only to complete the merge, should be removed! + const methods = testableFunctions.getPaymentMethods!(props as any, { onlyPaymentMethodCanPay: true, isPaymentOnGoing: true, isPaypalEnabled: false, @@ -192,8 +193,9 @@ describe("getPaymentMethods", () => { ).toEqual("notImplemented"); }); - it("bpay should be always notImplemented if Bpay onboaring FF is OFF", () => { - const methods = testableFunctions.getPaymentMethods!(props, { + it("bpay should be always notImplemented if Bpay onboarding FF is OFF", () => { + // TODO: ⚠️ cast to any only to complete the merge, should be removed! + const methods = testableFunctions.getPaymentMethods!(props as any, { onlyPaymentMethodCanPay: true, isPaymentOnGoing: true, isPaypalEnabled: true, @@ -204,8 +206,9 @@ describe("getPaymentMethods", () => { ).toEqual("notImplemented"); }); - it("bpay should be always implemented if Bpay onboaring FF is ON and onlyPaymentMethodCanPay flag is OFF", () => { - const methods = testableFunctions.getPaymentMethods!(props, { + it("bpay should be always implemented if Bpay onboarding FF is ON and onlyPaymentMethodCanPay flag is OFF", () => { + // TODO: ⚠️ cast to any only to complete the merge, should be removed! + const methods = testableFunctions.getPaymentMethods!(props as any, { onlyPaymentMethodCanPay: false, isPaymentOnGoing: true, isPaypalEnabled: true, @@ -216,8 +219,9 @@ describe("getPaymentMethods", () => { ).toEqual("implemented"); }); - it("bpay should be notImplemented implemented if Bpay onboaring FF is ON and onlyPaymentMethodCanPay flag is ON", () => { - const methods = testableFunctions.getPaymentMethods!(props, { + it("bpay should be notImplemented implemented if Bpay onboarding FF is ON and onlyPaymentMethodCanPay flag is ON", () => { + // TODO: ⚠️ cast to any only to complete the merge, should be removed! + const methods = testableFunctions.getPaymentMethods!(props as any, { onlyPaymentMethodCanPay: true, isPaymentOnGoing: true, isPaypalEnabled: true, @@ -243,7 +247,7 @@ const getComponent = () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); - return renderScreenFakeNavRedux( + return renderScreenFakeNavRedux( ToBeTested, ROUTES.WALLET_ADD_CARD, params, diff --git a/ts/screens/wallet/__tests__/ConfirmCardDetailScreen.test.tsx b/ts/screens/wallet/__tests__/ConfirmCardDetailScreen.test.tsx index c6d3ac6a13b..2d741b45c7a 100644 --- a/ts/screens/wallet/__tests__/ConfirmCardDetailScreen.test.tsx +++ b/ts/screens/wallet/__tests__/ConfirmCardDetailScreen.test.tsx @@ -17,7 +17,6 @@ import { fetchWalletsRequest } from "../../../store/actions/wallet/wallets"; -jest.unmock("react-navigation"); jest.mock("react-native-share", () => ({ open: jest.fn() })); @@ -74,10 +73,12 @@ const getComponent = () => { const globalState = appReducer(undefined, applicationChangeState("active")); const store = createStore(appReducer, globalState as any); - const component = renderScreenFakeNavRedux< - GlobalState, - ConfirmCardDetailsScreenNavigationParams - >(ToBeTested, ROUTES.WALLET_ADD_CARD, params, store); + const component = renderScreenFakeNavRedux( + ToBeTested, + ROUTES.WALLET_ADD_CARD, + params, + store + ); return { component, store }; }; diff --git a/ts/screens/wallet/__tests__/WalletHomeScreen.test.tsx b/ts/screens/wallet/__tests__/WalletHomeScreen.test.tsx index 800607a5dbe..e16e8068ffb 100644 --- a/ts/screens/wallet/__tests__/WalletHomeScreen.test.tsx +++ b/ts/screens/wallet/__tests__/WalletHomeScreen.test.tsx @@ -1,5 +1,5 @@ import DeviceInfo from "react-native-device-info"; -import { NavigationParams } from "react-navigation"; + import { createStore } from "redux"; import { versionInfoLoadSuccess } from "../../../common/versionInfo/store/actions/versionInfo"; import { mockIoVersionInfo } from "../../../common/versionInfo/store/reducers/__mock__/ioVersionInfo"; @@ -12,11 +12,6 @@ import { GlobalState } from "../../../store/reducers/types"; import { renderScreenFakeNavRedux } from "../../../utils/testWrapper"; import WalletHomeScreen from "../WalletHomeScreen"; -jest.mock("react-native-device-info", () => ({ - getVersion: jest.fn(), - getReadableVersion: jest.fn() -})); - describe("WalletHomeScreen", () => { jest.useFakeTimers(); minAppVersionAppVersionTestCases.forEach(t => { @@ -53,7 +48,7 @@ const testWalletHomeScreen = ( android: minVersion }); - const testComponent = renderScreenFakeNavRedux( + const testComponent = renderScreenFakeNavRedux( WalletHomeScreen, ROUTES.WALLET_HOME, {}, diff --git a/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptDetailScreen.tsx b/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptDetailScreen.tsx index 7c77c362d10..ca7c57775d5 100644 --- a/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptDetailScreen.tsx +++ b/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptDetailScreen.tsx @@ -1,7 +1,7 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import { Text, View } from "native-base"; import * as React from "react"; import { StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { useDispatch } from "react-redux"; import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; import ButtonDefaultOpacity from "../../../components/ButtonDefaultOpacity"; @@ -20,6 +20,8 @@ import { zendeskSupportStart } from "../../../features/zendesk/store/actions"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../navigation/params/WalletParamsList"; import { useIOSelector } from "../../../store/hooks"; import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; @@ -41,8 +43,14 @@ export type CreditCardOnboardingAttemptDetailScreenNavigationParams = Readonly<{ attempt: CreditCardInsertion; }>; -type Props = - NavigationStackScreenProps; +type Props = { + navigation: CompatNavigationProp< + IOStackNavigationProp< + WalletParamsList, + "CREDIT_CARD_ONBOARDING_ATTEMPT_DETAIL" + > + >; +}; const styles = StyleSheet.create({ row: { diff --git a/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptsScreen.tsx b/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptsScreen.tsx index a73cefef0dc..810c773b743 100644 --- a/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptsScreen.tsx +++ b/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptsScreen.tsx @@ -1,28 +1,31 @@ import { Content, View } from "native-base"; import * as React from "react"; import { StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; +import { Body } from "../../../components/core/typography/Body"; +import { H2 } from "../../../components/core/typography/H2"; import { withValidatedEmail } from "../../../components/helpers/withValidatedEmail"; import { withValidatedPagoPaVersion } from "../../../components/helpers/withValidatedPagoPaVersion"; import BaseScreenComponent from "../../../components/screens/BaseScreenComponent"; import { EdgeBorderComponent } from "../../../components/screens/EdgeBorderComponent"; -import { H2 } from "../../../components/core/typography/H2"; +import { CreditCardAttemptsList } from "../../../components/wallet/creditCardOnboardingAttempts/CreditCardAttemptsList"; import I18n from "../../../i18n"; +import { + AppParamsList, + IOStackNavigationRouteProps +} from "../../../navigation/params/AppParamsList"; import { navigateToCreditCardOnboardingAttempt } from "../../../store/actions/navigation"; import { Dispatch } from "../../../store/actions/types"; import { GlobalState } from "../../../store/reducers/types"; -import variables from "../../../theme/variables"; import { creditCardAttemptsSelector, CreditCardInsertion } from "../../../store/reducers/wallet/creditCard"; -import { Body } from "../../../components/core/typography/Body"; -import { CreditCardAttemptsList } from "../../../components/wallet/creditCardOnboardingAttempts/CreditCardAttemptsList"; +import variables from "../../../theme/variables"; type Props = ReturnType & ReturnType & - NavigationStackScreenProps; + IOStackNavigationRouteProps; const styles = StyleSheet.create({ noBottomPadding: { diff --git a/ts/screens/wallet/payment/ConfirmPaymentMethodScreen.tsx b/ts/screens/wallet/payment/ConfirmPaymentMethodScreen.tsx index 58f249dc80e..920ed991158 100644 --- a/ts/screens/wallet/payment/ConfirmPaymentMethodScreen.tsx +++ b/ts/screens/wallet/payment/ConfirmPaymentMethodScreen.tsx @@ -1,32 +1,52 @@ import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { CompatNavigationProp } from "@react-navigation/compat"; +import { useNavigation } from "@react-navigation/native"; import { fromNullable, none, Option, some } from "fp-ts/lib/Option"; import { ActionSheet, Content, View } from "native-base"; import * as React from "react"; import { Alert, SafeAreaView, StyleSheet, Text } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { ImportoEuroCents } from "../../../../definitions/backend/ImportoEuroCents"; import { PaymentRequestsGetResponse } from "../../../../definitions/backend/PaymentRequestsGetResponse"; +import { PspData } from "../../../../definitions/pagopa/PspData"; +import CardIcon from "../../../../img/wallet/card.svg"; +import bancomatPayLogo from "../../../../img/wallet/payment-methods/bancomatpay-logo.png"; +import PaypalLogo from "../../../../img/wallet/payment-methods/paypal/paypal_logo.svg"; +import TagIcon from "../../../../img/wallet/tag.svg"; +import { H1 } from "../../../components/core/typography/H1"; +import { H3 } from "../../../components/core/typography/H3"; import { H4 } from "../../../components/core/typography/H4"; +import { LabelSmall } from "../../../components/core/typography/LabelSmall"; +import { IOColors } from "../../../components/core/variables/IOColors"; +import { IOStyles } from "../../../components/core/variables/IOStyles"; +import { withLightModalContext } from "../../../components/helpers/withLightModalContext"; +import { withLoadingSpinner } from "../../../components/helpers/withLoadingSpinner"; import BaseScreenComponent, { ContextualHelpPropsMarkdown } from "../../../components/screens/BaseScreenComponent"; +import FooterWithButtons from "../../../components/ui/FooterWithButtons"; +import IconFont from "../../../components/ui/IconFont"; import { LightModalContextInterface } from "../../../components/ui/LightModal"; +import { getCardIconFromBrandLogo } from "../../../components/wallet/card/Logo"; import { PayWebViewModal } from "../../../components/wallet/PayWebViewModal"; +import { SelectionBox } from "../../../components/wallet/SelectionBox"; import { pagoPaApiUrlPrefix, pagoPaApiUrlPrefixTest } from "../../../config"; +import { confirmButtonProps } from "../../../features/bonus/bonusVacanze/components/buttons/ButtonConfigurations"; import { getValueOrElse, isError, isLoading, isReady } from "../../../features/bonus/bpd/model/RemoteValue"; -import PaypalLogo from "../../../../img/wallet/payment-methods/paypal/paypal_logo.svg"; +import { BrandImage } from "../../../features/wallet/component/card/BrandImage"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../navigation/params/WalletParamsList"; +import ROUTES from "../../../navigation/routes"; import { navigateToPaymentOutcomeCode, navigateToPaymentPickPaymentMethodScreen, - navigateToPaymentPickPspScreen, - navigateToPayPalUpdatePspForPayment + navigateToPaymentPickPspScreen } from "../../../store/actions/navigation"; import { Dispatch } from "../../../store/actions/types"; import { paymentOutcomeCode } from "../../../store/actions/wallet/outcomeCode"; @@ -64,32 +84,14 @@ import { Wallet } from "../../../types/pagopa"; import { PayloadForAction } from "../../../types/utils"; +import { getTranslatedShortNumericMonthYear } from "../../../utils/dates"; import { getLocalePrimaryWithFallback } from "../../../utils/locale"; import { isPaymentOutcomeCodeSuccessfully } from "../../../utils/payment"; +import { getPaypalAccountEmail } from "../../../utils/paypal"; +import { getLookUpIdPO } from "../../../utils/pmLookUpId"; import { showToast } from "../../../utils/showToast"; import { formatNumberCentsToAmount } from "../../../utils/stringBuilder"; -import { useNavigationContext } from "../../../utils/hooks/useOnFocus"; -import { PspData } from "../../../../definitions/pagopa/PspData"; -import { withLightModalContext } from "../../../components/helpers/withLightModalContext"; -import { withLoadingSpinner } from "../../../components/helpers/withLoadingSpinner"; -import { getLookUpIdPO } from "../../../utils/pmLookUpId"; -import { H1 } from "../../../components/core/typography/H1"; -import { IOStyles } from "../../../components/core/variables/IOStyles"; -import { IOColors } from "../../../components/core/variables/IOColors"; -import IconFont from "../../../components/ui/IconFont"; -import { H3 } from "../../../components/core/typography/H3"; -import { LabelSmall } from "../../../components/core/typography/LabelSmall"; -import { BrandImage } from "../../../features/wallet/component/card/BrandImage"; -import { getCardIconFromBrandLogo } from "../../../components/wallet/card/Logo"; -import FooterWithButtons from "../../../components/ui/FooterWithButtons"; -import { confirmButtonProps } from "../../../features/bonus/bonusVacanze/components/buttons/ButtonConfigurations"; import { openWebUrl } from "../../../utils/url"; -import TagIcon from "../../../../img/wallet/tag.svg"; -import CardIcon from "../../../../img/wallet/card.svg"; -import { SelectionBox } from "../../../components/wallet/SelectionBox"; -import { getTranslatedShortNumericMonthYear } from "../../../utils/dates"; -import { getPaypalAccountEmail } from "../../../utils/paypal"; -import bancomatPayLogo from "../../../../img/wallet/payment-methods/bancomatpay-logo.png"; // temporary feature flag since this feature is still WIP // (missing task to complete https://pagopa.atlassian.net/browse/IA-684?filter=10121) @@ -104,8 +106,14 @@ export type ConfirmPaymentMethodScreenNavigationParams = Readonly<{ psps: ReadonlyArray; }>; -type OwnProps = - NavigationStackScreenProps; +type ConfirmPaymentNavigationProps = IOStackNavigationProp< + WalletParamsList, + "PAYMENT_CONFIRM_PAYMENT_METHOD" +>; + +type OwnProps = { + navigation: CompatNavigationProp; +}; type Props = ReturnType & ReturnType & @@ -220,7 +228,7 @@ const ConfirmPaymentMethodScreen: React.FC = (props: Props) => { const paymentReason = verifica.causaleVersamento; const maybePsp = fromNullable(wallet.psp); const isPayingWithPaypal = isRawPayPal(wallet.paymentMethod); - const navigation = useNavigationContext(); + const navigation = useNavigation(); // each payment method has its own psp fee const paymentMethodType = isPayingWithPaypal ? "PayPal" : "CreditCard"; const fee: number | undefined = isPayingWithPaypal @@ -277,12 +285,10 @@ const ConfirmPaymentMethodScreen: React.FC = (props: Props) => { // navigate to the screen where the user can pick the desired psp const handleOnEditPaypalPsp = () => { - navigation.navigate( - navigateToPayPalUpdatePspForPayment({ - idPayment, - idWallet: wallet.idWallet - }) - ); + navigation.navigate(ROUTES.WALLET_PAYPAL_UPDATE_PAYMENT_PSP, { + idWallet: wallet.idWallet, + idPayment + }); }; // Handle the PSP change, this will trigger @@ -299,8 +305,7 @@ const ConfirmPaymentMethodScreen: React.FC = (props: Props) => { .getOrElse({}); const paymentMethod = props.getPaymentMethodById(wallet.idWallet); - - const ispaymentMethodCreditCard = + const isPaymentMethodCreditCard = paymentMethod !== undefined && isCreditCard(paymentMethod); const formattedSingleAmount = formatNumberCentsToAmount( @@ -497,7 +502,7 @@ const ConfirmPaymentMethodScreen: React.FC = (props: Props) => { ; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = OwnProps & ReturnType & @@ -261,8 +267,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ navigateToPaymentTransactionSummaryScreen({ rptId, initialAmount, - paymentStartOrigin: "manual_insertion", - startRoute: NavigationService.getCurrentRoute() + paymentStartOrigin: "manual_insertion" }); } }); diff --git a/ts/screens/wallet/payment/PaymentOutcomeCodeMessage.tsx b/ts/screens/wallet/payment/PaymentOutcomeCodeMessage.tsx index 07feb9a31a3..361b7ed1fb4 100644 --- a/ts/screens/wallet/payment/PaymentOutcomeCodeMessage.tsx +++ b/ts/screens/wallet/payment/PaymentOutcomeCodeMessage.tsx @@ -1,6 +1,6 @@ +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import React from "react"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import { ImportoEuroCents } from "../../../../definitions/backend/ImportoEuroCents"; @@ -12,6 +12,8 @@ import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import OutcomeCodeMessageComponent from "../../../components/wallet/OutcomeCodeMessageComponent"; import { cancelButtonProps } from "../../../features/bonus/bonusVacanze/components/buttons/ButtonConfigurations"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../navigation/params/WalletParamsList"; import { navigateToWalletHome } from "../../../store/actions/navigation"; import { profileEmailSelector } from "../../../store/reducers/profile"; import { GlobalState } from "../../../store/reducers/types"; @@ -24,8 +26,11 @@ export type PaymentOutcomeCodeMessageNavigationParams = Readonly<{ fee: ImportoEuroCents; }>; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & ReturnType & diff --git a/ts/screens/wallet/payment/PickPaymentMethodScreen.tsx b/ts/screens/wallet/payment/PickPaymentMethodScreen.tsx index 2f624f6e362..75de152c88f 100644 --- a/ts/screens/wallet/payment/PickPaymentMethodScreen.tsx +++ b/ts/screens/wallet/payment/PickPaymentMethodScreen.tsx @@ -2,13 +2,13 @@ * This screen allows the user to select the payment method for a selected transaction */ import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { CompatNavigationProp } from "@react-navigation/compat"; import { some } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { Content, View } from "native-base"; import * as React from "react"; import { FlatList, SafeAreaView } from "react-native"; import { ScrollView } from "react-native-gesture-handler"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { PaymentRequestsGetResponse } from "../../../../definitions/backend/PaymentRequestsGetResponse"; import { withLoadingSpinner } from "../../../components/helpers/withLoadingSpinner"; @@ -18,6 +18,8 @@ import BaseScreenComponent, { import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../navigation/params/WalletParamsList"; import { navigateBack, navigateToWalletAddPaymentMethod @@ -58,8 +60,11 @@ export type PickPaymentMethodScreenNavigationParams = Readonly<{ idPayment: string; }>; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & ReturnType & diff --git a/ts/screens/wallet/payment/PickPspScreen.tsx b/ts/screens/wallet/payment/PickPspScreen.tsx index 62720d5b68f..f5ce0a59a58 100644 --- a/ts/screens/wallet/payment/PickPspScreen.tsx +++ b/ts/screens/wallet/payment/PickPspScreen.tsx @@ -1,9 +1,9 @@ import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { CompatNavigationProp } from "@react-navigation/compat"; import * as pot from "italia-ts-commons/lib/pot"; import { H3, View } from "native-base"; import * as React from "react"; import { FlatList, SafeAreaView, StyleSheet } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { PaymentRequestsGetResponse } from "../../../../definitions/backend/PaymentRequestsGetResponse"; @@ -21,6 +21,8 @@ import { PspComponent } from "../../../components/wallet/payment/PspComponent"; import { cancelButtonProps } from "../../../features/bonus/bonusVacanze/components/buttons/ButtonConfigurations"; import { LoadingErrorComponent } from "../../../features/bonus/bonusVacanze/components/loadingErrorScreen/LoadingErrorComponent"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../navigation/params/WalletParamsList"; import { navigateBack } from "../../../store/actions/navigation"; import { Dispatch } from "../../../store/actions/types"; import { paymentFetchAllPspsForPaymentId } from "../../../store/actions/wallet/payment"; @@ -42,7 +44,11 @@ export type PickPspScreenNavigationParams = Readonly<{ chooseToChange?: boolean; }>; -type OwnProps = NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & ReturnType & diff --git a/ts/screens/wallet/payment/ScanQrCodeScreen.tsx b/ts/screens/wallet/payment/ScanQrCodeScreen.tsx index 1f41946607d..73073ac136b 100644 --- a/ts/screens/wallet/payment/ScanQrCodeScreen.tsx +++ b/ts/screens/wallet/payment/ScanQrCodeScreen.tsx @@ -2,6 +2,7 @@ * The screen allows to identify a transaction by the QR code on the analogic notice */ import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { NavigationEvents } from "@react-navigation/compat"; import { head } from "fp-ts/lib/Array"; import { fromNullable, isSome } from "fp-ts/lib/Option"; import { ITuple2 } from "italia-ts-commons/lib/tuples"; @@ -20,8 +21,6 @@ import * as ImagePicker from "react-native-image-picker"; import { ImageLibraryOptions } from "react-native-image-picker/src/types"; import * as ReaderQR from "react-native-lewin-qrcode"; import QRCodeScanner from "react-native-qrcode-scanner"; -import { NavigationEvents } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import ButtonDefaultOpacity from "../../../components/ButtonDefaultOpacity"; import { IOStyles } from "../../../components/core/variables/IOStyles"; @@ -33,7 +32,10 @@ import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import { CameraMarker } from "../../../components/wallet/CameraMarker"; import { cancelButtonProps } from "../../../features/bonus/bonusVacanze/components/buttons/ButtonConfigurations"; import I18n from "../../../i18n"; -import NavigationService from "../../../navigation/NavigationService"; +import { + AppParamsList, + IOStackNavigationRouteProps +} from "../../../navigation/params/AppParamsList"; import { navigateToPaymentManualDataInsertion, navigateToPaymentTransactionSummaryScreen, @@ -49,9 +51,8 @@ import { decodePagoPaQrCode } from "../../../utils/payment"; import { isAndroid } from "../../../utils/platform"; import { showToast } from "../../../utils/showToast"; -type OwnProps = NavigationStackScreenProps; - -type Props = OwnProps & ReturnType; +type Props = IOStackNavigationRouteProps & + ReturnType; type State = { scanningState: ComponentProps["state"]; @@ -391,8 +392,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ navigateToPaymentTransactionSummaryScreen({ rptId, initialAmount, - paymentStartOrigin: "qrcode_scan", - startRoute: NavigationService.getCurrentRoute() + paymentStartOrigin: "qrcode_scan" }); } }); diff --git a/ts/screens/wallet/payment/TransactionErrorScreen.tsx b/ts/screens/wallet/payment/TransactionErrorScreen.tsx index 4b3e6531a6d..2450165ff6e 100644 --- a/ts/screens/wallet/payment/TransactionErrorScreen.tsx +++ b/ts/screens/wallet/payment/TransactionErrorScreen.tsx @@ -2,17 +2,36 @@ * The screen to display to the user the various types of errors that occurred during the transaction. * Inside the cancel and retry buttons are conditionally returned. */ -import * as t from "io-ts"; +import { RptId, RptIdFromString } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { CompatNavigationProp } from "@react-navigation/compat"; import { Option } from "fp-ts/lib/Option"; +import * as t from "io-ts"; +import { View } from "native-base"; import * as React from "react"; import { ComponentProps } from "react"; import { Image, ImageSourcePropType, SafeAreaView } from "react-native"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; -import { View } from "native-base"; -import { RptId, RptIdFromString } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { Detail_v2Enum } from "../../../../definitions/backend/PaymentProblemJson"; +import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; +import { ZendeskCategory } from "../../../../definitions/content/ZendeskCategory"; +import CopyButtonComponent from "../../../components/CopyButtonComponent"; +import { H4 } from "../../../components/core/typography/H4"; +import { IOStyles } from "../../../components/core/variables/IOStyles"; +import { InfoScreenComponent } from "../../../components/infoScreen/InfoScreenComponent"; import BaseScreenComponent from "../../../components/screens/BaseScreenComponent"; +import { + cancelButtonProps, + confirmButtonProps +} from "../../../features/bonus/bonusVacanze/components/buttons/ButtonConfigurations"; +import { FooterStackButton } from "../../../features/bonus/bonusVacanze/components/buttons/FooterStackButtons"; +import { useHardwareBackButton } from "../../../features/bonus/bonusVacanze/components/hooks/useHardwareBackButton"; +import { + zendeskSelectedCategory, + zendeskSupportStart +} from "../../../features/zendesk/store/actions"; import I18n from "../../../i18n"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../navigation/params/WalletParamsList"; import { navigateToPaymentManualDataInsertion } from "../../../store/actions/navigation"; import { Dispatch } from "../../../store/actions/types"; import { @@ -21,6 +40,12 @@ import { paymentIdPolling, paymentVerifica } from "../../../store/actions/wallet/payment"; +import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; +import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; +import { + PaymentHistory, + paymentsHistorySelector +} from "../../../store/reducers/payments/history"; import { GlobalState } from "../../../store/reducers/types"; import { PayloadForAction } from "../../../types/utils"; import { @@ -29,22 +54,6 @@ import { getPaymentHistoryDetails, getV2ErrorMainType } from "../../../utils/payment"; -import { useHardwareBackButton } from "../../../features/bonus/bonusVacanze/components/hooks/useHardwareBackButton"; -import { InfoScreenComponent } from "../../../components/infoScreen/InfoScreenComponent"; -import { H4 } from "../../../components/core/typography/H4"; -import CopyButtonComponent from "../../../components/CopyButtonComponent"; -import { - cancelButtonProps, - confirmButtonProps -} from "../../../features/bonus/bonusVacanze/components/buttons/ButtonConfigurations"; -import { IOStyles } from "../../../components/core/variables/IOStyles"; -import { Detail_v2Enum } from "../../../../definitions/backend/PaymentProblemJson"; -import { - PaymentHistory, - paymentsHistorySelector -} from "../../../store/reducers/payments/history"; -import { FooterStackButton } from "../../../features/bonus/bonusVacanze/components/buttons/FooterStackButtons"; -import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; import { addTicketCustomField, appendLog, @@ -54,13 +63,6 @@ import { zendeskCategoryId, zendeskPaymentCategory } from "../../../utils/supportAssistance"; -import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; -import { - zendeskSelectedCategory, - zendeskSupportStart -} from "../../../features/zendesk/store/actions"; -import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; -import { ZendeskCategory } from "../../../../definitions/content/ZendeskCategory"; export type TransactionErrorScreenNavigationParams = { error: Option< @@ -74,8 +76,11 @@ export type TransactionErrorScreenNavigationParams = { onCancel: () => void; }; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = OwnProps & ReturnType & diff --git a/ts/screens/wallet/payment/TransactionSummaryScreen.tsx b/ts/screens/wallet/payment/TransactionSummaryScreen.tsx index 82c7f116477..68c15ff8410 100644 --- a/ts/screens/wallet/payment/TransactionSummaryScreen.tsx +++ b/ts/screens/wallet/payment/TransactionSummaryScreen.tsx @@ -3,13 +3,12 @@ import { PaymentNoticeNumberFromString, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; +import { CompatNavigationProp } from "@react-navigation/compat"; import { fromNullable, none, Option, some } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; import { ActionSheet, Text, View } from "native-base"; import * as React from "react"; import { SafeAreaView, StyleSheet } from "react-native"; -import { NavigationLeafRoute, StackActions } from "react-navigation"; -import { NavigationStackScreenProps } from "react-navigation-stack"; import { connect } from "react-redux"; import { PaymentRequestsGetResponse } from "../../../../definitions/backend/PaymentRequestsGetResponse"; @@ -20,7 +19,8 @@ import FooterWithButtons from "../../../components/ui/FooterWithButtons"; import { PaymentSummaryComponent } from "../../../components/wallet/PaymentSummaryComponent"; import { SlidedContentComponent } from "../../../components/wallet/SlidedContentComponent"; import I18n from "../../../i18n"; -import ROUTES from "../../../navigation/routes"; +import { IOStackNavigationProp } from "../../../navigation/params/AppParamsList"; +import { WalletParamsList } from "../../../navigation/params/WalletParamsList"; import { navigateToPaymentManualDataInsertion, navigateToPaymentPickPaymentMethodScreen, @@ -41,6 +41,7 @@ import { runDeleteActivePaymentSaga, runStartOrResumePaymentActivationSaga } from "../../../store/actions/wallet/payment"; +import { fetchWalletsRequestWithExpBackoff } from "../../../store/actions/wallet/wallets"; import { isPaypalEnabledSelector } from "../../../store/reducers/backendStatus"; import { GlobalState } from "../../../store/reducers/types"; import { @@ -69,11 +70,13 @@ export type TransactionSummaryScreenNavigationParams = Readonly<{ rptId: RptId; initialAmount: AmountInEuroCents; paymentStartOrigin: PaymentStartOrigin; - startRoute: NavigationLeafRoute | undefined; }>; -type OwnProps = - NavigationStackScreenProps; +type OwnProps = { + navigation: CompatNavigationProp< + IOStackNavigationProp + >; +}; type Props = ReturnType & ReturnType & @@ -105,6 +108,9 @@ class TransactionSummaryScreen extends React.Component { // on component mount, fetch the payment summary if we haven't already this.props.dispatchPaymentVerificaRequest(); } + if (!pot.isSome(this.props.walletById)) { + this.props.loadWallets(); + } } public componentDidUpdate(prevProps: Props) { @@ -161,26 +167,7 @@ class TransactionSummaryScreen extends React.Component { } ); } else { - /** - * Since the payment flow starts from the next screen, even though we are already - * in the payment flow, it is really difficult to make up for the static stack organization in a homogeneous way. - * The only solution that allows to avoid to heavily modify the existing logic is to distinguish based on the starting screen, - * in order to perform the right navigation actions if we are not in the wallet stack. - * TODO: This is a temporary (and not scalable) solution, a complete refactoring of the payment workflow is strongly recommended - */ - const startRoute = this.props.navigation.getParam("startRoute"); - if (startRoute !== undefined) { - // The payment flow is inside the wallet stack, if we start outside this stack we need to reset the stack - if ( - startRoute.routeName === ROUTES.MESSAGE_DETAIL || - startRoute.routeName === ROUTES.MESSAGE_DETAIL_PAGINATED - ) { - this.props.navigation.dispatch(StackActions.popToTop()); - } - this.props.navigation.navigate(startRoute); - } else { - this.props.navigation.goBack(); - } + this.props.navigation.goBack(); } }; @@ -427,7 +414,8 @@ const mapStateToProps = (state: GlobalState) => { paymentId, maybeFavoriteWallet, hasPayableMethods, - hasPagoPaMethods + hasPagoPaMethods, + walletById }; }; @@ -507,6 +495,7 @@ const mapDispatchToProps = (dispatch: Dispatch, props: OwnProps) => { }); return { + loadWallets: () => dispatch(fetchWalletsRequestWithExpBackoff()), navigateToWalletHome: () => navigateToWalletHome(), backToEntrypointPayment: () => dispatch(backToEntrypointPayment()), navigateToWalletAddPaymentMethod: () => diff --git a/ts/screens/wallet/payment/__tests__/ConfirmPaymentMethodScreen.test.tsx b/ts/screens/wallet/payment/__tests__/ConfirmPaymentMethodScreen.test.tsx index ea2f59843c9..202e92f638c 100644 --- a/ts/screens/wallet/payment/__tests__/ConfirmPaymentMethodScreen.test.tsx +++ b/ts/screens/wallet/payment/__tests__/ConfirmPaymentMethodScreen.test.tsx @@ -1,44 +1,41 @@ import { createStore, DeepPartial, Store } from "redux"; -import ConfirmPaymentMethodScreen, { - ConfirmPaymentMethodScreenNavigationParams -} from "../ConfirmPaymentMethodScreen"; -import { - myRptId, - myInitialAmount, - myVerifiedData, - myWallet, - myPsp, - AuthSeq -} from "../../../../utils/testFaker"; -import { getLookUpIdPO, newLookUpId } from "../../../../utils/pmLookUpId"; -import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; -import { appReducer } from "../../../../store/reducers/"; +import { PayWebViewModal } from "../../../../components/wallet/PayWebViewModal"; +import { remoteReady } from "../../../../features/bonus/bpd/model/RemoteValue"; import ROUTES from "../../../../navigation/routes"; +import { appReducer } from "../../../../store/reducers/"; +import { + bancomatPayConfigSelector, + isPaypalEnabledSelector +} from "../../../../store/reducers/backendStatus"; import { GlobalState } from "../../../../store/reducers/types"; -import { reproduceSequence } from "../../../../utils/tests"; -import { formatNumberCentsToAmount } from "../../../../utils/stringBuilder"; +import { pspSelectedV2ListSelector } from "../../../../store/reducers/wallet/payment"; +import { paymentMethodByIdSelector } from "../../../../store/reducers/wallet/wallets"; import { BPayPaymentMethod, CreditCardPaymentMethod, PayPalPaymentMethod } from "../../../../types/pagopa"; -import I18n from "../../../../i18n"; -import { paymentMethodByIdSelector } from "../../../../store/reducers/wallet/wallets"; -import { pspSelectedV2ListSelector } from "../../../../store/reducers/wallet/payment"; -import { - bancomatPayConfigSelector, - isPaypalEnabledSelector -} from "../../../../store/reducers/backendStatus"; import { getTranslatedShortNumericMonthYear } from "../../../../utils/dates"; -import { PayWebViewModal } from "../../../../components/wallet/PayWebViewModal"; -import { remoteReady } from "../../../../features/bonus/bpd/model/RemoteValue"; +import { getLookUpIdPO, newLookUpId } from "../../../../utils/pmLookUpId"; +import { formatNumberCentsToAmount } from "../../../../utils/stringBuilder"; +import { + AuthSeq, + myInitialAmount, + myPsp, + myRptId, + myVerifiedData, + myWallet +} from "../../../../utils/testFaker"; +import { reproduceSequence } from "../../../../utils/tests"; +import { renderScreenFakeNavRedux } from "../../../../utils/testWrapper"; +import ConfirmPaymentMethodScreen, { + ConfirmPaymentMethodScreenNavigationParams +} from "../ConfirmPaymentMethodScreen"; +import I18n from "../../../../i18n"; // Mock react native share jest.mock("react-native-share", () => jest.fn()); -// Be sure that navigation is unmocked -jest.unmock("react-navigation"); - // Mock the PayWebViewModal jest.mock("../../../../components/wallet/PayWebViewModal", () => { const actualModule = jest.requireActual( @@ -156,10 +153,7 @@ describe("Integration Tests With Actual Store and Simplified Navigation", () => payment: true }); - const rendered = renderScreenFakeNavRedux< - GlobalState, - ConfirmPaymentMethodScreenNavigationParams - >( + const rendered = renderScreenFakeNavRedux( ConfirmPaymentMethodScreen, ROUTES.PAYMENT_CONFIRM_PAYMENT_METHOD, params, @@ -236,10 +230,7 @@ describe("Integration Tests With Actual Store and Simplified Navigation", () => } }; - const rendered = renderScreenFakeNavRedux< - GlobalState, - ConfirmPaymentMethodScreenNavigationParams - >( + const rendered = renderScreenFakeNavRedux( ConfirmPaymentMethodScreen, ROUTES.PAYMENT_CONFIRM_PAYMENT_METHOD, paypalParams, @@ -302,10 +293,7 @@ describe("Integration Tests With Actual Store and Simplified Navigation", () => } }; - const rendered = renderScreenFakeNavRedux< - GlobalState, - ConfirmPaymentMethodScreenNavigationParams - >( + const rendered = renderScreenFakeNavRedux( ConfirmPaymentMethodScreen, ROUTES.PAYMENT_CONFIRM_PAYMENT_METHOD, bpayParams, @@ -381,10 +369,7 @@ describe("Integration Tests With Actual Store and Simplified Navigation", () => customInitState as any ); - renderScreenFakeNavRedux< - GlobalState, - ConfirmPaymentMethodScreenNavigationParams - >( + renderScreenFakeNavRedux( ConfirmPaymentMethodScreen, ROUTES.PAYMENT_CONFIRM_PAYMENT_METHOD, params, diff --git a/ts/screens/wallet/payment/__tests__/PickPaymentMethodScreen.test.tsx b/ts/screens/wallet/payment/__tests__/PickPaymentMethodScreen.test.tsx index 30b42867b58..64e76fbb481 100644 --- a/ts/screens/wallet/payment/__tests__/PickPaymentMethodScreen.test.tsx +++ b/ts/screens/wallet/payment/__tests__/PickPaymentMethodScreen.test.tsx @@ -2,7 +2,7 @@ import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; import { fireEvent } from "@testing-library/react-native"; import { some } from "fp-ts/lib/Option"; import * as pot from "italia-ts-commons/lib/pot"; -import { NavigationParams } from "react-navigation"; + import { Action, Store } from "redux"; import configureMockStore from "redux-mock-store"; import { PaymentRequestsGetResponse } from "../../../../../definitions/backend/PaymentRequestsGetResponse"; @@ -239,7 +239,7 @@ describe("PickPaymentMethodScreen", () => { }); const renderPickPaymentMethodScreen = (store: Store) => - renderScreenFakeNavRedux( + renderScreenFakeNavRedux( PickPaymentMethodScreen, WALLET_ONBOARDING_PRIVATIVE_ROUTES.SEARCH_AVAILABLE, { diff --git a/ts/screens/wallet/payment/__tests__/PickPspScreen.test.tsx b/ts/screens/wallet/payment/__tests__/PickPspScreen.test.tsx index e8dae688099..d8389e1b758 100644 --- a/ts/screens/wallet/payment/__tests__/PickPspScreen.test.tsx +++ b/ts/screens/wallet/payment/__tests__/PickPspScreen.test.tsx @@ -1,4 +1,3 @@ -import { NavigationParams } from "react-navigation"; import configureMockStore from "redux-mock-store"; import { AmountInEuroCents, RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; @@ -53,7 +52,7 @@ const renderComponent = () => { } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( PickPspScreen, ROUTES.PAYMENT_PICK_PSP, { diff --git a/ts/screens/wallet/payment/__tests__/TransactionErrorScreen.test.tsx b/ts/screens/wallet/payment/__tests__/TransactionErrorScreen.test.tsx index bb910d50325..e00920bc6b4 100644 --- a/ts/screens/wallet/payment/__tests__/TransactionErrorScreen.test.tsx +++ b/ts/screens/wallet/payment/__tests__/TransactionErrorScreen.test.tsx @@ -1,5 +1,5 @@ import configureMockStore from "redux-mock-store"; -import { NavigationParams } from "react-navigation"; + import { RptId } from "@pagopa/io-pagopa-commons/lib/pagopa"; import { Option, some } from "fp-ts/lib/Option"; @@ -196,7 +196,7 @@ const renderComponent = ( } as GlobalState); return { - component: renderScreenFakeNavRedux( + component: renderScreenFakeNavRedux( TransactionErrorScreen, ROUTES.PAYMENT_TRANSACTION_ERROR, { diff --git a/ts/store/actions/deepLink.ts b/ts/store/actions/deepLink.ts deleted file mode 100644 index 8b8b4a7bdec..00000000000 --- a/ts/store/actions/deepLink.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Action types and action creator related to the deep link handling. - */ - -import { NavigationNavigateActionPayload } from "react-navigation"; -import { - ActionType, - createAction, - createStandardAction -} from "typesafe-actions"; - -/** - * Saves the deep link to navigate to. - * - * When immediate is true, the app will immediately navigate to the route. - */ -export const setDeepLink = createAction( - "SET_DEEPLINK", - resolve => - ( - navigationPayload: NavigationNavigateActionPayload, - immediate: boolean = false - ) => - resolve({ navigationPayload, immediate }) -); - -export const clearDeepLink = createStandardAction("CLEAR_DEEPLINK")(); - -export const navigateToDeepLink = createAction( - "NAVIGATE_TO_DEEPLINK", - resolve => - ( - navigationPayload: NavigationNavigateActionPayload, - prevRouteKey?: string - ) => - resolve({ ...navigationPayload, key: prevRouteKey }) -); - -export type DeepLinkActions = ActionType< - typeof setDeepLink | typeof clearDeepLink | typeof navigateToDeepLink ->; diff --git a/ts/store/actions/navigation.ts b/ts/store/actions/navigation.ts index 9228a87c65a..620f6238d36 100644 --- a/ts/store/actions/navigation.ts +++ b/ts/store/actions/navigation.ts @@ -1,8 +1,4 @@ -import { - NavigationActions, - NavigationBackActionPayload, - StackActions -} from "react-navigation"; +import { CommonActions } from "@react-navigation/native"; import { CreditCardDetailScreenNavigationParams } from "../../features/wallet/creditCard/screen/CreditCardDetailScreen"; import NavigationService from "../../navigation/NavigationService"; import ROUTES from "../../navigation/routes"; @@ -35,21 +31,15 @@ import { PrivativePaymentMethod, SatispayPaymentMethod } from "../../types/pagopa"; -import { PayPalPspUpdateScreenNavigationParams } from "../../features/wallet/paypal/screen/PayPalPspUpdateScreen"; /** * @deprecated */ export const resetToAuthenticationRoute = () => NavigationService.dispatchNavigationAction( - StackActions.reset({ + CommonActions.reset({ index: 0, - key: null, - actions: [ - NavigationActions.navigate({ - routeName: ROUTES.AUTHENTICATION - }) - ] + routes: [{ name: ROUTES.AUTHENTICATION }] }) ); @@ -58,22 +48,17 @@ export const resetToAuthenticationRoute = () => */ export const navigateToMainNavigatorAction = () => NavigationService.dispatchNavigationAction( - StackActions.reset({ - key: "StackRouterRoot", + CommonActions.reset({ index: 0, - actions: [ - NavigationActions.navigate({ - routeName: ROUTES.MAIN - }) - ] + routes: [{ name: ROUTES.MAIN }] }) ); /** * @deprecated */ -export const navigateBack = (options?: NavigationBackActionPayload) => - NavigationService.dispatchNavigationAction(NavigationActions.back(options)); +export const navigateBack = () => + NavigationService.dispatchNavigationAction(CommonActions.goBack()); /** * Authentication @@ -84,11 +69,8 @@ export const navigateBack = (options?: NavigationBackActionPayload) => */ export const navigateToIdpSelectionScreenAction = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.AUTHENTICATION, - action: NavigationActions.navigate({ - routeName: ROUTES.AUTHENTICATION_IDP_SELECTION - }) + CommonActions.navigate(ROUTES.AUTHENTICATION, { + screen: ROUTES.AUTHENTICATION_IDP_SELECTION }) ); @@ -97,9 +79,8 @@ export const navigateToIdpSelectionScreenAction = () => */ export const navigateToOnboardingPinScreenAction = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.ONBOARDING, - action: NavigationActions.navigate({ routeName: ROUTES.ONBOARDING_PIN }) + CommonActions.navigate(ROUTES.ONBOARDING, { + screen: ROUTES.ONBOARDING_PIN }) ); @@ -110,8 +91,8 @@ export const navigateToOnboardingFingerprintScreenAction = ( params: FingerprintScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.ONBOARDING_FINGERPRINT, + CommonActions.navigate(ROUTES.ONBOARDING, { + screen: ROUTES.ONBOARDING_FINGERPRINT, params }) ); @@ -121,9 +102,8 @@ export const navigateToOnboardingFingerprintScreenAction = ( */ export const navigateToTosScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.ONBOARDING, - action: NavigationActions.navigate({ routeName: ROUTES.ONBOARDING_TOS }) + CommonActions.navigate(ROUTES.ONBOARDING, { + screen: ROUTES.ONBOARDING_TOS }) ); @@ -132,8 +112,8 @@ export const navigateToTosScreen = () => */ export const navigateToOnboardingServicePreferenceCompleteAction = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.ONBOARDING_SERVICES_PREFERENCE_COMPLETE + CommonActions.navigate(ROUTES.ONBOARDING, { + screen: ROUTES.ONBOARDING_SERVICES_PREFERENCE_COMPLETE }) ); @@ -144,8 +124,8 @@ export const navigateToServicesPreferenceModeSelectionScreen = ( params: OnboardingServicesPreferenceScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.ONBOARDING_SERVICES_PREFERENCE, + CommonActions.navigate(ROUTES.ONBOARDING, { + screen: ROUTES.ONBOARDING_SERVICES_PREFERENCE, params }) ); @@ -157,22 +137,20 @@ export const navigateToServicesPreferenceModeSelectionScreen = ( /** * @deprecated */ -export const navigateToEmailReadScreen = () => +export const navigateToEmailReadScreen = () => { NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.READ_EMAIL_SCREEN - }) + CommonActions.navigate(ROUTES.READ_EMAIL_SCREEN) ); +}; /** * @deprecated */ -export const navigateToEmailInsertScreen = () => +export const navigateToEmailInsertScreen = () => { NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.INSERT_EMAIL_SCREEN - }) + CommonActions.navigate(ROUTES.INSERT_EMAIL_SCREEN) ); +}; /** * Message @@ -185,8 +163,8 @@ export const navigateToMessageDetailScreenAction = ( params: MessageDetailScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.MESSAGE_DETAIL, + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: ROUTES.MESSAGE_DETAIL, params }) ); @@ -197,8 +175,8 @@ export const navigateToMessageDetailScreenAction = ( export const navigateToPaginatedMessageDetailScreenAction = ( params: MessageDetailScreenPaginatedNavigationParams ) => - NavigationActions.navigate({ - routeName: ROUTES.MESSAGE_DETAIL_PAGINATED, + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: ROUTES.MESSAGE_DETAIL_PAGINATED, params }); @@ -208,8 +186,8 @@ export const navigateToPaginatedMessageDetailScreenAction = ( export const navigateToPaginatedMessageRouterAction = ( params: MessageRouterScreenPaginatedNavigationParams ) => - NavigationActions.navigate({ - routeName: ROUTES.MESSAGE_ROUTER_PAGINATED, + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: ROUTES.MESSAGE_ROUTER_PAGINATED, params }); @@ -220,8 +198,8 @@ export const navigateToMessageRouterScreen = ( params: MessageDetailScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.MESSAGE_ROUTER, + CommonActions.navigate(ROUTES.MESSAGES_NAVIGATOR, { + screen: ROUTES.MESSAGE_ROUTER, params }) ); @@ -235,8 +213,8 @@ export const navigateToMessageRouterScreen = ( */ export const navigateToServiceHomeScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.SERVICES_HOME + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: ROUTES.SERVICES_HOME }) ); @@ -247,8 +225,8 @@ export const navigateToServiceDetailsScreen = ( params: ServiceDetailsScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.SERVICE_DETAIL, + CommonActions.navigate(ROUTES.SERVICES_NAVIGATOR, { + screen: ROUTES.SERVICE_DETAIL, params }) ); @@ -262,8 +240,8 @@ export const navigateToServiceDetailsScreen = ( */ export const navigateToEmailForwardingPreferenceScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_PREFERENCES_EMAIL_FORWARDING + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PREFERENCES_EMAIL_FORWARDING }) ); @@ -272,8 +250,8 @@ export const navigateToEmailForwardingPreferenceScreen = () => */ export const navigateToServicePreferenceScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_PREFERENCES_SERVICES + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PREFERENCES_SERVICES }) ); @@ -282,8 +260,8 @@ export const navigateToServicePreferenceScreen = () => */ export const navigateToCalendarPreferenceScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_PREFERENCES_CALENDAR + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PREFERENCES_CALENDAR }) ); @@ -292,8 +270,8 @@ export const navigateToCalendarPreferenceScreen = () => */ export const navigateToLanguagePreferenceScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_PREFERENCES_LANGUAGE + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PREFERENCES_LANGUAGE }) ); @@ -302,8 +280,8 @@ export const navigateToLanguagePreferenceScreen = () => */ export const navigateToLogout = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_LOGOUT + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_LOGOUT }) ); @@ -312,8 +290,8 @@ export const navigateToLogout = () => */ export const navigateToRemoveAccountSuccess = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_REMOVE_ACCOUNT_SUCCESS + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_REMOVE_ACCOUNT_SUCCESS }) ); @@ -322,8 +300,8 @@ export const navigateToRemoveAccountSuccess = () => */ export const navigateToRemoveAccountDetailScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_REMOVE_ACCOUNT_DETAILS + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_REMOVE_ACCOUNT_DETAILS }) ); @@ -332,11 +310,11 @@ export const navigateToRemoveAccountDetailScreen = () => */ export const navigateToPrivacyScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_PRIVACY_MAIN, - action: NavigationActions.navigate({ - routeName: ROUTES.PROFILE_PRIVACY_MAIN - }) + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PRIVACY_MAIN, + params: { + screen: ROUTES.PROFILE_PRIVACY_MAIN + } }) ); @@ -345,8 +323,8 @@ export const navigateToPrivacyScreen = () => */ export const navigateToPrivacyShareData = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PROFILE_PRIVACY_SHARE_DATA + CommonActions.navigate(ROUTES.PROFILE_NAVIGATOR, { + screen: ROUTES.PROFILE_PRIVACY_SHARE_DATA }) ); @@ -361,8 +339,8 @@ export const navigateToPaymentTransactionSummaryScreen = ( params: TransactionSummaryScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_TRANSACTION_SUMMARY, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_TRANSACTION_SUMMARY, params }) ); @@ -374,8 +352,8 @@ export const navigateToPaymentTransactionErrorScreen = ( params: TransactionErrorScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_TRANSACTION_ERROR, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_TRANSACTION_ERROR, params }) ); @@ -387,8 +365,8 @@ export const navigateToPaymentPickPaymentMethodScreen = ( params: PickPaymentMethodScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_PICK_PAYMENT_METHOD, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_PICK_PAYMENT_METHOD, params }) ); @@ -400,8 +378,8 @@ export const navigateToTransactionDetailsScreen = ( params: TransactionDetailsScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_TRANSACTION_DETAILS, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_TRANSACTION_DETAILS, params }) ); @@ -413,8 +391,8 @@ export const navigateToCreditCardDetailScreen = ( params: CreditCardDetailScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_CREDIT_CARD_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_CREDIT_CARD_DETAIL, params }) ); @@ -426,8 +404,8 @@ export const navigateToBancomatDetailScreen = ( bancomat: BancomatPaymentMethod ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_BANCOMAT_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_BANCOMAT_DETAIL, params: { bancomat } }) ); @@ -439,23 +417,15 @@ export const navigateToSatispayDetailScreen = ( satispay: SatispayPaymentMethod ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_SATISPAY_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_SATISPAY_DETAIL, params: { satispay } }) ); export const navigateToPayPalDetailScreen = () => - NavigationActions.navigate({ - routeName: ROUTES.WALLET_PAYPAL_DETAIL - }); - -export const navigateToPayPalUpdatePspForPayment = ( - params: PayPalPspUpdateScreenNavigationParams -) => - NavigationActions.navigate({ - routeName: ROUTES.WALLET_PAYPAL_UPDATE_PAYMENT_PSP, - params + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_PAYPAL_DETAIL }); /** @@ -463,8 +433,8 @@ export const navigateToPayPalUpdatePspForPayment = ( */ export const navigateToBPayDetailScreen = (bPay: BPayPaymentMethod) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_BPAY_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_BPAY_DETAIL, params: { bPay } }) ); @@ -476,8 +446,8 @@ export const navigateToCobadgeDetailScreen = ( cobadge: CreditCardPaymentMethod ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_COBADGE_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_COBADGE_DETAIL, params: { cobadge } }) ); @@ -489,8 +459,8 @@ export const navigateToPrivativeDetailScreen = ( privative: PrivativePaymentMethod ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_PRIVATIVE_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_PRIVATIVE_DETAIL, params: { privative } }) ); @@ -502,8 +472,8 @@ export const navigateToPaymentPickPspScreen = ( params: PickPspScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_PICK_PSP, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_PICK_PSP, params }) ); @@ -515,8 +485,8 @@ export const navigateToPaymentConfirmPaymentMethodScreen = ( params: ConfirmPaymentMethodScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_CONFIRM_PAYMENT_METHOD, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_CONFIRM_PAYMENT_METHOD, params }) ); @@ -528,8 +498,8 @@ export const navigateToPaymentHistoryDetail = ( params: PaymentHistoryDetailsScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_HISTORY_DETAIL_INFO, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_HISTORY_DETAIL_INFO, params }) ); @@ -541,8 +511,8 @@ export const navigateToCreditCardOnboardingAttempt = ( params: CreditCardOnboardingAttemptDetailScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.CREDIT_CARD_ONBOARDING_ATTEMPT_DETAIL, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.CREDIT_CARD_ONBOARDING_ATTEMPT_DETAIL, params }) ); @@ -552,8 +522,8 @@ export const navigateToCreditCardOnboardingAttempt = ( */ export const navigateToWalletHome = (params?: WalletHomeNavigationParams) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_HOME, + CommonActions.navigate(ROUTES.MAIN, { + screen: ROUTES.WALLET_HOME, params }) ); @@ -565,8 +535,8 @@ export const navigateToWalletAddPaymentMethod = ( params: AddPaymentMethodScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_ADD_PAYMENT_METHOD, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_ADD_PAYMENT_METHOD, params }) ); @@ -578,8 +548,8 @@ export const navigateToWalletAddCreditCard = ( params: AddCardScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_ADD_CARD, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_ADD_CARD, params }) ); @@ -591,8 +561,8 @@ export const navigateToWalletConfirmCardDetails = ( params: ConfirmCardDetailsScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WALLET_CONFIRM_CARD_DETAILS, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.WALLET_CONFIRM_CARD_DETAILS, params }) ); @@ -602,8 +572,8 @@ export const navigateToWalletConfirmCardDetails = ( */ export const navigateToPaymentScanQrCode = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_SCAN_QR_CODE + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_SCAN_QR_CODE }) ); @@ -614,8 +584,8 @@ export const navigateToPaymentManualDataInsertion = ( params?: ManualDataInsertionScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_MANUAL_DATA_INSERTION, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_MANUAL_DATA_INSERTION, params }) ); @@ -627,8 +597,8 @@ export const navigateToAddCreditCardOutcomeCode = ( params: AddCreditCardOutcomeCodeMessageNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.ADD_CREDIT_CARD_OUTCOMECODE_MESSAGE, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.ADD_CREDIT_CARD_OUTCOMECODE_MESSAGE, params }) ); @@ -640,8 +610,8 @@ export const navigateToPaymentOutcomeCode = ( params: PaymentOutcomeCodeMessageNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.PAYMENT_OUTCOMECODE_MESSAGE, + CommonActions.navigate(ROUTES.WALLET_NAVIGATOR, { + screen: ROUTES.PAYMENT_OUTCOMECODE_MESSAGE, params }) ); @@ -655,8 +625,8 @@ export const navigateToPaymentOutcomeCode = ( */ export const navigateToCieInvalidScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.CIE_EXPIRED_SCREEN + CommonActions.navigate(ROUTES.AUTHENTICATION, { + screen: ROUTES.CIE_EXPIRED_SCREEN }) ); @@ -665,8 +635,8 @@ export const navigateToCieInvalidScreen = () => */ export const navigateToCiePinScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.CIE_PIN_SCREEN + CommonActions.navigate(ROUTES.AUTHENTICATION, { + screen: ROUTES.CIE_PIN_SCREEN }) ); @@ -677,8 +647,8 @@ export const navigateToCieCardReaderScreen = ( params?: CieCardReaderScreenNavigationParams ) => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.CIE_CARD_READER_SCREEN, + CommonActions.navigate(ROUTES.AUTHENTICATION, { + screen: ROUTES.CIE_CARD_READER_SCREEN, params }) ); @@ -688,9 +658,7 @@ export const navigateToCieCardReaderScreen = ( */ export const navigateToWorkunitGenericFailureScreen = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.WORKUNIT_GENERIC_FAILURE - }) + CommonActions.navigate(ROUTES.WORKUNIT_GENERIC_FAILURE) ); /** @@ -701,8 +669,8 @@ export const navigateToWorkunitGenericFailureScreen = () => */ export const navigateToSPIDTestIDP = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.AUTHENTICATION_IDP_TEST + CommonActions.navigate(ROUTES.AUTHENTICATION, { + screen: ROUTES.AUTHENTICATION_IDP_TEST }) ); @@ -711,7 +679,7 @@ export const navigateToSPIDTestIDP = () => */ export const navigateToSPIDLogin = () => NavigationService.dispatchNavigationAction( - NavigationActions.navigate({ - routeName: ROUTES.AUTHENTICATION_IDP_LOGIN + CommonActions.navigate(ROUTES.AUTHENTICATION, { + screen: ROUTES.AUTHENTICATION_IDP_LOGIN }) ); diff --git a/ts/store/actions/types.ts b/ts/store/actions/types.ts index 74421e2042e..024e5a84b6c 100644 --- a/ts/store/actions/types.ts +++ b/ts/store/actions/types.ts @@ -33,7 +33,6 @@ import { CieAuthenticationActions } from "./cie"; import { ContentActions } from "./content"; import { CrossSessionsActions } from "./crossSessions"; import { DebugActions } from "./debug"; -import { DeepLinkActions } from "./deepLink"; import { IdentificationActions } from "./identification"; import { InstallationActions } from "./installation"; import { InternalRouteNavigationActions } from "./internalRouteNavigation"; @@ -62,7 +61,6 @@ export type Action = | BackendStatusActions | CieAuthenticationActions | VersionInfoActions - | DeepLinkActions | MessagesActions | MixpanelActions | NotificationsActions diff --git a/ts/store/middlewares/navigation.ts b/ts/store/middlewares/navigation.ts index 0157cee02e2..f3f9266a9ad 100644 --- a/ts/store/middlewares/navigation.ts +++ b/ts/store/middlewares/navigation.ts @@ -1,29 +1,20 @@ -import { NavigationState } from "react-navigation"; import { mixpanelTrack } from "../../mixpanel"; import { noAnalyticsRoutes } from "../../utils/analytics"; -import { getCurrentRouteName } from "../../utils/navigation"; export const trackScreen = ( - previousState: NavigationState, - currentState: NavigationState + previousScreen: string | undefined, + currentScreen: string ) => { - const previousScreenName = getCurrentRouteName(previousState); - const screenName = getCurrentRouteName(currentState); - - if ( - previousScreenName !== undefined && - screenName !== undefined && - previousScreenName !== screenName - ) { + if (previousScreen !== currentScreen) { // track only those events that are not included in the blacklist - if (!noAnalyticsRoutes.has(screenName)) { + if (!noAnalyticsRoutes.has(currentScreen)) { void mixpanelTrack("SCREEN_CHANGE_V2", { - SCREEN_NAME: screenName + SCREEN_NAME: currentScreen }); } - // sent to 10-days retention project + // send to 10-days retention project void mixpanelTrack("SCREEN_CHANGE", { - SCREEN_NAME: screenName + SCREEN_NAME: currentScreen }); } }; diff --git a/ts/store/reducers/deepLink.ts b/ts/store/reducers/deepLink.ts deleted file mode 100644 index 70590093afe..00000000000 --- a/ts/store/reducers/deepLink.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * A reducer for deep link - */ - -import { NavigationNavigateActionPayload } from "react-navigation"; -import { getType } from "typesafe-actions"; - -import { clearDeepLink, setDeepLink } from "../actions/deepLink"; -import { Action } from "../actions/types"; - -export type DeepLinkState = Readonly<{ - deepLink: NavigationNavigateActionPayload | null; - immediate: boolean; -}>; - -const INITIAL_STATE: DeepLinkState = { - deepLink: null, - immediate: false -}; - -export default ( - state: DeepLinkState = INITIAL_STATE, - action: Action -): DeepLinkState => { - switch (action.type) { - case getType(setDeepLink): - return { - ...state, - deepLink: action.payload.navigationPayload, - immediate: action.payload.immediate - }; - - case getType(clearDeepLink): - return { - ...state, - deepLink: null - }; - - default: - return state; - } -}; diff --git a/ts/store/reducers/index.ts b/ts/store/reducers/index.ts index 6f5152e3380..b1d52e99cc6 100644 --- a/ts/store/reducers/index.ts +++ b/ts/store/reducers/index.ts @@ -17,6 +17,7 @@ import { Action } from "../actions/types"; import createSecureStorage from "../storages/keychain"; import { DateISO8601Transform } from "../transforms/dateISO8601Tranform"; import appStateReducer from "./appState"; +import assistanceToolsReducer from "./assistanceTools"; import authenticationReducer, { AuthenticationState, INITIAL_STATE as autenticationInitialState @@ -29,7 +30,6 @@ import contentReducer, { } from "./content"; import crossSessionsReducer from "./crossSessions"; import { debugReducer } from "./debug"; -import deepLinkReducer from "./deepLink"; import emailValidationReducer from "./emailValidation"; import entitiesReducer, { entitiesPersistConfig, @@ -52,7 +52,6 @@ import { GlobalState } from "./types"; import userDataProcessingReducer from "./userDataProcessing"; import userMetadataReducer from "./userMetadata"; import walletReducer from "./wallet"; -import assistanceToolsReducer from "./assistanceTools"; // A custom configuration to store the authentication into the Keychain export const authenticationPersistConfig: PersistConfig = { @@ -89,7 +88,6 @@ export const appReducer: Reducer = combineReducers< appState: appStateReducer, navigation: navigationReducer, backoffError: backoffErrorReducer, - deepLink: deepLinkReducer, wallet: walletReducer, versionInfo: versionInfoReducer, backendStatus: backendStatusReducer, diff --git a/ts/store/reducers/types.ts b/ts/store/reducers/types.ts index d03a5b8aecd..0f17aa6b7f2 100644 --- a/ts/store/reducers/types.ts +++ b/ts/store/reducers/types.ts @@ -12,7 +12,6 @@ import { CieState } from "./cie"; import { ContentState } from "./content"; import { CrossSessionsState } from "./crossSessions"; import { DebugState } from "./debug"; -import { DeepLinkState } from "./deepLink"; import { EmailValidationState } from "./emailValidation"; import { PersistedEntitiesState } from "./entities"; import { PersistedIdentificationState } from "./identification"; @@ -36,7 +35,6 @@ export type GlobalState = Readonly<{ authentication: PersistedAuthenticationState; backendStatus: BackendStatusState; versionInfo: VersionInfoState; - deepLink: DeepLinkState; entities: PersistedEntitiesState; backoffError: BackoffErrorState; notifications: NotificationsState; diff --git a/ts/utils/__tests__/fetch.test.ts b/ts/utils/__tests__/fetch.test.ts index 0ef5817442b..1e009f7eaa3 100644 --- a/ts/utils/__tests__/fetch.test.ts +++ b/ts/utils/__tests__/fetch.test.ts @@ -16,7 +16,10 @@ const TEST_PATH = "/transient-error"; describe("defaultRetryingFetch function", () => { // Mock server is restarted per each test - beforeEach(() => mockServer.start()); + beforeEach(async () => { + jest.useRealTimers(); + await mockServer.start(); + }); afterEach(() => mockServer.stop()); describe(`when 429 code is returned`, () => { @@ -46,7 +49,10 @@ describe("defaultRetryingFetch function", () => { describe("constantPollingFetch function", () => { // Mock server is restarted per each test - beforeEach(() => mockServer.start()); + beforeEach(async () => { + jest.useRealTimers(); + await mockServer.start(); + }); afterEach(() => mockServer.stop()); const MAX_POLLING_RETRIES = 10; diff --git a/ts/utils/__tests__/internalLink.test.ts b/ts/utils/__tests__/internalLink.test.ts index 62f4a445050..5a02173562b 100644 --- a/ts/utils/__tests__/internalLink.test.ts +++ b/ts/utils/__tests__/internalLink.test.ts @@ -1,16 +1,24 @@ -import { Tuple2 } from "italia-ts-commons/lib/tuples"; import { none, some } from "fp-ts/lib/Option"; +import { Tuple2 } from "italia-ts-commons/lib/tuples"; import { getInternalRoute, IO_INTERNAL_LINK_PREFIX, testableALLOWED_ROUTE_NAMES } from "../../components/ui/Markdown/handlers/internalLink"; +import ROUTES from "../../navigation/routes"; describe("getInternalRoute", () => { - const allowedRoutes = testableALLOWED_ROUTE_NAMES!.map(r => - Tuple2(`${IO_INTERNAL_LINK_PREFIX}${r}`, some({ routeName: r })) + const allowedRoutes = Object.entries(testableALLOWED_ROUTE_NAMES!).map( + ([r, v]) => + Tuple2( + `${IO_INTERNAL_LINK_PREFIX}${r}`, + some({ + navigationAction: v, + routeName: r + }) + ) ); - const validRoute = testableALLOWED_ROUTE_NAMES![0]; + const validRoute = Object.keys(testableALLOWED_ROUTE_NAMES!)[0]; it("should recognize a valid internal route", () => { [ ...allowedRoutes, @@ -21,6 +29,15 @@ describe("getInternalRoute", () => { IO_INTERNAL_LINK_PREFIX + validRoute + "?param1=value1¶m2=value2", some({ routeName: validRoute, + navigationAction: { + payload: { + name: ROUTES.MAIN, + params: { + screen: ROUTES.MESSAGES_HOME + } + }, + type: "NAVIGATE" + }, params: { param1: "value1", param2: "value2" @@ -31,6 +48,15 @@ describe("getInternalRoute", () => { IO_INTERNAL_LINK_PREFIX + validRoute + "?param1=¶m2=value2", some({ routeName: validRoute, + navigationAction: { + payload: { + name: ROUTES.MAIN, + params: { + screen: ROUTES.MESSAGES_HOME + } + }, + type: "NAVIGATE" + }, params: { param1: "", param2: "value2" diff --git a/ts/utils/deepLink.ts b/ts/utils/deepLink.ts deleted file mode 100644 index 01a0889c1ac..00000000000 --- a/ts/utils/deepLink.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Platform } from "react-native"; -import { NavigationNavigateActionPayload } from "react-navigation"; -import { IO_INTERNAL_LINK_PREFIX } from "../components/ui/Markdown/handlers/internalLink"; - -export function getNavigateActionFromDeepLink( - url: string, - // on Android, the URI prefix contains a host in addition to scheme - deepLinkPrefix: string = Platform.OS === "android" - ? `${IO_INTERNAL_LINK_PREFIX}ioit/` - : IO_INTERNAL_LINK_PREFIX -): NavigationNavigateActionPayload { - const route = url.slice(deepLinkPrefix.length); - const routeParts = route.split("/"); - const routeName = routeParts[0]; - const id = routeParts[1] || undefined; - - // FIXME: whitelist allowed routes - return { routeName, params: { id } }; -} diff --git a/ts/utils/hooks/useLoadPotValue.ts b/ts/utils/hooks/useLoadPotValue.ts index 613de360fdf..ed18bf19fa5 100644 --- a/ts/utils/hooks/useLoadPotValue.ts +++ b/ts/utils/hooks/useLoadPotValue.ts @@ -1,8 +1,8 @@ /* eslint-disable functional/immutable-data */ +import { useNavigation } from "@react-navigation/native"; import * as pot from "italia-ts-commons/lib/pot"; import { Millisecond } from "italia-ts-commons/lib/units"; -import { useCallback, useContext, useEffect, useRef, useState } from "react"; -import { NavigationContext } from "react-navigation"; +import { useCallback, useEffect, useRef, useState } from "react"; const retryTimeout = 5000 as Millisecond; @@ -19,7 +19,7 @@ export const useLoadPotValue = ( ) => { const [idState, setId] = useState(""); const timerRetry = useRef(undefined); - const navigation = useContext(NavigationContext); + const navigation = useNavigation(); const retry = useCallback(() => { timerRetry.current = undefined; loadAction(); diff --git a/ts/utils/hooks/useOnFocus.tsx b/ts/utils/hooks/useOnFocus.tsx index a99fc883437..1cfeddd6788 100644 --- a/ts/utils/hooks/useOnFocus.tsx +++ b/ts/utils/hooks/useOnFocus.tsx @@ -1,6 +1,6 @@ +import { useNavigation } from "@react-navigation/native"; import { Millisecond } from "italia-ts-commons/lib/units"; -import { useContext, useEffect, useState } from "react"; -import { NavigationContext } from "react-navigation"; +import { useEffect, useState } from "react"; /** * Call the action when the component isFocused() and dontExecuteBefore has passed since the last update. @@ -14,7 +14,7 @@ export const useActionOnFocus = ( ) => { const [lastUpdate, setLastUpdate] = useState(undefined); - const navigation = useNavigationContext(); + const navigation = useNavigation(); const isFocused = navigation.isFocused(); useEffect(() => { const now = new Date(); @@ -29,5 +29,3 @@ export const useActionOnFocus = ( } }, [isFocused]); }; - -export const useNavigationContext = () => useContext(NavigationContext); diff --git a/ts/utils/navigation.ts b/ts/utils/navigation.ts index b9c0e21272c..583f10e9bce 100644 --- a/ts/utils/navigation.ts +++ b/ts/utils/navigation.ts @@ -1,71 +1,14 @@ // gets the current screen from navigation state - -import { - NavigationLeafRoute, - NavigationRoute, - NavigationState -} from "react-navigation"; -import NavigationService from "../navigation/NavigationService"; +import { navigationRef } from "../navigation/NavigationService"; import ROUTES from "../navigation/routes"; -/** - * Assuming that each and every NavigationRoute will eventually lead - * to a NavigationLeafRoute. - */ -const findLeafRoute = ( - branchOrLeaf: NavigationRoute | undefined -): NavigationLeafRoute | undefined => { - if (branchOrLeaf?.routes) { - const { routes, index } = branchOrLeaf; - return findLeafRoute(routes[index]); - } - // a branch without routes is assumed to be a leaf - return branchOrLeaf; -}; - -/** - * @param navState - */ -export function getCurrentRouteName( - navState: NavigationState -): string | undefined { - try { - return findLeafRoute(navState.routes[navState.index])?.routeName; - } catch { - return undefined; - } -} - -/** - * @param navState - */ -export function getCurrentRouteKey( - navState: NavigationState -): string | undefined { - try { - return findLeafRoute(navState.routes[navState.index])?.key; - } catch { - return undefined; - } -} - -export const getCurrentRoute = ( - navState: NavigationState -): NavigationLeafRoute | undefined => { - try { - return findLeafRoute(navState.routes[navState.index]); - } catch { - return undefined; - } -}; - /** * @deprecated */ export const isOnboardingCompleted = () => { - const route = NavigationService.getCurrentState(); + const route = navigationRef?.current?.getRootState(); if (route === null) { return false; } - return route.routes?.length > 0 && route.routes[0].routeName === ROUTES.MAIN; + return route?.routes[0].name === ROUTES.MAIN; }; diff --git a/ts/utils/testWrapper.tsx b/ts/utils/testWrapper.tsx index 9195c11e45f..55eb4d110d1 100644 --- a/ts/utils/testWrapper.tsx +++ b/ts/utils/testWrapper.tsx @@ -1,65 +1,88 @@ +import { createCompatNavigatorFactory } from "@react-navigation/compat"; +import { createStackNavigator } from "@react-navigation/stack"; import { render, RenderOptions } from "@testing-library/react-native"; -import React, { ReactElement, useEffect } from "react"; -import { createAppContainer, NavigationNavigator } from "react-navigation"; -import { - createStackNavigator, - NavigationStackScreenProps -} from "react-navigation-stack"; +import React from "react"; import { Provider } from "react-redux"; import { Store } from "redux"; +import { TestInnerNavigationContainer } from "../navigation/AppStackNavigator"; -// Creates a simple wrapper for the render method which encloses the element to render in a store provider -export function renderWithRedux( - ui: ReactElement, - store: Store, - renderOptions: RenderOptions -) { - function Wrapper({ children }: any) { - return {children}; - } - return render(ui, { wrapper: Wrapper, ...renderOptions }); -} - -export // If the screen to render and test is reachable via a navigator, create an app and render it -function renderNavContainerRedux( - navContainer: NavigationNavigator, - store: Store, - renderOptions: RenderOptions -) { - const App = createAppContainer(navContainer); - return renderWithRedux(, store, renderOptions); -} - -export function fakeScreenFactory(route: string, params: NP) { - // The fake screen fires a navigation to the screen under test when mounted, so as to avoid mocking navigation route parmeters. - return ({ navigation }: NavigationStackScreenProps) => { - useEffect(() => { - navigation.navigate(route, params); - }); - return <>; - }; -} - -export function renderScreenFakeNavRedux( +/** + * This should be used to test component that requires a compat navigation context (inside a compat navigator) + * @param screen + * @param route + * @param params + * @param store + * @param renderOptions + */ +export const renderScreenFakeNavRedux = ( screen: React.ComponentType, // I need any to avoid passing navigation route: string, - params: NP, + params: Record, store: Store, renderOptions: RenderOptions = {} -) { +) => { const customRouteConfigMap = { - [route]: screen, - // fakeScreen is needed to inject params in navigation route - [0]: fakeScreenFactory(route, params) // not sure if 0 is right + [route]: { screen, params } }; - const customNavigator = createStackNavigator(customRouteConfigMap, { - // Let each screen handle the header and navigation - headerMode: "none", - defaultNavigationOptions: { - gesturesEnabled: false + const customNavigator = createCompatNavigatorFactory(createStackNavigator)( + customRouteConfigMap, + { + // Let each screen handle the header and navigation + headerMode: "none", + defaultNavigationOptions: { + gestureEnabled: false + } } - }); + ); + + const Stack = createStackNavigator(); + const component = ( + + + + + + + + ); + + return render(component, renderOptions); +}; + +/** + * This should be used to test component in a new navigator + * @param screen + * @param route + * @param params + * @param store + * @param renderOptions + */ +export const renderScreenWithNavigationStoreContext = ( + screen: React.ComponentType, // I need any to avoid passing navigation + route: string, + params: Record, + store: Store, + renderOptions: RenderOptions = {} +) => { + const Stack = createStackNavigator(); + const component = ( + + + + + + + + ); - return renderNavContainerRedux(customNavigator, store, renderOptions); -} + return render(component, renderOptions); +}; diff --git a/yarn.lock b/yarn.lock index 61d317d1546..41b92f64dec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2825,23 +2825,61 @@ resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-1.0.0.tgz#05bb0031533598f9458cf65a502b8df0eecae780" integrity sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w== -"@react-navigation/core@^3.7.9": - version "3.7.9" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.7.9.tgz#3f7ba0fcb6c8d74a77a057382af198d84c7c4e3b" - integrity sha512-EknbzM8OI9A5alRxXtQRV5Awle68B+z1QAxNty5DxmlS3BNfmduWNGnim159ROyqxkuDffK9L/U/Tbd45mx+Jg== +"@react-navigation/bottom-tabs@^5.11.15": + version "5.11.15" + resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-5.11.15.tgz#f973625cc32d9c5a4067851f084cb11ccd68fe79" + integrity sha512-TBY419W6aN/HZg98xbVp5Bx1HEF5sXuHR5f55W6KMI4k2AvxlwelKD1wbfvEcX2iuQT0YUiiXsACRFUSECYhkw== dependencies: - hoist-non-react-statics "^3.3.2" - path-to-regexp "^1.8.0" + color "^3.1.3" + react-native-iphone-x-helper "^1.3.0" + +"@react-navigation/compat@^5.3.20": + version "5.3.20" + resolved "https://registry.yarnpkg.com/@react-navigation/compat/-/compat-5.3.20.tgz#96cc6995f4bd40f70958b420735a189a87b22a0e" + integrity sha512-4CDw3QRN2zKj2L1Fxjq6ZOK95EW8UOnW3Par1o+P07qc+dZTAL1poKeRx74yqGLQyGVawozTHOgyE8/XWjdDvg== + +"@react-navigation/core@^5.16.1": + version "5.16.1" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-5.16.1.tgz#e0d308bd9bbd930114ce55c4151806b6d7907f69" + integrity sha512-3AToC7vPNeSNcHFLd1h71L6u34hfXoRAS1CxF9Fc4uC8uOrVqcNvphpeFbE0O9Bw6Zpl0BnMFl7E5gaL3KGzNA== + dependencies: + "@react-navigation/routers" "^5.7.4" + escape-string-regexp "^4.0.0" + nanoid "^3.1.15" query-string "^6.13.6" react-is "^16.13.0" -"@react-navigation/native@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.8.4.tgz#4d77f86506364ecf18b33c7f8740afb6763d0b37" - integrity sha512-gXSVcL7bfFDyVkvyg1FiAqTCIgZub5K1X/TZqURBs2CPqDpfX1OsCtB9D33eTF14SpbfgHW866btqrrxoCACfg== +"@react-navigation/drawer@^5.12.9": + version "5.12.9" + resolved "https://registry.yarnpkg.com/@react-navigation/drawer/-/drawer-5.12.9.tgz#b07d7391a6fea4ce07cd7a7421fdbaea37cdbb46" + integrity sha512-SYb2BCEAn+BiEwC6WBfCzs1VlWD+ZdQbxmsim6vo1o+ndPW2e+kiq7FXKRs0vUXhQRZVl2oOB3vBn0c3YCllQg== dependencies: - hoist-non-react-statics "^3.3.2" - react-native-safe-area-view "^0.14.9" + color "^3.1.3" + react-native-iphone-x-helper "^1.3.0" + +"@react-navigation/native@^5.9.8": + version "5.9.8" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-5.9.8.tgz#ac76ee6390ea7ce807486ca5c38d903e23433a97" + integrity sha512-DNbcDHXQPSFDLn51kkVVJjT3V7jJy2GztNYZe/2bEg29mi5QEcHHcpifjMCtyFKntAOWzKlG88UicIQ17UEghg== + dependencies: + "@react-navigation/core" "^5.16.1" + escape-string-regexp "^4.0.0" + nanoid "^3.1.15" + +"@react-navigation/routers@^5.7.4": + version "5.7.4" + resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-5.7.4.tgz#8b5460e841a0c64f6c9a5fbc2a1eb832432d4fb0" + integrity sha512-0N202XAqsU/FlE53Nmh6GHyMtGm7g6TeC93mrFAFJOqGRKznT0/ail+cYlU6tNcPA9AHzZu1Modw1eoDINSliQ== + dependencies: + nanoid "^3.1.15" + +"@react-navigation/stack@^5.14.9": + version "5.14.9" + resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.14.9.tgz#49c7b9316e6fb456e9766c901e0d607862f0ea7d" + integrity sha512-DuvrT9P+Tz8ezZLQYxORZqOGqO+vEufaxlW1hSLw1knLD4jNxkz8TJDXtfKwaz//9gb43UhTNccNM02vm7iPqQ== + dependencies: + color "^3.1.3" + react-native-iphone-x-helper "^1.3.0" "@redux-saga/core@^1.1.3": version "1.1.3" @@ -5392,7 +5430,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0, color-convert@^1.9.1: +color-convert@^1.9.0, color-convert@^1.9.1, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -5424,6 +5462,14 @@ color-string@^1.5.2: color-name "^1.0.0" simple-swizzle "^0.2.2" +color-string@^1.6.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.0.tgz#63b6ebd1bec11999d1df3a79a7569451ac2be8aa" + integrity sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + color@^3.0.0, color@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" @@ -5432,6 +5478,14 @@ color@^3.0.0, color@~3.1.2: color-convert "^1.9.1" color-string "^1.5.2" +color@^3.1.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + colorette@^1.0.7: version "1.3.0" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.3.0.tgz#ff45d2f0edb244069d3b772adeb04fed38d0a0af" @@ -8347,11 +8401,6 @@ hoist-non-react-statics@^1.0.5: resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" integrity sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs= -hoist-non-react-statics@^2.3.1: - version "2.5.5" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" - integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== - hoist-non-react-statics@^3.0.1, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -11563,6 +11612,11 @@ nan@^2.14.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== +nanoid@^3.1.15: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + nanoid@^3.1.20, nanoid@^3.1.23: version "3.2.0" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" @@ -12463,13 +12517,6 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-to-regexp@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -12754,7 +12801,7 @@ prop-types@15.6.2: loose-envify "^1.3.1" object-assign "^4.1.1" -prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -12961,11 +13008,6 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - react-native-android-open-settings@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/react-native-android-open-settings/-/react-native-android-open-settings-1.3.0.tgz#c6257f3c88ada62945fffe887933a2a828adf45d" @@ -13250,12 +13292,10 @@ react-native-responsive-screen@^1.4.1: resolved "https://registry.yarnpkg.com/react-native-responsive-screen/-/react-native-responsive-screen-1.4.1.tgz#0270bc8f03a208b578299c1594495db69aff506b" integrity sha512-WuMkVyCPeepzKQaT3N+mbUAvQLL0jGsBnGf6yDtA7vyA/sp1imXYVPYjCNMRaKV+PSM5GzEMXxl4Bj+tUpD2Tw== -react-native-safe-area-view@^0.14.9: - version "0.14.9" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.9.tgz#90ee8383037010d9a5055a97cf97e4c1da1f0c3d" - integrity sha512-WII/ulhpVyL/qbYb7vydq7dJAfZRBcEhg4/UWt6F6nAKpLa3gAceMOxBxI914ppwSP/TdUsandFy6lkJQE0z4A== - dependencies: - hoist-non-react-statics "^2.3.1" +react-native-safe-area-context@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz#9549a2ce580f2374edb05e49d661258d1b8bcaed" + integrity sha512-yOwiiPJ1rk+/nfK13eafbpW6sKW0jOnsRem2C1LPJjM3tfTof6hlvV5eWHATye3XOpu2cJ7N+HdkUvUDGwFD2Q== react-native-screen-brightness@^2.0.0-alpha: version "2.0.0-alpha" @@ -13300,18 +13340,6 @@ react-native-svg@^12.3.0: css-select "^4.2.1" css-tree "^1.0.0-alpha.39" -react-native-tab-view@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-1.4.1.tgz#f113cd87485808f0c991abec937f70fa380478b9" - integrity sha512-Bke8KkDcDhvB/z0AS7MnQKMD2p6Kwfc1rSKlMOvg9CC5CnClQ2QEnhPSbwegKDYhUkBI92iH/BYy7hNSm5kbUQ== - dependencies: - prop-types "^15.6.1" - -react-native-tab-view@^2.15.2: - version "2.16.0" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.16.0.tgz#cae72c7084394bd328fac5fefb86cd966df37a86" - integrity sha512-ac2DmT7+l13wzIFqtbfXn4wwfgtPoKzWjjZyrK1t+T8sdemuUvD4zIt+UImg03fu3s3VD8Wh/fBrIdcqQyZJWg== - react-native-vector-icons@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/react-native-vector-icons/-/react-native-vector-icons-7.0.0.tgz#5b92ed363c867645daad48c559e1f99efcfbb813" @@ -13372,38 +13400,6 @@ react-native@0.64.2: whatwg-fetch "^3.0.0" ws "^6.1.4" -react-navigation-drawer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.4.0.tgz#70f3dd83e3da9cd4ea6e2739526502c823d466b9" - integrity sha512-ZyWBozcjB2aZ7vwCALv90cYA2NpDjM+WALaiYRshvPvue8l7cqynePbHK8GhlMGyJDwZqp4MxQmu8u1XAKp3Bw== - dependencies: - react-native-tab-view "^1.2.0" - -react-navigation-stack@^1.7.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.10.3.tgz#e714e442b20427f0d2d3c18fce1f9e8cfe69be0b" - integrity sha512-1gksFi/g/Lg9sBhgLlD0OiEB5xnatHb4C0eNMA5tli9cTVlhq375XNPIqOiTyftibBmjdApAsZFj5srUCoOu/w== - dependencies: - prop-types "^15.7.2" - -react-navigation-tabs@^2.11.1: - version "2.11.1" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.11.1.tgz#dd2ccb04c540b4439aadc4bc8f5a776dfc90439f" - integrity sha512-wq2wR3awu6PKimmVOycBf+iTPA9FWThbJwcaDBQEhQiiviXQzAtT3lw3nV9oqNIg4v65tdPhL1Dg8ptTJ03NjQ== - dependencies: - hoist-non-react-statics "^3.3.2" - react-lifecycles-compat "^3.0.4" - react-native-iphone-x-helper "^1.3.0" - react-native-tab-view "^2.15.2" - -react-navigation@^4.4.4: - version "4.4.4" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-4.4.4.tgz#8cda2219196311db440e54998bc724523359949f" - integrity sha512-08Nzy1aKEd73496CsuzN49vLFmxPKYF5WpKGgGvkQ10clB79IRM2BtAfVl6NgPKuUM8FXq1wCsrjo/c5ftl5og== - dependencies: - "@react-navigation/core" "^3.7.9" - "@react-navigation/native" "^3.8.4" - react-proxy@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a"