78 lines
2.2 KiB
TypeScript

import React, { useEffect, useRef } from 'react';
import { StatusBar, StyleSheet, useColorScheme, View } from 'react-native';
import {
SafeAreaProvider,
useSafeAreaInsets,
} from 'react-native-safe-area-context';
import RootNavigator from '@navigation/rootNavigator';
import { Provider } from 'react-redux';
import { useAppTheme } from '@theme';
import { persistor, store, useAppSelector } from '@store';
import { PersistGate } from 'redux-persist/integration/react';
import { socketService } from '@services';
import { checkPendingOfferThunk } from '@store/commonReducers/delivery';
function App() {
const isDarkMode = useColorScheme() === 'dark';
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<SafeAreaProvider>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<AppContent />
</SafeAreaProvider>
</PersistGate>
</Provider>
);
}
function AppContent() {
const safeAreaInsets = useSafeAreaInsets();
const { colors } = useAppTheme();
const accessToken = useAppSelector(state => state.auth.accessToken);
const prevTokenRef = useRef<string | null>(null);
// Bootstrap the socket service once with the store reference.
// The navigationRef is managed inside RootNavigator, so we pass null here;
// it will be injected from rootNavigator.tsx.
useEffect(() => {
socketService.bootstrap(store, null);
}, []);
// Connect / disconnect the socket when the auth token changes.
useEffect(() => {
if (accessToken && accessToken !== prevTokenRef.current) {
socketService.connect(accessToken);
// Check for any delivery offer the server held while the app was closed
store.dispatch(checkPendingOfferThunk());
} else if (!accessToken && prevTokenRef.current) {
socketService.disconnect();
}
prevTokenRef.current = accessToken;
}, [accessToken]);
return (
<View
style={[
styles.container,
{
paddingTop: safeAreaInsets.top,
paddingBottom: safeAreaInsets.bottom,
backgroundColor: colors.background,
},
]}
>
<RootNavigator />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default App;