From 5321f3757b9b489443e7b16e3ba38c2679acc24d Mon Sep 17 00:00:00 2001 From: Justin Hernandez Date: Tue, 16 Dec 2025 14:12:30 -0800 Subject: [PATCH] SELF-1670: Hide document-only settings without documents (#1512) * Hide document-only settings without documents * revert document info screen changes, rely on hiding option from settings view * agent feedback * hide settings options that depend on having a document --- app/README.md | 2 +- .../account/settings/SettingsScreen.tsx | 48 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/app/README.md b/app/README.md index 9ec0dca8f..e6e8c6cc8 100644 --- a/app/README.md +++ b/app/README.md @@ -1,4 +1,4 @@ -# OpenPassport App +# Self.xyz Mobile App ## Requirements diff --git a/app/src/screens/account/settings/SettingsScreen.tsx b/app/src/screens/account/settings/SettingsScreen.tsx index ab415fa97..b8e76452d 100644 --- a/app/src/screens/account/settings/SettingsScreen.tsx +++ b/app/src/screens/account/settings/SettingsScreen.tsx @@ -3,14 +3,14 @@ // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. import type { PropsWithChildren } from 'react'; -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { Linking, Platform, Share, View as RNView } from 'react-native'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import { getCountry, getLocales, getTimeZone } from 'react-native-localize'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import type { SvgProps } from 'react-native-svg'; import { Button, ScrollView, View, XStack, YStack } from 'tamagui'; -import { useNavigation } from '@react-navigation/native'; +import { useFocusEffect, useNavigation } from '@react-navigation/native'; import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { Bug, FileText } from '@tamagui/lucide-icons'; @@ -44,6 +44,7 @@ import { xUrl, } from '@/consts/links'; import { impactLight } from '@/integrations/haptics'; +import { usePassport } from '@/providers/passportDataProvider'; import { useSettingStore } from '@/stores/settingStore'; import { extraYPadding } from '@/utils/styleUtils'; @@ -103,6 +104,12 @@ const DEBUG_MENU: [React.FC, string, RouteOption][] = [ [Bug as React.FC, 'Debug menu', 'DevSettings'], ]; +const DOCUMENT_DEPENDENT_ROUTES: RouteOption[] = [ + 'CloudBackupSettings', + 'DocumentDataInfo', + 'ShowRecoveryPhrase', +]; + const social = [ [X, xUrl], [Github, gitHubUrl], @@ -152,10 +159,43 @@ const SettingsScreen: React.FC = () => { const { isDevMode, setDevModeOn } = useSettingStore(); const navigation = useNavigation>(); + const { loadDocumentCatalog } = usePassport(); + const [hasRealDocument, setHasRealDocument] = useState(null); + + const refreshDocumentAvailability = useCallback(async () => { + try { + const catalog = await loadDocumentCatalog(); + if (!catalog?.documents || !Array.isArray(catalog.documents)) { + console.warn('SettingsScreen: invalid catalog structure'); + setHasRealDocument(false); + return; + } + setHasRealDocument(catalog.documents.some(doc => !doc.mock)); + } catch { + console.warn('SettingsScreen: failed to load document catalog'); + setHasRealDocument(false); + } + }, [loadDocumentCatalog]); + + useFocusEffect( + useCallback(() => { + refreshDocumentAvailability(); + }, [refreshDocumentAvailability]), + ); const screenRoutes = useMemo(() => { - return isDevMode ? [...routes, ...DEBUG_MENU] : routes; - }, [isDevMode]); + const baseRoutes = isDevMode ? [...routes, ...DEBUG_MENU] : routes; + + // Show all routes while loading or if user has a real document + if (hasRealDocument === null || hasRealDocument === true) { + return baseRoutes; + } + + // Only filter out document-related routes if we've confirmed user has no real documents + return baseRoutes.filter( + ([, , route]) => !DOCUMENT_DEPENDENT_ROUTES.includes(route), + ); + }, [hasRealDocument, isDevMode]); const devModeTap = Gesture.Tap() .numberOfTaps(5)