|
1 | 1 | import { useAuth, useUser } from '@clerk/clerk-expo'; |
2 | | -import React, { useEffect, useRef,useState } from 'react'; |
3 | | -import { ActivityIndicator,View } from 'react-native'; |
| 2 | +import * as SplashScreen from 'expo-splash-screen'; |
| 3 | +import React, { useEffect, useRef, useState } from 'react'; |
| 4 | +import { ActivityIndicator, View } from 'react-native'; |
4 | 5 |
|
5 | 6 | import { useMasterPassword } from '../hooks/useMasterPassword'; |
6 | 7 | import { logger } from '../lib/logger'; |
@@ -31,6 +32,7 @@ export const AppWrapper: React.FC<AppWrapperProps> = ({ children }) => { |
31 | 32 | const [showLoading, setShowLoading] = useState(false); |
32 | 33 | const lastUserIdRef = useRef<string | undefined>(undefined); |
33 | 34 | const [userChanging, setUserChanging] = useState(false); |
| 35 | + const splashHiddenRef = useRef(false); |
34 | 36 |
|
35 | 37 | // Automatically sync pending mutations when device comes back online |
36 | 38 | useSyncOnReconnect(); |
@@ -59,6 +61,25 @@ export const AppWrapper: React.FC<AppWrapperProps> = ({ children }) => { |
59 | 61 | } |
60 | 62 | }, [userChanging, isChecking]); |
61 | 63 |
|
| 64 | + // Hide splash screen when auth state is fully determined |
| 65 | + // This prevents the flash of sign-in/master password screens |
| 66 | + useEffect(() => { |
| 67 | + // Don't hide splash until we know exactly what screen to show: |
| 68 | + // 1. Clerk must be loaded |
| 69 | + // 2. If not signed in - show auth screen (hide splash) |
| 70 | + // 3. If signed in - must wait for master password check to complete |
| 71 | + const clerkReady = isLoaded; |
| 72 | + const notSignedIn = clerkReady && !isSignedIn; |
| 73 | + const signedInAndReady = clerkReady && isSignedIn && userLoaded && !isChecking; |
| 74 | + |
| 75 | + const shouldHideSplash = notSignedIn || signedInAndReady; |
| 76 | + |
| 77 | + if (shouldHideSplash && !splashHiddenRef.current) { |
| 78 | + splashHiddenRef.current = true; |
| 79 | + SplashScreen.hideAsync(); |
| 80 | + } |
| 81 | + }, [isLoaded, isSignedIn, userLoaded, isChecking]); |
| 82 | + |
62 | 83 | // Simple logic: show loading only for initial Clerk loading, nothing else |
63 | 84 | const isLoading = !isLoaded || (isSignedIn && !userLoaded) || (isSignedIn && userLoaded && !user); |
64 | 85 |
|
@@ -127,9 +148,11 @@ export const AppWrapper: React.FC<AppWrapperProps> = ({ children }) => { |
127 | 148 | } |
128 | 149 |
|
129 | 150 | // User is signed in - check master password state |
130 | | - // IMPORTANT: If we're checking OR need unlock OR user just changed, show master password screen |
131 | | - // This prevents notes from loading prematurely |
132 | | - if (needsUnlock || isChecking || userChanging) { |
| 151 | + // Show master password screen if: |
| 152 | + // 1. Still checking (isChecking) - we don't know the state yet |
| 153 | + // 2. Needs unlock (needsUnlock) - user must enter password |
| 154 | + // Note: Don't show just for userChanging - if user is already unlocked, go straight to app |
| 155 | + if (isChecking || needsUnlock) { |
133 | 156 | return ( |
134 | 157 | <MasterPasswordScreen |
135 | 158 | key={userId} // Force remount when userId changes to reset all state |
|
0 commit comments