mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
[SEL-154] Step 1: Scan your passport (#511)
* simplify navigation logic * use aesop design hook * save wip * add new aesop redesign screens * save wip design * refactor nav bar logic * fix paths * save wip * stub progress navbar and save wip * save wip progress bar animation * save wip progress bar, almost done with design * fix progress bar design * fix bottom padding * disable git commit for now * fix flaky android downloads that causes pipeline to crash * update lock for ci
This commit is contained in:
@@ -30,6 +30,8 @@ buildscript {
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url "https://jitpack.io" }
|
||||
jcenter()
|
||||
}
|
||||
configurations.configureEach {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#Mon Feb 03 16:12:34 CET 2025
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
|
||||
networkTimeout=10000
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
networkTimeout=600000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
SEGMENT_KEY=
|
||||
SENTRY_DSN=
|
||||
IS_TEST_BUILD=
|
||||
|
||||
@@ -1,379 +0,0 @@
|
||||
import React from 'react';
|
||||
import { StatusBar } from 'react-native';
|
||||
import 'react-native-gesture-handler';
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||
|
||||
import {
|
||||
StaticParamList,
|
||||
createNavigationContainerRef,
|
||||
createStaticNavigation,
|
||||
} from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
|
||||
import DefaultNavBar from './components/DefaultNavBar';
|
||||
import HomeNavBar from './components/HomeNavBar';
|
||||
import AppLayout from './layouts/AppLayout';
|
||||
import AccountRecoveryChoiceScreen from './screens/AccountFlow/AccountRecoveryChoiceScreen';
|
||||
import AccountRecoveryScreen from './screens/AccountFlow/AccountRecoveryScreen';
|
||||
import AccountVerifiedSuccessScreen from './screens/AccountFlow/AccountVerifiedSuccessScreen';
|
||||
import RecoverWithPhraseScreen from './screens/AccountFlow/RecoverWithPhraseScreen';
|
||||
import SaveRecoveryPhraseScreen from './screens/AccountFlow/SaveRecoveryPhraseScreen';
|
||||
import DisclaimerScreen from './screens/DisclaimerScreen';
|
||||
import HomeScreen from './screens/HomeScreen';
|
||||
import LaunchScreen from './screens/LaunchScreen';
|
||||
import MockDataScreen from './screens/MockDataScreen';
|
||||
import ConfirmBelongingScreen from './screens/Onboarding/ConfirmBelongingScreen';
|
||||
import LoadingScreen from './screens/Onboarding/LoadingScreen';
|
||||
import PassportCameraScreen from './screens/Onboarding/PassportCameraScreen';
|
||||
import PassportCameraTrouble from './screens/Onboarding/PassportCameraTrouble';
|
||||
import PassportDataNotFound from './screens/Onboarding/PassportDataNotFound';
|
||||
import PassportNFCScanScreen from './screens/Onboarding/PassportNFCScanScreen';
|
||||
import PassportNFCTrouble from './screens/Onboarding/PassportNFCTrouble';
|
||||
import PassportOnboardingScreen from './screens/Onboarding/PassportOnboardingScreen';
|
||||
import UnsupportedPassportScreen from './screens/Onboarding/UnsupportedPassport';
|
||||
import ProofRequestStatusScreen from './screens/ProveFlow/ProofRequestStatusScreen';
|
||||
import ProveScreen from './screens/ProveFlow/ProveScreen';
|
||||
import QRCodeTroubleScreen from './screens/ProveFlow/QRCodeTrouble';
|
||||
import QRCodeViewFinderScreen from './screens/ProveFlow/ViewFinder';
|
||||
import CloudBackupScreen from './screens/Settings/CloudBackupScreen';
|
||||
import DevSettingsScreen from './screens/Settings/DevSettingsScreen';
|
||||
import ModalScreen from './screens/Settings/ModalScreen';
|
||||
import PassportDataInfoScreen from './screens/Settings/PassportDataInfoScreen';
|
||||
import ShowRecoveryPhraseScreen from './screens/Settings/ShowRecoveryPhraseScreen';
|
||||
import SettingsScreen from './screens/SettingsScreen';
|
||||
import SplashScreen from './screens/SplashScreen';
|
||||
import { useApp } from './stores/appProvider';
|
||||
import { useProofInfo } from './stores/proofProvider';
|
||||
import analytics from './utils/analytics';
|
||||
import { black, slate300, white } from './utils/colors';
|
||||
import { setupUniversalLinkListenerInNavigation } from './utils/qrCodeNew';
|
||||
|
||||
const AppNavigation = createNativeStackNavigator({
|
||||
initialRouteName: 'Splash',
|
||||
orientation: 'portrait_up',
|
||||
screenOptions: {
|
||||
header: DefaultNavBar,
|
||||
navigationBarColor: white,
|
||||
},
|
||||
layout: AppLayout,
|
||||
screens: {
|
||||
/**
|
||||
* STATIC SCREENS
|
||||
*/
|
||||
Splash: {
|
||||
screen: SplashScreen,
|
||||
options: {
|
||||
header: () => (
|
||||
<StatusBar barStyle="light-content" backgroundColor={black} />
|
||||
),
|
||||
navigationBarColor: black,
|
||||
},
|
||||
},
|
||||
Launch: {
|
||||
screen: LaunchScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
gestureEnabled: false,
|
||||
},
|
||||
},
|
||||
Modal: {
|
||||
screen: ModalScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
presentation: 'transparentModal',
|
||||
animation: 'fade',
|
||||
},
|
||||
},
|
||||
/**
|
||||
* SCAN PASSPORT FLOW
|
||||
*/
|
||||
PassportOnboarding: {
|
||||
screen: PassportOnboardingScreen,
|
||||
options: {
|
||||
animation: 'slide_from_bottom',
|
||||
// presentation: 'modal' wanted to do this but seems to break stuff
|
||||
headerShown: false,
|
||||
},
|
||||
},
|
||||
PassportCameraTrouble: {
|
||||
screen: PassportCameraTrouble,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
presentation: 'modal',
|
||||
},
|
||||
},
|
||||
PassportNFCTrouble: {
|
||||
screen: PassportNFCTrouble,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
presentation: 'modal',
|
||||
},
|
||||
},
|
||||
PassportCamera: {
|
||||
screen: PassportCameraScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
},
|
||||
},
|
||||
PassportNFCScan: {
|
||||
screen: PassportNFCScanScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
},
|
||||
initialParams: {
|
||||
passportNumber: '',
|
||||
dateOfBirth: '',
|
||||
dateOfExpiry: '',
|
||||
},
|
||||
},
|
||||
ConfirmBelongingScreen: {
|
||||
screen: ConfirmBelongingScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
},
|
||||
},
|
||||
UnsupportedPassport: {
|
||||
screen: UnsupportedPassportScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
},
|
||||
},
|
||||
LoadingScreen: {
|
||||
screen: LoadingScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
navigationBarColor: black,
|
||||
},
|
||||
},
|
||||
CreateMock: {
|
||||
screen: MockDataScreen,
|
||||
options: {
|
||||
title: 'Mock Passport',
|
||||
},
|
||||
},
|
||||
/**
|
||||
* HOME SECTION
|
||||
*/
|
||||
Home: {
|
||||
screen: HomeScreen,
|
||||
options: {
|
||||
title: 'Self',
|
||||
header: HomeNavBar,
|
||||
navigationBarColor: black,
|
||||
presentation: 'card',
|
||||
},
|
||||
},
|
||||
Disclaimer: {
|
||||
screen: DisclaimerScreen,
|
||||
options: {
|
||||
title: 'Disclaimer',
|
||||
headerShown: false,
|
||||
},
|
||||
},
|
||||
/**
|
||||
* QR CODE SCANNING + PROVE FLOW
|
||||
*/
|
||||
QRCodeViewFinder: {
|
||||
screen: QRCodeViewFinderScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
// presentation: 'modal',
|
||||
},
|
||||
},
|
||||
QRCodeTrouble: {
|
||||
screen: QRCodeTroubleScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
presentation: 'modal',
|
||||
},
|
||||
},
|
||||
PassportDataNotFound: {
|
||||
screen: PassportDataNotFound,
|
||||
options: {
|
||||
headerShown: false,
|
||||
gestureEnabled: false,
|
||||
animation: 'slide_from_bottom',
|
||||
// presentation: 'modal',
|
||||
},
|
||||
},
|
||||
ProveScreen: {
|
||||
screen: ProveScreen,
|
||||
options: {
|
||||
title: 'Request Proof',
|
||||
headerStyle: {
|
||||
backgroundColor: black,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: white,
|
||||
},
|
||||
},
|
||||
},
|
||||
ProofRequestStatusScreen: {
|
||||
screen: ProofRequestStatusScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
},
|
||||
},
|
||||
/**
|
||||
* CREATE OR RECOVER ACCOUNT
|
||||
*/
|
||||
AccountRecovery: {
|
||||
screen: AccountRecoveryScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
},
|
||||
},
|
||||
AccountRecoveryChoice: {
|
||||
screen: AccountRecoveryChoiceScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
},
|
||||
},
|
||||
SaveRecoveryPhrase: {
|
||||
screen: SaveRecoveryPhraseScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
},
|
||||
},
|
||||
RecoverWithPhrase: {
|
||||
screen: RecoverWithPhraseScreen,
|
||||
options: {
|
||||
headerTintColor: black,
|
||||
title: 'Enter Recovery Phrase',
|
||||
headerStyle: {
|
||||
backgroundColor: black,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: slate300,
|
||||
},
|
||||
headerBackTitle: 'close',
|
||||
},
|
||||
},
|
||||
AccountVerifiedSuccess: {
|
||||
screen: AccountVerifiedSuccessScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
},
|
||||
},
|
||||
/**
|
||||
* SETTINGS
|
||||
*/
|
||||
Settings: {
|
||||
screen: SettingsScreen,
|
||||
options: {
|
||||
animation: 'slide_from_bottom',
|
||||
title: 'Settings',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: black,
|
||||
},
|
||||
navigationBarColor: black,
|
||||
},
|
||||
config: {
|
||||
screens: {},
|
||||
},
|
||||
},
|
||||
ShowRecoveryPhrase: {
|
||||
screen: ShowRecoveryPhraseScreen,
|
||||
options: {
|
||||
title: 'Recovery Phrase',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
},
|
||||
},
|
||||
PassportDataInfo: {
|
||||
screen: PassportDataInfoScreen,
|
||||
options: {
|
||||
title: 'Passport Data Info',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
},
|
||||
},
|
||||
DevSettings: {
|
||||
screen: DevSettingsScreen,
|
||||
options: {
|
||||
title: 'Developer Settings',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
},
|
||||
},
|
||||
CloudBackupSettings: {
|
||||
screen: CloudBackupScreen,
|
||||
options: {
|
||||
title: 'Cloud backup',
|
||||
headerStyle: {
|
||||
backgroundColor: black,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: slate300,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export type RootStackParamList = StaticParamList<typeof AppNavigation>;
|
||||
|
||||
declare global {
|
||||
namespace ReactNavigation {
|
||||
interface RootParamList extends RootStackParamList {}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a ref that we can use to access the navigation state
|
||||
export const navigationRef = createNavigationContainerRef();
|
||||
|
||||
const { trackScreenView } = analytics();
|
||||
|
||||
const Navigation = createStaticNavigation(AppNavigation);
|
||||
const NavigationWithTracking = () => {
|
||||
const trackScreen = () => {
|
||||
const currentRoute = navigationRef.getCurrentRoute();
|
||||
if (currentRoute) {
|
||||
console.log(`Screen View: ${currentRoute.name}`);
|
||||
trackScreenView(`${currentRoute.name}`, {
|
||||
screenName: currentRoute.name,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Add these hooks to get access to the necessary functions
|
||||
const { setSelectedApp, cleanSelfApp } = useProofInfo();
|
||||
const { startAppListener } = useApp();
|
||||
|
||||
// Setup universal link handling at the navigation level
|
||||
React.useEffect(() => {
|
||||
const cleanup = setupUniversalLinkListenerInNavigation(
|
||||
navigationRef,
|
||||
setSelectedApp,
|
||||
cleanSelfApp,
|
||||
startAppListener,
|
||||
);
|
||||
|
||||
return () => {
|
||||
cleanup();
|
||||
};
|
||||
}, [setSelectedApp, cleanSelfApp, startAppListener]);
|
||||
|
||||
return (
|
||||
<GestureHandlerRootView>
|
||||
<Navigation ref={navigationRef} onStateChange={trackScreen} />
|
||||
</GestureHandlerRootView>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavigationWithTracking;
|
||||
27
app/src/Navigation/account.ts
Normal file
27
app/src/Navigation/account.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
||||
|
||||
import { HomeNavBar } from '../components/NavBar';
|
||||
import DisclaimerScreen from '../screens/DisclaimerScreen';
|
||||
import HomeScreen from '../screens/HomeScreen';
|
||||
import { black } from '../utils/colors';
|
||||
|
||||
const accountScreens = {
|
||||
Home: {
|
||||
screen: HomeScreen,
|
||||
options: {
|
||||
title: 'Self',
|
||||
header: HomeNavBar,
|
||||
navigationBarColor: black,
|
||||
presentation: 'card',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
Disclaimer: {
|
||||
screen: DisclaimerScreen,
|
||||
options: {
|
||||
title: 'Disclaimer',
|
||||
headerShown: false,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default accountScreens;
|
||||
67
app/src/Navigation/aesop.ts
Normal file
67
app/src/Navigation/aesop.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
||||
|
||||
import { ProgressNavBar } from '../components/NavBar';
|
||||
import { shouldShowAesopRedesign } from '../hooks/useAesopRedesign';
|
||||
import PassportOnboardingScreen from '../screens/_Aesop/PassportOnboardingScreen';
|
||||
import { white } from '../utils/colors';
|
||||
|
||||
const aesopScreens = {
|
||||
PassportOnboarding: {
|
||||
screen: PassportOnboardingScreen,
|
||||
options: {
|
||||
animation: 'slide_from_bottom',
|
||||
header: ProgressNavBar,
|
||||
title: 'Scan your passport',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
headerCurrentStep: 1,
|
||||
headerTotalSteps: 4,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
|
||||
// stub the rest of the steps. will update in future pr
|
||||
PassportCamera: {
|
||||
screen: PassportOnboardingScreen,
|
||||
options: {
|
||||
animation: 'slide_from_bottom',
|
||||
header: ProgressNavBar,
|
||||
title: 'Take a photo',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
headerCurrentStep: 2,
|
||||
headerTotalSteps: 4,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
|
||||
PassportNFC: {
|
||||
screen: PassportOnboardingScreen,
|
||||
options: {
|
||||
animation: 'slide_from_bottom',
|
||||
header: ProgressNavBar,
|
||||
title: 'Scan NFC',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
headerCurrentStep: 3,
|
||||
headerTotalSteps: 4,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
|
||||
PassportComplete: {
|
||||
screen: PassportOnboardingScreen,
|
||||
options: {
|
||||
animation: 'slide_from_bottom',
|
||||
header: ProgressNavBar,
|
||||
title: 'Complete',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
headerCurrentStep: 4,
|
||||
headerTotalSteps: 4,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default shouldShowAesopRedesign() ? aesopScreens : {};
|
||||
27
app/src/Navigation/home.ts
Normal file
27
app/src/Navigation/home.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
||||
|
||||
import HomeNavBar from '../components/NavBar/HomeNavBar';
|
||||
import DisclaimerScreen from '../screens/DisclaimerScreen';
|
||||
import HomeScreen from '../screens/HomeScreen';
|
||||
import { black } from '../utils/colors';
|
||||
|
||||
const homeScreens = {
|
||||
Home: {
|
||||
screen: HomeScreen,
|
||||
options: {
|
||||
title: 'Self',
|
||||
header: HomeNavBar,
|
||||
navigationBarColor: black,
|
||||
presentation: 'card',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
Disclaimer: {
|
||||
screen: DisclaimerScreen,
|
||||
options: {
|
||||
title: 'Disclaimer',
|
||||
headerShown: false,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default homeScreens;
|
||||
96
app/src/Navigation/index.tsx
Normal file
96
app/src/Navigation/index.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import React from 'react';
|
||||
import 'react-native-gesture-handler';
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||
|
||||
import {
|
||||
StaticParamList,
|
||||
createNavigationContainerRef,
|
||||
createStaticNavigation,
|
||||
} from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
|
||||
import { DefaultNavBar } from '../components/NavBar';
|
||||
import AppLayout from '../layouts/AppLayout';
|
||||
import { useApp } from '../stores/appProvider';
|
||||
import { useProofInfo } from '../stores/proofProvider';
|
||||
import analytics from '../utils/analytics';
|
||||
import { white } from '../utils/colors';
|
||||
import { setupUniversalLinkListenerInNavigation } from '../utils/qrCodeNew';
|
||||
import accountScreens from './account';
|
||||
import aesopScreens from './aesop';
|
||||
import homeScreens from './home';
|
||||
import passportScreens from './passport';
|
||||
import proveScreens from './prove';
|
||||
import settingsScreens from './settings';
|
||||
import staticScreens from './static';
|
||||
|
||||
const AppNavigation = createNativeStackNavigator({
|
||||
initialRouteName: 'Splash',
|
||||
orientation: 'portrait_up',
|
||||
screenOptions: {
|
||||
header: DefaultNavBar,
|
||||
navigationBarColor: white,
|
||||
},
|
||||
layout: AppLayout,
|
||||
screens: {
|
||||
...staticScreens,
|
||||
...passportScreens,
|
||||
...homeScreens,
|
||||
...proveScreens,
|
||||
...accountScreens,
|
||||
...settingsScreens,
|
||||
...aesopScreens,
|
||||
},
|
||||
});
|
||||
|
||||
export type RootStackParamList = StaticParamList<typeof AppNavigation>;
|
||||
|
||||
declare global {
|
||||
namespace ReactNavigation {
|
||||
interface RootParamList extends RootStackParamList {}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a ref that we can use to access the navigation state
|
||||
export const navigationRef = createNavigationContainerRef();
|
||||
|
||||
const { trackScreenView } = analytics();
|
||||
|
||||
const Navigation = createStaticNavigation(AppNavigation);
|
||||
const NavigationWithTracking = () => {
|
||||
const trackScreen = () => {
|
||||
const currentRoute = navigationRef.getCurrentRoute();
|
||||
if (currentRoute) {
|
||||
console.log(`Screen View: ${currentRoute.name}`);
|
||||
trackScreenView(`${currentRoute.name}`, {
|
||||
screenName: currentRoute.name,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Add these hooks to get access to the necessary functions
|
||||
const { setSelectedApp, cleanSelfApp } = useProofInfo();
|
||||
const { startAppListener } = useApp();
|
||||
|
||||
// Setup universal link handling at the navigation level
|
||||
React.useEffect(() => {
|
||||
const cleanup = setupUniversalLinkListenerInNavigation(
|
||||
navigationRef,
|
||||
setSelectedApp,
|
||||
cleanSelfApp,
|
||||
startAppListener,
|
||||
);
|
||||
|
||||
return () => {
|
||||
cleanup();
|
||||
};
|
||||
}, [setSelectedApp, cleanSelfApp, startAppListener]);
|
||||
|
||||
return (
|
||||
<GestureHandlerRootView>
|
||||
<Navigation ref={navigationRef} onStateChange={trackScreen} />
|
||||
</GestureHandlerRootView>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavigationWithTracking;
|
||||
85
app/src/Navigation/passport.ts
Normal file
85
app/src/Navigation/passport.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
||||
|
||||
import MockDataScreen from '../screens/MockDataScreen';
|
||||
import ConfirmBelongingScreen from '../screens/Onboarding/ConfirmBelongingScreen';
|
||||
import LoadingScreen from '../screens/Onboarding/LoadingScreen';
|
||||
import PassportCameraScreen from '../screens/Onboarding/PassportCameraScreen';
|
||||
import PassportCameraTrouble from '../screens/Onboarding/PassportCameraTrouble';
|
||||
import PassportNFCScanScreen from '../screens/Onboarding/PassportNFCScanScreen';
|
||||
import PassportNFCTrouble from '../screens/Onboarding/PassportNFCTrouble';
|
||||
import PassportOnboardingScreen from '../screens/Onboarding/PassportOnboardingScreen';
|
||||
import UnsupportedPassportScreen from '../screens/Onboarding/UnsupportedPassport';
|
||||
import { black } from '../utils/colors';
|
||||
|
||||
const passportScreens = {
|
||||
PassportOnboarding: {
|
||||
screen: PassportOnboardingScreen,
|
||||
options: {
|
||||
animation: 'slide_from_bottom',
|
||||
// presentation: 'modal' wanted to do this but seems to break stuff
|
||||
headerShown: false,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
PassportCameraTrouble: {
|
||||
screen: PassportCameraTrouble,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
presentation: 'modal',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
PassportNFCTrouble: {
|
||||
screen: PassportNFCTrouble,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
presentation: 'modal',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
PassportCamera: {
|
||||
screen: PassportCameraScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
PassportNFCScan: {
|
||||
screen: PassportNFCScanScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
} as NativeStackNavigationOptions,
|
||||
initialParams: {
|
||||
passportNumber: '',
|
||||
dateOfBirth: '',
|
||||
dateOfExpiry: '',
|
||||
},
|
||||
},
|
||||
ConfirmBelongingScreen: {
|
||||
screen: ConfirmBelongingScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
UnsupportedPassport: {
|
||||
screen: UnsupportedPassportScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
LoadingScreen: {
|
||||
screen: LoadingScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
navigationBarColor: black,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
CreateMock: {
|
||||
screen: MockDataScreen,
|
||||
options: {
|
||||
title: 'Mock Passport',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default passportScreens;
|
||||
57
app/src/Navigation/prove.ts
Normal file
57
app/src/Navigation/prove.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
||||
|
||||
import PassportDataNotFound from '../screens/Onboarding/PassportDataNotFound';
|
||||
import ProofRequestStatusScreen from '../screens/ProveFlow/ProofRequestStatusScreen';
|
||||
import ProveScreen from '../screens/ProveFlow/ProveScreen';
|
||||
import QRCodeTroubleScreen from '../screens/ProveFlow/QRCodeTrouble';
|
||||
import QRCodeViewFinderScreen from '../screens/ProveFlow/ViewFinder';
|
||||
import { black, white } from '../utils/colors';
|
||||
|
||||
const proveScreens = {
|
||||
QRCodeViewFinder: {
|
||||
screen: QRCodeViewFinderScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
// presentation: 'modal',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
QRCodeTrouble: {
|
||||
screen: QRCodeTroubleScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
presentation: 'modal',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
PassportDataNotFound: {
|
||||
screen: PassportDataNotFound,
|
||||
options: {
|
||||
headerShown: false,
|
||||
gestureEnabled: false,
|
||||
animation: 'slide_from_bottom',
|
||||
// presentation: 'modal',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
ProveScreen: {
|
||||
screen: ProveScreen,
|
||||
options: {
|
||||
title: 'Request Proof',
|
||||
headerStyle: {
|
||||
backgroundColor: black,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: white,
|
||||
},
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
ProofRequestStatusScreen: {
|
||||
screen: ProofRequestStatusScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default proveScreens;
|
||||
53
app/src/Navigation/recovery.ts
Normal file
53
app/src/Navigation/recovery.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
||||
|
||||
import AccountRecoveryChoiceScreen from '../screens/AccountFlow/AccountRecoveryChoiceScreen';
|
||||
import AccountRecoveryScreen from '../screens/AccountFlow/AccountRecoveryScreen';
|
||||
import AccountVerifiedSuccessScreen from '../screens/AccountFlow/AccountVerifiedSuccessScreen';
|
||||
import RecoverWithPhraseScreen from '../screens/AccountFlow/RecoverWithPhraseScreen';
|
||||
import SaveRecoveryPhraseScreen from '../screens/AccountFlow/SaveRecoveryPhraseScreen';
|
||||
import { black, slate300 } from '../utils/colors';
|
||||
|
||||
const recoveryScreens = {
|
||||
AccountRecovery: {
|
||||
screen: AccountRecoveryScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
AccountRecoveryChoice: {
|
||||
screen: AccountRecoveryChoiceScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
SaveRecoveryPhrase: {
|
||||
screen: SaveRecoveryPhraseScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
RecoverWithPhrase: {
|
||||
screen: RecoverWithPhraseScreen,
|
||||
options: {
|
||||
headerTintColor: black,
|
||||
title: 'Enter Recovery Phrase',
|
||||
headerStyle: {
|
||||
backgroundColor: black,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: slate300,
|
||||
},
|
||||
headerBackTitle: 'close',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
AccountVerifiedSuccess: {
|
||||
screen: AccountVerifiedSuccessScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
animation: 'slide_from_bottom',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default recoveryScreens;
|
||||
69
app/src/Navigation/settings.ts
Normal file
69
app/src/Navigation/settings.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
||||
|
||||
import CloudBackupScreen from '../screens/Settings/CloudBackupScreen';
|
||||
import DevSettingsScreen from '../screens/Settings/DevSettingsScreen';
|
||||
import PassportDataInfoScreen from '../screens/Settings/PassportDataInfoScreen';
|
||||
import ShowRecoveryPhraseScreen from '../screens/Settings/ShowRecoveryPhraseScreen';
|
||||
import SettingsScreen from '../screens/SettingsScreen';
|
||||
import { black, slate300, white } from '../utils/colors';
|
||||
|
||||
const settingsScreens = {
|
||||
Settings: {
|
||||
screen: SettingsScreen,
|
||||
options: {
|
||||
animation: 'slide_from_bottom',
|
||||
title: 'Settings',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: black,
|
||||
},
|
||||
navigationBarColor: black,
|
||||
} as NativeStackNavigationOptions,
|
||||
config: {
|
||||
screens: {},
|
||||
},
|
||||
},
|
||||
ShowRecoveryPhrase: {
|
||||
screen: ShowRecoveryPhraseScreen,
|
||||
options: {
|
||||
title: 'Recovery Phrase',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
PassportDataInfo: {
|
||||
screen: PassportDataInfoScreen,
|
||||
options: {
|
||||
title: 'Passport Data Info',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
DevSettings: {
|
||||
screen: DevSettingsScreen,
|
||||
options: {
|
||||
title: 'Developer Settings',
|
||||
headerStyle: {
|
||||
backgroundColor: white,
|
||||
},
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
CloudBackupSettings: {
|
||||
screen: CloudBackupScreen,
|
||||
options: {
|
||||
title: 'Cloud backup',
|
||||
headerStyle: {
|
||||
backgroundColor: black,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: slate300,
|
||||
},
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default settingsScreens;
|
||||
38
app/src/Navigation/static.tsx
Normal file
38
app/src/Navigation/static.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import { StatusBar } from 'react-native';
|
||||
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
||||
|
||||
import LaunchScreen from '../screens/LaunchScreen';
|
||||
import ModalScreen from '../screens/Settings/ModalScreen';
|
||||
import SplashScreen from '../screens/SplashScreen';
|
||||
import { black } from '../utils/colors';
|
||||
|
||||
const staticScreens = {
|
||||
Splash: {
|
||||
screen: SplashScreen,
|
||||
options: {
|
||||
header: () => (
|
||||
<StatusBar barStyle="light-content" backgroundColor={black} />
|
||||
),
|
||||
navigationBarColor: black,
|
||||
},
|
||||
},
|
||||
Launch: {
|
||||
screen: LaunchScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
gestureEnabled: false,
|
||||
},
|
||||
},
|
||||
Modal: {
|
||||
screen: ModalScreen,
|
||||
options: {
|
||||
headerShown: false,
|
||||
presentation: 'transparentModal',
|
||||
animation: 'fade',
|
||||
} as NativeStackNavigationOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default staticScreens;
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
|
||||
import { shouldShowAesopRedesign } from '../hooks/useAesopRedesign';
|
||||
|
||||
interface ButtonsContainerProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
@@ -14,7 +16,7 @@ export default ButtonsContainer;
|
||||
const styles = StyleSheet.create({
|
||||
buttonsContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexDirection: shouldShowAesopRedesign() ? 'row' : 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: 10,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
XStackProps,
|
||||
} from 'tamagui';
|
||||
|
||||
import { Title } from './typography/Title';
|
||||
import { Title } from '../typography/Title';
|
||||
|
||||
interface NavBarProps extends XStackProps {
|
||||
children: React.ReactNode;
|
||||
@@ -4,11 +4,11 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { NativeStackHeaderProps } from '@react-navigation/native-stack';
|
||||
import { TextStyle, ViewStyle } from 'tamagui';
|
||||
|
||||
import { white } from '../utils/colors';
|
||||
import { buttonTap } from '../utils/haptic';
|
||||
import { NavBar } from './NavBar';
|
||||
import { white } from '../../utils/colors';
|
||||
import { buttonTap } from '../../utils/haptic';
|
||||
import { NavBar } from './BaseNavBar';
|
||||
|
||||
const DefaultNavBar = (props: NativeStackHeaderProps) => {
|
||||
export const DefaultNavBar = (props: NativeStackHeaderProps) => {
|
||||
const { goBack, canGoBack } = props.navigation;
|
||||
const { options } = props;
|
||||
const headerStyle = (options.headerStyle || {}) as ViewStyle;
|
||||
@@ -43,5 +43,3 @@ const DefaultNavBar = (props: NativeStackHeaderProps) => {
|
||||
</NavBar.Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default DefaultNavBar;
|
||||
@@ -4,13 +4,13 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { NativeStackHeaderProps } from '@react-navigation/native-stack';
|
||||
import { Button } from 'tamagui';
|
||||
|
||||
import ActivityIcon from '../images/icons/activity.svg';
|
||||
import SettingsIcon from '../images/icons/settings.svg';
|
||||
import { black, neutral400, white } from '../utils/colors';
|
||||
import { buttonTap } from '../utils/haptic';
|
||||
import { NavBar } from './NavBar';
|
||||
import ActivityIcon from '../../images/icons/activity.svg';
|
||||
import SettingsIcon from '../../images/icons/settings.svg';
|
||||
import { black, neutral400, white } from '../../utils/colors';
|
||||
import { buttonTap } from '../../utils/haptic';
|
||||
import { NavBar } from './BaseNavBar';
|
||||
|
||||
const HomeNavBar = (props: NativeStackHeaderProps) => {
|
||||
export const HomeNavBar = (props: NativeStackHeaderProps) => {
|
||||
const insets = useSafeAreaInsets();
|
||||
return (
|
||||
<NavBar.Container
|
||||
@@ -61,5 +61,3 @@ const HomeNavBar = (props: NativeStackHeaderProps) => {
|
||||
</NavBar.Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default HomeNavBar;
|
||||
109
app/src/components/NavBar/ProgressNavBar.tsx
Normal file
109
app/src/components/NavBar/ProgressNavBar.tsx
Normal file
@@ -0,0 +1,109 @@
|
||||
import React from 'react';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
import {
|
||||
NativeStackHeaderProps,
|
||||
NativeStackNavigationOptions,
|
||||
} from '@react-navigation/native-stack';
|
||||
import { TextStyle, ViewStyle, XStack, YStack } from 'tamagui';
|
||||
|
||||
import { cyan300, slate200, white } from '../../utils/colors';
|
||||
import { buttonTap } from '../../utils/haptic';
|
||||
import { NavBar } from './BaseNavBar';
|
||||
|
||||
interface ProgressNavBarProps extends NativeStackHeaderProps {
|
||||
currentStep?: number;
|
||||
totalSteps?: number;
|
||||
}
|
||||
|
||||
interface ProgressNavigationOptions extends NativeStackNavigationOptions {
|
||||
headerCurrentStep?: number;
|
||||
headerTotalSteps?: number;
|
||||
}
|
||||
|
||||
export const ProgressNavBar = (props: NativeStackHeaderProps) => {
|
||||
const { goBack, canGoBack } = props.navigation;
|
||||
const { options } = props;
|
||||
const headerStyle = (options.headerStyle || {}) as ViewStyle;
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
const progressOptions = options as ProgressNavigationOptions;
|
||||
|
||||
const currentStep =
|
||||
progressOptions.headerCurrentStep ||
|
||||
(props as ProgressNavBarProps).currentStep ||
|
||||
1;
|
||||
|
||||
const totalSteps =
|
||||
progressOptions.headerTotalSteps ||
|
||||
(props as ProgressNavBarProps).totalSteps ||
|
||||
1;
|
||||
|
||||
const segments = Array.from({ length: totalSteps }, (_, index) => index + 1);
|
||||
|
||||
return (
|
||||
<YStack>
|
||||
<NavBar.Container
|
||||
gap={14}
|
||||
paddingHorizontal={20}
|
||||
paddingTop={Math.max(insets.top, 12)}
|
||||
paddingBottom={14}
|
||||
backgroundColor={headerStyle.backgroundColor as string}
|
||||
barStyle={
|
||||
options.headerTintColor === white ||
|
||||
(options.headerTitleStyle as TextStyle)?.color === white
|
||||
? 'light-content'
|
||||
: 'dark-content'
|
||||
}
|
||||
>
|
||||
<XStack width="100%" alignItems="center">
|
||||
<XStack width={50} justifyContent="flex-start">
|
||||
<NavBar.LeftAction
|
||||
component={
|
||||
options.headerBackTitle || (canGoBack() ? 'back' : undefined)
|
||||
}
|
||||
onPress={() => {
|
||||
buttonTap();
|
||||
goBack();
|
||||
}}
|
||||
{...(options.headerTitleStyle as ViewStyle)}
|
||||
/>
|
||||
</XStack>
|
||||
|
||||
<XStack flex={1} justifyContent="center" alignItems="center">
|
||||
<NavBar.Title {...(options.headerTitleStyle as ViewStyle)}>
|
||||
{props.options.title}
|
||||
</NavBar.Title>
|
||||
</XStack>
|
||||
|
||||
<XStack width={50} />
|
||||
</XStack>
|
||||
</NavBar.Container>
|
||||
|
||||
<YStack
|
||||
backgroundColor={
|
||||
(props.options.headerStyle as ViewStyle)?.backgroundColor || white
|
||||
}
|
||||
paddingHorizontal={20}
|
||||
paddingBottom={20}
|
||||
>
|
||||
<XStack width="100%" height={4} gap={4}>
|
||||
{segments.map((step, index) => (
|
||||
<YStack
|
||||
key={step}
|
||||
flex={1}
|
||||
height={5}
|
||||
backgroundColor={step <= currentStep ? cyan300 : slate200}
|
||||
borderRadius={0}
|
||||
borderTopLeftRadius={index === 0 ? 4 : 0}
|
||||
borderBottomLeftRadius={index === 0 ? 4 : 0}
|
||||
borderTopRightRadius={index === segments.length - 1 ? 4 : 0}
|
||||
borderBottomRightRadius={index === segments.length - 1 ? 4 : 0}
|
||||
overflow="hidden"
|
||||
/>
|
||||
))}
|
||||
</XStack>
|
||||
</YStack>
|
||||
</YStack>
|
||||
);
|
||||
};
|
||||
3
app/src/components/NavBar/index.ts
Normal file
3
app/src/components/NavBar/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { DefaultNavBar } from './DefaultNavBar';
|
||||
export { HomeNavBar } from './HomeNavBar';
|
||||
export { ProgressNavBar } from './ProgressNavBar';
|
||||
@@ -1,12 +1,13 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { StyleSheet, View, ViewStyle } from 'react-native';
|
||||
|
||||
interface TextsContainerProps {
|
||||
children: React.ReactNode;
|
||||
style?: ViewStyle;
|
||||
}
|
||||
|
||||
const TextsContainer = ({ children }: TextsContainerProps) => {
|
||||
return <View style={styles.textsContainer}>{children}</View>;
|
||||
const TextsContainer = ({ children, style }: TextsContainerProps) => {
|
||||
return <View style={[styles.textsContainer, style]}>{children}</View>;
|
||||
};
|
||||
|
||||
export default TextsContainer;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { StyleSheet, ViewStyle } from 'react-native';
|
||||
|
||||
import { Button, Text, ViewProps } from 'tamagui';
|
||||
|
||||
import { shouldShowAesopRedesign } from '../../hooks/useAesopRedesign';
|
||||
import { dinot } from '../../utils/fonts';
|
||||
import { pressedStyle } from './pressedStyle';
|
||||
|
||||
@@ -58,7 +59,7 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
flexGrow: 0,
|
||||
flexShrink: 0,
|
||||
width: '100%',
|
||||
width: shouldShowAesopRedesign() ? '48%' : '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
rowGap: 12,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, Text, TextProps } from 'react-native';
|
||||
|
||||
import { shouldShowAesopRedesign } from '../../hooks/useAesopRedesign';
|
||||
import { slate400 } from '../../utils/colors';
|
||||
import { dinot } from '../../utils/fonts';
|
||||
|
||||
@@ -24,5 +25,10 @@ const styles = StyleSheet.create({
|
||||
color: slate400,
|
||||
marginTop: 10,
|
||||
fontFamily: dinot,
|
||||
textTransform: 'none',
|
||||
...(shouldShowAesopRedesign() && {
|
||||
fontSize: 11.5,
|
||||
textTransform: 'uppercase',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import { StyleSheet } from 'react-native';
|
||||
|
||||
import { Text, TextProps } from 'tamagui';
|
||||
|
||||
import { shouldShowAesopRedesign } from '../../hooks/useAesopRedesign';
|
||||
import { slate500 } from '../../utils/colors';
|
||||
import { dinot } from '../../utils/fonts';
|
||||
|
||||
@@ -29,5 +30,9 @@ const styles = StyleSheet.create({
|
||||
lineHeight: 23,
|
||||
textAlign: 'center',
|
||||
fontFamily: dinot,
|
||||
...(shouldShowAesopRedesign() && {
|
||||
textAlign: 'left',
|
||||
fontSize: 16,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
9
app/src/components/typography/DescriptionTitle.tsx
Normal file
9
app/src/components/typography/DescriptionTitle.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Text, styled } from 'tamagui';
|
||||
|
||||
import { dinot } from '../../utils/fonts';
|
||||
|
||||
export const DescriptionTitle = styled(Text, {
|
||||
fontSize: 18,
|
||||
lineHeight: 35,
|
||||
fontFamily: dinot,
|
||||
});
|
||||
@@ -1,17 +1,26 @@
|
||||
import { StyleProp, TextStyle } from 'react-native';
|
||||
|
||||
import { Text, styled } from 'tamagui';
|
||||
|
||||
import { advercase } from '../../utils/fonts';
|
||||
|
||||
export const Title = styled(Text, {
|
||||
fontSize: 28,
|
||||
lineHeight: 35,
|
||||
fontFamily: advercase,
|
||||
variants: {
|
||||
size: {
|
||||
large: {
|
||||
fontSize: 38,
|
||||
lineHeight: 47,
|
||||
export const Title = styled(
|
||||
Text,
|
||||
{
|
||||
fontSize: 28,
|
||||
lineHeight: 35,
|
||||
fontFamily: advercase,
|
||||
variants: {
|
||||
size: {
|
||||
large: {
|
||||
fontSize: 38,
|
||||
lineHeight: 47,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
{
|
||||
acceptsClassName: true,
|
||||
style: (props: { style?: StyleProp<TextStyle> }) => props.style,
|
||||
},
|
||||
);
|
||||
|
||||
9
app/src/hooks/useAesopRedesign.ts
Normal file
9
app/src/hooks/useAesopRedesign.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { IS_TEST_BUILD } from '@env';
|
||||
|
||||
export const shouldShowAesopRedesign = (): boolean => {
|
||||
return IS_TEST_BUILD === 'true';
|
||||
};
|
||||
|
||||
export const useAesopRedesign = (): boolean => {
|
||||
return shouldShowAesopRedesign();
|
||||
};
|
||||
109
app/src/screens/_Aesop/PassportOnboardingScreen.tsx
Normal file
109
app/src/screens/_Aesop/PassportOnboardingScreen.tsx
Normal file
@@ -0,0 +1,109 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { StatusBar, StyleSheet, View } from 'react-native';
|
||||
|
||||
import LottieView from 'lottie-react-native';
|
||||
|
||||
import passportOnboardingAnimation from '../../assets/animations/passport_onboarding.json';
|
||||
import ButtonsContainer from '../../components/ButtonsContainer';
|
||||
import TextsContainer from '../../components/TextsContainer';
|
||||
import { PrimaryButton } from '../../components/buttons/PrimaryButton';
|
||||
import { SecondaryButton } from '../../components/buttons/SecondaryButton';
|
||||
import Additional from '../../components/typography/Additional';
|
||||
import Description from '../../components/typography/Description';
|
||||
import { DescriptionTitle } from '../../components/typography/DescriptionTitle';
|
||||
import useHapticNavigation from '../../hooks/useHapticNavigation';
|
||||
import Scan from '../../images/icons/passport_camera_scan.svg';
|
||||
import { ExpandableBottomLayout } from '../../layouts/ExpandableBottomLayout';
|
||||
import { black, slate100, white } from '../../utils/colors';
|
||||
|
||||
interface PassportOnboardingScreenProps {}
|
||||
|
||||
const PassportOnboardingScreen: React.FC<
|
||||
PassportOnboardingScreenProps
|
||||
> = ({}) => {
|
||||
const handleCameraPress = useHapticNavigation('PassportCamera');
|
||||
const onCancelPress = useHapticNavigation('Launch', { action: 'cancel' });
|
||||
const animationRef = useRef<LottieView>(null);
|
||||
|
||||
useEffect(() => {
|
||||
animationRef.current?.play();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ExpandableBottomLayout.Layout backgroundColor={white}>
|
||||
<StatusBar barStyle="light-content" backgroundColor={white} />
|
||||
<ExpandableBottomLayout.TopSection backgroundColor={white}>
|
||||
<LottieView
|
||||
ref={animationRef}
|
||||
autoPlay={false}
|
||||
loop={false}
|
||||
onAnimationFinish={() => {
|
||||
setTimeout(() => {
|
||||
animationRef.current?.play();
|
||||
}, 5000); // Pause 5 seconds before playing again
|
||||
}}
|
||||
source={passportOnboardingAnimation}
|
||||
style={styles.animation}
|
||||
cacheComposition={true}
|
||||
renderMode="HARDWARE"
|
||||
/>
|
||||
</ExpandableBottomLayout.TopSection>
|
||||
<ExpandableBottomLayout.BottomSection
|
||||
style={styles.bottomSection}
|
||||
backgroundColor={white}
|
||||
>
|
||||
<TextsContainer style={styles.textContainer}>
|
||||
<View style={styles.textIconWrapper}>
|
||||
<Scan
|
||||
style={styles.scanIcon}
|
||||
height={40}
|
||||
width={40}
|
||||
color={black}
|
||||
/>
|
||||
<View>
|
||||
<DescriptionTitle>Open to the photograph page</DescriptionTitle>
|
||||
<Description textBreakStrategy="balanced">
|
||||
Lay the Passport flat and position the machine readable text in
|
||||
the viewfinder.
|
||||
</Description>
|
||||
</View>
|
||||
</View>
|
||||
</TextsContainer>
|
||||
<TextsContainer>
|
||||
<Additional textBreakStrategy="balanced">
|
||||
Self will not capture an image of your passport.
|
||||
</Additional>
|
||||
</TextsContainer>
|
||||
<ButtonsContainer>
|
||||
<PrimaryButton onPress={handleCameraPress}>Open Camera</PrimaryButton>
|
||||
<SecondaryButton onPress={onCancelPress}>Cancel</SecondaryButton>
|
||||
</ButtonsContainer>
|
||||
</ExpandableBottomLayout.BottomSection>
|
||||
</ExpandableBottomLayout.Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default PassportOnboardingScreen;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
animation: {
|
||||
backgroundColor: slate100,
|
||||
width: '115%',
|
||||
height: '115%',
|
||||
},
|
||||
textIconWrapper: {
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 20,
|
||||
},
|
||||
scanIcon: {
|
||||
marginRight: 10,
|
||||
},
|
||||
textContainer: {
|
||||
marginBottom: 10,
|
||||
},
|
||||
bottomSection: {
|
||||
paddingBottom: 32,
|
||||
},
|
||||
});
|
||||
@@ -15,6 +15,7 @@ export const slate800 = '#1E293B';
|
||||
export const sky500 = '#0EA5E9';
|
||||
export const green500 = '#22C55E';
|
||||
export const red500 = '#EF4444';
|
||||
export const cyan300 = '#67E8F9';
|
||||
export const teal300 = '#5EEAD4';
|
||||
export const teal500 = '#5EEAD4';
|
||||
export const neutral400 = '#A3A3A3';
|
||||
|
||||
Reference in New Issue
Block a user