mirror of
https://github.com/selfxyz/self.git
synced 2026-02-19 02:24:25 -05:00
refactor: remove blur on document when selected + show old view ID data (#1747)
* refactor: remove blur on document when selected * fix: show original 'view ID data'
This commit is contained in:
@@ -2,11 +2,10 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import type { FC } from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { Image, Pressable, StyleSheet } from 'react-native';
|
||||
import React, { type FC, useCallback } from 'react';
|
||||
import { Dimensions, Image, Pressable, StyleSheet } from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import { Text, XStack, YStack } from 'tamagui';
|
||||
import { Separator, Text, XStack, YStack } from 'tamagui';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
|
||||
import type { AadhaarData } from '@selfxyz/common';
|
||||
@@ -20,11 +19,18 @@ import {
|
||||
import { WarningTriangleIcon } from '@selfxyz/euclid/dist/components/icons/WarningTriangleIcon';
|
||||
import { RoundFlag } from '@selfxyz/mobile-sdk-alpha/components';
|
||||
import {
|
||||
black,
|
||||
red600,
|
||||
slate100,
|
||||
slate300,
|
||||
slate400,
|
||||
slate500,
|
||||
white,
|
||||
yellow500,
|
||||
} from '@selfxyz/mobile-sdk-alpha/constants/colors';
|
||||
import { dinot, plexMono } from '@selfxyz/mobile-sdk-alpha/constants/fonts';
|
||||
import AadhaarIcon from '@selfxyz/mobile-sdk-alpha/svgs/icons/aadhaar.svg';
|
||||
import EPassport from '@selfxyz/mobile-sdk-alpha/svgs/icons/epassport.svg';
|
||||
|
||||
import CardBackgroundId1 from '@/assets/images/card_background_id1.png';
|
||||
import CardBackgroundId2 from '@/assets/images/card_background_id2.png';
|
||||
@@ -34,14 +40,20 @@ import CardBackgroundId5 from '@/assets/images/card_background_id5.png';
|
||||
import CardBackgroundId6 from '@/assets/images/card_background_id6.png';
|
||||
import DevCardLogo from '@/assets/images/dev_card_logo.svg';
|
||||
import DevCardWave from '@/assets/images/dev_card_wave.svg';
|
||||
import LogoGray from '@/assets/images/logo_gray.svg';
|
||||
import SelfLogoPending from '@/assets/images/self_logo_pending.svg';
|
||||
import WaveOverlay from '@/assets/images/wave_overlay.png';
|
||||
import { getSecurityLevel } from '@/components/homescreen/cardSecurityBadge';
|
||||
import { cardStyles } from '@/components/homescreen/cardStyles';
|
||||
import KycIdCard from '@/components/homescreen/KycIdCard';
|
||||
import { SvgXml } from '@/components/homescreen/SvgXmlWrapper';
|
||||
import { useCardDimensions } from '@/hooks/useCardDimensions';
|
||||
import { getBackgroundIndex } from '@/utils/cardBackgroundSelector';
|
||||
import { getDocumentAttributes } from '@/utils/documentAttributes';
|
||||
import {
|
||||
formatDateFromYYMMDD,
|
||||
getDocumentAttributes,
|
||||
getNameAndSurname,
|
||||
} from '@/utils/documentAttributes';
|
||||
import { registerModalCallbacks } from '@/utils/modalCallbackRegistry';
|
||||
|
||||
const CARD_BACKGROUNDS = [
|
||||
@@ -282,6 +294,12 @@ const getCountryDemonym = (code: string): string => {
|
||||
return COUNTRY_DEMONYMS[upperCode] || upperCode;
|
||||
};
|
||||
|
||||
const logoSvg = `<svg width="47" height="46" viewBox="0 0 47 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.7814 13.2168C12.7814 12.7057 13.1992 12.2969 13.7214 12.2969H30.0017L42.5676 0H11.2408L0 11.0001V29.0973H12.7814V13.2104V13.2168Z" fill="white"/>
|
||||
<path d="M34.2186 16.8515V32.3552C34.2186 32.8663 33.8008 33.2751 33.2786 33.2751H17.4357L4.43236 46H35.7592L47 34.9999V16.8579H34.2186V16.8515Z" fill="white"/>
|
||||
<path d="M28.9703 17.6525H18.0362V28.3539H28.9703V17.6525Z" fill="#00FFB6"/>
|
||||
</svg>`;
|
||||
|
||||
interface IdCardLayoutAttributes {
|
||||
idDocument: PassportData | AadhaarData | KycData | null;
|
||||
selected: boolean;
|
||||
@@ -356,6 +374,331 @@ const IdCardLayout: FC<IdCardLayoutAttributes> = ({
|
||||
<KycIdCard idDocument={idDocument} selected={selected} hidden={hidden} />
|
||||
);
|
||||
}
|
||||
|
||||
// When data is revealed (hidden=false), show the white data-view card
|
||||
if (!hidden && selected) {
|
||||
const { width: screenWidth } = Dimensions.get('window');
|
||||
const revealedWidth = screenWidth * 0.95 - 16;
|
||||
const revealedHeight = revealedWidth * 0.645;
|
||||
const revealedBorderRadius = revealedWidth * 0.04;
|
||||
const revealedPadding = revealedWidth * 0.035;
|
||||
const revealedFontSize = {
|
||||
large: revealedWidth * 0.045,
|
||||
small: revealedWidth * 0.028,
|
||||
xsmall: revealedWidth * 0.022,
|
||||
};
|
||||
const imageSize = {
|
||||
width: revealedWidth * 0.2,
|
||||
height: revealedWidth * 0.29,
|
||||
};
|
||||
const contentLeftOffset = imageSize.width + revealedPadding;
|
||||
const docAttributes = getDocumentAttributes(idDocument);
|
||||
const nameData = getNameAndSurname(docAttributes.nameSlice);
|
||||
|
||||
return (
|
||||
<YStack width="100%" alignItems="center" justifyContent="center">
|
||||
<YStack
|
||||
width={revealedWidth}
|
||||
height={revealedHeight}
|
||||
backgroundColor={white}
|
||||
borderRadius={revealedBorderRadius}
|
||||
borderWidth={0.75}
|
||||
borderColor={'#E0E0E0'}
|
||||
padding={revealedPadding}
|
||||
shadowColor={black}
|
||||
shadowOffset={{ width: 0, height: 2 }}
|
||||
shadowOpacity={0.1}
|
||||
shadowRadius={4}
|
||||
elevation={4}
|
||||
marginBottom={8}
|
||||
justifyContent="center"
|
||||
>
|
||||
{/* Header Section */}
|
||||
<XStack>
|
||||
<XStack alignItems="center">
|
||||
{isAadhaarDocument(idDocument) ? (
|
||||
<AadhaarIcon
|
||||
width={revealedFontSize.large * 3}
|
||||
height={revealedFontSize.large * 3 * 0.617}
|
||||
/>
|
||||
) : (
|
||||
<EPassport
|
||||
width={revealedFontSize.large * 3}
|
||||
height={revealedFontSize.large * 3 * 0.617}
|
||||
/>
|
||||
)}
|
||||
<YStack marginLeft={imageSize.width - revealedFontSize.large * 3}>
|
||||
<Text
|
||||
fontWeight="bold"
|
||||
fontFamily={dinot}
|
||||
fontSize={revealedFontSize.large * 1.4}
|
||||
color="black"
|
||||
>
|
||||
{isMRZDocument(idDocument) &&
|
||||
idDocument.documentCategory === 'passport'
|
||||
? 'Passport'
|
||||
: isAadhaarDocument(idDocument)
|
||||
? 'Aadhaar'
|
||||
: 'ID Card'}
|
||||
</Text>
|
||||
<Text
|
||||
fontSize={revealedFontSize.small}
|
||||
color={slate400}
|
||||
fontFamily={dinot}
|
||||
>
|
||||
Verified{' '}
|
||||
{isMRZDocument(idDocument) &&
|
||||
idDocument.documentCategory === 'passport'
|
||||
? 'Biometric Passport'
|
||||
: isAadhaarDocument(idDocument)
|
||||
? 'Aadhaar Document'
|
||||
: 'Biometric ID Card'}
|
||||
</Text>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack flex={1} justifyContent="flex-end">
|
||||
{idDocument.mock && (
|
||||
<YStack
|
||||
marginTop={revealedPadding / 4}
|
||||
borderWidth={1}
|
||||
borderColor={slate300}
|
||||
borderRadius={100}
|
||||
paddingHorizontal={revealedPadding / 2}
|
||||
alignSelf="flex-start"
|
||||
backgroundColor={slate100}
|
||||
paddingVertical={revealedPadding / 8}
|
||||
>
|
||||
<Text
|
||||
fontSize={revealedFontSize.xsmall}
|
||||
color={slate400}
|
||||
fontFamily={dinot}
|
||||
letterSpacing={revealedFontSize.xsmall * 0.15}
|
||||
>
|
||||
DEVELOPER
|
||||
</Text>
|
||||
</YStack>
|
||||
)}
|
||||
</XStack>
|
||||
</XStack>
|
||||
|
||||
<Separator
|
||||
backgroundColor={'#E0E0E0'}
|
||||
height={1}
|
||||
width={revealedWidth - 1}
|
||||
marginLeft={-revealedPadding}
|
||||
marginTop={revealedPadding}
|
||||
/>
|
||||
|
||||
{/* Main Content Section */}
|
||||
<XStack height="60%" paddingVertical={revealedPadding}>
|
||||
{/* Person Image Placeholder */}
|
||||
<YStack
|
||||
width={imageSize.width}
|
||||
height={imageSize.height}
|
||||
backgroundColor="#F5F5F5"
|
||||
borderRadius={revealedBorderRadius * 0.5}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
marginRight={revealedPadding}
|
||||
>
|
||||
<SvgXml
|
||||
xml={logoSvg}
|
||||
width={imageSize.width * 0.6}
|
||||
height={imageSize.height * 0.6}
|
||||
/>
|
||||
</YStack>
|
||||
|
||||
{/* ID Attributes Grid */}
|
||||
<YStack
|
||||
flex={1}
|
||||
justifyContent="space-between"
|
||||
height={imageSize.height}
|
||||
>
|
||||
<XStack flex={1} gap={revealedPadding * 0.3}>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="TYPE"
|
||||
value={
|
||||
isMRZDocument(idDocument) &&
|
||||
idDocument.documentCategory === 'passport'
|
||||
? 'PASSPORT'
|
||||
: isAadhaarDocument(idDocument)
|
||||
? 'AADHAAR'
|
||||
: 'ID CARD'
|
||||
}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="CODE"
|
||||
value={idDocument.mock ? 'SELF DEV' : 'SELF ID'}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="DOC NO."
|
||||
value={docAttributes.passNoSlice}
|
||||
/>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack flex={1} gap={revealedPadding * 0.3}>
|
||||
{isAadhaarDocument(idDocument) ? (
|
||||
<>
|
||||
<YStack flex={2}>
|
||||
<IdAttribute
|
||||
name="NAME"
|
||||
value={[...nameData.surname, ...nameData.names].join(
|
||||
' ',
|
||||
)}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute name="SEX" value={docAttributes.sexSlice} />
|
||||
</YStack>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="SURNAME"
|
||||
value={nameData.surname.join(' ')}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="NAME"
|
||||
value={nameData.names.join(' ')}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute name="SEX" value={docAttributes.sexSlice} />
|
||||
</YStack>
|
||||
</>
|
||||
)}
|
||||
</XStack>
|
||||
<XStack flex={1} gap={revealedPadding * 0.3}>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="NATIONALITY"
|
||||
value={docAttributes.nationalitySlice}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="DOB"
|
||||
value={formatDateFromYYMMDD(docAttributes.dobSlice, true)}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="EXPIRY DATE"
|
||||
value={formatDateFromYYMMDD(docAttributes.expiryDateSlice)}
|
||||
/>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack flex={1} gap={revealedPadding * 0.3}>
|
||||
<YStack flex={1}>
|
||||
<IdAttribute
|
||||
name="AUTHORITY"
|
||||
value={docAttributes.issuingStateSlice}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack flex={1} />
|
||||
<YStack flex={1} />
|
||||
</XStack>
|
||||
</YStack>
|
||||
</XStack>
|
||||
|
||||
{/* Footer Section - MRZ */}
|
||||
{isMRZDocument(idDocument) && idDocument.mrz && (
|
||||
<XStack
|
||||
alignItems="center"
|
||||
backgroundColor={slate100}
|
||||
borderRadius={revealedBorderRadius / 3}
|
||||
paddingHorizontal={revealedPadding / 2}
|
||||
paddingVertical={revealedPadding / 4}
|
||||
>
|
||||
<XStack width={contentLeftOffset} alignItems="center">
|
||||
<LogoGray
|
||||
width={revealedFontSize.large}
|
||||
height={revealedFontSize.large}
|
||||
/>
|
||||
</XStack>
|
||||
<YStack marginLeft={-revealedPadding / 2}>
|
||||
{idDocument.documentCategory === 'passport' ? (
|
||||
<>
|
||||
<Text
|
||||
fontSize={revealedFontSize.xsmall}
|
||||
letterSpacing={revealedFontSize.xsmall * 0.1}
|
||||
fontFamily={plexMono}
|
||||
color={slate400}
|
||||
>
|
||||
{idDocument.mrz.slice(0, 44)}
|
||||
</Text>
|
||||
<Text
|
||||
fontSize={revealedFontSize.xsmall}
|
||||
letterSpacing={revealedFontSize.xsmall * 0.1}
|
||||
fontFamily={plexMono}
|
||||
color={slate400}
|
||||
>
|
||||
{idDocument.mrz.slice(44, 88)}
|
||||
</Text>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Text
|
||||
fontSize={revealedFontSize.xsmall}
|
||||
letterSpacing={revealedFontSize.xsmall * 0.44}
|
||||
fontFamily={plexMono}
|
||||
color={slate400}
|
||||
>
|
||||
{idDocument.mrz.slice(0, 30)}
|
||||
</Text>
|
||||
<Text
|
||||
fontSize={revealedFontSize.xsmall}
|
||||
letterSpacing={revealedFontSize.xsmall * 0.44}
|
||||
fontFamily={plexMono}
|
||||
color={slate400}
|
||||
>
|
||||
{idDocument.mrz.slice(30, 60)}
|
||||
</Text>
|
||||
<Text
|
||||
fontSize={revealedFontSize.xsmall}
|
||||
letterSpacing={revealedFontSize.xsmall * 0.44}
|
||||
fontFamily={plexMono}
|
||||
color={slate400}
|
||||
>
|
||||
{idDocument.mrz.slice(60, 90)}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</YStack>
|
||||
</XStack>
|
||||
)}
|
||||
|
||||
{/* Footer Section - Empty placeholder for Aadhaar */}
|
||||
{isAadhaarDocument(idDocument) && (
|
||||
<XStack
|
||||
alignItems="center"
|
||||
backgroundColor={slate100}
|
||||
borderRadius={revealedBorderRadius / 3}
|
||||
paddingHorizontal={revealedPadding / 2}
|
||||
paddingVertical={revealedPadding / 4}
|
||||
minHeight={revealedFontSize.xsmall * 2.5}
|
||||
>
|
||||
<XStack width={contentLeftOffset} alignItems="center">
|
||||
<LogoGray
|
||||
width={revealedFontSize.large}
|
||||
height={revealedFontSize.large}
|
||||
/>
|
||||
</XStack>
|
||||
</XStack>
|
||||
)}
|
||||
</YStack>
|
||||
</YStack>
|
||||
);
|
||||
}
|
||||
|
||||
const padding = cardWidth * 0.04;
|
||||
|
||||
// Get document attributes
|
||||
@@ -712,4 +1055,33 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
interface IdAttributeProps {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const IdAttribute: FC<IdAttributeProps> = ({ name, value }) => {
|
||||
const { width: screenWidth } = Dimensions.get('window');
|
||||
const attrFontSize = {
|
||||
label: screenWidth * 0.024,
|
||||
value: screenWidth * 0.02,
|
||||
};
|
||||
|
||||
return (
|
||||
<YStack>
|
||||
<Text
|
||||
fontWeight="bold"
|
||||
fontSize={attrFontSize.label}
|
||||
color={slate500}
|
||||
fontFamily={dinot}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
<Text fontSize={attrFontSize.value} color={slate400} fontFamily={dinot}>
|
||||
{value}
|
||||
</Text>
|
||||
</YStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default IdCardLayout;
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { Button, Text, XStack, YStack, ZStack } from 'tamagui';
|
||||
import { BlurView } from '@react-native-community/blur';
|
||||
import { useFocusEffect, useNavigation } from '@react-navigation/native';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
|
||||
import type { DocumentCatalog, IDDocument } from '@selfxyz/common/utils/types';
|
||||
import {
|
||||
@@ -36,18 +36,6 @@ const IdDetailsScreen: React.FC = () => {
|
||||
const navigation = useNavigation();
|
||||
const { bottom } = useSafeAreaInsets();
|
||||
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
|
||||
// Added to unmount BlurView when screen loses focus
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
setIsFocused(true);
|
||||
return () => {
|
||||
setIsFocused(false);
|
||||
};
|
||||
}, []),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const loadDocumentAndCatalog = async () => {
|
||||
const allDocs = await getAllDocuments();
|
||||
@@ -140,21 +128,17 @@ const IdDetailsScreen: React.FC = () => {
|
||||
{ListHeader}
|
||||
<ZStack flex={1}>
|
||||
<ProofHistoryList documentId={documentId} />
|
||||
{isFocused && (
|
||||
<BlurView
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 100,
|
||||
}}
|
||||
blurType="light"
|
||||
blurAmount={4}
|
||||
reducedTransparencyFallbackColor={slate50}
|
||||
pointerEvents="none"
|
||||
/>
|
||||
)}
|
||||
<LinearGradient
|
||||
colors={['transparent', slate50]}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 100,
|
||||
}}
|
||||
pointerEvents="none"
|
||||
/>
|
||||
<YStack position="absolute" bottom={bottom + 20} left={20} right={20}>
|
||||
<Button
|
||||
backgroundColor={isConnected ? slate100 : white}
|
||||
|
||||
Reference in New Issue
Block a user