From 0488086f74cba7fc1465ba97ec4db02c46910b1a Mon Sep 17 00:00:00 2001 From: LazyAfternoons Date: Fri, 24 Nov 2023 15:24:27 +0100 Subject: [PATCH] fix(IT Wallet): [SIW-699] Credential image disappearing from wallet (#5250) ## Short description This PR resolves a bug which causes the disappearance of the credential image between usage sessions. The issue is caused by the persistence of mock display data, in particular by the `require` result for the asset which is not constant between usage session. This inconsistency leads to the disappearance of the credential image when restarting the app. ## List of changes proposed in this pull request - Instead of including the required assets in the display data which is then persisted, use the credential type to get the assets at runtime with the `getImageFromCredentialType` helper function. Note that the `CredentialType` enum serves the purpose of avoiding the use of arbitrary strings to represent the credential type. Despite this, the credential type is still represented as a string to align with the library's typing requirements and due to the fact that it remains mocked and subject to potential changes. Therefore, although it is not strictly type checked at the moment, it is used in place of string constants in the mock declaration but not in the underlying Redux state. ## How to test Obtain a PID and a credential. Check if the background image is properly shown in the preview, home and details screen. Then restart the app (kill it from the background apps list) and test it again. --------- Co-authored-by: Mario Perrotta --- .../it-wallet/components/ItwClaimsWrapper.tsx | 11 ++++-- .../components/ItwCredentialCard.tsx | 11 +++++- .../it-wallet/screens/ItwHomeScreen.tsx | 5 ++- .../credential/ItwCredentialPreviewScreen.tsx | 1 + .../issuing/pid/cie/ItwPidPreviewScreen.tsx | 4 +- .../presentation/ItwPrCredentialDetails.tsx | 5 ++- .../screens/presentation/ItwPrPidDetails.tsx | 7 +++- ts/features/it-wallet/utils/mocks.ts | 37 +++++++++++++++---- 8 files changed, 63 insertions(+), 18 deletions(-) diff --git a/ts/features/it-wallet/components/ItwClaimsWrapper.tsx b/ts/features/it-wallet/components/ItwClaimsWrapper.tsx index 857669a19bd..0ad8935a88a 100644 --- a/ts/features/it-wallet/components/ItwClaimsWrapper.tsx +++ b/ts/features/it-wallet/components/ItwClaimsWrapper.tsx @@ -1,16 +1,21 @@ import React from "react"; import { ImageBackground, StyleSheet, View } from "react-native"; import { H6, IOColors } from "@pagopa/io-app-design-system"; -import { CredentialCatalogDisplay } from "../utils/mocks"; +import { + CredentialCatalogDisplay, + getImageFromCredentialType +} from "../utils/mocks"; /** * Props of the component. * @param displayData - the display data of the credential. * @param children - the children of the component. + * @param type - the credential type. */ type Props = { displayData: CredentialCatalogDisplay; children: React.ReactNode; + type: string; }; /** @@ -21,11 +26,11 @@ const BORDER_RADIUS = 16; /** * Renders a wrapper for the claims of a credential which shows an header with background image and title. */ -const ItwClaimsWrapper = ({ displayData, children }: Props) => ( +const ItwClaimsWrapper = ({ displayData, children, type }: Props) => ( <> diff --git a/ts/features/it-wallet/components/ItwCredentialCard.tsx b/ts/features/it-wallet/components/ItwCredentialCard.tsx index 92f6df3ae6c..e2dbcce2ef7 100644 --- a/ts/features/it-wallet/components/ItwCredentialCard.tsx +++ b/ts/features/it-wallet/components/ItwCredentialCard.tsx @@ -3,14 +3,19 @@ import { View, Dimensions, Image, StyleSheet } from "react-native"; import { Body, H6, IOColors, Label } from "@pagopa/io-app-design-system"; import { PidWithToken } from "@pagopa/io-react-native-wallet/lib/typescript/pid/sd-jwt"; import customVariables from "../../../theme/variables"; -import { CredentialCatalogDisplay } from "../utils/mocks"; +import { + CredentialCatalogDisplay, + getImageFromCredentialType +} from "../utils/mocks"; /** * Common props for the component. * @param display - the display configuration for the credential. + * @param type - the type of the credential. */ type CommonProps = { display: CredentialCatalogDisplay; + type: string; }; /** @@ -89,7 +94,9 @@ const ItwCredentialCard = (props: CredentialCardProps) => { const { firstLine, secondLine } = getLines(); - const { image, textColor, title } = props.display; + const { textColor, title } = props.display; + + const image = getImageFromCredentialType(props.type); return ( diff --git a/ts/features/it-wallet/screens/ItwHomeScreen.tsx b/ts/features/it-wallet/screens/ItwHomeScreen.tsx index a43038da655..3b4a0e1631c 100644 --- a/ts/features/it-wallet/screens/ItwHomeScreen.tsx +++ b/ts/features/it-wallet/screens/ItwHomeScreen.tsx @@ -28,7 +28,7 @@ import { itwCredentialsSelector } from "../store/reducers/itwCredentialsReducer" import { itwDecodedPidValueSelector } from "../store/reducers/itwPidDecodeReducer"; import { useItwResetFlow } from "../hooks/useItwResetFlow"; import ItwCredentialCard from "../components/ItwCredentialCard"; -import { getPidDisplayData } from "../utils/mocks"; +import { CredentialType, getPidDisplayData } from "../utils/mocks"; const contextualHelpMarkdown: ContextualHelpPropsMarkdown = { title: "wallet.contextualHelpTitle", @@ -60,6 +60,7 @@ const ItwHomeScreen = () => { I18n.t("features.itWallet.homeScreen.categories.bonus") ]; const pidDisplayData = getPidDisplayData(); + const pidType = CredentialType.PID; /** * Condionally navigate to the credentials catalog screen if the experimental feature flag is true. @@ -100,6 +101,7 @@ const ItwHomeScreen = () => { @@ -122,6 +124,7 @@ const ItwHomeScreen = () => { diff --git a/ts/features/it-wallet/screens/issuing/credential/ItwCredentialPreviewScreen.tsx b/ts/features/it-wallet/screens/issuing/credential/ItwCredentialPreviewScreen.tsx index aeeafddf5e8..fc994b34852 100644 --- a/ts/features/it-wallet/screens/issuing/credential/ItwCredentialPreviewScreen.tsx +++ b/ts/features/it-wallet/screens/issuing/credential/ItwCredentialPreviewScreen.tsx @@ -110,6 +110,7 @@ const ItwCredentialPreviewScreen = () => { diff --git a/ts/features/it-wallet/screens/issuing/pid/cie/ItwPidPreviewScreen.tsx b/ts/features/it-wallet/screens/issuing/pid/cie/ItwPidPreviewScreen.tsx index cfb939e546a..0f36ca7ac59 100644 --- a/ts/features/it-wallet/screens/issuing/pid/cie/ItwPidPreviewScreen.tsx +++ b/ts/features/it-wallet/screens/issuing/pid/cie/ItwPidPreviewScreen.tsx @@ -32,7 +32,7 @@ import { useOnFirstRender } from "../../../../../../utils/hooks/useOnFirstRender import { itwDecodePid } from "../../../../store/actions/itwCredentialsActions"; import { itwPidValueSelector } from "../../../../store/reducers/itwPidReducer"; import ItwCredentialCard from "../../../../components/ItwCredentialCard"; -import { getPidDisplayData } from "../../../../utils/mocks"; +import { CredentialType, getPidDisplayData } from "../../../../utils/mocks"; type ContentViewProps = { decodedPid: PidWithToken; @@ -48,6 +48,7 @@ const ItwPidPreviewScreen = () => { const pid = useIOSelector(itwPidValueSelector); const decodedPidPot = useIOSelector(ItwDecodedPidPotSelector); const pidDisplayData = getPidDisplayData(); + const pidType = CredentialType.PID; /** * Dispatches the action to decode the PID on first render. @@ -83,6 +84,7 @@ const ItwPidPreviewScreen = () => { { - + diff --git a/ts/features/it-wallet/screens/presentation/ItwPrPidDetails.tsx b/ts/features/it-wallet/screens/presentation/ItwPrPidDetails.tsx index e754b16968d..5653a8fbc93 100644 --- a/ts/features/it-wallet/screens/presentation/ItwPrPidDetails.tsx +++ b/ts/features/it-wallet/screens/presentation/ItwPrPidDetails.tsx @@ -19,7 +19,7 @@ import { itwDecodedPidValueSelector } from "../../store/reducers/itwPidDecodeRed import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList"; import { ItwParamsList } from "../../navigation/ItwParamsList"; import ItwPidClaimsList from "../../components/ItwPidClaimsList"; -import { getPidDisplayData } from "../../utils/mocks"; +import { CredentialType, getPidDisplayData } from "../../utils/mocks"; import ItwClaimsWrapper from "../../components/ItwClaimsWrapper"; import { ITW_ROUTES } from "../../navigation/ItwRoutes"; import ItwKoView from "../../components/ItwKoView"; @@ -60,7 +60,10 @@ const ItwPrPidDetails = () => { - + { export const CREDENTIAL_ISSUER = "eFarma"; +/** + * Credential types mocks. + */ +export enum CredentialType { + HEALTH_CARD = "HealthCard", + EUROPEAN_DISABILITY_CARD = "EuropeanDisabilityCard", + DRIVING_LICENSE = "DrivingLicense", + PID = "PID" +} + export type CredentialCatalogDisplay = { textColor: "black" | "white"; - image: ImageSourcePropType; title: string; icon?: IOIcons; firstLine?: Array; @@ -73,7 +81,7 @@ export type CredentialCatalogItem = */ export const getCredentialsCatalog = (): Array => [ { - type: "EuropeanDisabilityCard", + type: CredentialType.EUROPEAN_DISABILITY_CARD, issuerUrl: "https://api.eudi-wallet-it-issuer.it/rp", title: I18n.t( "features.itWallet.verifiableCredentials.type.disabilityCard" @@ -81,7 +89,6 @@ export const getCredentialsCatalog = (): Array => [ icon: "disabilityCard", incoming: false, textColor: "black", - image: require("../assets/img/credentials/cards/europeanDisabilityCardFront.png"), firstLine: ["given_name", "family_name"], secondLine: ["serial_number"], order: [ @@ -98,7 +105,6 @@ export const getCredentialsCatalog = (): Array => [ title: I18n.t("features.itWallet.verifiableCredentials.type.healthCard"), icon: "healthCard", textColor: "black", - image: require("../assets/img/credentials/cards/healthInsuranceFront.png"), firstLine: [], secondLine: [] }, @@ -109,12 +115,27 @@ export const getCredentialsCatalog = (): Array => [ icon: "driverLicense", incoming: true, textColor: "black", - image: require("../assets/img/credentials/cards/drivingLicenseFront.png"), firstLine: [], secondLine: [] } ]; +/** + * Returns the mocked background image for the credential. + * @param type - the credential type + * @returns the mocked background image. + */ +export const getImageFromCredentialType = (type: string) => { + switch (type) { + case CredentialType.EUROPEAN_DISABILITY_CARD: + return require("../assets/img/credentials/cards/europeanDisabilityCardFront.png"); + case CredentialType.PID: + return require("../assets/img/credentials/cards/pidFront.png"); + default: + return require("../assets/img/credentials/cards/default.png"); + } +}; + /** * Hard coded display feature for PID */ @@ -123,8 +144,7 @@ export const getPidDisplayData = (): CredentialCatalogDisplay => ({ "features.itWallet.verifiableCredentials.type.digitalCredential" ), icon: "archive", - textColor: "white", - image: require("../assets/img/credentials/cards/pidFront.png") + textColor: "white" }); export const getRequestedClaims = ( @@ -208,5 +228,6 @@ export const rpPidMock: RpMock = { /** * Regex to validate the date format of a credential. + * This is mocked because the date format is not yet defined. */ export const dateFormatRegex = new RegExp(/^\d{4}-\d{2}-\d{2}$/);