312 lines
11 KiB
TypeScript
312 lines
11 KiB
TypeScript
// App.tsx
|
||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||
import { NavigationContainer } from '@react-navigation/native';
|
||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||
import { toastConfig } from 'components/CustomAlertModal';
|
||
import { navigationRef } from 'components/NavigationRef';
|
||
import i18n from 'i18n/i18n';
|
||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||
import { I18nextProvider } from 'react-i18next';
|
||
import {
|
||
Animated,
|
||
Dimensions,
|
||
LogBox,
|
||
StatusBar,
|
||
StyleSheet,
|
||
View,
|
||
} from 'react-native';
|
||
import Toast from 'react-native-toast-message';
|
||
import SplashScreen from './src/components/SplashScreen';
|
||
|
||
// Screens
|
||
import Login from 'screens/auth/login/ui';
|
||
import Confirm from 'screens/auth/login/ui/Confirm';
|
||
import Register from 'screens/auth/registeration/ui';
|
||
import SecondStep from 'screens/auth/registeration/ui/SecondStep';
|
||
import TermsAndConditions from 'screens/auth/registeration/ui/TermsAndConditions';
|
||
import SelectAuth from 'screens/auth/select-auth/SelectAuth';
|
||
import Branches from 'screens/home/branches/ui/Branches';
|
||
import ListBranches from 'screens/home/branches/ui/ListBranches';
|
||
import CargoPrices from 'screens/home/cargoPrices/ui/CargoPrices';
|
||
import Home from 'screens/home/home/ui/Home';
|
||
import RestrictedProduct from 'screens/home/restrictedProduct/ui/RestrictedProduct';
|
||
import CreatePassword from 'screens/passport/createPassport/ui/CreatePassword';
|
||
import Passport from 'screens/passport/myPassport/ui/Passport';
|
||
import Profile from 'screens/profile/myProfile/ui/Profile';
|
||
import AddedLock from 'screens/profile/settings/ui/AddedLock';
|
||
import Settings from 'screens/profile/settings/ui/Settings';
|
||
import SettingsLock from 'screens/profile/settings/ui/SettingsLock';
|
||
import Support from 'screens/profile/support/ui/Support';
|
||
import Warehouses from 'screens/profile/warehouses/ui/Warehouses';
|
||
import Status from 'screens/status/ui/Status';
|
||
import EnterCard from 'screens/wallet/enterCard/ui/EnterCard';
|
||
import Wallet from 'screens/wallet/payment/ui/Wallet';
|
||
import PaymentMethod from 'screens/wallet/paymentMethod/ui/PaymentMethod';
|
||
import PaymentQrCode from 'screens/wallet/successPayment/ui/PaymentQrCode';
|
||
import Onboarding from 'screens/welcome/Onboarding';
|
||
|
||
LogBox.ignoreLogs([
|
||
'Non-serializable values were found in the navigation state',
|
||
'ViewPropTypes will be removed',
|
||
]);
|
||
|
||
const Stack = createNativeStackNavigator();
|
||
const screenWidth = Dimensions.get('window').width;
|
||
const queryClient = new QueryClient();
|
||
|
||
// const saveNotification = async (remoteMessage: any) => {
|
||
// try {
|
||
// const stored = await AsyncStorage.getItem('notifications');
|
||
// const notifications = stored ? JSON.parse(stored) : [];
|
||
|
||
// const newNotification = {
|
||
// id: Date.now(),
|
||
// title:
|
||
// remoteMessage.notification?.title ||
|
||
// remoteMessage.data?.title ||
|
||
// 'Yangi bildirishnoma',
|
||
// message:
|
||
// remoteMessage.notification?.body ||
|
||
// remoteMessage.data?.body ||
|
||
// 'Matn yo‘q',
|
||
// sentTime: remoteMessage.sentTime || Date.now(),
|
||
// };
|
||
|
||
// await AsyncStorage.setItem(
|
||
// 'notifications',
|
||
// JSON.stringify([newNotification, ...notifications]),
|
||
// );
|
||
// } catch (e) {
|
||
// console.error('Notification saqlashda xato:', e);
|
||
// }
|
||
// };
|
||
|
||
// async function onDisplayNotification(remoteMessage: any) {
|
||
// const channelId = await notifee.createChannel({
|
||
// id: 'default',
|
||
// name: 'Umumiy bildirishnomalar',
|
||
// sound: 'default',
|
||
// importance: AndroidImportance.HIGH,
|
||
// });
|
||
|
||
// await notifee.displayNotification({
|
||
// title:
|
||
// remoteMessage.notification?.title ||
|
||
// remoteMessage.data?.title ||
|
||
// 'Yangi xabar',
|
||
// body:
|
||
// remoteMessage.notification?.body ||
|
||
// remoteMessage.data?.body ||
|
||
// 'Matn yo‘q',
|
||
// android: {
|
||
// channelId,
|
||
// largeIcon: 'ic_launcher_foreground',
|
||
// sound: 'default',
|
||
// pressAction: {
|
||
// id: 'default',
|
||
// },
|
||
// },
|
||
// });
|
||
// }
|
||
|
||
// async function requestNotificationPermission() {
|
||
// if (Platform.OS === 'android' && Platform.Version >= 33) {
|
||
// const granted = await PermissionsAndroid.request(
|
||
// PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
|
||
// );
|
||
// console.log('POST_NOTIFICATIONS permission:', granted);
|
||
// }
|
||
// }
|
||
|
||
export default function App() {
|
||
const [initialRoute, setInitialRoute] = useState<string | null>(null);
|
||
const slideAnim = useRef(new Animated.Value(0)).current;
|
||
const [isSplashVisible, setIsSplashVisible] = useState(true);
|
||
|
||
// useEffect(() => {
|
||
// requestNotificationPermission();
|
||
|
||
// const messagingInstance = getMessaging();
|
||
|
||
// const unsubscribe = onMessage(messagingInstance, async remoteMessage => {
|
||
// console.log('Foreground message:', remoteMessage);
|
||
// await saveNotification(remoteMessage);
|
||
// await onDisplayNotification(remoteMessage);
|
||
// });
|
||
|
||
// const unsubscribeOpened = onNotificationOpenedApp(
|
||
// messagingInstance,
|
||
// remoteMessage => {
|
||
// console.log('Backgrounddan ochildi:', remoteMessage);
|
||
// saveNotification(remoteMessage);
|
||
// },
|
||
// );
|
||
|
||
// (async () => {
|
||
// const remoteMessage = await getInitialNotification(messagingInstance);
|
||
// if (remoteMessage) {
|
||
// console.log('Killeddan ochildi:', remoteMessage);
|
||
// saveNotification(remoteMessage);
|
||
// }
|
||
// })();
|
||
|
||
// return () => {
|
||
// unsubscribe();
|
||
// unsubscribeOpened();
|
||
// };
|
||
// }, []);
|
||
|
||
useEffect(() => {
|
||
const initializeApp = async () => {
|
||
try {
|
||
const [seen, token, lang] = await Promise.all([
|
||
AsyncStorage.getItem('hasSeenOnboarding'),
|
||
AsyncStorage.getItem('token'),
|
||
AsyncStorage.getItem('language'),
|
||
]);
|
||
|
||
if (lang) await i18n.changeLanguage(lang);
|
||
|
||
const initialRouteName = !seen
|
||
? 'Onboarding'
|
||
: token
|
||
? 'Home'
|
||
: 'select-auth';
|
||
setInitialRoute(initialRouteName);
|
||
} catch (error) {
|
||
console.error('App initialization error:', error);
|
||
setInitialRoute('select-auth');
|
||
}
|
||
};
|
||
|
||
initializeApp();
|
||
}, []);
|
||
|
||
const handleSplashFinish = useMemo(
|
||
() => () => {
|
||
Animated.timing(slideAnim, {
|
||
toValue: -screenWidth,
|
||
duration: 600,
|
||
useNativeDriver: true,
|
||
}).start(() => setIsSplashVisible(false));
|
||
},
|
||
[slideAnim],
|
||
);
|
||
|
||
const handleOnboardingFinish = useMemo(
|
||
() => async (navigation: any) => {
|
||
await AsyncStorage.setItem('hasSeenOnboarding', 'true');
|
||
navigation.replace('select-auth');
|
||
},
|
||
[],
|
||
);
|
||
// const [firebaseToken, setFirebseToken] = useState<{
|
||
// fcmToken: string;
|
||
// deviceId: string;
|
||
// deviceName: string;
|
||
// } | null>();
|
||
// const app = getApp();
|
||
// const messaging = getMessaging(app);
|
||
|
||
// const getDeviceData = async () => {
|
||
// try {
|
||
// const fcmToken = await getToken(messaging);
|
||
// return {
|
||
// fcmToken,
|
||
// deviceId: await DeviceInfo.getUniqueId(),
|
||
// deviceName: await DeviceInfo.getDeviceName(),
|
||
// };
|
||
// } catch (e) {
|
||
// console.log('Xato:', e);
|
||
// return null;
|
||
// }
|
||
// };
|
||
// console.log(firebaseToken);
|
||
|
||
// useEffect(() => {
|
||
// getDeviceData().then(data => {
|
||
// setFirebseToken(data);
|
||
// });
|
||
// }, []);
|
||
|
||
if (!initialRoute) return null;
|
||
|
||
return (
|
||
<QueryClientProvider client={queryClient}>
|
||
<I18nextProvider i18n={i18n}>
|
||
<View style={{ flex: 1 }}>
|
||
<StatusBar barStyle="dark-content" backgroundColor="#fff" />
|
||
<NavigationContainer ref={navigationRef}>
|
||
<Stack.Navigator
|
||
screenOptions={{
|
||
headerShown: false,
|
||
animation: 'none',
|
||
gestureEnabled: false,
|
||
}}
|
||
initialRouteName={initialRoute}
|
||
>
|
||
<Stack.Screen name="Onboarding">
|
||
{props => (
|
||
<Onboarding
|
||
{...props}
|
||
onFinish={() => handleOnboardingFinish(props.navigation)}
|
||
/>
|
||
)}
|
||
</Stack.Screen>
|
||
<Stack.Screen name="select-auth" component={SelectAuth} />
|
||
<Stack.Screen name="Login" component={Login} />
|
||
<Stack.Screen name="Login-Confirm" component={Confirm} />
|
||
<Stack.Screen name="Register" component={Register} />
|
||
<Stack.Screen name="Confirm" component={SecondStep} />
|
||
<Stack.Screen name="SettingsLock" component={SettingsLock} />
|
||
<Stack.Screen name="AddLock" component={AddedLock} />
|
||
<Stack.Screen name="Home" component={Home} />
|
||
<Stack.Screen name="Status" component={Status} />
|
||
<Stack.Screen name="Passports" component={Passport} />
|
||
<Stack.Screen name="CargoPrices" component={CargoPrices} />
|
||
<Stack.Screen name="create-password" component={CreatePassword} />
|
||
<Stack.Screen name="Wallet" component={Wallet} />
|
||
<Stack.Screen name="PaymentMethod" component={PaymentMethod} />
|
||
<Stack.Screen name="EnterCard" component={EnterCard} />
|
||
<Stack.Screen name="PaymentQrCode" component={PaymentQrCode} />
|
||
<Stack.Screen name="Profile" component={Profile} />
|
||
<Stack.Screen name="Settings" component={Settings} />
|
||
{/* {Platform.OS === 'android' && (
|
||
<Stack.Screen name="Notifications" component={Notifications} />
|
||
)} */}
|
||
<Stack.Screen name="Warehouses" component={Warehouses} />
|
||
<Stack.Screen name="Support" component={Support} />
|
||
<Stack.Screen name="ListBranches" component={ListBranches} />
|
||
<Stack.Screen name="Branches" component={Branches} />
|
||
<Stack.Screen
|
||
name="RestrictedProduct"
|
||
component={RestrictedProduct}
|
||
/>
|
||
<Stack.Screen
|
||
name="TermsAndConditions"
|
||
component={TermsAndConditions}
|
||
/>
|
||
</Stack.Navigator>
|
||
</NavigationContainer>
|
||
|
||
{/* Splash transition */}
|
||
{isSplashVisible && (
|
||
<Animated.View
|
||
style={{
|
||
...StyleSheet.absoluteFillObject,
|
||
transform: [{ translateX: slideAnim }],
|
||
zIndex: 10,
|
||
}}
|
||
>
|
||
<SplashScreen onFinish={handleSplashFinish} />
|
||
</Animated.View>
|
||
)}
|
||
|
||
<Toast config={toastConfig} />
|
||
</View>
|
||
</I18nextProvider>
|
||
</QueryClientProvider>
|
||
);
|
||
}
|