11import React , { useEffect , useState } from 'react' ;
22import { Provider } from 'react-redux' ;
33import { PersistGate } from 'redux-persist/integration/react' ;
4- import { persistor , store , performStorageMigration } from './src/Redux/Store' ;
4+ import {
5+ initializeStore ,
6+ performStorageMigration ,
7+ store ,
8+ persistor ,
9+ isStoreReady
10+ } from './src/Redux/Store' ;
511import { GestureHandlerRootView } from 'react-native-gesture-handler' ;
612import { RootNavigation } from './src/Navigation' ;
713import Loading from './src/Components/UIComp/Loading' ;
@@ -20,102 +26,115 @@ import {
2026import NotificationSubscriptionBootstrapper from './src/InkNest-Externals/Notifications/components/NotificationSubscriptionBootstrapper' ;
2127
2228/**
23- * Migration gate component that handles AsyncStorage -> MMKV migration
24- * before rendering the app
29+ * AppContent component - rendered after store is initialized
2530 */
26- function MigrationGate ( { children } ) {
27- const [ isMigrating , setIsMigrating ] = useState ( true ) ;
28- const [ migrationError , setMigrationError ] = useState ( null ) ;
29-
31+ function AppContent ( ) {
3032 useEffect ( ( ) => {
31- async function runMigration ( ) {
32- try {
33- // Perform migration from AsyncStorage to MMKV
34- await performStorageMigration ( ) ;
35- setIsMigrating ( false ) ;
36- } catch ( error ) {
37- console . error ( 'Migration failed:' , error ) ;
38- crashlytics ( ) . recordError ( error ) ;
39- setMigrationError ( error ) ;
40- // Even on error, allow app to continue (may lose old data but app works)
41- setIsMigrating ( false ) ;
42- }
43- }
44-
45- runMigration ( ) ;
46- } , [ ] ) ;
47-
48- if ( isMigrating ) {
49- return < Loading /> ;
50- }
51-
52- return children ;
53- }
54-
55- /**
56- * The main App component that sets up the root of the application.
57- * It includes the GestureHandlerRootView for gesture handling,
58- * the Redux Provider for state management, and the PersistGate
59- * for persisting the Redux store.
60- *
61- * @returns {JSX.Element } The root component of the application.
62- */
63- const App = ( ) => {
64- useEffect ( ( ) => {
65- // Configure Google Sign-In
6633 configureGoogleSignIn ( ) ;
67-
68- // Listen to auth state changes
6934 const unsubscribeAuth = store . dispatch ( listenToAuthChanges ( ) ) ;
7035
7136 if ( ! __DEV__ ) {
72- // Initialize Firebase Crashlytics
7337 crashlytics ( ) . log ( 'App mounted.' ) ;
74-
75- // Enable analytics collection
7638 analytics ( ) . setAnalyticsCollectionEnabled ( true ) ;
7739
78- // Catch JS errors and report to Crashlytics
7940 const errorHandler = ( error , isFatal ) => {
8041 if ( isFatal ) {
8142 crashlytics ( ) . recordError ( error ) ;
8243 }
8344 return false ;
8445 } ;
85-
86- // Set error handlers
8746 ErrorUtils . setGlobalHandler ( errorHandler ) ;
88-
89- return ( ) => {
90- // Clean up auth listener
91- if ( unsubscribeAuth ) unsubscribeAuth ( ) ;
92- } ;
9347 }
9448
9549 return ( ) => {
96- // Clean up auth listener
9750 if ( unsubscribeAuth ) unsubscribeAuth ( ) ;
9851 } ;
9952 } , [ ] ) ;
10053
54+ return (
55+ < Provider store = { store } >
56+ < PersistGate loading = { < Loading /> } persistor = { persistor } >
57+ < PaperProvider >
58+ < BannerProvider >
59+ < NotificationSubscriptionBootstrapper />
60+ < RootNavigation />
61+ < Toast />
62+ < ForceUpdate />
63+ </ BannerProvider >
64+ </ PaperProvider >
65+ </ PersistGate >
66+ </ Provider >
67+ ) ;
68+ }
69+
70+ /**
71+ * Main App component
72+ */
73+ const App = ( ) => {
74+ const [ isReady , setIsReady ] = useState ( false ) ;
75+ const [ migrationError , setMigrationError ] = useState ( null ) ;
76+
77+ useEffect ( ( ) => {
78+ let isMounted = true ;
79+
80+ async function setupApp ( ) {
81+ try {
82+ console . log ( '[App] Starting app setup...' ) ;
83+
84+ // Run migration before anything else
85+ console . log ( '[App] Running storage migration...' ) ;
86+ await performStorageMigration ( ) ;
87+
88+ // Initialize store after migration
89+ console . log ( '[App] Initializing store...' ) ;
90+ initializeStore ( ) ;
91+
92+ if ( ! isStoreReady ( ) ) {
93+ throw new Error ( 'Store initialization failed' ) ;
94+ }
95+
96+ console . log ( '[App] Setup complete' ) ;
97+ if ( isMounted ) {
98+ setIsReady ( true ) ;
99+ }
100+ } catch ( error ) {
101+ console . error ( '[App] Setup failed:' , error ) ;
102+ crashlytics ( ) . recordError ( error ) ;
103+
104+ // Try to recover by initializing store anyway
105+ try {
106+ initializeStore ( ) ;
107+ if ( isStoreReady ( ) && isMounted ) {
108+ setIsReady ( true ) ;
109+ }
110+ } catch ( recoveryError ) {
111+ if ( isMounted ) {
112+ setMigrationError ( recoveryError ) ;
113+ }
114+ }
115+ }
116+ }
117+
118+ setupApp ( ) ;
119+
120+ return ( ) => {
121+ isMounted = false ;
122+ } ;
123+ } , [ ] ) ;
124+
125+ if ( ! isReady ) {
126+ return (
127+ < GestureHandlerRootView style = { { flex : 1 } } >
128+ < Loading />
129+ </ GestureHandlerRootView >
130+ ) ;
131+ }
132+
101133 return (
102134 < GestureHandlerRootView style = { { flex : 1 } } >
103135 < ConfigCatProvider
104136 sdkKey = { __DEV__ ? CONFIGCAT_SDK_KEY_TEST : CONFIGCAT_SDK_KEY_PROD } >
105- < Provider store = { store } >
106- < MigrationGate >
107- < PersistGate loading = { < Loading /> } persistor = { persistor } >
108- < PaperProvider >
109- < BannerProvider >
110- < NotificationSubscriptionBootstrapper />
111- < RootNavigation />
112- < Toast />
113- < ForceUpdate />
114- </ BannerProvider >
115- </ PaperProvider >
116- </ PersistGate >
117- </ MigrationGate >
118- </ Provider >
137+ < AppContent />
119138 </ ConfigCatProvider >
120139 </ GestureHandlerRootView >
121140 ) ;
0 commit comments