mirror of
https://github.com/selfxyz/self.git
synced 2026-02-19 02:24:25 -05:00
Show badge for inactive documents (#1487)
* Show badge for inactive documents * fix * refactor to use the new flag * add inactive check to ProveScreen * lint * fix for proving button not working * use new qrHashlogic * increase bundle size threshold to 46MB * remove commented out line * add kyc related changes --------- Co-authored-by: seshanthS <seshanth@protonmail.com>
This commit is contained in:
committed by
GitHub
parent
ec8b8fc419
commit
abf01c82c0
@@ -3,10 +3,11 @@
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
import { Image, StyleSheet } from 'react-native';
|
||||
import React, { 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';
|
||||
import type { PassportData } from '@selfxyz/common/types/passport';
|
||||
@@ -16,8 +17,18 @@ import {
|
||||
isKycDocument,
|
||||
isMRZDocument,
|
||||
} from '@selfxyz/common/utils/types';
|
||||
import { WarningTriangleIcon } from '@selfxyz/euclid/dist/components/icons/WarningTriangleIcon';
|
||||
import { RoundFlag } from '@selfxyz/mobile-sdk-alpha/components';
|
||||
import { white } from '@selfxyz/mobile-sdk-alpha/constants/colors';
|
||||
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 CardBackgroundId1 from '@/assets/images/card_background_id1.png';
|
||||
@@ -28,14 +39,21 @@ 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 = [
|
||||
CardBackgroundId1,
|
||||
@@ -279,6 +297,7 @@ interface IdCardLayoutAttributes {
|
||||
idDocument: PassportData | AadhaarData | KycData | null;
|
||||
selected: boolean;
|
||||
hidden: boolean;
|
||||
isInactive?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,7 +312,38 @@ const IdCardLayout: FC<IdCardLayoutAttributes> = ({
|
||||
idDocument,
|
||||
selected,
|
||||
hidden,
|
||||
isInactive = false,
|
||||
}) => {
|
||||
const navigation = useNavigation();
|
||||
const navigateToDocumentOnboarding = useCallback(() => {
|
||||
switch (idDocument?.documentCategory) {
|
||||
case 'passport':
|
||||
case 'id_card':
|
||||
navigation.navigate('DocumentOnboarding');
|
||||
break;
|
||||
case 'aadhaar':
|
||||
navigation.navigate('AadhaarUpload', { countryCode: 'IND' });
|
||||
break;
|
||||
}
|
||||
}, [idDocument?.documentCategory, navigation]);
|
||||
|
||||
const handleInactivePress = useCallback(() => {
|
||||
const callbackId = registerModalCallbacks({
|
||||
onButtonPress: navigateToDocumentOnboarding,
|
||||
onModalDismiss: () => {},
|
||||
});
|
||||
|
||||
navigation.navigate('Modal', {
|
||||
titleText: 'Your ID needs to be reactivated to continue',
|
||||
bodyText:
|
||||
'Make sure that you have your document and recovery method ready.',
|
||||
buttonText: 'Continue',
|
||||
secondaryButtonText: 'Not now',
|
||||
callbackId,
|
||||
});
|
||||
}, [navigateToDocumentOnboarding, navigation]);
|
||||
|
||||
// Early return if document is null
|
||||
// Call hooks at the top, before any conditional returns
|
||||
const {
|
||||
cardWidth,
|
||||
@@ -399,7 +449,47 @@ const IdCardLayout: FC<IdCardLayoutAttributes> = ({
|
||||
const truncatedId = getTruncatedId();
|
||||
|
||||
return (
|
||||
<YStack width="100%" alignItems="center" justifyContent="center">
|
||||
// Container wrapper to handle shadow space properly
|
||||
<YStack
|
||||
width="100%" // Add space for horizontal margins
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
{isInactive && (
|
||||
<Pressable
|
||||
style={styles.inactiveWarningContainer}
|
||||
onPress={handleInactivePress}
|
||||
>
|
||||
<XStack
|
||||
backgroundColor={red600}
|
||||
borderRadius={8}
|
||||
padding={16}
|
||||
gap={16}
|
||||
>
|
||||
<YStack padding={8} backgroundColor={white} borderRadius={8}>
|
||||
<WarningTriangleIcon color={yellow500} />
|
||||
</YStack>
|
||||
<YStack gap={4}>
|
||||
<Text
|
||||
color={white}
|
||||
fontFamily={dinot}
|
||||
fontSize={16}
|
||||
fontWeight="500"
|
||||
>
|
||||
Your document is inactive
|
||||
</Text>
|
||||
<Text
|
||||
color={white}
|
||||
fontFamily={dinot}
|
||||
fontSize={14}
|
||||
fontWeight="400"
|
||||
>
|
||||
Tap here to recover your ID
|
||||
</Text>
|
||||
</YStack>
|
||||
</XStack>
|
||||
</Pressable>
|
||||
)}
|
||||
<YStack
|
||||
width={cardWidth}
|
||||
height={cardHeight}
|
||||
@@ -566,23 +656,45 @@ const IdCardLayout: FC<IdCardLayoutAttributes> = ({
|
||||
</Text>
|
||||
</YStack>
|
||||
|
||||
{/* Security Badge */}
|
||||
<YStack
|
||||
backgroundColor="rgba(0, 0, 0, 0.5)"
|
||||
borderRadius={30}
|
||||
paddingHorizontal={padding * 0.6}
|
||||
paddingVertical={padding * 0.3}
|
||||
>
|
||||
<Text
|
||||
fontFamily={dinot}
|
||||
fontSize={fontSize.badge}
|
||||
fontWeight="500"
|
||||
color={white}
|
||||
textTransform="uppercase"
|
||||
letterSpacing={0.6}
|
||||
{/* Bottom Right: Badges */}
|
||||
<YStack alignItems="flex-end" gap={4}>
|
||||
{isInactive && (
|
||||
<YStack
|
||||
backgroundColor={red600}
|
||||
borderRadius={30}
|
||||
paddingHorizontal={padding * 0.6}
|
||||
paddingVertical={padding * 0.3}
|
||||
>
|
||||
<Text
|
||||
fontFamily={dinot}
|
||||
fontSize={fontSize.badge}
|
||||
fontWeight="500"
|
||||
color={white}
|
||||
textTransform="uppercase"
|
||||
letterSpacing={0.6}
|
||||
>
|
||||
INACTIVE
|
||||
</Text>
|
||||
</YStack>
|
||||
)}
|
||||
{/* Security Badge */}
|
||||
<YStack
|
||||
backgroundColor="rgba(0, 0, 0, 0.5)"
|
||||
borderRadius={30}
|
||||
paddingHorizontal={padding * 0.6}
|
||||
paddingVertical={padding * 0.3}
|
||||
>
|
||||
{securityLevel}
|
||||
</Text>
|
||||
<Text
|
||||
fontFamily={dinot}
|
||||
fontSize={fontSize.badge}
|
||||
fontWeight="500"
|
||||
color={white}
|
||||
textTransform="uppercase"
|
||||
letterSpacing={0.6}
|
||||
>
|
||||
{securityLevel}
|
||||
</Text>
|
||||
</YStack>
|
||||
</YStack>
|
||||
</XStack>
|
||||
</YStack>
|
||||
@@ -605,6 +717,10 @@ const styles = StyleSheet.create({
|
||||
height: '90%',
|
||||
opacity: 0.6,
|
||||
},
|
||||
inactiveWarningContainer: {
|
||||
width: '100%',
|
||||
marginBottom: 16,
|
||||
},
|
||||
});
|
||||
|
||||
export default IdCardLayout;
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface BottomVerifyBarProps {
|
||||
isReadyToProve: boolean;
|
||||
isDocumentExpired: boolean;
|
||||
testID?: string;
|
||||
hasCheckedForInactiveDocument: boolean;
|
||||
}
|
||||
|
||||
export const BottomVerifyBar: React.FC<BottomVerifyBarProps> = ({
|
||||
@@ -28,6 +29,7 @@ export const BottomVerifyBar: React.FC<BottomVerifyBarProps> = ({
|
||||
isReadyToProve,
|
||||
isDocumentExpired,
|
||||
testID = 'bottom-verify-bar',
|
||||
hasCheckedForInactiveDocument,
|
||||
}) => {
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
@@ -46,6 +48,7 @@ export const BottomVerifyBar: React.FC<BottomVerifyBarProps> = ({
|
||||
isScrollable={isScrollable}
|
||||
isReadyToProve={isReadyToProve}
|
||||
isDocumentExpired={isDocumentExpired}
|
||||
hasCheckedForInactiveDocument={hasCheckedForInactiveDocument}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -52,6 +52,7 @@ import type {
|
||||
import {
|
||||
brutforceSignatureAlgorithmDsc,
|
||||
calculateContentHash,
|
||||
inferDocumentCategory,
|
||||
} from '@selfxyz/common/utils';
|
||||
import { parseCertificateSimple } from '@selfxyz/common/utils/certificate_parsing/parseCertificateSimple';
|
||||
import type {
|
||||
@@ -869,6 +870,12 @@ export async function storeDocumentWithDeduplication(
|
||||
// Store new document using contentHash as service name
|
||||
await storeDocumentDirectlyToKeychain(contentHash, passportData);
|
||||
|
||||
const documentCategory =
|
||||
passportData.documentCategory ||
|
||||
inferDocumentCategory(
|
||||
(passportData as PassportData | AadhaarData).documentType,
|
||||
);
|
||||
|
||||
// Add to catalog
|
||||
let dataField: string;
|
||||
if (isMRZDocument(passportData)) {
|
||||
@@ -886,6 +893,8 @@ export async function storeDocumentWithDeduplication(
|
||||
data: dataField,
|
||||
mock: passportData.mock || false,
|
||||
isRegistered: false,
|
||||
hasExpirationDate:
|
||||
documentCategory === 'id_card' || documentCategory === 'passport',
|
||||
...(isKycDocument(passportData)
|
||||
? (() => {
|
||||
try {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import React from 'react';
|
||||
import { ScrollView } from 'react-native';
|
||||
import { Alert, ScrollView } from 'react-native';
|
||||
import { YStack } from 'tamagui';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
|
||||
@@ -13,6 +13,10 @@ import { useSafeBottomPadding } from '@selfxyz/mobile-sdk-alpha/hooks';
|
||||
import BugIcon from '@/assets/icons/bug_icon.svg';
|
||||
import ErrorBoundary from '@/components/ErrorBoundary';
|
||||
import type { RootStackParamList } from '@/navigation';
|
||||
import {
|
||||
loadDocumentCatalogDirectlyFromKeychain,
|
||||
saveDocumentCatalogDirectlyToKeychain,
|
||||
} from '@/providers/passportDataProvider';
|
||||
import { ErrorInjectionSelector } from '@/screens/dev/components/ErrorInjectionSelector';
|
||||
import { LogLevelSelector } from '@/screens/dev/components/LogLevelSelector';
|
||||
import { ParameterSection } from '@/screens/dev/components/ParameterSection';
|
||||
@@ -52,6 +56,32 @@ const DevSettingsScreen: React.FC = () => {
|
||||
handleClearPendingVerificationsPress,
|
||||
} = useDangerZoneActions();
|
||||
|
||||
const handleRemoveExpirationDateFlagPress = () => {
|
||||
Alert.alert(
|
||||
'Remove Expiration Date Flag',
|
||||
'Are you sure you want to remove the expiration date flag for the current (selected) document?.',
|
||||
[
|
||||
{ text: 'Cancel', style: 'cancel' },
|
||||
{
|
||||
text: 'Remove',
|
||||
style: 'destructive',
|
||||
onPress: async () => {
|
||||
const catalog = await loadDocumentCatalogDirectlyFromKeychain();
|
||||
const selectedDocumentId = catalog.selectedDocumentId;
|
||||
const selectedDocument = catalog.documents.find(
|
||||
document => document.id === selectedDocumentId,
|
||||
);
|
||||
|
||||
if (selectedDocument) {
|
||||
delete selectedDocument.hasExpirationDate;
|
||||
|
||||
await saveDocumentCatalogDirectlyToKeychain(catalog);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
);
|
||||
};
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ScrollView showsVerticalScrollIndicator={false}>
|
||||
@@ -109,6 +139,7 @@ const DevSettingsScreen: React.FC = () => {
|
||||
onResetBackupState={handleResetBackupStatePress}
|
||||
onClearBackupEvents={handleClearBackupEventsPress}
|
||||
onClearPendingKyc={handleClearPendingVerificationsPress}
|
||||
onRemoveExpirationDateFlag={handleRemoveExpirationDateFlagPress}
|
||||
/>
|
||||
</YStack>
|
||||
</ScrollView>
|
||||
|
||||
@@ -23,6 +23,7 @@ interface DangerZoneSectionProps {
|
||||
onResetBackupState: () => void;
|
||||
onClearBackupEvents: () => void;
|
||||
onClearPendingKyc: () => void;
|
||||
onRemoveExpirationDateFlag: () => void;
|
||||
}
|
||||
|
||||
export const DangerZoneSection: React.FC<DangerZoneSectionProps> = ({
|
||||
@@ -32,6 +33,7 @@ export const DangerZoneSection: React.FC<DangerZoneSectionProps> = ({
|
||||
onResetBackupState,
|
||||
onClearBackupEvents,
|
||||
onClearPendingKyc,
|
||||
onRemoveExpirationDateFlag,
|
||||
}) => {
|
||||
const dangerActions = [
|
||||
{
|
||||
@@ -64,6 +66,11 @@ export const DangerZoneSection: React.FC<DangerZoneSectionProps> = ({
|
||||
onPress: onClearPendingKyc,
|
||||
dangerTheme: true,
|
||||
},
|
||||
{
|
||||
label: 'Remove expiration date flag',
|
||||
onPress: onRemoveExpirationDateFlag,
|
||||
dangerTheme: true,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
@@ -59,6 +59,7 @@ import {
|
||||
checkDocumentExpiration,
|
||||
getDocumentAttributes,
|
||||
} from '@/utils/documentAttributes';
|
||||
import { isDocumentInactive } from '@/utils/documents';
|
||||
|
||||
const HomeScreen: React.FC = () => {
|
||||
const selfClient = useSelfClient();
|
||||
@@ -80,6 +81,9 @@ const HomeScreen: React.FC = () => {
|
||||
>({});
|
||||
const [loading, setLoading] = useState(true);
|
||||
const hasIncrementedOnFocus = useRef(false);
|
||||
const [isSelectedDocumentInactive, setIsSelectedDocumentInactive] = useState<
|
||||
boolean | null
|
||||
>(null);
|
||||
|
||||
const { pendingVerifications, removeExpiredVerifications } =
|
||||
usePendingKycStore();
|
||||
@@ -126,12 +130,28 @@ const HomeScreen: React.FC = () => {
|
||||
|
||||
const loadDocuments = useCallback(async () => {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
const catalog = await loadDocumentCatalog();
|
||||
const docs = await getAllDocuments();
|
||||
|
||||
setDocumentCatalog(catalog);
|
||||
setAllDocuments(docs);
|
||||
|
||||
if (catalog.selectedDocumentId) {
|
||||
const documentData = docs[catalog.selectedDocumentId];
|
||||
|
||||
if (documentData) {
|
||||
try {
|
||||
setIsSelectedDocumentInactive(
|
||||
isDocumentInactive(documentData.metadata),
|
||||
);
|
||||
} catch (error) {
|
||||
// we don't want to block the home screen from loading
|
||||
console.warn('Failed to check if document is inactive:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to load documents:', error);
|
||||
}
|
||||
@@ -307,6 +327,11 @@ const HomeScreen: React.FC = () => {
|
||||
>
|
||||
<IdCardLayout
|
||||
idDocument={documentData.data}
|
||||
isInactive={
|
||||
isSelected &&
|
||||
isSelectedDocumentInactive === true &&
|
||||
!metadata.mock
|
||||
}
|
||||
selected={isSelected}
|
||||
hidden={true}
|
||||
/>
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
} from '@react-navigation/native';
|
||||
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
|
||||
import type { DocumentMetadata } from '@selfxyz/common';
|
||||
import { isMRZDocument } from '@selfxyz/common';
|
||||
import { loadSelectedDocument, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
|
||||
import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
|
||||
@@ -51,10 +52,12 @@ import {
|
||||
} from '@/services/points';
|
||||
import { useProofHistoryStore } from '@/stores/proofHistoryStore';
|
||||
import { ProofStatus } from '@/stores/proofTypes';
|
||||
import { registerModalCallbacks } from '@/utils';
|
||||
import {
|
||||
checkDocumentExpiration,
|
||||
getDocumentAttributes,
|
||||
} from '@/utils/documentAttributes';
|
||||
import { isDocumentInactive } from '@/utils/documents';
|
||||
import { getDocumentTypeName } from '@/utils/documentUtils';
|
||||
|
||||
const ProveScreen: React.FC = () => {
|
||||
@@ -85,6 +88,9 @@ const ProveScreen: React.FC = () => {
|
||||
const scrollViewRef = useRef<ScrollViewType>(null);
|
||||
const hasInitializedScrollStateRef = useRef(false);
|
||||
|
||||
const [hasCheckedForInactiveDocument, setHasCheckedForInactiveDocument] =
|
||||
useState<boolean>(false);
|
||||
|
||||
const isContentShorterThanScrollView = useMemo(
|
||||
() => scrollViewContentHeight <= scrollViewHeight + 50,
|
||||
[scrollViewContentHeight, scrollViewHeight],
|
||||
@@ -114,8 +120,70 @@ const ProveScreen: React.FC = () => {
|
||||
|
||||
const { addProofHistory } = useProofHistoryStore();
|
||||
const { loadDocumentCatalog } = usePassport();
|
||||
const navigateToDocumentOnboarding = useCallback(
|
||||
(documentMetadata: DocumentMetadata) => {
|
||||
switch (documentMetadata.documentCategory) {
|
||||
case 'passport':
|
||||
case 'id_card':
|
||||
navigate('DocumentOnboarding');
|
||||
break;
|
||||
case 'aadhaar':
|
||||
navigate('AadhaarUpload', { countryCode: 'IND' });
|
||||
break;
|
||||
}
|
||||
},
|
||||
[navigate],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Don't check twice
|
||||
if (hasCheckedForInactiveDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
const checkForInactiveDocument = async () => {
|
||||
const catalog = await loadDocumentCatalog();
|
||||
const selectedDocumentId = catalog.selectedDocumentId;
|
||||
|
||||
for (const documentMetadata of catalog.documents) {
|
||||
if (
|
||||
documentMetadata.id === selectedDocumentId &&
|
||||
isDocumentInactive(documentMetadata)
|
||||
) {
|
||||
const callbackId = registerModalCallbacks({
|
||||
onButtonPress: () => navigateToDocumentOnboarding(documentMetadata),
|
||||
onModalDismiss: () => navigate('Home' as never),
|
||||
});
|
||||
|
||||
navigate('Modal', {
|
||||
titleText: 'Your ID needs to be reactivated to continue',
|
||||
bodyText:
|
||||
'Make sure that you have your document and recovery method ready.',
|
||||
buttonText: 'Continue',
|
||||
secondaryButtonText: 'Not now',
|
||||
callbackId,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setHasCheckedForInactiveDocument(true);
|
||||
};
|
||||
|
||||
checkForInactiveDocument();
|
||||
}, [
|
||||
loadDocumentCatalog,
|
||||
navigateToDocumentOnboarding,
|
||||
navigate,
|
||||
hasCheckedForInactiveDocument,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasCheckedForInactiveDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
const addHistory = async () => {
|
||||
if (provingStore.uuid && selectedApp) {
|
||||
const catalog = await loadDocumentCatalog();
|
||||
@@ -137,9 +205,19 @@ const ProveScreen: React.FC = () => {
|
||||
}
|
||||
};
|
||||
addHistory();
|
||||
}, [addProofHistory, loadDocumentCatalog, provingStore.uuid, selectedApp]);
|
||||
}, [
|
||||
addProofHistory,
|
||||
provingStore.uuid,
|
||||
selectedApp,
|
||||
loadDocumentCatalog,
|
||||
hasCheckedForInactiveDocument,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasCheckedForInactiveDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for actual measurements before determining initial scroll state
|
||||
// Both start at 0, causing false-positive on first render
|
||||
const hasMeasurements = scrollViewContentHeight > 0 && scrollViewHeight > 0;
|
||||
@@ -161,10 +239,11 @@ const ProveScreen: React.FC = () => {
|
||||
isContentShorterThanScrollView,
|
||||
scrollViewContentHeight,
|
||||
scrollViewHeight,
|
||||
hasCheckedForInactiveDocument,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isFocused || !selectedApp) {
|
||||
if (!isFocused || !selectedApp || !hasCheckedForInactiveDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -229,12 +308,21 @@ const ProveScreen: React.FC = () => {
|
||||
//removed provingStore from dependencies because it causes infinite re-render on longpressing the button
|
||||
//as it sets provingStore.setUserConfirmed()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedApp?.sessionId, isFocused, selfClient]);
|
||||
}, [
|
||||
selectedApp?.sessionId,
|
||||
isFocused,
|
||||
selfClient,
|
||||
hasCheckedForInactiveDocument,
|
||||
]);
|
||||
|
||||
// Enhance selfApp with user's points address if not already set
|
||||
useEffect(() => {
|
||||
console.log('useEffect selectedApp', selectedApp);
|
||||
if (!selectedApp || selectedApp.selfDefinedData) {
|
||||
if (
|
||||
!selectedApp ||
|
||||
selectedApp.selfDefinedData ||
|
||||
!hasCheckedForInactiveDocument
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -277,11 +365,11 @@ const ProveScreen: React.FC = () => {
|
||||
};
|
||||
|
||||
enhanceApp();
|
||||
}, [selectedApp, selfClient]);
|
||||
}, [selectedApp, selfClient, hasCheckedForInactiveDocument]);
|
||||
|
||||
function onVerify() {
|
||||
provingStore.setUserConfirmed(selfClient);
|
||||
buttonTap();
|
||||
provingStore.setUserConfirmed(selfClient);
|
||||
trackEvent(ProofEvents.PROOF_VERIFY_CONFIRMATION_ACCEPTED, {
|
||||
appName: selectedApp?.appName,
|
||||
sessionId: provingStore.uuid,
|
||||
@@ -388,6 +476,7 @@ const ProveScreen: React.FC = () => {
|
||||
isReadyToProve={isReadyToProve}
|
||||
isDocumentExpired={isDocumentExpired}
|
||||
testID="prove-screen-verify-bar"
|
||||
hasCheckedForInactiveDocument={hasCheckedForInactiveDocument}
|
||||
/>
|
||||
|
||||
{formattedUserId && selectedApp?.userId && (
|
||||
|
||||
22
app/src/utils/documents.ts
Normal file
22
app/src/utils/documents.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import type { DocumentMetadata } from '@selfxyz/common';
|
||||
|
||||
export const isDocumentInactive = (metadata: DocumentMetadata): boolean => {
|
||||
if (
|
||||
metadata.documentCategory === 'id_card' ||
|
||||
metadata.documentCategory === 'passport' ||
|
||||
metadata.documentCategory === 'kyc'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//for aadhaar migration
|
||||
if (metadata.hasExpirationDate === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
Reference in New Issue
Block a user