Skip to content

Commit

Permalink
feat: unify UI for DIDComm and OpenID flows for Offer and details scr…
Browse files Browse the repository at this point in the history
…eens (#1365)

Signed-off-by: Mostafa Gamal <[email protected]>
  • Loading branch information
MosCD3 authored Jan 9, 2025
1 parent bd408eb commit 08e12a6
Show file tree
Hide file tree
Showing 16 changed files with 588 additions and 285 deletions.
40 changes: 36 additions & 4 deletions packages/legacy/core/App/components/misc/CredentialCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CredentialExchangeRecord, W3cCredentialRecord } from '@credo-ts/core'
import { Attribute, BrandingOverlayType, Predicate } from '@hyperledger/aries-oca/build/legacy'
import React from 'react'
import { Attribute, BrandingOverlayType, CredentialOverlay, Predicate } from '@hyperledger/aries-oca/build/legacy'
import React, { useEffect, useState } from 'react'
import { ViewStyle } from 'react-native'

import { TOKENS, useServices } from '../../container-api'
Expand All @@ -9,8 +9,11 @@ import { GenericFn } from '../../types/fn'

import CredentialCard10 from './CredentialCard10'
import CredentialCard11, { CredentialErrors } from './CredentialCard11'
import OpenIDCredentialCard from '../../modules/openid/components/OpenIDCredentialCard'
import { GenericCredentialExchangeRecord } from '../../types/credentials'
import { BrandingOverlay } from '@hyperledger/aries-oca'
import { getCredentialForDisplay } from '../../modules/openid/display'
import { buildOverlayFromW3cCredential } from '../../utils/oca'
import { useTranslation } from 'react-i18next'

interface CredentialCardProps {
credential?: GenericCredentialExchangeRecord
Expand Down Expand Up @@ -42,6 +45,27 @@ const CredentialCard: React.FC<CredentialCardProps> = ({
// add ability to reference credential by ID, allows us to get past react hook restrictions
const [bundleResolver] = useServices([TOKENS.UTIL_OCA_RESOLVER])
const { ColorPallet } = useTheme()
const [overlay, setOverlay] = useState<CredentialOverlay<BrandingOverlay>>({})
const { i18n } = useTranslation()

useEffect(() => {
const resolveOverlay = async (w3cCred: W3cCredentialRecord) => {
const credentialDisplay = getCredentialForDisplay(w3cCred)

const resolvedOverlay = await buildOverlayFromW3cCredential({
credentialDisplay,
language: i18n.language,
resolver: bundleResolver,
})

setOverlay(resolvedOverlay)
}

if (credential instanceof W3cCredentialRecord) {
resolveOverlay(credential)
}
}, [credential, bundleResolver, i18n.language])

const getCredOverlayType = (type: BrandingOverlayType) => {
if (proof) {
return (
Expand Down Expand Up @@ -90,7 +114,15 @@ const CredentialCard: React.FC<CredentialCardProps> = ({
}

if (credential instanceof W3cCredentialRecord) {
return <OpenIDCredentialCard credentialRecord={credential as W3cCredentialRecord} onPress={onPress} />
return (
<CredentialCard11
credential={undefined}
style={style}
onPress={onPress}
brandingOverlay={overlay}
credentialErrors={credentialErrors ?? []}
/>
)
} else {
return getCredOverlayType(bundleResolver.getBrandingOverlayType())
}
Expand Down
8 changes: 8 additions & 0 deletions packages/legacy/core/App/components/misc/CredentialCard11.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ interface CredentialCard11Props {
credentialErrors: CredentialErrors[]
hasAltCredentials?: boolean
handleAltCredChange?: () => void
brandingOverlay?: CredentialOverlay<BrandingOverlay>
}

/*
Expand Down Expand Up @@ -93,6 +94,7 @@ const CredentialCard11: React.FC<CredentialCard11Props> = ({
hasAltCredentials,
credentialErrors = [],
handleAltCredChange,
brandingOverlay,
}) => {
const { width } = useWindowDimensions()
const borderRadius = 10
Expand Down Expand Up @@ -285,6 +287,11 @@ const CredentialCard11: React.FC<CredentialCard11Props> = ({
}, [credential, cardData, parseAttribute, flaggedAttributes])

useEffect(() => {
if (brandingOverlay) {
setOverlay(brandingOverlay as unknown as CredentialOverlay<BrandingOverlay>)
return
}

const params = {
identifiers: credential ? getCredentialIdentifiers(credential) : { schemaId, credentialDefinitionId: credDefId },
attributes: proof ? [] : credential?.credentialAttributes,
Expand Down Expand Up @@ -335,6 +342,7 @@ const CredentialCard11: React.FC<CredentialCard11Props> = ({
proof,
credHelpActionOverrides,
navigation,
brandingOverlay,
])

const CredentialCardLogo: React.FC = () => {
Expand Down
58 changes: 58 additions & 0 deletions packages/legacy/core/App/components/views/CredentialCardLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Image, StyleSheet, Text, View } from 'react-native'
import { BrandingOverlay } from '@hyperledger/aries-oca'
import { CredentialOverlay } from '@hyperledger/aries-oca/build/legacy'
import { useTheme } from '../../contexts/theme'
import { toImageSource } from '../../utils/credential'

type Props = {
overlay: CredentialOverlay<BrandingOverlay>
}

const logoHeight = 80
const paddingHorizontal = 24

const CredentialCardLogo: React.FC<Props> = ({ overlay }: Props) => {
const { TextTheme } = useTheme()

const styles = StyleSheet.create({
logoContainer: {
top: -0.5 * logoHeight,
left: paddingHorizontal,
marginBottom: -1 * logoHeight,
width: logoHeight,
height: logoHeight,
backgroundColor: '#ffffff',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 1,
height: 1,
},
shadowOpacity: 0.3,
},
})

return (
<View style={styles.logoContainer}>
{overlay.brandingOverlay?.logo ? (
<Image
source={toImageSource(overlay.brandingOverlay?.logo)}
style={{
resizeMode: 'cover',
width: logoHeight,
height: logoHeight,
borderRadius: 8,
}}
/>
) : (
<Text style={[TextTheme.title, { fontSize: 0.5 * logoHeight, color: '#000' }]}>
{(overlay.metaOverlay?.name ?? overlay.metaOverlay?.issuer ?? 'C')?.charAt(0).toUpperCase()}
</Text>
)}
</View>
)
}

export default CredentialCardLogo
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { StyleSheet, Text, useWindowDimensions, View } from 'react-native'
import { BrandingOverlay } from '@hyperledger/aries-oca'
import { CredentialOverlay } from '@hyperledger/aries-oca/build/legacy'
import CardWatermark from '../../components/misc/CardWatermark'
import { useTheme } from '../../contexts/theme'
import { credentialTextColor } from '../../utils/credential'
import { testIdWithKey } from '../../utils/testable'

type CredentialDetailPrimaryHeaderProps = {
overlay: CredentialOverlay<BrandingOverlay>
}

const paddingHorizontal = 24
const paddingVertical = 16
const logoHeight = 80

const CredentialDetailPrimaryHeader: React.FC<CredentialDetailPrimaryHeaderProps> = ({ overlay }: CredentialDetailPrimaryHeaderProps) => {
const { TextTheme, ColorPallet } = useTheme()
const { width, height } = useWindowDimensions()
const styles = StyleSheet.create({
primaryHeaderContainer: {
paddingHorizontal,
paddingVertical,
},
textContainer: {
color: credentialTextColor(ColorPallet, overlay.brandingOverlay?.primaryBackgroundColor),
},
})

return (
<View
testID={testIdWithKey('CredentialDetailsPrimaryHeader')}
style={[styles.primaryHeaderContainer, { zIndex: -1 }]}
>
<View>
{overlay.metaOverlay?.watermark && (
<CardWatermark width={width} height={height} watermark={overlay.metaOverlay?.watermark} />
)}
<Text
testID={testIdWithKey('CredentialIssuer')}
style={[
TextTheme.label,
styles.textContainer,
{
paddingLeft: logoHeight + paddingVertical,
paddingBottom: paddingVertical,
lineHeight: 19,
opacity: 0.8,
},
]}
numberOfLines={1}
>
{overlay.metaOverlay?.issuer}
</Text>
<Text
testID={testIdWithKey('CredentialName')}
style={[
TextTheme.normal,
styles.textContainer,
{
lineHeight: 24,
},
]}
>
{overlay.metaOverlay?.name}
</Text>
</View>
</View>
)
}

export default CredentialDetailPrimaryHeader
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import { BrandingOverlay } from '@hyperledger/aries-oca'
import { CredentialOverlay } from '@hyperledger/aries-oca/build/legacy'
import { ImageBackground, StyleSheet, View } from 'react-native'
import { toImageSource } from '../../utils/credential'
import { testIdWithKey } from '../../utils/testable'

type CredentialDetailSecondaryHeaderProps = {
overlay: CredentialOverlay<BrandingOverlay>
}

const logoHeight = 80

const CredentialDetailSecondaryHeader: React.FC<CredentialDetailSecondaryHeaderProps> = ({ overlay }: CredentialDetailSecondaryHeaderProps) => {
const styles = StyleSheet.create({
secondaryHeaderContainer: {
height: 1.5 * logoHeight,
backgroundColor:
(overlay.brandingOverlay?.backgroundImage
? 'rgba(0, 0, 0, 0)'
: overlay.brandingOverlay?.secondaryBackgroundColor) ?? 'rgba(0, 0, 0, 0.24)',
},
})

return (
<>
{overlay.brandingOverlay?.backgroundImage ? (
<ImageBackground
source={toImageSource(overlay.brandingOverlay?.backgroundImage)}
imageStyle={{
resizeMode: 'cover',
}}
>
<View testID={testIdWithKey('CredentialDetailsSecondaryHeader')} style={styles.secondaryHeaderContainer} />
</ImageBackground>
) : (
<View testID={testIdWithKey('CredentialDetailsSecondaryHeader')} style={styles.secondaryHeaderContainer} />
)}
</>
)
}

export default CredentialDetailSecondaryHeader
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type OpenIDCredentialRecord = W3cCredentialRecord | SdJwtVcRecord | undefined

export type OpenIDCredentialContext = {
openIdState: OpenIDCredentialRecordState
getCredentialById: (id: string) => Promise<W3cCredentialRecord | SdJwtVcRecord | undefined>
storeCredential: (cred: W3cCredentialRecord | SdJwtVcRecord) => Promise<void>
removeCredential: (cred: W3cCredentialRecord | SdJwtVcRecord) => Promise<void>
}
Expand Down Expand Up @@ -87,6 +88,11 @@ export const OpenIDCredentialRecordProvider: React.FC<PropsWithChildren<OpenIDCr
}
}

async function getCredentialById(id: string): Promise<W3cCredentialRecord | SdJwtVcRecord | undefined> {
checkAgent()
return await agent?.w3cCredentials.getCredentialRecordById(id)
}

async function storeCredential(cred: W3cCredentialRecord | SdJwtVcRecord): Promise<void> {
checkAgent()
if (cred instanceof W3cCredentialRecord) {
Expand Down Expand Up @@ -146,6 +152,7 @@ export const OpenIDCredentialRecordProvider: React.FC<PropsWithChildren<OpenIDCr
openIdState: state,
storeCredential: storeCredential,
removeCredential: deleteCredential,
getCredentialById: getCredentialById,
}}
>
{children}
Expand Down
Loading

0 comments on commit 08e12a6

Please sign in to comment.