parent
a680b975c3
commit
ebaefb4b66
63 changed files with 1726 additions and 1103 deletions
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 46 KiB |
@ -1,116 +0,0 @@ |
||||
import * as React from 'react'; |
||||
import {NavigationContainer} from '@react-navigation/native'; |
||||
import {createNativeStackNavigator} from '@react-navigation/native-stack'; |
||||
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; |
||||
import Splash from './src/screens/Splash'; |
||||
import Home from './src/screens/Home'; |
||||
import Login from './src/screens/Login'; |
||||
import Otp from './src/screens/Otp'; |
||||
import Product from './src/screens/Product'; |
||||
import Products from './src/screens/Products'; |
||||
import ShoppingCart from './src/screens/ShoppingCart'; |
||||
import QR from './src/screens/QR/index'; |
||||
import i18n from './src/services/i18n'; |
||||
import {useTranslation} from 'react-i18next'; |
||||
import Profile from './src/screens/Profile'; |
||||
import Videos from './src/screens/Videos'; |
||||
import Exams from './src/screens/Exams'; |
||||
import OrderDetails from './src/screens/OrderDetails'; |
||||
|
||||
const mapStateToProps = state => { |
||||
return { |
||||
profile: state.profile, |
||||
config: state.config, |
||||
}; |
||||
}; |
||||
|
||||
const Stack = createNativeStackNavigator(); |
||||
const Tab = createBottomTabNavigator(); |
||||
|
||||
function BottomTab(props) { |
||||
|
||||
return ( |
||||
<Tab.Navigator initialRouteName={'Home'}> |
||||
<Tab.Screen |
||||
name={'Profile'} |
||||
component={Profile} |
||||
/> |
||||
<Tab.Screen |
||||
name={'Exams'} |
||||
component={Exams} |
||||
/> |
||||
<Tab.Screen |
||||
name={'Videos'} |
||||
component={Videos} |
||||
/> |
||||
<Tab.Screen |
||||
name={'محصولات'} |
||||
component={Products} |
||||
/> |
||||
<Tab.Screen |
||||
name={'خانه'} |
||||
component={Home} |
||||
options={{ |
||||
headerShown : false |
||||
// title: t('home'),
|
||||
}} |
||||
/> |
||||
</Tab.Navigator> |
||||
); |
||||
} |
||||
|
||||
function Navigator(props) { |
||||
React.useEffect(() => { |
||||
// i18n.changeLanguage(props.config.lan);
|
||||
}, [props.config]); |
||||
|
||||
return ( |
||||
<NavigationContainer> |
||||
<Stack.Navigator> |
||||
<Stack.Screen |
||||
options={{headerShown: false}} |
||||
name="Splash" |
||||
component={Splash} |
||||
/> |
||||
<Stack.Screen |
||||
name="Login" |
||||
component={Login} |
||||
options={{headerShown: false}} |
||||
/> |
||||
{/* <Stack.Screen |
||||
name="Home" |
||||
component={Home} |
||||
options={{headerShown: false}} |
||||
/> */} |
||||
<Stack.Screen |
||||
name="Otp" |
||||
component={Otp} |
||||
options={{headerShown: false}} |
||||
/> |
||||
<Stack.Screen |
||||
name="Home" |
||||
component={BottomTab} |
||||
options={{headerShown: false}} |
||||
/> |
||||
<Stack.Screen |
||||
name="Product" |
||||
component={Product} |
||||
options={{headerShown: false}} |
||||
/> |
||||
<Stack.Screen |
||||
name="Products" |
||||
component={BottomTab} |
||||
options={{headerShown: false}} |
||||
/> |
||||
<Stack.Screen name="QR" component={QR} options={{headerShown: true}} /> |
||||
<Stack.Screen |
||||
name="سبد خرید" |
||||
component={ShoppingCart} |
||||
options={{headerShown: true}} |
||||
/> |
||||
</Stack.Navigator> |
||||
</NavigationContainer> |
||||
); |
||||
} |
||||
|
||||
export default Navigator; |
@ -1,2 +0,0 @@ |
||||
export const PROFILE_RECORD = 'PROFILE_RECORD'; |
||||
export const APP_CONFIG = 'APP_CONFIG'; |
@ -0,0 +1,9 @@ |
||||
export const ApiConfig = { |
||||
apiKey: 'AIzaSyBBksq-Asxq2M4Ot-75X19IyrEYJqNBPcg', |
||||
authDomain: 'dnvn.ir', |
||||
baseUrl: 'https://dnvn.ir/api/v1', |
||||
//baseUrl: 'http://localhost:3030/api/v1',
|
||||
loginURL: 'user/login', |
||||
otploginURL: 'user/otp/login', |
||||
logoutURL: 'user/logout', |
||||
}; |
@ -1,29 +0,0 @@ |
||||
export function DefaultReducer(key, initialState = {}) { |
||||
return (state = initialState, {type = '', payload = {}}) => { |
||||
switch (type) { |
||||
case key: |
||||
return {...state, ...payload}; |
||||
} |
||||
return state; |
||||
}; |
||||
} |
||||
|
||||
export function buildAction(id) { |
||||
return function(payload) { |
||||
return { |
||||
type: id, |
||||
payload: payload, |
||||
}; |
||||
}; |
||||
} |
||||
|
||||
export function buildActionForKey(id, key) { |
||||
return function(payload) { |
||||
let result = { |
||||
type: id, |
||||
payload: {}, |
||||
}; |
||||
result.payload[key] = payload; |
||||
return result; |
||||
}; |
||||
} |
@ -1,14 +0,0 @@ |
||||
import {combineReducers} from 'redux'; |
||||
import {DefaultReducer} from './DefaultReducer'; |
||||
import * as action from '../actions/actionTypes'; |
||||
|
||||
const allReducers = combineReducers({ |
||||
profile: DefaultReducer(action.PROFILE_RECORD, { |
||||
isLogin: false, |
||||
}), |
||||
config: DefaultReducer(action.APP_CONFIG, { |
||||
lan: 'fa', |
||||
}), |
||||
}); |
||||
|
||||
export default allReducers; |
@ -0,0 +1,27 @@ |
||||
import proxy from "../proxy"; |
||||
const blog = { |
||||
list: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("public/blogList", data, { dispatch }), |
||||
// update:
|
||||
// (data = {}, data2 = {}) =>
|
||||
// async (dispatch : Dispatch) => {
|
||||
// await proxy.put("blog/update", data);
|
||||
// await proxy.get("blog/list", data2, { dispatch });
|
||||
// },
|
||||
// add:
|
||||
// (data = {}, data2 = {}) =>
|
||||
// async (dispatch : Dispatch) => {
|
||||
// await proxy.post("blog/add", data);
|
||||
// await proxy.get("blog/list", data2, { dispatch });
|
||||
// },
|
||||
// del:
|
||||
// (data = {}, data2 = {}) =>
|
||||
// async (dispatch : Dispatch) => {
|
||||
// await proxy.delete("blog/delete", data);
|
||||
// await proxy.get("blog/list", data2, { dispatch });
|
||||
// },
|
||||
}; |
||||
|
||||
export default blog; |
@ -0,0 +1,44 @@ |
||||
import proxy from "../proxy"; |
||||
const book = { |
||||
list: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("book/list", data, { dispatch }), |
||||
info: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("book/info", data, { dispatch }), |
||||
setLessonActive: (data) => async (dispatch) => |
||||
await dispatch({ type: "book/lesson/active", data: data }), |
||||
gradeFilter: (data) => async (dispatch) => |
||||
await dispatch({ type: "book/gradeFilter", data: data }), |
||||
sortFilter: (data) => async (dispatch) => |
||||
await dispatch({ type: "book/sortFilter", data: data }), |
||||
|
||||
// update:
|
||||
// (data = {}, data2 = {}) =>
|
||||
// async (dispatch : Dispatch) => {
|
||||
// await proxy.put("book/update", data);
|
||||
// await proxy.get("book/list", data2, { dispatch });
|
||||
// },
|
||||
// add:
|
||||
// (data = {}, data2 = {}) =>
|
||||
// async (dispatch) => {
|
||||
// await proxy.post("book/add", data);
|
||||
// await proxy.get("book/list", data2, { dispatch });
|
||||
// },
|
||||
// del:
|
||||
// (data = {}, data2 = {}) =>
|
||||
// async (dispatch) => {
|
||||
// await proxy.delete("book/delete", data);
|
||||
// await proxy.get("book/list", data2, { dispatch });
|
||||
// },
|
||||
// searchBook: (data) => async (dispatch) => {
|
||||
// dispatch({ type: "book/search", data: data });
|
||||
// },
|
||||
// filterBook: (data) => async (dispatch) => {
|
||||
// dispatch({ type: "book/filter", data: data });
|
||||
// },
|
||||
}; |
||||
|
||||
export default book; |
@ -0,0 +1,14 @@ |
||||
import proxy from "../proxy"; |
||||
import { Dispatch } from "redux"; |
||||
const content = { |
||||
listVOD: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("content/listVOD", data, { dispatch }), |
||||
infoVOD: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("content/infoVOD", data, { dispatch }), |
||||
}; |
||||
|
||||
export default content; |
@ -0,0 +1,20 @@ |
||||
import proxy from "../proxy"; |
||||
import { Dispatch } from "redux"; |
||||
const faq = { |
||||
list: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("faq/list", data, { dispatch }), |
||||
add: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.post("faq/add", data, { dispatch }), |
||||
selectFaq: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await dispatch({ type: "faq/selectFaq", data: data }), |
||||
searchFaq: (data) => async (dispatch) => |
||||
await dispatch({ type: "faq/search", data: data }), |
||||
}; |
||||
|
||||
export default faq; |
@ -0,0 +1,22 @@ |
||||
import proxy from "../proxy"; |
||||
const file = { |
||||
upload: |
||||
(data = {}) => |
||||
async (dispatch) => { |
||||
var formData = new FormData(); |
||||
for (let key in data) formData.append(key, data[key]); |
||||
return await proxy.post( |
||||
"file/upload", |
||||
formData, |
||||
{ |
||||
dispatch, |
||||
headers: { |
||||
"Content-Type": "multipart/form-data", |
||||
}, |
||||
}, |
||||
data |
||||
); |
||||
}, |
||||
}; |
||||
|
||||
export default file; |
@ -0,0 +1,16 @@ |
||||
// @create-index
|
||||
export { default as publicApi } from "./public"; |
||||
export { default as user } from "./user"; |
||||
export { default as book } from "./book"; |
||||
export { default as blog } from "./blog"; |
||||
export { default as product } from "./product"; |
||||
export { default as userFactor } from "./userFactor"; |
||||
export { default as userProduct } from "./userProduct"; |
||||
export { default as content } from "./content"; |
||||
export { default as faq } from "./faq"; |
||||
export { default as file } from "./file"; |
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,26 @@ |
||||
import proxy from "../proxy"; |
||||
const product = { |
||||
listVOD: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("product/listVOD", data, { dispatch }), |
||||
addVOD: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.post("product/addVOD", data); |
||||
await proxy.get("product/listVOD", data2, { dispatch }); |
||||
}, |
||||
deleteVOD: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.delete("product/deleteVOD", data); |
||||
await proxy.get("product/listVOD", data2, { dispatch }); |
||||
}, |
||||
selectVOD: |
||||
(data = {}) => |
||||
async (dispatch) => { |
||||
await dispatch({ type: "product/selectVOD", data }); |
||||
}, |
||||
}; |
||||
|
||||
export default product; |
@ -0,0 +1,50 @@ |
||||
import proxy from "../proxy"; |
||||
const publicApi = { |
||||
setIsDark: (data) => async (dispatch) => |
||||
await dispatch({ type: "public/setIsDark", data: data }), |
||||
getHomeData: (data) => async (dispatch) => |
||||
await proxy.get("public/homePage", data, { dispatch }), |
||||
|
||||
setFaqActive: (data) => async (dispatch) => |
||||
await dispatch({ type: "public/faq/activate", data: data }), |
||||
bookInfo: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("public/vod/bookCourse", data, { dispatch }), |
||||
bookSection: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("public/vod/bookSection", data, { dispatch }), |
||||
getContactData: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("public/contact", data, { dispatch }), |
||||
|
||||
getBlogList: (data) => async (dispatch) => |
||||
await proxy.get("public/blogList", data, { dispatch }), |
||||
|
||||
getBlogInfo: (data) => async (dispatch) => |
||||
await proxy.get("public/blogInfo", data, { dispatch }), |
||||
setSubscribe: (data) => async (dispatch) => |
||||
await dispatch({ type: "public/setSubscribe", data: data }), |
||||
getProvince: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("public/province", data, { dispatch }), |
||||
getCity: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("public/city", data, { dispatch }), |
||||
selectMenu: (data) => async (dispatch) => |
||||
await dispatch({ type: "public/selectMenu", data: data }), |
||||
getHeader: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("public/VOD/homePage", data, { dispatch }), |
||||
activeCategory: (data) => async (dispatch) => |
||||
await dispatch({ type: "active/category", data: data }), |
||||
setVideoActive: (data) => async (dispatch) => |
||||
await dispatch({ type: "active/video", data: data }), |
||||
}; |
||||
|
||||
export default publicApi; |
@ -0,0 +1,65 @@ |
||||
import proxy from "../proxy"; |
||||
|
||||
const user = { |
||||
otp: (data) => async (dispatch) => { |
||||
console.log(data); |
||||
await proxy.post("public/sendOTP", data, { dispatch }); |
||||
}, |
||||
|
||||
otp_login: (data) => async (dispatch) => |
||||
await proxy.login("user/otp/login", data, { dispatch }), |
||||
|
||||
login: (data) => async (dispatch) => |
||||
await proxy.login("user/login", data, { dispatch }), |
||||
|
||||
// register: (data : undefined) => async (dispatch : Dispatch) =>
|
||||
// await proxy.login("user/register", data, { dispatch }),
|
||||
|
||||
// switchRole: (data : String) => async (dispatch : Dispatch) =>
|
||||
// await proxy.login("user/switchRole", data, { dispatch }),
|
||||
|
||||
logout: (data) => async (dispatch) => |
||||
await proxy.logout("user/logout", data, { dispatch }), |
||||
|
||||
getUserRole: (data) => async (dispatch) => |
||||
await proxy.get("user/getUserRole", data, { dispatch }), |
||||
|
||||
// list:
|
||||
// (data = {}) =>
|
||||
// async (dispatch : Dispatch) =>
|
||||
// await proxy.get("user/list", data, { dispatch }),
|
||||
// domains:
|
||||
// (data = {}) =>
|
||||
// async (dispatch : Dispatch) =>
|
||||
// await proxy.get("user/domains", data, { dispatch }),
|
||||
// getmothers:
|
||||
// (data = {}) =>
|
||||
// async (dispatch : Dispatch) =>
|
||||
// await proxy.get("mothers/list", data, {
|
||||
// dispatch,
|
||||
// }),
|
||||
getProfile: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("user/getProfile", data, { dispatch }), |
||||
setProfile: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.put("user/setProfile", data, { dispatch }); |
||||
await proxy.get("user/getProfile", data2, { dispatch }); |
||||
}, |
||||
add: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.post("user/add", data); |
||||
await proxy.get("user/list", data2, { dispatch }); |
||||
}, |
||||
del: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.delete("user/delete", data); |
||||
await proxy.get("user/list", data2, { dispatch }); |
||||
}, |
||||
}; |
||||
|
||||
export default user; |
@ -0,0 +1,55 @@ |
||||
import proxy from "../proxy"; |
||||
const userFactor = { |
||||
//dnvn
|
||||
list: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("userFactor/list", data, { dispatch }), |
||||
payment: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.post("userFactor/payment", data, { dispatch }); |
||||
}, |
||||
add: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.post("userFactor/add", data, { dispatch }); |
||||
await proxy.get("userFactor/list", data2, { dispatch }); |
||||
}, |
||||
del: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.delete("userFactor/delete", data); |
||||
await proxy.get("userFactor/list", data2, { dispatch }); |
||||
}, |
||||
|
||||
//vod
|
||||
payment: |
||||
(data1 = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.post("userProduct/addVOD", data1, { dispatch }); |
||||
await proxy.post("userFactor/paymentVOD", data2, { dispatch }); |
||||
}, |
||||
verify: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.post("userFactor/verifyVOD", data, { dispatch }), |
||||
info: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("userFactor/info", data, { dispatch }), |
||||
update: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.put("userFactor/update", data, { dispatch }); |
||||
await proxy.get("userFactor/info", data2, { dispatch }); |
||||
}, |
||||
deleteUserOffCode: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.delete("userFactor/deleteUserOffCode", data, { dispatch }); |
||||
await proxy.get("userFactor/info", data2, { dispatch }); |
||||
}, |
||||
}; |
||||
|
||||
export default userFactor; |
@ -0,0 +1,33 @@ |
||||
import proxy from "../proxy"; |
||||
const userProduct = { |
||||
list: |
||||
(data = {}) => |
||||
async (dispatch) => { |
||||
await proxy.get("userProduct/list", data, { dispatch }); |
||||
}, |
||||
info: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.get("userProduct/info", data, { dispatch }), |
||||
update: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.put("userProduct/update", data); |
||||
await proxy.get("userProduct/list", data2, { dispatch }); |
||||
}, |
||||
add: |
||||
(data = {}, data2 = {}, data3 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.post("userProduct/add", data, { dispatch }); |
||||
await proxy.get("userProduct/list", data2, { dispatch }); |
||||
await proxy.get("userFactor/info", data3, { dispatch }); |
||||
}, |
||||
del: |
||||
(data = {}, data2 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.delete("userProduct/delete", data); |
||||
await proxy.get("userProduct/list", data2, { dispatch }); |
||||
}, |
||||
}; |
||||
|
||||
export default userProduct; |
@ -0,0 +1,6 @@ |
||||
// @create-index
|
||||
|
||||
export { default as actions } from './actions'; |
||||
export { default as proxy } from './proxy.js'; |
||||
export { default as reducers } from './reducers'; |
||||
export { default as store } from './store.js'; |
@ -0,0 +1,171 @@ |
||||
import { ApiConfig } from "../constants/defaultValues"; |
||||
import axios from "axios"; |
||||
import AsyncStorage from "@react-native-async-storage/async-storage"; |
||||
import { useNavigation } from "@react-navigation/native"; |
||||
|
||||
let { baseUrl } = ApiConfig; |
||||
let access; |
||||
() => { |
||||
access = AsyncStorage.getItem("access"); |
||||
}; |
||||
|
||||
baseUrl = baseUrl + "/"; |
||||
|
||||
const Axios = axios.create({ |
||||
withCredentials: true, |
||||
validateStatus: null, |
||||
baseURL: baseUrl, |
||||
//headers: access ? { Authorization: `Bearer ${access}` } : {},
|
||||
}); |
||||
class Proxy { |
||||
get = (url, params, opt, data) => { |
||||
try { |
||||
this.check( |
||||
url, |
||||
opt, |
||||
() => Axios.get(url, { params, ...opt }), |
||||
data || params |
||||
); |
||||
} catch (error) { |
||||
console.log("proxy get error! : ", error); |
||||
} |
||||
}; |
||||
|
||||
post = (url, params, opt, data) => { |
||||
try { |
||||
this.check( |
||||
url, |
||||
opt, |
||||
() => Axios.post(url, params, opt), |
||||
data || params |
||||
); |
||||
} catch (error) { |
||||
console.log("proxy post error! : ", error); |
||||
} |
||||
}; |
||||
|
||||
put = (url, params, opt, data) => { |
||||
try { |
||||
this.check( |
||||
url, |
||||
opt, |
||||
() => Axios.put(url, params, opt), |
||||
data || params |
||||
); |
||||
} catch (error) { |
||||
console.log("proxy put error! : ", error); |
||||
} |
||||
}; |
||||
|
||||
delete = (url, params, opt, data) => { |
||||
try { |
||||
this.check( |
||||
url, |
||||
opt, |
||||
() => Axios.delete(url, { ...opt, data: params }), |
||||
data || params |
||||
); |
||||
} catch (error) { |
||||
console.log("proxy delete error! : ", error); |
||||
} |
||||
}; |
||||
|
||||
check = (url, { dispatch }, fetch, params) => { |
||||
try { |
||||
dispatch = dispatch || (() => {}); |
||||
dispatch({ type: url.split("/")[0] + "/" + "loading" }); |
||||
let response = fetch(); |
||||
switch (response.status) { |
||||
case 200: |
||||
dispatch({ type: url, data: response.data.data, params }); |
||||
return response.data.data; |
||||
case 401: |
||||
if (this.refresh()) { |
||||
let response = fetch(); |
||||
dispatch({ type: url, data: response.data.data, params }); |
||||
return response.data.data; |
||||
} |
||||
break; |
||||
default: |
||||
dispatch({ |
||||
type: url.split("/")[0] + "/" + "error", |
||||
data: response.data, |
||||
params, |
||||
}); |
||||
} |
||||
return false; |
||||
} catch (error) { |
||||
console.log("proxy check error! : ", error); |
||||
} |
||||
}; |
||||
|
||||
refresh = () => { |
||||
try { |
||||
const navigation = useNavigation(); |
||||
let refresh = AsyncStorage.getItem("refresh"); |
||||
if (!refresh) navigation.push("Root"); |
||||
let login = this.login( |
||||
"user/login", |
||||
{}, |
||||
{ headers: { Authorization: `Bearer ${refresh}` } } |
||||
); |
||||
return login ? true : false; |
||||
} catch (error) { |
||||
console.log("proxy refresh error! : ", error); |
||||
} |
||||
}; |
||||
|
||||
login = (url, params, { dispatch }) => { |
||||
try { |
||||
console.log('------------------------------login---------------------------------'); |
||||
this.post(url, params, { |
||||
dispatch: (obj) => { |
||||
let login = obj.data; |
||||
console.log('login data: ',login); |
||||
if (!login || !login.refreshToken) return false; |
||||
const refresh = ["refresh", login.refreshToken]; |
||||
const access = ["access", login.accessToken]; |
||||
const userData = ["userData", JSON.stringify(login.profile)]; |
||||
AsyncStorage.multiSet([refresh, access, userData]); |
||||
delete login.refreshToken; |
||||
delete login.accessToken; |
||||
dispatch(obj); |
||||
}, |
||||
}); |
||||
} catch (error) { |
||||
console.log("proxy login error! : ", error); |
||||
} |
||||
}; |
||||
|
||||
logout = (url, params, { dispatch }) => { |
||||
try { |
||||
this.post(url, params, { |
||||
dispatch: (obj) => { |
||||
const keys = ["refresh", "access", "userData"]; |
||||
AsyncStorage.multiRemove(keys); |
||||
dispatch(obj); |
||||
}, |
||||
}); |
||||
} catch (error) { |
||||
console.log("proxy logout error : ", error); |
||||
} |
||||
}; |
||||
status = () => { |
||||
try { |
||||
let refresh = AsyncStorage.getItem("refresh"); |
||||
let userData = AsyncStorage.getItem("userData"); |
||||
if (!refresh) return false; |
||||
if (refresh == "undefined") { |
||||
const keys = ["refresh", "access", "userData"]; |
||||
AsyncStorage.multiRemove(keys); |
||||
return false; |
||||
} |
||||
return userData || null; |
||||
} catch (error) { |
||||
console.log("proxy status error : ", error); |
||||
} |
||||
}; |
||||
} |
||||
const _proxy = new Proxy(); |
||||
|
||||
export default _proxy; |
@ -0,0 +1,26 @@ |
||||
const initialState = { |
||||
loading: false, |
||||
error: null, |
||||
list: [], |
||||
}; |
||||
export default function blog(state = initialState, action) { |
||||
let { type, data } = action; |
||||
switch (type) { |
||||
case "public/blogList": |
||||
return { ...state, loading: false, list: data, error: null }; |
||||
// case "blog/update":
|
||||
// return { ...state, loading: false, error: null };
|
||||
// case "blog/add":
|
||||
// return { ...state, loading: false, error: null };
|
||||
// case "blog/delete":
|
||||
// return { ...state, loading: false, error: null };
|
||||
/////////////
|
||||
case "blog/loading": |
||||
return { ...state, loading: true }; |
||||
case "blog/error": |
||||
// toast.error(data.message);
|
||||
return { ...state, loading: false, error: data.message }; |
||||
default: |
||||
return state; |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
const initialState = { |
||||
loading: false, |
||||
error: null, |
||||
list: [], |
||||
searchResult: [], |
||||
search: null, |
||||
}; |
||||
|
||||
export default function faq(state = initialState, action) { |
||||
let { type, data } = action; |
||||
switch (type) { |
||||
case "faq/list": |
||||
return { ...state, loading: false, list: data, error: null }; |
||||
case "faq/add": |
||||
return { ...state, loading: false, error: null }; |
||||
case "faq/selectFaq": |
||||
return { |
||||
...state, |
||||
loading: false, |
||||
error: null, |
||||
list: !state.search |
||||
? state.list.map((item) => |
||||
item.id === data |
||||
? { ...item, active: !item.active } |
||||
: { ...item, active: false } |
||||
) |
||||
: state.list, |
||||
searchResult: state.search |
||||
? state.searchResult.map((item) => |
||||
item.id === data |
||||
? { ...item, active: !item.active } |
||||
: { ...item, active: false } |
||||
) |
||||
: state.searchResult, |
||||
}; |
||||
case "faq/search": |
||||
return { |
||||
...state, |
||||
loading: false, |
||||
error: null, |
||||
search: data, |
||||
searchResult: state.list.filter( |
||||
(item) => |
||||
item.title.indexOf(data) !== -1 || |
||||
item.description.indexOf(data) !== -1 |
||||
), |
||||
}; |
||||
case "faq/loading": |
||||
return { ...state, loading: true }; |
||||
case "faq/error": |
||||
// toast.error(data.message);
|
||||
return { ...state, loading: false, error: data.message }; |
||||
default: |
||||
return state; |
||||
} |
||||
} |
@ -0,0 +1,26 @@ |
||||
const initialState = { |
||||
loading: false, |
||||
error: null, |
||||
uploads: {}, |
||||
lastUpload: null, |
||||
}; |
||||
|
||||
export default function file(state = initialState, action) { |
||||
let { type, data, params } = action; |
||||
switch (type) { |
||||
case "file/upload": |
||||
return { |
||||
...state, |
||||
loading: false, |
||||
error: null, |
||||
uploads: { ...state.uploads, [params?.target || "last"]: data.id }, |
||||
lastUpload: data.id, |
||||
}; |
||||
case "file/loading": |
||||
return { ...state, loading: true }; |
||||
case "file/error": |
||||
return { ...state, loading: false, error: data.message }; |
||||
default: |
||||
return state; |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
// @create-index
|
||||
export { default as publicApi } from "./public"; |
||||
export { default as user } from "./user"; |
||||
export { default as book } from "./book"; |
||||
export { default as blog } from "./blog"; |
||||
export { default as product } from "./product"; |
||||
export { default as faq } from "./faq"; |
||||
export { default as file } from "./file"; |
||||
export { default as userFactor } from "./userFactor"; |
||||
export { default as userProduct } from "./userProduct"; |
@ -0,0 +1,26 @@ |
||||
const initialState = { |
||||
loading: false, |
||||
error: null, |
||||
listVOD: [], |
||||
selectedVOD: null, |
||||
}; |
||||
export default function product(state = initialState, action) { |
||||
let { type, data } = action; |
||||
switch (type) { |
||||
case "product/listVOD": |
||||
return { ...state, loading: false, listVOD: data, error: null }; |
||||
case "product/addVOD": |
||||
return { ...state, loading: false, error: null }; |
||||
case "product/deleteVOD": |
||||
return { ...state, loading: false, error: null }; |
||||
case "product/selectVOD": |
||||
return {...state, selectedVOD : data}; |
||||
case "product/loading": |
||||
return { ...state, loading: true }; |
||||
case "product/error": |
||||
// toast.error(data.message);
|
||||
return { ...state, loading: false, error: data.message }; |
||||
default: |
||||
return state; |
||||
} |
||||
} |
@ -0,0 +1,64 @@ |
||||
import proxy from "../proxy"; |
||||
import AsyncStorage from "@react-native-async-storage/async-storage"; |
||||
|
||||
let initialState = { |
||||
status: proxy.status(), |
||||
loading: false, |
||||
error: null, |
||||
list: null, |
||||
domains: [], |
||||
mothers: [], |
||||
profileStatus: false, |
||||
setDone: false, |
||||
setLogin: false, |
||||
check : 'check' |
||||
}; |
||||
|
||||
const user = (state = initialState, action) => { |
||||
let { type, data } = action; |
||||
switch (type) { |
||||
// case "user/login":
|
||||
// case "user/register":
|
||||
// case "user/switchRole":
|
||||
case "public/sendOTP": |
||||
return { ...state, loading: false, error: null }; |
||||
case "user/login": |
||||
case "user/otp/login": |
||||
return { |
||||
...state, |
||||
loading: false, |
||||
status: data.profile, |
||||
error: null, |
||||
setLogin: !state.setLogin, |
||||
}; |
||||
case "user/getProfile": |
||||
const myData = JSON.stringify(data); |
||||
try{ |
||||
AsyncStorage.setItem("userData", myData); |
||||
}catch(error){ |
||||
console.log('user/getProfile', error); |
||||
} |
||||
return { |
||||
...state, |
||||
loading: false, |
||||
status: data, |
||||
error: null, |
||||
setDone: false, |
||||
}; |
||||
case "user/logout": |
||||
return { ...state, loading: false, status: proxy.status(), error: null }; |
||||
case "user/getUserRole": |
||||
return { ...state, loading: false, userRoles: data, error: null }; |
||||
case "user/setProfile": |
||||
// toast.success("تغییرات اعمال شد.");
|
||||
return { ...state, loading: false, error: null, setDone: true }; |
||||
case "loading": |
||||
return { ...state, loading: true }; |
||||
case "error": |
||||
return { ...state, loading: false, error: data.message }; |
||||
default: |
||||
return state; |
||||
} |
||||
} |
||||
|
||||
export default user; |
@ -0,0 +1,60 @@ |
||||
import {useNavigation} from '@react-navigation/native'; |
||||
|
||||
const initialState = { |
||||
loading: false, |
||||
error: null, |
||||
list: null, |
||||
info: null, |
||||
sum: null, |
||||
checkEmpty: false, |
||||
isVerified: null, |
||||
}; |
||||
export default function userFactor(state = initialState, action) { |
||||
// const navigation = useNavigation();
|
||||
|
||||
let { type, data } = action; |
||||
switch (type) { |
||||
//dnvn
|
||||
case "userFactor/list": |
||||
const checkEmpty = data.filter( |
||||
(item) => item.condition === 2 && item.product.productType === (1 || 3) |
||||
); |
||||
return { |
||||
...state, |
||||
loading: false, |
||||
list: data, |
||||
checkEmpty: checkEmpty.length > 0 ? false : true, |
||||
error: null, |
||||
}; |
||||
case "userFactor/info": |
||||
return { ...state, loading: false, info: data, error: null }; |
||||
case "userFactor/add": |
||||
// toast.success("درخواست شما با موفقیت انجام شد.");
|
||||
return { ...state, loading: false, error: null, sum: data.payPrice }; |
||||
case "userFactor/delete": |
||||
return { ...state, loading: false, error: null }; |
||||
case "userFactor/payment": |
||||
// navigation.push(data);
|
||||
return { ...state, loading: false, error: null }; |
||||
//vod
|
||||
case "userFactor/myList": |
||||
return { ...state, loading: false, list: data, error: null }; |
||||
case "userFactor/update": |
||||
// toast.success("درخواست شما با موفقیت انجام شد.");
|
||||
return { ...state, loading: false, error: null }; |
||||
case "userFactor/deleteUserOffCode": |
||||
return { ...state, loading: false, error: null }; |
||||
case "userFactor/paymentVOD": |
||||
// navigation.push(data);
|
||||
return { ...state, loading: false, error: null, isVerified: false }; |
||||
case "userFactor/verifyVOD": |
||||
return { ...state, loading: false, error: null, isVerified: true }; |
||||
case "userFactor/loading": |
||||
return { ...state, loading: true }; |
||||
case "userFactor/error": |
||||
// toast.error(data.message);
|
||||
return { ...state, loading: false, error: data.message }; |
||||
default: |
||||
return state; |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
const initialState = { |
||||
loading: false, |
||||
error: null, |
||||
list: [], |
||||
info: null, |
||||
sum: null, |
||||
checkEmpty: false, |
||||
hasPhysical: false, |
||||
}; |
||||
export default function userFactor(state = initialState, action) { |
||||
let { type, data } = action; |
||||
switch (type) { |
||||
case "userProduct/list": |
||||
const checkEmpty = data.filter( |
||||
(item) => item.condition === 2 && item.product.productType === (1 || 3) |
||||
); |
||||
const hasPhysical = |
||||
data.filter((item) => item.product.productType === 2).length > 0 |
||||
? true |
||||
: false; |
||||
return { |
||||
...state, |
||||
loading: false, |
||||
list: data, |
||||
checkEmpty: checkEmpty.length > 0 ? false : true, |
||||
error: null, |
||||
hasPhysical: hasPhysical, |
||||
}; |
||||
case "userProduct/info": |
||||
return { ...state, loading: false, info: data, error: null }; |
||||
case "userProduct/update": |
||||
return { ...state, loading: false, error: null }; |
||||
case "userProduct/add": |
||||
// if (window.location.pathname.indexOf("products") !== -1) {
|
||||
// toast.success("درخواست شما با موفقیت انجام شد.");
|
||||
// }
|
||||
return { ...state, loading: false, error: null, sum: data.payPrice }; |
||||
case "userProduct/delete": |
||||
return { ...state, loading: false, error: null }; |
||||
case "userProduct/loading": |
||||
return { ...state, loading: true }; |
||||
case "userProduct/error": |
||||
// toast.error(data.message);
|
||||
return { ...state, loading: false, error: data.message }; |
||||
default: |
||||
return state; |
||||
} |
||||
} |
@ -1,10 +0,0 @@ |
||||
import mocks from './mocks'; |
||||
import mainServices from './services'; |
||||
|
||||
const mock = false; |
||||
|
||||
let services = {...mainServices}; |
||||
if (mock) { |
||||
services = mocks; |
||||
} |
||||
export default services; |
@ -1,18 +0,0 @@ |
||||
import { asyncAwesomeAlert, randomApiSleep } from '../../../utils/AsyncWrappers'; |
||||
|
||||
const data = { |
||||
|
||||
}; |
||||
|
||||
const getSmsCode = async () => { |
||||
await randomApiSleep(); |
||||
return { |
||||
ok: true, |
||||
data: data |
||||
}; |
||||
}; |
||||
|
||||
|
||||
|
||||
const mocks = {getSmsCode}; |
||||
export default mocks; |
@ -1,13 +0,0 @@ |
||||
import {nextFetchApi} from '../../../services/api'; |
||||
const getSmsCode = async (obj) => { |
||||
return await nextFetchApi('/public/sendOTP', { |
||||
method: 'POST', |
||||
payload: obj |
||||
}); |
||||
}; |
||||
|
||||
const mainServices = { |
||||
getSmsCode, |
||||
}; |
||||
|
||||
export default mainServices; |
@ -1,10 +0,0 @@ |
||||
import mocks from './mocks'; |
||||
import mainServices from './services'; |
||||
|
||||
const mock = false; |
||||
|
||||
let services = {...mainServices}; |
||||
if (mock) { |
||||
services = mocks; |
||||
} |
||||
export default services; |
@ -1,18 +0,0 @@ |
||||
import { asyncAwesomeAlert, randomApiSleep } from '../../../utils/AsyncWrappers'; |
||||
|
||||
const data = { |
||||
|
||||
}; |
||||
|
||||
const sendOtpCode = async () => { |
||||
await randomApiSleep(); |
||||
return { |
||||
ok: true, |
||||
data: data |
||||
}; |
||||
}; |
||||
|
||||
|
||||
|
||||
const mocks = {sendOtpCode}; |
||||
export default mocks; |
@ -1,13 +0,0 @@ |
||||
import {nextFetchApi} from '../../../services/api'; |
||||
const sendOtpCode = async (obj) => { |
||||
return await nextFetchApi('/user/otp/login', { |
||||
method: 'POST', |
||||
payload: obj |
||||
}); |
||||
}; |
||||
|
||||
const mainServices = { |
||||
sendOtpCode, |
||||
}; |
||||
|
||||
export default mainServices; |
@ -1,13 +1,68 @@ |
||||
import React from 'react' |
||||
import { View, Text } from 'react-native'; |
||||
import {connect} from 'react-redux'; |
||||
|
||||
function Videos({}) { |
||||
return ( |
||||
<View> |
||||
<Text></Text> |
||||
</View> |
||||
) |
||||
import React, { useState } from "react"; |
||||
import { |
||||
View, |
||||
StyleSheet, |
||||
Dimensions, |
||||
ScrollView, |
||||
SafeAreaView, |
||||
StatusBar, |
||||
Platform, |
||||
LayoutAnimation |
||||
} from "react-native"; |
||||
import tw from "tailwind-react-native-classnames"; |
||||
import Navbar from "../../components/Navbar"; |
||||
import Drawer from "../../components/Drawer"; |
||||
import Search from "../../components/Search"; |
||||
|
||||
//assets
|
||||
|
||||
const width = Dimensions.get("window").width; |
||||
|
||||
function Videos(props) { |
||||
const [search, setSearch] = useState(""); |
||||
const [position, setPosition] = useState("100%"); |
||||
|
||||
const setBoxPosition = () => { |
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); |
||||
setPosition(position === "100%" ? "0%" : "100%"); |
||||
}; |
||||
|
||||
return ( |
||||
<SafeAreaView |
||||
style={{ |
||||
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0, |
||||
position: "relative", |
||||
}} |
||||
> |
||||
<Navbar setBoxPosition={setBoxPosition} /> |
||||
<Drawer setBoxPosition={setBoxPosition} position={position} /> |
||||
<ScrollView |
||||
contentContainerStyle={styles.contentContainerStyle} |
||||
style={[styles.container, { width: width }]} |
||||
> |
||||
<Search |
||||
value={search} |
||||
onChange={setSearch} |
||||
placeholder={"نام کتاب یا دوره را جستجو کنید"} |
||||
/> |
||||
</ScrollView> |
||||
</SafeAreaView> |
||||
); |
||||
} |
||||
|
||||
// Later on in your styles..
|
||||
const styles = StyleSheet.create({ |
||||
contentContainerStyle: { |
||||
paddingBottom: 100, |
||||
alignItems: "flex-end", |
||||
}, |
||||
container: { |
||||
width: Dimensions.get("window").width, |
||||
backgroundColor: "white", |
||||
flexDirection: "column", |
||||
paddingVertical: 0, |
||||
paddingHorizontal: 16, |
||||
}, |
||||
}); |
||||
|
||||
export default Videos; |
||||
|
@ -1,3 +0,0 @@ |
||||
export default { |
||||
dev: 'https://dnvn.ir/api/v1', |
||||
}; |
@ -1,118 +0,0 @@ |
||||
'use strict'; |
||||
|
||||
module.exports = function (fetch, defaults) { |
||||
defaults = defaults || {}; |
||||
if (typeof fetch !== 'function') { |
||||
throw new ArgumentError('fetch must be a function'); |
||||
} |
||||
|
||||
if (typeof defaults !== 'object') { |
||||
throw new ArgumentError('defaults must be an object'); |
||||
} |
||||
|
||||
if (defaults.retries !== undefined && !isPositiveInteger(defaults.retries)) { |
||||
throw new ArgumentError('retries must be a positive integer'); |
||||
} |
||||
|
||||
if (defaults.retryDelay !== undefined && !isPositiveInteger(defaults.retryDelay) && typeof defaults.retryDelay !== 'function') { |
||||
throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer'); |
||||
} |
||||
|
||||
if (defaults.retryOn !== undefined && !Array.isArray(defaults.retryOn) && typeof defaults.retryOn !== 'function') { |
||||
throw new ArgumentError('retryOn property expects an array or function'); |
||||
} |
||||
|
||||
var baseDefaults = { |
||||
retries: 3, |
||||
retryDelay: 1000, |
||||
retryOn: [500, 502, 503, 504], |
||||
}; |
||||
|
||||
defaults = Object.assign(baseDefaults, defaults); |
||||
|
||||
return function fetchRetry(input, init) { |
||||
var retries = defaults.retries; |
||||
var retryDelay = defaults.retryDelay; |
||||
var retryOn = defaults.retryOn; |
||||
|
||||
if (init && init.retries !== undefined) { |
||||
if (isPositiveInteger(init.retries)) { |
||||
retries = init.retries; |
||||
} else { |
||||
throw new ArgumentError('retries must be a positive integer'); |
||||
} |
||||
} |
||||
|
||||
if (init && init.retryDelay !== undefined) { |
||||
if (isPositiveInteger(init.retryDelay) || (typeof init.retryDelay === 'function')) { |
||||
retryDelay = init.retryDelay; |
||||
} else { |
||||
throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer'); |
||||
} |
||||
} |
||||
|
||||
if (init && init.retryOn) { |
||||
if (Array.isArray(init.retryOn) || (typeof init.retryOn === 'function')) { |
||||
retryOn = init.retryOn; |
||||
} else { |
||||
throw new ArgumentError('retryOn property expects an array or function'); |
||||
} |
||||
} |
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
return new Promise(function (resolve, reject) { |
||||
var wrappedFetch = function (attempt) { |
||||
fetch(input, init) |
||||
.then(function (response) { |
||||
if (Array.isArray(retryOn) && retryOn.indexOf(response.status) === -1) { |
||||
resolve(response); |
||||
} else if (typeof retryOn === 'function') { |
||||
if (retryOn(attempt, null, response)) { |
||||
retry(attempt, null, response); |
||||
} else { |
||||
resolve(response); |
||||
} |
||||
} else { |
||||
if (attempt < retries) { |
||||
retry(attempt, null, response); |
||||
} else { |
||||
resolve(response); |
||||
} |
||||
} |
||||
}) |
||||
.catch(function (error) { |
||||
if (typeof retryOn === 'function') { |
||||
if (retryOn(attempt, error, null)) { |
||||
retry(attempt, error, null); |
||||
} else { |
||||
reject(error); |
||||
} |
||||
} else if (attempt < retries) { |
||||
retry(attempt, error, null); |
||||
} else { |
||||
reject(error); |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
function retry(attempt, error, response) { |
||||
var delay = (typeof retryDelay === 'function') ? |
||||
retryDelay(attempt, error, response) : retryDelay; |
||||
setTimeout(function () { |
||||
wrappedFetch(++attempt); |
||||
}, delay); |
||||
} |
||||
|
||||
wrappedFetch(0); |
||||
}); |
||||
}; |
||||
}; |
||||
|
||||
function isPositiveInteger(value) { |
||||
return Number.isInteger(value) && value >= 0; |
||||
} |
||||
|
||||
function ArgumentError(message) { |
||||
this.name = 'ArgumentError'; |
||||
this.message = message; |
||||
} |
@ -1,149 +0,0 @@ |
||||
import {Alert} from 'react-native'; |
||||
import {toastMessage} from '../../utils/message'; |
||||
import { |
||||
restartApp, |
||||
getToken, |
||||
deviceHeaders, |
||||
getUrl, |
||||
isUnexpected, |
||||
renewTokenHandler, |
||||
resetApp, |
||||
networkAlert, |
||||
unexpectedAlert, |
||||
} from './utils'; |
||||
import FetchRetry from './fetch-retry'; |
||||
import {asyncApiAwesomeAlert} from '../../utils/AsyncWrappers'; |
||||
|
||||
const fetchRetry = FetchRetry(fetch, {}); |
||||
let deviceInfo; |
||||
|
||||
export async function fetchApi( |
||||
endPoint, |
||||
payload = {}, |
||||
method = 'GET', |
||||
headers = {}, |
||||
isS = false, |
||||
splash = false, |
||||
dev = 'production', |
||||
) { |
||||
var timeout = setTimeout(() => { |
||||
console.log(endPoint, ' TIMEOUT '); |
||||
asyncApiAwesomeAlert('خطای ارتباط', '. لطفا اینترنت خود را بررسی کنید .').then( |
||||
async () => await fetchApi(endPoint, payload, method, headers, isS), |
||||
); |
||||
}, 30000); |
||||
if (!deviceInfo) { |
||||
deviceInfo = await deviceHeaders(); |
||||
if (!deviceInfo) { |
||||
deviceInfo = []; |
||||
} |
||||
} |
||||
let options = { |
||||
method, |
||||
headers: { |
||||
Accept: 'application/json;charset=utf-8', |
||||
'Content-Type': 'application/json;charset=utf-8', |
||||
Authorization: await getToken(), |
||||
...deviceInfo, |
||||
...headers, |
||||
}, |
||||
}; |
||||
if (['POST', 'PUT'].includes(method)) { |
||||
options.body = JSON.stringify(payload); |
||||
} |
||||
console.log('===========================') |
||||
console.log(await getUrl(endPoint, dev)) |
||||
console.log(options) |
||||
console.log('===========================') |
||||
try { |
||||
// console.log('req', await getUrl(endPoint), options)
|
||||
let res = await fetchRetry(await getUrl(endPoint, dev), options); |
||||
|
||||
clearTimeout(timeout); |
||||
let statusCode = res.status; |
||||
// console.log('RES', { statusCode, url: await getUrl(endPoint) })
|
||||
if (isUnexpected(statusCode)) { |
||||
console.log('unexpected', await res.json()); |
||||
console.log('RES-unexpected', {statusCode, url: await getUrl(endPoint)}); |
||||
let check = await unexpectedAlert(); |
||||
|
||||
return await fetchApi( |
||||
endPoint, |
||||
payload, |
||||
method, |
||||
headers, |
||||
isS, |
||||
false, |
||||
true, |
||||
); |
||||
} |
||||
let {data, error, status} = await res.json(); |
||||
if (res.ok) { |
||||
return data; |
||||
} |
||||
if (!res.ok) { |
||||
// if (data.hasOwnProperty('message')) {
|
||||
// toastMessage(data.message);
|
||||
// }
|
||||
console.log('=====================') |
||||
console.log(statusCode) |
||||
console.log(data) |
||||
console.log(error) |
||||
console.log('=====================') |
||||
if (statusCode === 403) { |
||||
console.log('req-401', await getUrl(endPoint), options); |
||||
|
||||
return resetApp(); |
||||
} |
||||
if (statusCode === 401) { |
||||
let checkRenew = await renewTokenHandler(); |
||||
if (!checkRenew.ok && checkRenew.restart) { |
||||
console.log('req-401', await getUrl(endPoint), options); |
||||
|
||||
resetApp(); |
||||
} else if (!checkRenew.ok) { |
||||
console.log('req-401', await getUrl(endPoint), options); |
||||
|
||||
restartApp(); |
||||
} |
||||
return await fetchApi(endPoint, payload, method, headers, isS, splash); |
||||
} |
||||
if (statusCode === 400) { |
||||
return error; |
||||
} |
||||
return data; |
||||
} |
||||
} catch (err) { |
||||
clearTimeout(timeout); |
||||
console.log('catch', endPoint, err); |
||||
// global.globalAlert({
|
||||
// show: true
|
||||
// })
|
||||
let check = await networkAlert(); |
||||
return await fetchApi(endPoint, payload, method, headers, isS); |
||||
} |
||||
} |
||||
/** |
||||
* next version of fetch API |
||||
* @param {String} endPoint |
||||
* @param {Object} options |
||||
* @param {string} options.method |
||||
* @param {string} options.payload |
||||
* @param {string} options.headers |
||||
* @param {Boolean} options.splash |
||||
*/ |
||||
export async function nextFetchApi(endPoint, options = {}) { |
||||
let {payload, method, headers, isS, splash} = options; |
||||
try { |
||||
let res = await fetchApi(endPoint, payload, method, headers, isS, splash); |
||||
return { |
||||
ok: true, |
||||
data: res, |
||||
}; |
||||
} catch (error) { |
||||
return { |
||||
ok: false, |
||||
data: error, |
||||
}; |
||||
} |
||||
} |
@ -1,203 +0,0 @@ |
||||
/* global fetch */ |
||||
|
||||
import apiConfig from './config'; |
||||
import { |
||||
Alert, |
||||
AlertIOS, |
||||
Platform, |
||||
ToastAndroid, |
||||
} from 'react-native'; |
||||
import AsyncStorage from '@react-native-async-storage/async-storage'; |
||||
import {toastMessage} from '../../utils/message'; |
||||
|
||||
import RNRestart from 'react-native-restart'; |
||||
import config from './config'; |
||||
import Refresh from './fetch-retry'; |
||||
import FetchRetry from './fetch-retry'; |
||||
let fetchRetry = FetchRetry(fetch, {}); |
||||
|
||||
function restartApp() { |
||||
AsyncStorage.setItem('UID_USER', JSON.stringify({}), () => { |
||||
RNRestart.Restart(); |
||||
}); |
||||
} |
||||
|
||||
export function fetchApi( |
||||
endPoint, |
||||
payload = {}, |
||||
method = 'GET', |
||||
headers = {}, |
||||
isS = false, |
||||
splash = false, |
||||
) { |
||||
return new Promise((resolve, reject) => { |
||||
var timeout = setTimeout(() => { |
||||
console.log(endPoint, ' TIMEOUT '); |
||||
Alert.alert('خطای ارتباط', 'خطایی ارتباط با سرور پیش امده .', [ |
||||
{ |
||||
text: 'تلاش مجدد', |
||||
onPress: () => |
||||
resolve(fetchApi(endPoint, payload, method, headers, isS)), |
||||
}, |
||||
]); |
||||
}, 10000); |
||||
|
||||
AsyncStorage.getItem('UID_USER', (err, result) => { |
||||
var tokens = ''; |
||||
var refreshTokens = ''; |
||||
var userDATA = JSON.parse(result); |
||||
var headrsRequest = {}; |
||||
|
||||
if ( |
||||
userDATA != null && |
||||
userDATA.token != null && |
||||
userDATA.token != '' && |
||||
isS |
||||
) { |
||||
tokens = userDATA.token; |
||||
|
||||
refreshTokens = userDATA.refresh_token; |
||||
headers = { |
||||
Authorization: 'Bearer ' + tokens, |
||||
}; |
||||
} |
||||
|
||||
if (method === 'POST' || method === 'PUT') { |
||||
headrsRequest = { |
||||
method: method, |
||||
headers: { |
||||
Accept: 'application/json;charset=utf-8', |
||||
'Content-Type': 'application/json;charset=utf-8', |
||||
...headers, |
||||
}, |
||||
body: JSON.stringify(payload), |
||||
}; |
||||
} else { |
||||
headrsRequest = { |
||||
method: method, |
||||
headers: { |
||||
Accept: 'application/json;charset=utf-8', |
||||
'Content-Type': 'application/json;charset=utf-8', |
||||
...headers, |
||||
}, |
||||
}; |
||||
} |
||||
|
||||
AsyncStorage.getItem('SPLASH_DATA', (err, result) => { |
||||
var splashDATA = JSON.parse(result); |
||||
|
||||
var baseUrl; |
||||
|
||||
if (endPoint.includes('splash')) { |
||||
baseUrl = apiConfig.splash; |
||||
} else { |
||||
var baseUrl = splashDATA.base_urls.backend + '/v1.1'; |
||||
} |
||||
|
||||
fetchRetry(`${baseUrl}${endPoint}`, headrsRequest) |
||||
.then(response => { |
||||
const statusCode = response.status; |
||||
const data = response.json(); |
||||
return Promise.all([statusCode, data]); |
||||
}) |
||||
.then(([statusCode, data]) => { |
||||
console.log(baseUrl + endPoint, statusCode, data); |
||||
if (data.hasOwnProperty('message')) { |
||||
toastMessage(data.message); |
||||
} |
||||
|
||||
if (statusCode === 403) { |
||||
clearTimeout(timeout); |
||||
restartApp(); |
||||
} |
||||
|
||||
if (statusCode === 401) { |
||||
clearTimeout(timeout); |
||||
|
||||
var dataaaaa = { |
||||
method: 'POST', |
||||
body: JSON.stringify({ |
||||
refresh_token: refreshTokens, |
||||
}), |
||||
headers: { |
||||
Accept: 'application/json;charset=utf-8', |
||||
'Content-Type': 'application/json;charset=utf-8', |
||||
}, |
||||
}; |
||||
|
||||
fetchRetry(`${baseUrl}/auth/renew-token`, dataaaaa) |
||||
.then(response1 => { |
||||
const statusCode1 = response1.status; |
||||
const data1 = response1.json(); |
||||
return Promise.all([statusCode1, data1]); |
||||
}) |
||||
.then(([statusCode1, data1]) => { |
||||
console.log( |
||||
'refresh token call and response is ', |
||||
statusCode1, |
||||
data1, |
||||
refreshTokens, |
||||
); |
||||
|
||||
if (statusCode1 == 200) { |
||||
userDATA.token = data1.data.token; |
||||
AsyncStorage.setItem( |
||||
'UID_USER', |
||||
JSON.stringify(userDATA), |
||||
() => { |
||||
resolve( |
||||
fetchApi(endPoint, payload, method, headers, isS), |
||||
); |
||||
}, |
||||
); |
||||
} else { |
||||
restartApp(); |
||||
} |
||||
}) |
||||
.catch(e => restartApp()); |
||||
} |
||||
|
||||
if (statusCode === 400) { |
||||
toastMessage(data.error.message); |
||||
clearTimeout(timeout); |
||||
|
||||
reject(data.error); |
||||
} |
||||
|
||||
if (statusCode === 200) { |
||||
clearTimeout(timeout); |
||||
resolve(data.data); |
||||
} |
||||
|
||||
if (statusCode === 201) { |
||||
clearTimeout(timeout); |
||||
resolve(data.data); |
||||
} |
||||
|
||||
return data; |
||||
}) |
||||
.catch(async e => { |
||||
console.log('e', error.message); |
||||
let res = await neto(); |
||||
if (e.networkError) { |
||||
toastMessage('اشکال در اتصال اینترنت دوباره تلاش کنید .'); |
||||
Alert.alert( |
||||
'اینترنت', |
||||
'اشکال در اتصال اینترنت دوباره تلاش کنید .', |
||||
[ |
||||
{ |
||||
text: 'تلاش مجدد', |
||||
onPress: () => |
||||
resolve( |
||||
fetchApi(endPoint, payload, method, headers, isS), |
||||
), |
||||
}, |
||||
{text: 'بیخیال', onPress: () => reject(e)}, |
||||
], |
||||
); |
||||
} |
||||
}); |
||||
}); |
||||
}); |
||||
}); |
||||
} |
@ -1,145 +0,0 @@ |
||||
import RNRestart from 'react-native-restart'; |
||||
import { toastMessage } from "../../utils/message" |
||||
import { asyncAlert, asyncAwesomeAlert, asyncApiAwesomeAlert } from "../../utils/AsyncWrappers"; |
||||
import * as Device from 'expo-device'; |
||||
import { |
||||
ImageBackground, |
||||
Text, |
||||
Image, |
||||
View, |
||||
SafeAreaView, |
||||
StyleSheet, |
||||
BackHandler, |
||||
Platform, |
||||
} from 'react-native'; |
||||
import AsyncStorage from '@react-native-async-storage/async-storage'; |
||||
import apiConfig from './config'; |
||||
import FetchRetry from './fetch-retry' |
||||
import { nextFetchApi } from '.'; |
||||
|
||||
const fetchRetry = FetchRetry(fetch, {}) |
||||
|
||||
export const restartApp = () => { |
||||
RNRestart.Restart() |
||||
} |
||||
export const resetApp = () => { |
||||
AsyncStorage.setItem('UID_USER', JSON.stringify({}), () => { |
||||
RNRestart.Restart() |
||||
}); |
||||
} |
||||
export const networkAlert = async () => { |
||||
return await asyncApiAwesomeAlert("خطا", "خطا در اتصال به اینترنت", { |
||||
confirmText: "تلاش مجدد" |
||||
}) |
||||
} |
||||
export const unexpectedAlert = async () => { |
||||
return await asyncApiAwesomeAlert("خطا", "خطای داخلی سرور!", { |
||||
confirmText: "تلاش مجدد" |
||||
}) |
||||
// return await asyncAlert("خطا","خطای داخلی سرور!", [
|
||||
// { text: "تلاش مجدد", value: 'retry' },
|
||||
// // { text: "بیخیال", value: 'ignore' }
|
||||
// ])
|
||||
} |
||||
export const getToken = async () => { |
||||
let token = await AsyncStorage.getItem('accessToken') |
||||
if (!token) { |
||||
return '' |
||||
} |
||||
return 'Bearer ' + token |
||||
} |
||||
export const deviceHeaders = async () => { |
||||
return { |
||||
'dev-os': Platform.OS, |
||||
'dev-app-version': '1.6.0', |
||||
'dev-os-version': Platform.Version + '', |
||||
'dev-phone-manufacturer': Device.brand, |
||||
'dev-phone-model': Device.modelName, |
||||
'dev-phone-hash': Device.modelId, |
||||
} |
||||
} |
||||
export const getUrl = async (endpoint, dev) => { |
||||
if (endpoint.includes('splash')) { |
||||
if (dev === 'dev') { |
||||
return apiConfig.dev + endpoint |
||||
} |
||||
return apiConfig.splash + endpoint |
||||
} |
||||
let base_urls = await getBaseUrls() |
||||
return base_urls + endpoint |
||||
} |
||||
|
||||
export const isUnexpected = (statusCode) => { |
||||
if (![200, 201, 400, 401, 403].includes(statusCode)) return true |
||||
return false |
||||
} |
||||
export const renewTokenHandler = async () => { |
||||
try { |
||||
let refreshToken = JSON.parse(await AsyncStorage.getItem('refreshToken')) |
||||
if (!refreshToken) { |
||||
return { |
||||
ok: false, |
||||
restart: true |
||||
} |
||||
} |
||||
const options = { |
||||
method: 'POST', |
||||
body: JSON.stringify({ |
||||
refresh_token: refreshToken |
||||
}), |
||||
headers: { |
||||
Accept: 'application/json;charset=utf-8', |
||||
'Content-Type': 'application/json;charset=utf-8' |
||||
} |
||||
} |
||||
let res = await fetchRetry(await getUrl('/user/login'), options) |
||||
let { data } = await res.json() |
||||
const statusCode = res.status |
||||
if (statusCode == 200) { |
||||
await AsyncStorage.setItem('refreshToken', JSON.stringify(data.refreshToken)) |
||||
await AsyncStorage.setItem('accessToken', JSON.stringify(data.accessToken)) |
||||
return { |
||||
ok: true |
||||
} |
||||
} |
||||
if (statusCode == 400) { |
||||
return { |
||||
ok: false, |
||||
restart: true |
||||
} |
||||
} |
||||
return { |
||||
ok: false |
||||
} |
||||
} catch (error) { |
||||
return { |
||||
ok: false |
||||
} |
||||
} |
||||
} |
||||
export const getBaseUrls = async () => { |
||||
// let { base_urls } = JSON.parse((await AsyncStorage.getItem('SPLASH_DATA')))
|
||||
return apiConfig.dev |
||||
} |
||||
export const getCachedProfile = async () => { |
||||
return JSON.parse(await AsyncStorage.getItem('UID_USER')) |
||||
} |
||||
|
||||
export const cacheProfile = async () => { |
||||
let data = await getProfile() |
||||
let oldData = await getCachedProfile() |
||||
if (data) { |
||||
await AsyncStorage.removeItem('UID_USER') |
||||
|
||||
await AsyncStorage.setItem('UID_USER', JSON.stringify({ |
||||
...oldData, |
||||
...data |
||||
})) |
||||
} |
||||
|
||||
} |
||||
export const getProfile = async () => { |
||||
let { ok, data } = await nextFetchApi('/profile?with_details=1&no_cache=1') |
||||
if (!ok) return null |
||||
return data |
||||
} |
@ -1,16 +0,0 @@ |
||||
import i18n from "i18next"; |
||||
import { initReactI18next } from "react-i18next"; |
||||
import { Platform } from "react-native"; |
||||
import resources from './locales' |
||||
|
||||
i18n.use(initReactI18next).init({ |
||||
resources: resources, |
||||
lng: "fa", |
||||
fallbackLng: "fa", |
||||
compatibilityJSON: Platform.OS === 'android' ? 'v3' : '', |
||||
interpolation: { |
||||
escapeValue: false |
||||
}
|
||||
}); |
||||
|
||||
export default i18n; |
@ -1,28 +0,0 @@ |
||||
{ |
||||
"main": { |
||||
"home": "Home", |
||||
"settings": "Settings", |
||||
"profile": "Profile", |
||||
"filter": "filter" |
||||
}, |
||||
"filter": { |
||||
"newest": "newest", |
||||
"oldest": "oldest" |
||||
}, |
||||
"profile": { |
||||
"first name": "first name", |
||||
"last name": "last name", |
||||
"birthday": "birthday", |
||||
"gender": "gender", |
||||
"addresses": "addresses", |
||||
"day": "day", |
||||
"month": "month", |
||||
"year": "year", |
||||
"male": "male", |
||||
"female": "female", |
||||
"submit changes": "submit changes" |
||||
}, |
||||
"settings": { |
||||
"language": "language" |
||||
} |
||||
} |
@ -1,29 +0,0 @@ |
||||
{ |
||||
"main": { |
||||
"home": "صفحه اصلی", |
||||
"books": "کتاب ها", |
||||
"videos": "ویدئوها", |
||||
"exams": "آزمون ها", |
||||
"profile": "حساب کاربری" |
||||
}, |
||||
"filter": { |
||||
"newest": "جدیدترین", |
||||
"oldest": "قدیمی ترین" |
||||
}, |
||||
"profile": { |
||||
"first name": "نام", |
||||
"last name": "نام خانوادگی", |
||||
"birthday": "تاریخ تولد", |
||||
"gender": "جنسیت", |
||||
"addresses": "آدرس ها", |
||||
"day": "روز", |
||||
"month": "ماه", |
||||
"year": "سال", |
||||
"male": "آقا", |
||||
"female": "خانم", |
||||
"submit changes": "ثبت تغییرات" |
||||
}, |
||||
"settings": { |
||||
"language": "زبان" |
||||
} |
||||
} |
@ -1,11 +0,0 @@ |
||||
import en from './en/translation.json'; |
||||
import fa from './fa/translation.json'; |
||||
|
||||
export default { |
||||
en: { |
||||
translation: en |
||||
}, |
||||
fa: { |
||||
translation: fa |
||||
} |
||||
} |
Loading…
Reference in new issue