-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy path_layout.tsx
152 lines (138 loc) · 5.88 KB
/
_layout.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import { Redirect, Stack, useGlobalSearchParams, usePathname, useRouter } from 'expo-router'
import { TypedArrayEncoder } from '@credo-ts/core'
import { useSecureUnlock } from '@easypid/agent'
import { activityStorage } from '@easypid/features/activity/activityRecord'
import { useHasFinishedOnboarding } from '@easypid/features/onboarding'
import { resetWallet, useResetWalletDevMenu } from '@easypid/utils/resetWallet'
import { AgentProvider, WalletJsonStoreProvider } from '@package/agent'
import { type CredentialDataHandlerOptions, DeeplinkHandler, useHaptics } from '@package/app'
import { HeroIcons, IconContainer } from '@package/ui'
import { useEffect, useState } from 'react'
import { useTheme } from 'tamagui'
const jsonRecordIds = [activityStorage.recordId]
// When deeplink routing we want to push
export const credentialDataHandlerOptions = {
routeMethod: 'push',
} satisfies CredentialDataHandlerOptions
export default function AppLayout() {
useResetWalletDevMenu()
const secureUnlock = useSecureUnlock()
const theme = useTheme()
const router = useRouter()
const { withHaptics } = useHaptics()
const [redirectAfterUnlocked, setRedirectAfterUnlocked] = useState<string>()
const pathname = usePathname()
const params = useGlobalSearchParams()
// It could be that the onboarding is cut of mid-process, and e.g. the user closes the app
// if this is the case we will redo the onboarding
const [hasFinishedOnboarding] = useHasFinishedOnboarding()
const [hasResetWallet, setHasResetWallet] = useState(false)
const shouldResetWallet =
secureUnlock.state !== 'not-configured' && secureUnlock.state !== 'initializing' && !hasFinishedOnboarding
const isWalletLocked = secureUnlock.state === 'locked' || secureUnlock.state === 'acquired-wallet-key'
useEffect(() => {
// Reset state
if (hasResetWallet && !shouldResetWallet) {
setHasResetWallet(false)
return
}
if (!shouldResetWallet || hasResetWallet) return
setHasResetWallet(true)
resetWallet(secureUnlock)
}, [secureUnlock, hasResetWallet, shouldResetWallet])
// If we are intializing and the wallet was opened using a deeplinkg we will be redirected
// to the authentication screen. We first save the redirection url and use that when navigation
// to the auth screen
if (
(secureUnlock.state === 'initializing' || isWalletLocked) &&
pathname &&
pathname !== '/' &&
!redirectAfterUnlocked
) {
// Expo and urls as query params don't go well together, so we encoded the url as base64
const encodedRedirect = TypedArrayEncoder.toBase64URL(
TypedArrayEncoder.fromString(`${pathname}?${new URLSearchParams(params as Record<string, string>).toString()}`)
)
setRedirectAfterUnlocked(encodedRedirect)
}
// Clear the redirection in case the wallet is locked in the background
if (secureUnlock.state !== 'initializing' && secureUnlock.state !== 'locked' && redirectAfterUnlocked) {
setRedirectAfterUnlocked(undefined)
}
// This should show the splash screen
if (secureUnlock.state === 'initializing' || shouldResetWallet) {
return null
}
if (secureUnlock.state === 'not-configured') {
return <Redirect href="/onboarding" />
}
// Wallet is locked. Redirect to authentication screen
// We optionally pass an encoded redirect url that we should navigate to
// after the user has unlocked the wallet
if (isWalletLocked) {
return (
<Redirect
href={redirectAfterUnlocked ? `/authenticate?redirectAfterUnlock=${redirectAfterUnlocked}` : '/authenticate'}
/>
)
}
const headerNormalOptions = {
headerShown: true,
headerTransparent: true,
headerTintColor: theme['primary-500'].val,
headerTitle: '',
headerLeft: () => <IconContainer icon={<HeroIcons.ArrowLeft />} onPress={withHaptics(() => router.back())} />,
}
// Render the normal wallet, which is everything inside (app)
return (
<AgentProvider agent={secureUnlock.context.agent}>
<WalletJsonStoreProvider agent={secureUnlock.context.agent} recordIds={jsonRecordIds}>
<Stack screenOptions={{ headerShown: false }}>
<Stack.Screen
options={{
presentation: 'modal',
}}
name="(home)/scan"
/>
<Stack.Screen
options={{
presentation: 'modal',
}}
name="(home)/offline"
/>
<Stack.Screen
name="notifications/openIdPresentation"
options={{
gestureEnabled: false,
}}
/>
<Stack.Screen
name="notifications/openIdCredential"
options={{
gestureEnabled: false,
}}
/>
<Stack.Screen
name="notifications/offlinePresentation"
options={{
gestureEnabled: false,
}}
/>
<Stack.Screen name="credentials/index" options={headerNormalOptions} />
<Stack.Screen name="credentials/[id]/index" options={headerNormalOptions} />
<Stack.Screen name="credentials/[id]/attributes" options={headerNormalOptions} />
<Stack.Screen name="credentials/requestedAttributes" options={headerNormalOptions} />
<Stack.Screen name="menu/index" options={headerNormalOptions} />
<Stack.Screen name="menu/settings" options={headerNormalOptions} />
<Stack.Screen name="menu/about" options={headerNormalOptions} />
<Stack.Screen name="activity/index" options={headerNormalOptions} />
<Stack.Screen name="activity/[id]" options={headerNormalOptions} />
<Stack.Screen name="pinConfirmation" options={headerNormalOptions} />
<Stack.Screen name="pinLocked" options={headerNormalOptions} />
<Stack.Screen name="federation" options={headerNormalOptions} />
<Stack.Screen name="pidSetup" />
</Stack>
</WalletJsonStoreProvider>
</AgentProvider>
)
}