mirror of
https://github.com/selfxyz/self.git
synced 2026-01-07 22:04:03 -05:00
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
This commit is contained in:
@@ -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
|
||||
|
||||
2
.github/workflows/mobile-ci.yml
vendored
2
.github/workflows/mobile-ci.yml
vendored
@@ -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..."
|
||||
|
||||
16
.github/workflows/mobile-deploy.yml
vendored
16
.github/workflows/mobile-deploy.yml
vendored
@@ -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');
|
||||
|
||||
3
.github/workflows/mobile-sdk-demo-e2e.yml
vendored
3
.github/workflows/mobile-sdk-demo-e2e.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/npm-publish.yml
vendored
2
.github/workflows/npm-publish.yml
vendored
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -30,6 +30,8 @@ module.exports = {
|
||||
'<rootDir>/../packages/mobile-sdk-alpha/dist/cjs/index.cjs',
|
||||
'^@selfxyz/mobile-sdk-alpha/components$':
|
||||
'<rootDir>/../packages/mobile-sdk-alpha/dist/cjs/components/index.cjs',
|
||||
'^@selfxyz/mobile-sdk-alpha/hooks$':
|
||||
'<rootDir>/../packages/mobile-sdk-alpha/dist/cjs/hooks/index.cjs',
|
||||
'^@selfxyz/mobile-sdk-alpha/onboarding/(.*)$':
|
||||
'<rootDir>/../packages/mobile-sdk-alpha/dist/cjs/flows/onboarding/$1.cjs',
|
||||
'^@selfxyz/mobile-sdk-alpha/disclosing/(.*)$':
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<DevSettingsScreenProps> = ({}) => {
|
||||
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<DevSettingsScreenProps> = ({}) => {
|
||||
flex={1}
|
||||
paddingHorizontal="$4"
|
||||
paddingTop="$4"
|
||||
paddingBottom={paddingBottom}
|
||||
>
|
||||
<ParameterSection
|
||||
icon={<IdIcon />}
|
||||
|
||||
@@ -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<AadhaarUploadErrorRoute>();
|
||||
const { trackEvent } = useSelfClient();
|
||||
@@ -78,7 +78,7 @@ const AadhaarUploadErrorScreen: React.FC = () => {
|
||||
<YStack
|
||||
paddingHorizontal={25}
|
||||
backgroundColor={white}
|
||||
paddingBottom={bottom + extraYPadding + 35}
|
||||
paddingBottom={paddingBottom}
|
||||
paddingTop={25}
|
||||
>
|
||||
<XStack gap="$3" alignItems="stretch">
|
||||
|
||||
@@ -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<NativeStackNavigationProp<RootStackParamList>>();
|
||||
@@ -140,11 +140,7 @@ const AadhaarUploadScreen: React.FC = () => {
|
||||
]);
|
||||
|
||||
return (
|
||||
<YStack
|
||||
flex={1}
|
||||
backgroundColor={slate100}
|
||||
paddingBottom={bottom + extraYPadding + 50}
|
||||
>
|
||||
<YStack flex={1} backgroundColor={slate100} paddingBottom={paddingBottom}>
|
||||
<YStack flex={1} paddingHorizontal={20} paddingTop={20}>
|
||||
<YStack
|
||||
flex={1}
|
||||
|
||||
@@ -10,15 +10,15 @@ 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 BlueCheckIcon from '@/images/blue_check.svg';
|
||||
import { useSafeAreaInsets } from '@/mocks/react-native-safe-area-context';
|
||||
import type { RootStackParamList } from '@/navigation';
|
||||
import { black, slate100, slate200, slate500, white } from '@/utils/colors';
|
||||
import { extraYPadding } from '@/utils/constants';
|
||||
|
||||
const AadhaarUploadedSuccessScreen: React.FC = () => {
|
||||
const { bottom } = useSafeAreaInsets();
|
||||
const paddingBottom = useSafeBottomPadding(extraYPadding + 35);
|
||||
const navigation =
|
||||
useNavigation<NativeStackNavigationProp<RootStackParamList>>();
|
||||
const { trackEvent } = useSelfClient();
|
||||
@@ -62,7 +62,7 @@ const AadhaarUploadedSuccessScreen: React.FC = () => {
|
||||
<YStack
|
||||
paddingHorizontal={25}
|
||||
backgroundColor={white}
|
||||
paddingBottom={bottom + extraYPadding + 35}
|
||||
paddingBottom={paddingBottom}
|
||||
paddingTop={25}
|
||||
>
|
||||
<PrimaryButton
|
||||
|
||||
@@ -110,10 +110,10 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "yarn build:android && yarn build:ios && tsup && yarn postbuild",
|
||||
"build:ts-only": "tsup && yarn postbuild",
|
||||
"postbuild": "node ./scripts/postBuild.mjs",
|
||||
"build:android": "sh ./scripts/build-android.sh",
|
||||
"build:ios": "sh ./scripts/build-ios.sh",
|
||||
"postbuild": "node ./scripts/postBuild.mjs",
|
||||
"build:ts-only": "tsup && yarn postbuild",
|
||||
"fmt": "prettier --check .",
|
||||
"fmt:fix": "prettier --write .",
|
||||
"format": "sh -c 'if [ -z \"$SKIP_BUILD_DEPS\" ]; then yarn nice; else yarn fmt:fix; fi'",
|
||||
@@ -127,7 +127,8 @@
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||
"types": "tsc -p tsconfig.json --noEmit",
|
||||
"validate:exports": "node ./scripts/validate-exports.mjs",
|
||||
"validate:pkg": "node ./scripts/verify-conditions.mjs"
|
||||
"validate:pkg": "node ./scripts/verify-conditions.mjs",
|
||||
"watch": "pkill -f 'tsup.*--watch' 2>/dev/null || true && tsup && yarn postbuild && tsup --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.3",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<ExpandableBottomLayout.Layout backgroundColor={black}>
|
||||
|
||||
@@ -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 (
|
||||
<TouchableOpacity
|
||||
onPress={() => onSelect(countryCode)}
|
||||
style={{
|
||||
paddingVertical: 13,
|
||||
}}
|
||||
>
|
||||
<XStack alignItems="center" gap={16}>
|
||||
<TouchableOpacity onPress={() => onSelect(countryCode)} style={styles.countryItemContainer}>
|
||||
<XStack style={styles.countryItemContent}>
|
||||
<RoundFlag countryCode={countryCode} size={FLAG_SIZE} />
|
||||
<BodyText style={{ fontSize: 16, color: black, flex: 1 }}>{countryName}</BodyText>
|
||||
<BodyText style={styles.countryItemText}>{countryName}</BodyText>
|
||||
</XStack>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
@@ -49,7 +44,7 @@ const CountryItem = memo<{
|
||||
CountryItem.displayName = 'CountryItem';
|
||||
|
||||
const Loading = () => (
|
||||
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="small" />
|
||||
</View>
|
||||
);
|
||||
@@ -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 (
|
||||
<YStack flex={1} paddingTop="$4" paddingHorizontal="$4" backgroundColor={slate100}>
|
||||
<YStack marginTop="$4" marginBottom="$6">
|
||||
<BodyText style={{ fontSize: 29, fontFamily: advercase }}>Select the country that issued your ID</BodyText>
|
||||
<BodyText style={{ fontSize: 16, color: slate500, marginTop: 20 }}>
|
||||
<BodyText style={styles.titleText}>Select the country that issued your ID</BodyText>
|
||||
<BodyText style={styles.subtitleText}>
|
||||
Self has support for over 300 ID types. You can select the type of ID in the next step
|
||||
</BodyText>
|
||||
</YStack>
|
||||
@@ -122,32 +117,12 @@ const CountryPickerScreen: React.FC = () => {
|
||||
<YStack flex={1}>
|
||||
{showSuggestion && (
|
||||
<YStack marginBottom="$2">
|
||||
<BodyText
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color: black,
|
||||
fontFamily: dinot,
|
||||
letterSpacing: 0.8,
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
SUGGESTION
|
||||
</BodyText>
|
||||
<BodyText style={styles.sectionLabel}>SUGGESTION</BodyText>
|
||||
<CountryItem
|
||||
countryCode={userCountryCode as string /*safe due to showSuggestion*/}
|
||||
onSelect={onPressCountry}
|
||||
/>
|
||||
<BodyText
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color: black,
|
||||
fontFamily: dinot,
|
||||
letterSpacing: 0.8,
|
||||
marginTop: 20,
|
||||
}}
|
||||
>
|
||||
SELECT AN ISSUING COUNTRY
|
||||
</BodyText>
|
||||
<BodyText style={styles.sectionLabelBottom}>SELECT AN ISSUING COUNTRY</BodyText>
|
||||
</YStack>
|
||||
)}
|
||||
<FlatList
|
||||
@@ -169,4 +144,48 @@ const CountryPickerScreen: React.FC = () => {
|
||||
};
|
||||
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;
|
||||
|
||||
@@ -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<IDSelectionScreenProps> = props => {
|
||||
<SelfLogo width={24} height={24} />
|
||||
</YStack>
|
||||
</XStack>
|
||||
<BodyText
|
||||
style={{
|
||||
marginTop: 48,
|
||||
fontSize: 29,
|
||||
fontFamily: advercase,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
Select an ID type
|
||||
</BodyText>
|
||||
<BodyText style={styles.titleText}>Select an ID type</BodyText>
|
||||
</YStack>
|
||||
<YStack gap="$3">
|
||||
{documentTypes.map((docType: string) => (
|
||||
@@ -135,35 +127,42 @@ const IDSelectionScreen: React.FC<IDSelectionScreenProps> = props => {
|
||||
<XStack alignItems="center" gap={'$3'} flex={1}>
|
||||
{getDocumentLogo(docType)}
|
||||
<YStack gap={'$1'}>
|
||||
<BodyText style={{ fontSize: 24, fontFamily: dinot, color: black }}>
|
||||
{getDocumentName(docType)}
|
||||
</BodyText>
|
||||
<BodyText
|
||||
style={{
|
||||
fontSize: 14,
|
||||
fontFamily: dinot,
|
||||
color: slate400,
|
||||
}}
|
||||
>
|
||||
{getDocumentDescription(docType)}
|
||||
</BodyText>
|
||||
<BodyText style={styles.documentNameText}>{getDocumentName(docType)}</BodyText>
|
||||
<BodyText style={styles.documentDescriptionText}>{getDocumentDescription(docType)}</BodyText>
|
||||
</YStack>
|
||||
</XStack>
|
||||
</XStack>
|
||||
))}
|
||||
<BodyText
|
||||
style={{
|
||||
fontSize: 18,
|
||||
fontFamily: dinot,
|
||||
color: slate400,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
Be sure your document is ready to scan
|
||||
</BodyText>
|
||||
<BodyText style={styles.footerText}>Be sure your document is ready to scan</BodyText>
|
||||
</YStack>
|
||||
</YStack>
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
5
packages/mobile-sdk-alpha/src/hooks/index.ts
Normal file
5
packages/mobile-sdk-alpha/src/hooks/index.ts
Normal file
@@ -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';
|
||||
33
packages/mobile-sdk-alpha/src/hooks/useSafeBottomPadding.ts
Normal file
33
packages/mobile-sdk-alpha/src/hooks/useSafeBottomPadding.ts
Normal file
@@ -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);
|
||||
* <ExpandableBottomLayout.BottomSection paddingBottom={bottomPadding} />
|
||||
* ```
|
||||
*/
|
||||
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]);
|
||||
};
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
22
packages/mobile-sdk-demo/ios/scripts/pod-install-with-cache-fix.sh
Executable file
22
packages/mobile-sdk-demo/ios/scripts/pod-install-with-cache-fix.sh
Executable file
@@ -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
|
||||
@@ -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",
|
||||
|
||||
@@ -11,10 +11,5 @@
|
||||
"output": "animations"
|
||||
}
|
||||
],
|
||||
"allowedNonPeerDependencies": [
|
||||
"angularx-qrcode",
|
||||
"lottie-web",
|
||||
"socket.io-client",
|
||||
"uuid"
|
||||
]
|
||||
"allowedNonPeerDependencies": ["angularx-qrcode", "lottie-web", "socket.io-client", "uuid"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user