mmkv added
This commit is contained in:
208
App.tsx
208
App.tsx
@@ -1,5 +1,4 @@
|
|||||||
// App.tsx
|
// App.tsx
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import { NavigationContainer } from '@react-navigation/native';
|
import { NavigationContainer } from '@react-navigation/native';
|
||||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
@@ -20,6 +19,13 @@ import Toast from 'react-native-toast-message';
|
|||||||
import SplashScreen from './src/components/SplashScreen';
|
import SplashScreen from './src/components/SplashScreen';
|
||||||
|
|
||||||
// Screens
|
// Screens
|
||||||
|
import {
|
||||||
|
authEvents,
|
||||||
|
getLanguage,
|
||||||
|
getToken,
|
||||||
|
loadInitialAuthData,
|
||||||
|
storage,
|
||||||
|
} from 'helpers/event';
|
||||||
import Login from 'screens/auth/login/ui';
|
import Login from 'screens/auth/login/ui';
|
||||||
import Confirm from 'screens/auth/login/ui/Confirm';
|
import Confirm from 'screens/auth/login/ui/Confirm';
|
||||||
import Register from 'screens/auth/registeration/ui';
|
import Register from 'screens/auth/registeration/ui';
|
||||||
@@ -47,137 +53,80 @@ import PaymentQrCode from 'screens/wallet/successPayment/ui/PaymentQrCode';
|
|||||||
import Onboarding from 'screens/welcome/Onboarding';
|
import Onboarding from 'screens/welcome/Onboarding';
|
||||||
|
|
||||||
LogBox.ignoreLogs([
|
LogBox.ignoreLogs([
|
||||||
'Non-serializable values were found in the navigation state',
|
|
||||||
'ViewPropTypes will be removed',
|
'ViewPropTypes will be removed',
|
||||||
|
// NOTE: I recommend NOT ignoring "Non-serializable values were found in the navigation state"
|
||||||
|
// because it hides bugs that can cause crashes. Keep only if you understand the implications.
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const Stack = createNativeStackNavigator();
|
const Stack = createNativeStackNavigator();
|
||||||
const screenWidth = Dimensions.get('window').width;
|
const screenWidth = Dimensions.get('window').width;
|
||||||
const queryClient = new QueryClient();
|
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() {
|
export default function App() {
|
||||||
const [initialRoute, setInitialRoute] = useState<string | null>(null);
|
const [initialRoute, setInitialRoute] = useState<string | null>(null);
|
||||||
const slideAnim = useRef(new Animated.Value(0)).current;
|
const slideAnim = useRef(new Animated.Value(0)).current;
|
||||||
const [isSplashVisible, setIsSplashVisible] = useState(true);
|
const [isSplashVisible, setIsSplashVisible] = useState(true);
|
||||||
|
const isMounted = useRef(false);
|
||||||
|
const currentAnimation = useRef<Animated.CompositeAnimation | null>(null);
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// requestNotificationPermission();
|
loadInitialAuthData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
// const messagingInstance = getMessaging();
|
useEffect(() => {
|
||||||
|
const logoutListener = () => {
|
||||||
|
if (navigationRef.isReady()) {
|
||||||
|
navigationRef.reset({
|
||||||
|
index: 0,
|
||||||
|
routes: [{ name: 'Login' }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// const unsubscribe = onMessage(messagingInstance, async remoteMessage => {
|
authEvents.on('logout', logoutListener);
|
||||||
// console.log('Foreground message:', remoteMessage);
|
|
||||||
// await saveNotification(remoteMessage);
|
|
||||||
// await onDisplayNotification(remoteMessage);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const unsubscribeOpened = onNotificationOpenedApp(
|
return () => {
|
||||||
// messagingInstance,
|
authEvents.removeListener('logout', logoutListener);
|
||||||
// remoteMessage => {
|
};
|
||||||
// console.log('Backgrounddan ochildi:', remoteMessage);
|
}, []);
|
||||||
// saveNotification(remoteMessage);
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
|
|
||||||
// (async () => {
|
useEffect(() => {
|
||||||
// const remoteMessage = await getInitialNotification(messagingInstance);
|
isMounted.current = true;
|
||||||
// if (remoteMessage) {
|
return () => {
|
||||||
// console.log('Killeddan ochildi:', remoteMessage);
|
isMounted.current = false;
|
||||||
// saveNotification(remoteMessage);
|
if (currentAnimation.current) {
|
||||||
// }
|
currentAnimation.current.stop();
|
||||||
// })();
|
}
|
||||||
|
};
|
||||||
// return () => {
|
}, []);
|
||||||
// unsubscribe();
|
|
||||||
// unsubscribeOpened();
|
|
||||||
// };
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initializeApp = async () => {
|
const initializeApp = async () => {
|
||||||
try {
|
try {
|
||||||
const [seen, token, lang] = await Promise.all([
|
const seen = storage.getString('hasSeenOnboarding');
|
||||||
AsyncStorage.getItem('hasSeenOnboarding'),
|
const token = getToken();
|
||||||
AsyncStorage.getItem('token'),
|
const lang = getLanguage();
|
||||||
|
|
||||||
AsyncStorage.getItem('language'),
|
if (lang) {
|
||||||
]);
|
try {
|
||||||
|
await i18n.changeLanguage(lang);
|
||||||
if (lang) await i18n.changeLanguage(lang);
|
} catch (e) {
|
||||||
|
console.warn('i18n.changeLanguage failed:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const initialRouteName = !seen
|
const initialRouteName = !seen
|
||||||
? 'Onboarding'
|
? 'Onboarding'
|
||||||
: token
|
: token
|
||||||
? 'Home'
|
? 'Home'
|
||||||
: 'select-auth';
|
: 'select-auth';
|
||||||
|
|
||||||
|
if (isMounted.current) {
|
||||||
setInitialRoute(initialRouteName);
|
setInitialRoute(initialRouteName);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('App initialization error:', error);
|
console.error('App initialization error:', error);
|
||||||
setInitialRoute('select-auth');
|
if (isMounted.current) setInitialRoute('select-auth');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -186,52 +135,39 @@ export default function App() {
|
|||||||
|
|
||||||
const handleSplashFinish = useMemo(
|
const handleSplashFinish = useMemo(
|
||||||
() => () => {
|
() => () => {
|
||||||
Animated.timing(slideAnim, {
|
// create animation and keep ref so we can stop it on unmount
|
||||||
|
const animation = Animated.timing(slideAnim, {
|
||||||
toValue: -screenWidth,
|
toValue: -screenWidth,
|
||||||
duration: 600,
|
duration: 600,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start(() => setIsSplashVisible(false));
|
});
|
||||||
|
currentAnimation.current = animation;
|
||||||
|
animation.start(() => {
|
||||||
|
// ensure component still mounted before setting state
|
||||||
|
if (isMounted.current) {
|
||||||
|
setIsSplashVisible(false);
|
||||||
|
}
|
||||||
|
currentAnimation.current = null;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[slideAnim],
|
[slideAnim],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleOnboardingFinish = useMemo(
|
const handleOnboardingFinish = useMemo(
|
||||||
() => async (navigation: any) => {
|
() => async (navigation: any) => {
|
||||||
await AsyncStorage.setItem('hasSeenOnboarding', 'true');
|
try {
|
||||||
|
storage.set('hasSeenOnboarding', 'true');
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Failed to set hasSeenOnboarding', e);
|
||||||
|
}
|
||||||
navigation.replace('select-auth');
|
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 () => {
|
if (initialRoute === null) {
|
||||||
// try {
|
return <View style={{ flex: 1, backgroundColor: '#000' }} />;
|
||||||
// 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 (
|
return (
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
@@ -245,6 +181,7 @@ export default function App() {
|
|||||||
animation: 'none',
|
animation: 'none',
|
||||||
gestureEnabled: false,
|
gestureEnabled: false,
|
||||||
}}
|
}}
|
||||||
|
// initialRouteName set once (we ensure it's available before first render)
|
||||||
initialRouteName={initialRoute}
|
initialRouteName={initialRoute}
|
||||||
>
|
>
|
||||||
<Stack.Screen name="Onboarding">
|
<Stack.Screen name="Onboarding">
|
||||||
@@ -273,9 +210,6 @@ export default function App() {
|
|||||||
<Stack.Screen name="PaymentQrCode" component={PaymentQrCode} />
|
<Stack.Screen name="PaymentQrCode" component={PaymentQrCode} />
|
||||||
<Stack.Screen name="Profile" component={Profile} />
|
<Stack.Screen name="Profile" component={Profile} />
|
||||||
<Stack.Screen name="Settings" component={Settings} />
|
<Stack.Screen name="Settings" component={Settings} />
|
||||||
{/* {Platform.OS === 'android' && (
|
|
||||||
<Stack.Screen name="Notifications" component={Notifications} />
|
|
||||||
)} */}
|
|
||||||
<Stack.Screen name="Warehouses" component={Warehouses} />
|
<Stack.Screen name="Warehouses" component={Warehouses} />
|
||||||
<Stack.Screen name="Support" component={Support} />
|
<Stack.Screen name="Support" component={Support} />
|
||||||
<Stack.Screen name="ListBranches" component={ListBranches} />
|
<Stack.Screen name="ListBranches" component={ListBranches} />
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ android {
|
|||||||
applicationId "uz.felix.cpost"
|
applicationId "uz.felix.cpost"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 6
|
versionCode 7
|
||||||
versionName "0.6"
|
versionName "0.7"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,8 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ['module:@react-native/babel-preset'],
|
presets: ['module:@react-native/babel-preset'],
|
||||||
plugins: [
|
plugins: [
|
||||||
'react-native-reanimated/plugin',
|
// 'react-native-reanimated/plugin',
|
||||||
|
'react-native-worklets/plugin',
|
||||||
'@babel/plugin-transform-export-namespace-from',
|
'@babel/plugin-transform-export-namespace-from',
|
||||||
[
|
[
|
||||||
'module-resolver',
|
'module-resolver',
|
||||||
|
|||||||
362
package-lock.json
generated
362
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@
|
|||||||
"@react-navigation/native-stack": "^7.3.25",
|
"@react-navigation/native-stack": "^7.3.25",
|
||||||
"@tanstack/react-query": "^5.84.2",
|
"@tanstack/react-query": "^5.84.2",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
|
"events": "^3.3.0",
|
||||||
"i18next": "^25.3.2",
|
"i18next": "^25.3.2",
|
||||||
"lottie-react-native": "^7.3.0",
|
"lottie-react-native": "^7.3.0",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
@@ -41,7 +42,9 @@
|
|||||||
"react-native-linear-gradient": "^2.8.3",
|
"react-native-linear-gradient": "^2.8.3",
|
||||||
"react-native-localize": "^3.5.1",
|
"react-native-localize": "^3.5.1",
|
||||||
"react-native-mask-input": "^1.2.3",
|
"react-native-mask-input": "^1.2.3",
|
||||||
|
"react-native-mmkv": "^4.0.1",
|
||||||
"react-native-modal": "^14.0.0-rc.1",
|
"react-native-modal": "^14.0.0-rc.1",
|
||||||
|
"react-native-nitro-modules": "^0.31.10",
|
||||||
"react-native-push-notification": "^8.1.1",
|
"react-native-push-notification": "^8.1.1",
|
||||||
"react-native-reanimated": "^4.0.2",
|
"react-native-reanimated": "^4.0.2",
|
||||||
"react-native-safe-area-context": "^5.6.0",
|
"react-native-safe-area-context": "^5.6.0",
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
// axiosInstance
|
||||||
import axios, { AxiosError } from 'axios';
|
import axios from 'axios';
|
||||||
import { navigate } from 'components/NavigationRef';
|
import { authEvents, getLanguage, getToken, setToken } from 'helpers/event';
|
||||||
|
|
||||||
|
let isLoggingOut = false;
|
||||||
|
|
||||||
const axiosInstance = axios.create({
|
const axiosInstance = axios.create({
|
||||||
baseURL: 'https://api.cpcargo.uz/api/v1',
|
baseURL: 'https://api.cpcargo.uz/api/v1',
|
||||||
@@ -10,30 +12,38 @@ const axiosInstance = axios.create({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
axiosInstance.interceptors.request.use(async config => {
|
axiosInstance.interceptors.request.use(config => {
|
||||||
// Tokenni olish
|
const token = getToken();
|
||||||
const token = await AsyncStorage.getItem('token');
|
const lang = getLanguage();
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Language’ni olish
|
if (lang) {
|
||||||
const language = await AsyncStorage.getItem('language');
|
config.headers['Accept-Language'] = lang;
|
||||||
if (language) {
|
|
||||||
config.headers['Accept-Language'] = language;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
});
|
});
|
||||||
|
|
||||||
axiosInstance.interceptors.response.use(
|
axiosInstance.interceptors.response.use(
|
||||||
response => response,
|
res => res,
|
||||||
async (error: AxiosError) => {
|
err => {
|
||||||
if (error.response?.status === 401) {
|
const status = err.response?.status;
|
||||||
await AsyncStorage.removeItem('token');
|
|
||||||
navigate('Login');
|
if (status === 401 && !isLoggingOut) {
|
||||||
|
isLoggingOut = true;
|
||||||
|
|
||||||
|
setToken(null);
|
||||||
|
authEvents.emit('logout');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
isLoggingOut = false;
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
return Promise.reject(error);
|
|
||||||
|
return Promise.reject(err);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
39
src/helpers/event.ts
Normal file
39
src/helpers/event.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// helpers/event.ts
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
|
import { createMMKV } from 'react-native-mmkv';
|
||||||
|
export const authEvents = new EventEmitter();
|
||||||
|
|
||||||
|
// MMKV instance
|
||||||
|
export const storage = createMMKV();
|
||||||
|
|
||||||
|
// Memory cachez
|
||||||
|
let tokenCache: string | null = null;
|
||||||
|
let languageCache: string | null = null;
|
||||||
|
|
||||||
|
// Load on app start
|
||||||
|
export function loadInitialAuthData() {
|
||||||
|
tokenCache = storage.getString('token') || null;
|
||||||
|
languageCache = storage.getString('language') || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getToken() {
|
||||||
|
return tokenCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setToken(token: string | null) {
|
||||||
|
tokenCache = token;
|
||||||
|
if (token) {
|
||||||
|
storage.set('token', token);
|
||||||
|
} else {
|
||||||
|
storage.remove('token');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLanguage() {
|
||||||
|
return languageCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setLanguage(lang: string) {
|
||||||
|
languageCache = lang;
|
||||||
|
storage.set('language', lang);
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import { useMutation } from '@tanstack/react-query';
|
||||||
@@ -6,6 +5,7 @@ import { authApi } from 'api/auth';
|
|||||||
import { otpPayload, resendPayload } from 'api/auth/type';
|
import { otpPayload, resendPayload } from 'api/auth/type';
|
||||||
import AppText from 'components/AppText';
|
import AppText from 'components/AppText';
|
||||||
import ErrorNotification from 'components/ErrorNotification';
|
import ErrorNotification from 'components/ErrorNotification';
|
||||||
|
import { setToken } from 'helpers/event';
|
||||||
import formatPhone from 'helpers/formatPhone';
|
import formatPhone from 'helpers/formatPhone';
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -77,7 +77,7 @@ const Confirm = () => {
|
|||||||
const { mutate, isPending } = useMutation({
|
const { mutate, isPending } = useMutation({
|
||||||
mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload),
|
mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload),
|
||||||
onSuccess: async res => {
|
onSuccess: async res => {
|
||||||
await AsyncStorage.setItem('token', res.data.accessToken);
|
setToken(res.data.accessToken);
|
||||||
navigation.navigate('Home');
|
navigation.navigate('Home');
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
// import { getApp } from '@react-native-firebase/app';
|
// import { getApp } from '@react-native-firebase/app';
|
||||||
// import { getMessaging, getToken } from '@react-native-firebase/messaging';
|
// import { getMessaging, getToken } from '@react-native-firebase/messaging';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
@@ -8,6 +7,7 @@ import { authApi } from 'api/auth';
|
|||||||
import { otpPayload, resendPayload } from 'api/auth/type';
|
import { otpPayload, resendPayload } from 'api/auth/type';
|
||||||
import AppText from 'components/AppText';
|
import AppText from 'components/AppText';
|
||||||
import ErrorNotification from 'components/ErrorNotification';
|
import ErrorNotification from 'components/ErrorNotification';
|
||||||
|
import { setToken } from 'helpers/event';
|
||||||
import formatPhone from 'helpers/formatPhone';
|
import formatPhone from 'helpers/formatPhone';
|
||||||
import React, { useRef, useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -83,7 +83,7 @@ const Confirm = ({
|
|||||||
const { mutate, isPending } = useMutation({
|
const { mutate, isPending } = useMutation({
|
||||||
mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload),
|
mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload),
|
||||||
onSuccess: async res => {
|
onSuccess: async res => {
|
||||||
await AsyncStorage.setItem('token', res.data.accessToken);
|
setToken(res.data.accessToken);
|
||||||
navigation.navigate('Confirm');
|
navigation.navigate('Confirm');
|
||||||
setErrorConfirm(null);
|
setErrorConfirm(null);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const CargoPrices = (props: CargoPricesProps) => {
|
|||||||
<View style={{ marginTop: 10, gap: 10, marginBottom: 20 }}>
|
<View style={{ marginTop: 10, gap: 10, marginBottom: 20 }}>
|
||||||
{data &&
|
{data &&
|
||||||
data.map(ref => (
|
data.map(ref => (
|
||||||
<View style={styles.cardWhite}>
|
<View style={styles.cardWhite} key={ref.id}>
|
||||||
<View style={styles.priceCard}>
|
<View style={styles.priceCard}>
|
||||||
<AppText style={styles.titleBlack}>{ref.title}</AppText>
|
<AppText style={styles.titleBlack}>{ref.title}</AppText>
|
||||||
<AppText style={[styles.titleBlack, { fontSize: 16 }]}>
|
<AppText style={[styles.titleBlack, { fontSize: 16 }]}>
|
||||||
@@ -152,7 +152,7 @@ const CargoPrices = (props: CargoPricesProps) => {
|
|||||||
<View style={{ marginTop: 20, gap: 10, marginBottom: 20 }}>
|
<View style={{ marginTop: 20, gap: 10, marginBottom: 20 }}>
|
||||||
{data &&
|
{data &&
|
||||||
data.map(ref => (
|
data.map(ref => (
|
||||||
<View style={styles.cardWhite}>
|
<View style={styles.cardWhite} key={ref.id}>
|
||||||
<View style={styles.priceCard}>
|
<View style={styles.priceCard}>
|
||||||
<AppText style={styles.titleBlack}>{ref.title}</AppText>
|
<AppText style={styles.titleBlack}>{ref.title}</AppText>
|
||||||
<AppText style={[styles.titleBlack, { fontSize: 16 }]}>
|
<AppText style={[styles.titleBlack, { fontSize: 16 }]}>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||||
import AppText from 'components/AppText';
|
import AppText from 'components/AppText';
|
||||||
|
import { setToken } from 'helpers/event';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
@@ -36,7 +36,7 @@ const ProfilePages = (props: componentNameProps) => {
|
|||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
try {
|
try {
|
||||||
await AsyncStorage.removeItem('token');
|
setToken(null);
|
||||||
navigation.reset({
|
navigation.reset({
|
||||||
index: 0,
|
index: 0,
|
||||||
routes: [{ name: 'Login' }], // login sahifasiga qaytarish
|
routes: [{ name: 'Login' }], // login sahifasiga qaytarish
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import packetsApi from 'api/packets';
|
import packetsApi from 'api/packets';
|
||||||
import Layout from 'components/Layout';
|
import Layout from 'components/Layout';
|
||||||
@@ -15,7 +14,6 @@ import {
|
|||||||
View,
|
View,
|
||||||
useWindowDimensions,
|
useWindowDimensions,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import Serach from 'svg/Serach';
|
|
||||||
import { DataInfo } from '../lib/data';
|
import { DataInfo } from '../lib/data';
|
||||||
import Filter from './Filter';
|
import Filter from './Filter';
|
||||||
import Order from './Order';
|
import Order from './Order';
|
||||||
@@ -61,9 +59,6 @@ const Status = () => {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(AsyncStorage.getItem('token'));
|
|
||||||
console.log('statusData', statusData);
|
|
||||||
|
|
||||||
const [modalVisible, setModalVisible] = useState(false);
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
const scaleAnim = React.useRef(new Animated.Value(0.8)).current;
|
const scaleAnim = React.useRef(new Animated.Value(0.8)).current;
|
||||||
const opacityAnim = React.useRef(new Animated.Value(0)).current;
|
const opacityAnim = React.useRef(new Animated.Value(0)).current;
|
||||||
@@ -140,11 +135,6 @@ const Status = () => {
|
|||||||
[refreshing, isFetching, onRefresh],
|
[refreshing, isFetching, onRefresh],
|
||||||
);
|
);
|
||||||
|
|
||||||
const searchIcon = useMemo(
|
|
||||||
() => <Serach color="#D8DADC" width={20 * scale} height={20 * scale} />,
|
|
||||||
[scale],
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isLoading || isFetching) {
|
if (isLoading || isFetching) {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import AnimatedScreen from 'components/AnimatedScreen';
|
import AnimatedScreen from 'components/AnimatedScreen';
|
||||||
|
import { getLanguage, storage } from 'helpers/event';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import FirstStep from 'screens/welcome/FirstStep';
|
import FirstStep from 'screens/welcome/FirstStep';
|
||||||
import SecondStep from 'screens/welcome/SecondStep';
|
import SecondStep from 'screens/welcome/SecondStep';
|
||||||
@@ -17,7 +17,7 @@ const Onboarding = ({ onFinish }: OnboardingProps) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadLang = async () => {
|
const loadLang = async () => {
|
||||||
const savedLang = await AsyncStorage.getItem('selectedLanguage');
|
const savedLang = getLanguage();
|
||||||
if (savedLang === 'ru' || savedLang === 'uz') {
|
if (savedLang === 'ru' || savedLang === 'uz') {
|
||||||
setLang(savedLang);
|
setLang(savedLang);
|
||||||
setStep(1);
|
setStep(1);
|
||||||
@@ -30,7 +30,7 @@ const Onboarding = ({ onFinish }: OnboardingProps) => {
|
|||||||
if (step < 3) {
|
if (step < 3) {
|
||||||
setStep(step + 1);
|
setStep(step + 1);
|
||||||
} else {
|
} else {
|
||||||
await AsyncStorage.setItem('hasSeenOnboarding', 'true');
|
storage.set('hasSeenOnboarding', 'true');
|
||||||
onFinish();
|
onFinish();
|
||||||
}
|
}
|
||||||
}, [step, onFinish]);
|
}, [step, onFinish]);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import { setLanguage } from 'helpers/event';
|
||||||
import i18n from 'i18n/i18n';
|
import i18n from 'i18n/i18n';
|
||||||
|
|
||||||
export const changeLanguage = async (lang: string) => {
|
export const changeLanguage = async (lang: string) => {
|
||||||
try {
|
try {
|
||||||
await AsyncStorage.setItem('language', lang);
|
setLanguage(lang);
|
||||||
await i18n.changeLanguage(lang);
|
await i18n.changeLanguage(lang);
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user