From ccb9e148bed40851975348df9216f7f9ac711531 Mon Sep 17 00:00:00 2001 From: Justin Hernandez Date: Fri, 7 Nov 2025 10:26:08 -0800 Subject: [PATCH] App polish for 2.9 rd1 (#1359) * add useSafeBottomPadding * add bottom padding to dev screen * use safe bottom padding * skip uploading if building android bundle locally * fix tests * cache fix script * clean up country picker, fix font color * sort package jsons, add watcher for mobile sdk * formatting * only bump versions for successfull builds * move all css * cleaner script * kill watchers before starting new one --- .gitguardian.yml | 67 +++++++------ .github/workflows/mobile-ci.yml | 2 +- .github/workflows/mobile-deploy.yml | 16 +-- .github/workflows/mobile-sdk-demo-e2e.yml | 3 +- .github/workflows/npm-publish.yml | 2 +- app/Gemfile.lock | 4 +- app/fastlane/Fastfile | 8 ++ app/jest.config.cjs | 2 + app/package.json | 5 +- app/src/screens/dev/DevSettingsScreen.tsx | 4 + .../aadhaar/AadhaarUploadErrorScreen.tsx | 6 +- .../documents/aadhaar/AadhaarUploadScreen.tsx | 10 +- .../aadhaar/AadhaarUploadedSuccessScreen.tsx | 6 +- packages/mobile-sdk-alpha/package.json | 7 +- .../src/documents/useCountries.tsx | 6 +- .../onboarding/confirm-identification.tsx | 17 +--- .../onboarding/country-picker-screen.tsx | 97 +++++++++++-------- .../flows/onboarding/id-selection-screen.tsx | 63 ++++++------ packages/mobile-sdk-alpha/src/hooks/index.ts | 5 + .../src/hooks/useSafeBottomPadding.ts | 33 +++++++ packages/mobile-sdk-alpha/tsup.config.ts | 2 + .../ios/scripts/pod-install-with-cache-fix.sh | 22 +++++ packages/mobile-sdk-demo/package.json | 4 +- sdk/qrcode-angular/ng-package.json | 7 +- 24 files changed, 240 insertions(+), 158 deletions(-) create mode 100644 packages/mobile-sdk-alpha/src/hooks/index.ts create mode 100644 packages/mobile-sdk-alpha/src/hooks/useSafeBottomPadding.ts create mode 100755 packages/mobile-sdk-demo/ios/scripts/pod-install-with-cache-fix.sh diff --git a/.gitguardian.yml b/.gitguardian.yml index dd28311f4..0337ea8db 100644 --- a/.gitguardian.yml +++ b/.gitguardian.yml @@ -52,41 +52,40 @@ secrets-ignore: - "RSA Private Key" # For mock RSA keys - "EC Private Key" # For mock EC keys - secret: ignored_matches: - - match: 2036b4e50ad3042969b290e354d9864465107a14de6f5a36d49f81ea8290def8 - name: prebuilt-ios-arm64-apple-ios.private.swiftinterface + - match: 2036b4e50ad3042969b290e354d9864465107a14de6f5a36d49f81ea8290def8 + name: prebuilt-ios-arm64-apple-ios.private.swiftinterface ignored_paths: - - '**/*.swiftinterface' - - '**/*.xcframework/**' - - '**/packages/mobile-sdk-alpha/ios/Frameworks/**' - - '**/OpenSSL.xcframework/**' - - '**/demo-app/**/mock/**' - - common/src/mock_certificates/aadhaar/mockAadhaarCert.ts - - '**/NFCPassportReader.xcframework/**' - - common/src/utils/passports/genMockIdDoc.ts - - '**/tests/**/*.crt' - - '**/mock_certificates/**/*.crt' - - '**/mock_certificates/**/*.key' - - '**/demo-app/**/test-data/**' - - '**/generated/**/*.key' - - '**/SelfSDK.xcframework/**' - - '**/mock/**/*.crt' - - '**/generated/**/*.crt' - - '**/test/**/*.key' - - '**/mock/**/*.key' - - '**/test/**/*.crt' - - '**/test/**/*.pem' - - '**/constants/mockCertificates.ts' - - '**/mock/**/*.pem' - - '**/mock_certificates/**/*.pem' - - '**/mock-data/**' - - '**/packages/mobile-sdk-alpha/ios/SelfSDK/**' - - '**/tests/**/*.key' - - '**/generated/**/*.pem' - - '**/tests/**/*.pem' - - '**/test-data/**' - - common/src/mock_certificates/** - - '**/*.xcframework' + - "**/*.swiftinterface" + - "**/*.xcframework/**" + - "**/packages/mobile-sdk-alpha/ios/Frameworks/**" + - "**/OpenSSL.xcframework/**" + - "**/demo-app/**/mock/**" + - common/src/mock_certificates/aadhaar/mockAadhaarCert.ts + - "**/NFCPassportReader.xcframework/**" + - common/src/utils/passports/genMockIdDoc.ts + - "**/tests/**/*.crt" + - "**/mock_certificates/**/*.crt" + - "**/mock_certificates/**/*.key" + - "**/demo-app/**/test-data/**" + - "**/generated/**/*.key" + - "**/SelfSDK.xcframework/**" + - "**/mock/**/*.crt" + - "**/generated/**/*.crt" + - "**/test/**/*.key" + - "**/mock/**/*.key" + - "**/test/**/*.crt" + - "**/test/**/*.pem" + - "**/constants/mockCertificates.ts" + - "**/mock/**/*.pem" + - "**/mock_certificates/**/*.pem" + - "**/mock-data/**" + - "**/packages/mobile-sdk-alpha/ios/SelfSDK/**" + - "**/tests/**/*.key" + - "**/generated/**/*.pem" + - "**/tests/**/*.pem" + - "**/test-data/**" + - common/src/mock_certificates/** + - "**/*.xcframework" version: 2 diff --git a/.github/workflows/mobile-ci.yml b/.github/workflows/mobile-ci.yml index 5bc430d83..3c970a563 100644 --- a/.github/workflows/mobile-ci.yml +++ b/.github/workflows/mobile-ci.yml @@ -76,7 +76,7 @@ jobs: with: cache-version: ${{ env.GH_CACHE_VERSION }}-${{ env.NODE_VERSION_SANITIZED }} - name: Build dependencies (cache miss) - # Temporarily disabled due to `yarn types` failures when cache is used. + # Temporarily disabled due to `yarn types` failures when cache is used. # if: steps.built-deps.outputs.cache-hit != 'true' run: | echo "Cache miss for built dependencies. Building now..." diff --git a/.github/workflows/mobile-deploy.yml b/.github/workflows/mobile-deploy.yml index 2b079aa38..25ca53707 100644 --- a/.github/workflows/mobile-deploy.yml +++ b/.github/workflows/mobile-deploy.yml @@ -1276,17 +1276,21 @@ jobs: const version = JSON.parse(fs.readFileSync('version.json', 'utf8')); const timestamp = new Date().toISOString(); - version.ios.build = $IOS_BUILD; - version.android.build = $ANDROID_BUILD; - - // Update lastDeployed timestamp for successful builds + // Only bump build numbers for successful builds if ('$IOS_SUCCESS' === 'success') { + version.ios.build = $IOS_BUILD; version.ios.lastDeployed = timestamp; - console.log('✅ Updated iOS lastDeployed timestamp'); + console.log('✅ Updated iOS build number to $IOS_BUILD and lastDeployed timestamp'); + } else { + console.log('⏭️ Skipped iOS build number bump (build did not succeed)'); } + if ('$ANDROID_SUCCESS' === 'success') { + version.android.build = $ANDROID_BUILD; version.android.lastDeployed = timestamp; - console.log('✅ Updated Android lastDeployed timestamp'); + console.log('✅ Updated Android build number to $ANDROID_BUILD and lastDeployed timestamp'); + } else { + console.log('⏭️ Skipped Android build number bump (build did not succeed)'); } fs.writeFileSync('version.json', JSON.stringify(version, null, 2) + '\n'); diff --git a/.github/workflows/mobile-sdk-demo-e2e.yml b/.github/workflows/mobile-sdk-demo-e2e.yml index 17add2f24..2d7b6e8ed 100644 --- a/.github/workflows/mobile-sdk-demo-e2e.yml +++ b/.github/workflows/mobile-sdk-demo-e2e.yml @@ -319,7 +319,8 @@ jobs: echo "::add-mask::${SELFXYZ_INTERNAL_REPO_PAT}" fi cd packages/mobile-sdk-demo/ios - pod install + echo "📦 Installing pods via cache-fix script…" + bash scripts/pod-install-with-cache-fix.sh env: SELFXYZ_INTERNAL_REPO_PAT: ${{ secrets.SELFXYZ_INTERNAL_REPO_PAT }} GIT_TERMINAL_PROMPT: 0 diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index ff4a11545..03b28b776 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -8,7 +8,7 @@ on: - "sdk/core/package.json" - "sdk/qrcode/package.json" - "common/package.json" - - 'packages/mobile-sdk-alpha/package.json' + - "packages/mobile-sdk-alpha/package.json" - "sdk/qrcode-angular/package.json" - "contracts/package.json" workflow_dispatch: diff --git a/app/Gemfile.lock b/app/Gemfile.lock index 833e563d2..2af770c21 100644 --- a/app/Gemfile.lock +++ b/app/Gemfile.lock @@ -25,7 +25,7 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.4.0) - aws-partitions (1.1179.0) + aws-partitions (1.1181.0) aws-sdk-core (3.236.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) @@ -37,7 +37,7 @@ GEM aws-sdk-kms (1.116.0) aws-sdk-core (~> 3, >= 3.234.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.202.0) + aws-sdk-s3 (1.203.0) aws-sdk-core (~> 3, >= 3.234.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) diff --git a/app/fastlane/Fastfile b/app/fastlane/Fastfile index 7cb68f582..3101b9ee4 100644 --- a/app/fastlane/Fastfile +++ b/app/fastlane/Fastfile @@ -306,6 +306,14 @@ platform :android do skip_upload = options[:skip_upload] == true || options[:skip_upload] == "true" version_bump = options[:version_bump] || "build" + # Automatically skip uploads in local development (no local permissions for Play Store) + # Uploads must be done by CI/CD machines with proper authentication + if local_development && !skip_upload + skip_upload = true + UI.important("🏠 LOCAL DEVELOPMENT: Automatically skipping Play Store upload") + UI.important(" Uploads require CI/CD machine permissions and will be handled automatically") + end + if local_development if ENV["ANDROID_KEYSTORE_PATH"].nil? ENV["ANDROID_KEYSTORE_PATH"] = Fastlane::Helpers.android_create_keystore(android_keystore_path) diff --git a/app/jest.config.cjs b/app/jest.config.cjs index cb8ec6def..0d4c48181 100644 --- a/app/jest.config.cjs +++ b/app/jest.config.cjs @@ -30,6 +30,8 @@ module.exports = { '/../packages/mobile-sdk-alpha/dist/cjs/index.cjs', '^@selfxyz/mobile-sdk-alpha/components$': '/../packages/mobile-sdk-alpha/dist/cjs/components/index.cjs', + '^@selfxyz/mobile-sdk-alpha/hooks$': + '/../packages/mobile-sdk-alpha/dist/cjs/hooks/index.cjs', '^@selfxyz/mobile-sdk-alpha/onboarding/(.*)$': '/../packages/mobile-sdk-alpha/dist/cjs/flows/onboarding/$1.cjs', '^@selfxyz/mobile-sdk-alpha/disclosing/(.*)$': diff --git a/app/package.json b/app/package.json index 2f4ad6fd6..79b29b10a 100644 --- a/app/package.json +++ b/app/package.json @@ -50,8 +50,8 @@ "release:patch": "./scripts/release.sh patch", "setup": "yarn clean:build && yarn install && yarn build:deps && yarn setup:android-deps && cd ios && bundle install && bundle exec pod install --repo-update && cd .. && yarn clean:xcode-env-local", "setup:android-deps": "node scripts/setup-private-modules.cjs", - "start": "watchman watch-del-all && react-native start", - "start:clean": "watchman watch-del-all && cd android && ./gradlew clean && cd .. && react-native start --reset-cache", + "start": "watchman watch-del-all && yarn watch:sdk & react-native start", + "start:clean": "watchman watch-del-all && cd android && ./gradlew clean && cd .. && yarn watch:sdk & react-native start --reset-cache", "sync-versions": "bundle exec fastlane ios sync_version && bundle exec fastlane android sync_version", "tag:release": "node scripts/tag.cjs release", "tag:remove": "node scripts/tag.cjs remove", @@ -66,6 +66,7 @@ "test:tree-shaking": "node ./scripts/test-tree-shaking.cjs", "test:web-build": "jest tests/web-build-render.test.ts --testTimeout=180000", "types": "tsc --noEmit", + "watch:sdk": "yarn workspace @selfxyz/mobile-sdk-alpha watch", "web": "vite", "web:build": "yarn build:deps && vite build", "web:preview": "vite preview" diff --git a/app/src/screens/dev/DevSettingsScreen.tsx b/app/src/screens/dev/DevSettingsScreen.tsx index e9d080abb..afae0cd38 100644 --- a/app/src/screens/dev/DevSettingsScreen.tsx +++ b/app/src/screens/dev/DevSettingsScreen.tsx @@ -17,6 +17,8 @@ import { useNavigation } from '@react-navigation/native'; import type { NativeStackScreenProps } from '@react-navigation/native-stack'; import { Check, ChevronDown, ChevronRight } from '@tamagui/lucide-icons'; +import { useSafeBottomPadding } from '@selfxyz/mobile-sdk-alpha/hooks'; + import BugIcon from '@/images/icons/bug_icon.svg'; import IdIcon from '@/images/icons/id_icon.svg'; import WarningIcon from '@/images/icons/warning.svg'; @@ -295,6 +297,7 @@ const DevSettingsScreen: React.FC = ({}) => { const subscribedTopics = useSettingStore(state => state.subscribedTopics); const [hasNotificationPermission, setHasNotificationPermission] = useState(false); + const paddingBottom = useSafeBottomPadding(20); // Check notification permissions on mount useEffect(() => { @@ -466,6 +469,7 @@ const DevSettingsScreen: React.FC = ({}) => { flex={1} paddingHorizontal="$4" paddingTop="$4" + paddingBottom={paddingBottom} > } diff --git a/app/src/screens/documents/aadhaar/AadhaarUploadErrorScreen.tsx b/app/src/screens/documents/aadhaar/AadhaarUploadErrorScreen.tsx index dd73ce08d..dec7a71e0 100644 --- a/app/src/screens/documents/aadhaar/AadhaarUploadErrorScreen.tsx +++ b/app/src/screens/documents/aadhaar/AadhaarUploadErrorScreen.tsx @@ -14,10 +14,10 @@ import { SecondaryButton, } from '@selfxyz/mobile-sdk-alpha/components'; import { AadhaarEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics'; +import { useSafeBottomPadding } from '@selfxyz/mobile-sdk-alpha/hooks'; import { getErrorMessages } from '@selfxyz/mobile-sdk-alpha/onboarding/import-aadhaar'; import WarningIcon from '@/images/warning.svg'; -import { useSafeAreaInsets } from '@/mocks/react-native-safe-area-context'; import { black, slate100, slate200, slate500, white } from '@/utils/colors'; import { extraYPadding } from '@/utils/constants'; @@ -31,7 +31,7 @@ type AadhaarUploadErrorRoute = RouteProp< >; const AadhaarUploadErrorScreen: React.FC = () => { - const { bottom } = useSafeAreaInsets(); + const paddingBottom = useSafeBottomPadding(extraYPadding + 35); const navigation = useNavigation(); const route = useRoute(); const { trackEvent } = useSelfClient(); @@ -78,7 +78,7 @@ const AadhaarUploadErrorScreen: React.FC = () => { diff --git a/app/src/screens/documents/aadhaar/AadhaarUploadScreen.tsx b/app/src/screens/documents/aadhaar/AadhaarUploadScreen.tsx index 55705a51e..19f6273ea 100644 --- a/app/src/screens/documents/aadhaar/AadhaarUploadScreen.tsx +++ b/app/src/screens/documents/aadhaar/AadhaarUploadScreen.tsx @@ -12,11 +12,11 @@ import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useSelfClient } from '@selfxyz/mobile-sdk-alpha'; import { BodyText, PrimaryButton } from '@selfxyz/mobile-sdk-alpha/components'; import { AadhaarEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics'; +import { useSafeBottomPadding } from '@selfxyz/mobile-sdk-alpha/hooks'; import { useAadhaar } from '@selfxyz/mobile-sdk-alpha/onboarding/import-aadhaar'; import { useModal } from '@/hooks/useModal'; import AadhaarImage from '@/images/512w.png'; -import { useSafeAreaInsets } from '@/mocks/react-native-safe-area-context'; import type { RootStackParamList } from '@/navigation'; import { slate100, slate200, slate400, slate500, white } from '@/utils/colors'; import { extraYPadding } from '@/utils/constants'; @@ -26,7 +26,7 @@ import { } from '@/utils/qrScanner'; const AadhaarUploadScreen: React.FC = () => { - const { bottom } = useSafeAreaInsets(); + const paddingBottom = useSafeBottomPadding(extraYPadding + 50); const navigation = useNavigation>(); @@ -140,11 +140,7 @@ const AadhaarUploadScreen: React.FC = () => { ]); return ( - + { - const { bottom } = useSafeAreaInsets(); + const paddingBottom = useSafeBottomPadding(extraYPadding + 35); const navigation = useNavigation>(); const { trackEvent } = useSelfClient(); @@ -62,7 +62,7 @@ const AadhaarUploadedSuccessScreen: React.FC = () => { /dev/null || true && tsup && yarn postbuild && tsup --watch" }, "dependencies": { "@babel/runtime": "^7.28.3", diff --git a/packages/mobile-sdk-alpha/src/documents/useCountries.tsx b/packages/mobile-sdk-alpha/src/documents/useCountries.tsx index ab5381f29..f8adae9e2 100644 --- a/packages/mobile-sdk-alpha/src/documents/useCountries.tsx +++ b/packages/mobile-sdk-alpha/src/documents/useCountries.tsx @@ -45,9 +45,9 @@ export function useCountries() { if (result.status === 'success') { setCountryData(result.data); - if (__DEV__) { - console.log('Set country data:', result.data); - } + // if (__DEV__) { + // console.log('Set country data:', result.data); + // } } else { console.error('API returned non-success status:', result.status); } diff --git a/packages/mobile-sdk-alpha/src/flows/onboarding/confirm-identification.tsx b/packages/mobile-sdk-alpha/src/flows/onboarding/confirm-identification.tsx index e553ae06c..4562dd017 100644 --- a/packages/mobile-sdk-alpha/src/flows/onboarding/confirm-identification.tsx +++ b/packages/mobile-sdk-alpha/src/flows/onboarding/confirm-identification.tsx @@ -2,8 +2,8 @@ // SPDX-License-Identifier: BUSL-1.1 // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. -import { useCallback, useEffect, useMemo } from 'react'; -import { Dimensions, StyleSheet } from 'react-native'; +import { useCallback, useEffect } from 'react'; +import { StyleSheet } from 'react-native'; import type { DocumentCategory } from '@selfxyz/common/utils/types'; @@ -17,6 +17,7 @@ import { black, white } from '../../constants/colors'; import { useSelfClient } from '../../context'; import { loadSelectedDocument } from '../../documents/utils'; import { notificationSuccess } from '../../haptic'; +import { useSafeBottomPadding } from '../../hooks/useSafeBottomPadding'; import { ExpandableBottomLayout } from '../../layouts/ExpandableBottomLayout'; import { SdkEvents } from '../../types/events'; import type { SelfClient } from '../../types/public'; @@ -38,17 +39,7 @@ export const ConfirmIdentificationScreen = ({ onBeforeConfirm }: { onBeforeConfi await onConfirm(selfClient); }, [onBeforeConfirm, selfClient]); - // Calculate total bottom padding: base padding + fallback for smaller screens - const paddingBottom = useMemo(() => { - const basePadding = 20; - - // Estimate for smaller screens to account for safe areas - const windowHeight = Dimensions.get('window').height; - const isSmallScreen = windowHeight < 900; - const fallbackPadding = isSmallScreen ? 50 : 0; - - return basePadding + fallbackPadding; - }, []); + const paddingBottom = useSafeBottomPadding(20); return ( diff --git a/packages/mobile-sdk-alpha/src/flows/onboarding/country-picker-screen.tsx b/packages/mobile-sdk-alpha/src/flows/onboarding/country-picker-screen.tsx index ecfc230d8..83f1bef80 100644 --- a/packages/mobile-sdk-alpha/src/flows/onboarding/country-picker-screen.tsx +++ b/packages/mobile-sdk-alpha/src/flows/onboarding/country-picker-screen.tsx @@ -3,7 +3,7 @@ // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. import { memo, useCallback } from 'react'; -import { ActivityIndicator, FlatList, TouchableOpacity, View } from 'react-native'; +import { ActivityIndicator, FlatList, StyleSheet, TouchableOpacity, View } from 'react-native'; import { commonNames } from '@selfxyz/common/constants/countries'; @@ -32,15 +32,10 @@ const CountryItem = memo<{ if (!countryName) return null; return ( - onSelect(countryCode)} - style={{ - paddingVertical: 13, - }} - > - + onSelect(countryCode)} style={styles.countryItemContainer}> + - {countryName} + {countryName} ); @@ -49,7 +44,7 @@ const CountryItem = memo<{ CountryItem.displayName = 'CountryItem'; const Loading = () => ( - + ); @@ -63,11 +58,11 @@ const CountryPickerScreen: React.FC = () => { const onPressCountry = useCallback( (countryCode: string) => { buttonTap(); - if (__DEV__) { - console.log('Selected country code:', countryCode); - console.log('Current countryData:', countryData); - console.log('Available country codes:', Object.keys(countryData)); - } + // if (__DEV__) { + // console.log('Selected country code:', countryCode); + // console.log('Current countryData:', countryData); + // console.log('Available country codes:', Object.keys(countryData)); + // } const documentTypes = countryData[countryCode]; if (__DEV__) { console.log('documentTypes for', countryCode, ':', documentTypes); @@ -111,8 +106,8 @@ const CountryPickerScreen: React.FC = () => { return ( - Select the country that issued your ID - + Select the country that issued your ID + Self has support for over 300 ID types. You can select the type of ID in the next step @@ -122,32 +117,12 @@ const CountryPickerScreen: React.FC = () => { {showSuggestion && ( - - SUGGESTION - + SUGGESTION - - SELECT AN ISSUING COUNTRY - + SELECT AN ISSUING COUNTRY )} { }; CountryPickerScreen.displayName = 'CountryPickerScreen'; +const styles = StyleSheet.create({ + countryItemContainer: { + paddingVertical: 13, + }, + countryItemContent: { + alignItems: 'center', + gap: 16, + }, + countryItemText: { + fontSize: 16, + color: black, + flex: 1, + }, + loadingContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + titleText: { + fontSize: 29, + fontFamily: advercase, + color: black, + }, + subtitleText: { + fontSize: 16, + color: slate500, + marginTop: 20, + }, + sectionLabel: { + fontSize: 16, + color: black, + fontFamily: dinot, + letterSpacing: 0.8, + marginBottom: 8, + }, + sectionLabelBottom: { + fontSize: 16, + color: black, + fontFamily: dinot, + letterSpacing: 0.8, + marginTop: 20, + }, +}); + export default CountryPickerScreen; diff --git a/packages/mobile-sdk-alpha/src/flows/onboarding/id-selection-screen.tsx b/packages/mobile-sdk-alpha/src/flows/onboarding/id-selection-screen.tsx index e66eda5e1..3610fc911 100644 --- a/packages/mobile-sdk-alpha/src/flows/onboarding/id-selection-screen.tsx +++ b/packages/mobile-sdk-alpha/src/flows/onboarding/id-selection-screen.tsx @@ -3,6 +3,7 @@ // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. import type React from 'react'; +import { StyleSheet } from 'react-native'; import AadhaarLogo from '../../../svgs/icons/aadhaar.svg'; import EPassportLogoRounded from '../../../svgs/icons/epassport_rounded.svg'; @@ -105,16 +106,7 @@ const IDSelectionScreen: React.FC = props => { - - Select an ID type - + Select an ID type {documentTypes.map((docType: string) => ( @@ -135,35 +127,42 @@ const IDSelectionScreen: React.FC = props => { {getDocumentLogo(docType)} - - {getDocumentName(docType)} - - - {getDocumentDescription(docType)} - + {getDocumentName(docType)} + {getDocumentDescription(docType)} ))} - - Be sure your document is ready to scan - + Be sure your document is ready to scan ); }; +const styles = StyleSheet.create({ + titleText: { + marginTop: 48, + fontSize: 29, + fontFamily: advercase, + textAlign: 'center', + color: black, + }, + documentNameText: { + fontSize: 24, + fontFamily: dinot, + color: black, + }, + documentDescriptionText: { + fontSize: 14, + fontFamily: dinot, + color: slate400, + }, + footerText: { + fontSize: 18, + fontFamily: dinot, + color: slate400, + textAlign: 'center', + }, +}); + export default IDSelectionScreen; diff --git a/packages/mobile-sdk-alpha/src/hooks/index.ts b/packages/mobile-sdk-alpha/src/hooks/index.ts new file mode 100644 index 000000000..e81b2b0b2 --- /dev/null +++ b/packages/mobile-sdk-alpha/src/hooks/index.ts @@ -0,0 +1,5 @@ +// 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. + +export { useSafeBottomPadding } from './useSafeBottomPadding'; diff --git a/packages/mobile-sdk-alpha/src/hooks/useSafeBottomPadding.ts b/packages/mobile-sdk-alpha/src/hooks/useSafeBottomPadding.ts new file mode 100644 index 000000000..a537152e3 --- /dev/null +++ b/packages/mobile-sdk-alpha/src/hooks/useSafeBottomPadding.ts @@ -0,0 +1,33 @@ +// 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 { useMemo } from 'react'; +import { Dimensions } from 'react-native'; + +/** + * Custom hook to calculate bottom padding that prevents UI elements from bleeding + * into the system navigation area on smaller screens. + * + * This hook uses screen height detection to add extra padding for smaller screens + * (< 900px height) to account for system navigation bars and safe areas. + * + * @param basePadding - Base padding to add (default: 20) + * @returns Total bottom padding value + * + * @example + * ```tsx + * // For use with ExpandableBottomLayout.BottomSection + * const bottomPadding = useSafeBottomPadding(20); + * + * ``` + */ +export const useSafeBottomPadding = (basePadding: number = 20): number => { + const { height: windowHeight } = Dimensions.get('window'); + + return useMemo(() => { + const isSmallScreen = windowHeight < 900; + const fallbackPadding = isSmallScreen ? 50 : 0; + return basePadding + fallbackPadding; + }, [windowHeight, basePadding]); +}; diff --git a/packages/mobile-sdk-alpha/tsup.config.ts b/packages/mobile-sdk-alpha/tsup.config.ts index 36696c6cd..92d759510 100644 --- a/packages/mobile-sdk-alpha/tsup.config.ts +++ b/packages/mobile-sdk-alpha/tsup.config.ts @@ -40,6 +40,8 @@ const entry = { 'constants/analytics': 'src/constants/analytics.ts', 'constants/colors': 'src/constants/colors.ts', 'components/index': 'src/components/index.ts', + 'hooks/index': 'src/hooks/index.ts', + 'hooks/useSafeBottomPadding': 'src/hooks/useSafeBottomPadding.ts', stores: 'src/stores/index.ts', ...flowEntries, }; diff --git a/packages/mobile-sdk-demo/ios/scripts/pod-install-with-cache-fix.sh b/packages/mobile-sdk-demo/ios/scripts/pod-install-with-cache-fix.sh new file mode 100755 index 000000000..bf53eb847 --- /dev/null +++ b/packages/mobile-sdk-demo/ios/scripts/pod-install-with-cache-fix.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Pod install with hermes-engine cache fix for React Native upgrades +# This script handles CocoaPods cache mismatches that occur after React Native version upgrades + +set -e # Exit on any error + +echo "🧹 Clearing CocoaPods cache to prevent hermes-engine version conflicts..." +pod cache clean --all > /dev/null 2>&1 || true +rm -rf ~/Library/Caches/CocoaPods > /dev/null 2>&1 || true + +echo "📦 Attempting pod install..." +if pod install; then + echo "✅ Pods installed successfully" +else + echo "⚠️ Pod install failed, likely due to hermes-engine cache mismatch after React Native upgrade" + echo "🔧 Running targeted fix: pod update hermes-engine..." + pod update hermes-engine --no-repo-update + echo "🔄 Retrying pod install..." + pod install + echo "✅ Pods installed successfully after cache fix" +fi diff --git a/packages/mobile-sdk-demo/package.json b/packages/mobile-sdk-demo/package.json index dd0fd7e4e..5450494ea 100644 --- a/packages/mobile-sdk-demo/package.json +++ b/packages/mobile-sdk-demo/package.json @@ -23,9 +23,9 @@ "reinstall": "yarn clean && yarn install && yarn prebuild && cd ios && pod install && cd ..", "start": "react-native start", "test": "vitest run", + "test:e2e:android": "bash scripts/e2e-android-ci.sh", "test:watch": "vitest", - "types": "yarn prebuild && tsc --noEmit", - "test:e2e:android": "bash scripts/e2e-android-ci.sh" + "types": "yarn prebuild && tsc --noEmit" }, "dependencies": { "@babel/runtime": "^7.28.3", diff --git a/sdk/qrcode-angular/ng-package.json b/sdk/qrcode-angular/ng-package.json index 67b1b7fa1..346c2d33d 100644 --- a/sdk/qrcode-angular/ng-package.json +++ b/sdk/qrcode-angular/ng-package.json @@ -11,10 +11,5 @@ "output": "animations" } ], - "allowedNonPeerDependencies": [ - "angularx-qrcode", - "lottie-web", - "socket.io-client", - "uuid" - ] + "allowedNonPeerDependencies": ["angularx-qrcode", "lottie-web", "socket.io-client", "uuid"] }