mmkv added

This commit is contained in:
Samandar Turgunboyev
2025-12-04 15:39:48 +05:00
parent 684d09e6b5
commit 87bd8cdea6
15 changed files with 1470 additions and 1450 deletions

View File

@@ -1,6 +1,8 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import axios, { AxiosError } from 'axios';
import { navigate } from 'components/NavigationRef';
// axiosInstance
import axios from 'axios';
import { authEvents, getLanguage, getToken, setToken } from 'helpers/event';
let isLoggingOut = false;
const axiosInstance = axios.create({
baseURL: 'https://api.cpcargo.uz/api/v1',
@@ -10,30 +12,38 @@ const axiosInstance = axios.create({
},
});
axiosInstance.interceptors.request.use(async config => {
// Tokenni olish
const token = await AsyncStorage.getItem('token');
axiosInstance.interceptors.request.use(config => {
const token = getToken();
const lang = getLanguage();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// Languageni olish
const language = await AsyncStorage.getItem('language');
if (language) {
config.headers['Accept-Language'] = language;
if (lang) {
config.headers['Accept-Language'] = lang;
}
return config;
});
axiosInstance.interceptors.response.use(
response => response,
async (error: AxiosError) => {
if (error.response?.status === 401) {
await AsyncStorage.removeItem('token');
navigate('Login');
res => res,
err => {
const status = err.response?.status;
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
View 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);
}

View File

@@ -1,4 +1,3 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useMutation } from '@tanstack/react-query';
@@ -6,6 +5,7 @@ import { authApi } from 'api/auth';
import { otpPayload, resendPayload } from 'api/auth/type';
import AppText from 'components/AppText';
import ErrorNotification from 'components/ErrorNotification';
import { setToken } from 'helpers/event';
import formatPhone from 'helpers/formatPhone';
import React, { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
@@ -77,7 +77,7 @@ const Confirm = () => {
const { mutate, isPending } = useMutation({
mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload),
onSuccess: async res => {
await AsyncStorage.setItem('token', res.data.accessToken);
setToken(res.data.accessToken);
navigation.navigate('Home');
setVisible(false);
},

View File

@@ -1,4 +1,3 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
// import { getApp } from '@react-native-firebase/app';
// import { getMessaging, getToken } from '@react-native-firebase/messaging';
import { useNavigation } from '@react-navigation/native';
@@ -8,6 +7,7 @@ import { authApi } from 'api/auth';
import { otpPayload, resendPayload } from 'api/auth/type';
import AppText from 'components/AppText';
import ErrorNotification from 'components/ErrorNotification';
import { setToken } from 'helpers/event';
import formatPhone from 'helpers/formatPhone';
import React, { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
@@ -83,7 +83,7 @@ const Confirm = ({
const { mutate, isPending } = useMutation({
mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload),
onSuccess: async res => {
await AsyncStorage.setItem('token', res.data.accessToken);
setToken(res.data.accessToken);
navigation.navigate('Confirm');
setErrorConfirm(null);
},

View File

@@ -54,7 +54,7 @@ const CargoPrices = (props: CargoPricesProps) => {
<View style={{ marginTop: 10, gap: 10, marginBottom: 20 }}>
{data &&
data.map(ref => (
<View style={styles.cardWhite}>
<View style={styles.cardWhite} key={ref.id}>
<View style={styles.priceCard}>
<AppText style={styles.titleBlack}>{ref.title}</AppText>
<AppText style={[styles.titleBlack, { fontSize: 16 }]}>
@@ -152,7 +152,7 @@ const CargoPrices = (props: CargoPricesProps) => {
<View style={{ marginTop: 20, gap: 10, marginBottom: 20 }}>
{data &&
data.map(ref => (
<View style={styles.cardWhite}>
<View style={styles.cardWhite} key={ref.id}>
<View style={styles.priceCard}>
<AppText style={styles.titleBlack}>{ref.title}</AppText>
<AppText style={[styles.titleBlack, { fontSize: 16 }]}>

View File

@@ -1,7 +1,7 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import AppText from 'components/AppText';
import { setToken } from 'helpers/event';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import {
@@ -36,7 +36,7 @@ const ProfilePages = (props: componentNameProps) => {
style: 'destructive',
onPress: async () => {
try {
await AsyncStorage.removeItem('token');
setToken(null);
navigation.reset({
index: 0,
routes: [{ name: 'Login' }], // login sahifasiga qaytarish

View File

@@ -1,4 +1,3 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useQuery } from '@tanstack/react-query';
import packetsApi from 'api/packets';
import Layout from 'components/Layout';
@@ -15,7 +14,6 @@ import {
View,
useWindowDimensions,
} from 'react-native';
import Serach from 'svg/Serach';
import { DataInfo } from '../lib/data';
import Filter from './Filter';
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 scaleAnim = React.useRef(new Animated.Value(0.8)).current;
const opacityAnim = React.useRef(new Animated.Value(0)).current;
@@ -140,11 +135,6 @@ const Status = () => {
[refreshing, isFetching, onRefresh],
);
const searchIcon = useMemo(
() => <Serach color="#D8DADC" width={20 * scale} height={20 * scale} />,
[scale],
);
if (isLoading || isFetching) {
return (
<Layout>

View File

@@ -1,5 +1,5 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import AnimatedScreen from 'components/AnimatedScreen';
import { getLanguage, storage } from 'helpers/event';
import { useCallback, useEffect, useMemo, useState } from 'react';
import FirstStep from 'screens/welcome/FirstStep';
import SecondStep from 'screens/welcome/SecondStep';
@@ -17,7 +17,7 @@ const Onboarding = ({ onFinish }: OnboardingProps) => {
useEffect(() => {
const loadLang = async () => {
const savedLang = await AsyncStorage.getItem('selectedLanguage');
const savedLang = getLanguage();
if (savedLang === 'ru' || savedLang === 'uz') {
setLang(savedLang);
setStep(1);
@@ -30,7 +30,7 @@ const Onboarding = ({ onFinish }: OnboardingProps) => {
if (step < 3) {
setStep(step + 1);
} else {
await AsyncStorage.setItem('hasSeenOnboarding', 'true');
storage.set('hasSeenOnboarding', 'true');
onFinish();
}
}, [step, onFinish]);

View File

@@ -1,9 +1,9 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { setLanguage } from 'helpers/event';
import i18n from 'i18n/i18n';
export const changeLanguage = async (lang: string) => {
try {
await AsyncStorage.setItem('language', lang);
setLanguage(lang);
await i18n.changeLanguage(lang);
} catch (error) {}
};