diff --git a/HelloWorld/.ruby-version b/HelloWorld/.ruby-version deleted file mode 100644 index 460b6fd4..00000000 --- a/HelloWorld/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.7.5 \ No newline at end of file diff --git a/HelloWorld/.node-version b/HelloWorld/_node-version similarity index 100% rename from HelloWorld/.node-version rename to HelloWorld/_node-version diff --git a/HelloWorld/android/app/src/main/jni/CMakeLists.txt b/HelloWorld/android/app/src/main/jni/CMakeLists.txt index e5be16f0..91afb1b2 100644 --- a/HelloWorld/android/app/src/main/jni/CMakeLists.txt +++ b/HelloWorld/android/app/src/main/jni/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.13) # Define the library name here. -project(rndiffapp_appmodules) +project(helloworld_appmodules) # This file includes all the necessary to let you build your application with the New Architecture. include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake) \ No newline at end of file diff --git a/HelloWorld/android/app/src/main/jni/MainComponentsRegistry.cpp b/HelloWorld/android/app/src/main/jni/MainComponentsRegistry.cpp index 055bafdd..a27a0e92 100644 --- a/HelloWorld/android/app/src/main/jni/MainComponentsRegistry.cpp +++ b/HelloWorld/android/app/src/main/jni/MainComponentsRegistry.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace facebook { diff --git a/HelloWorld/ios/.xcode.env b/HelloWorld/ios/.xcode.env deleted file mode 100644 index a9d90672..00000000 --- a/HelloWorld/ios/.xcode.env +++ /dev/null @@ -1,11 +0,0 @@ -# This `.xcode.env` file is versioned and is used to source the environment -# used when running script phases inside Xcode. -# To customize your local environment, you can create an `.xcode.env.local` -# file that is not versioned. - -# NODE_BINARY variable contains the PATH to the node executable. -# -# Customize the NODE_BINARY variable here. -# For example, to use nvm with brew, add the following line -# . "$(brew --prefix nvm)/nvm.sh" --no-use -export NODE_BINARY=$(command -v node) \ No newline at end of file diff --git a/HelloWorld/ios/HelloWorld/LaunchScreen copy.storyboard b/HelloWorld/ios/HelloWorld/LaunchScreen copy.storyboard deleted file mode 100644 index e13962e9..00000000 --- a/HelloWorld/ios/HelloWorld/LaunchScreen copy.storyboard +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/HelloWorld/ios/Podfile b/HelloWorld/ios/Podfile index 5567e68b..92e7ee19 100644 --- a/HelloWorld/ios/Podfile +++ b/HelloWorld/ios/Podfile @@ -4,8 +4,6 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ platform :ios, '12.4' install! 'cocoapods', :deterministic_uuids => false -production = ENV["PRODUCTION"] == "1" - target 'HelloWorld' do config = use_native_modules! diff --git a/HelloWorld/package.json b/HelloWorld/package.json index c13ce422..9abbf0db 100644 --- a/HelloWorld/package.json +++ b/HelloWorld/package.json @@ -23,7 +23,7 @@ "@uiw/formatter": "~1.3.3", "@uiw/react-native": "^3.0.4", "react": "18.1.0", - "react-native": "0.70.5", + "react-native": "0.70.6", "react-native-device-info": "~10.0.2", "react-native-gesture-handler": "~2.5.0", "react-native-reanimated": "~2.9.1", @@ -31,7 +31,8 @@ "react-native-screens": "~3.15.0", "react-native-svg": "12.1.1", "react-redux": "7.2.6", - "redux": "4.1.2" + "redux": "4.1.2", + "react-query":"~3.39.2" }, "devDependencies": { "@babel/core": "~7.18.9", diff --git a/HelloWorld/src/App.js b/HelloWorld/src/App.js index 3e7a9429..4a072916 100644 --- a/HelloWorld/src/App.js +++ b/HelloWorld/src/App.js @@ -1,40 +1,44 @@ import 'react-native-gesture-handler'; import React from 'react'; -import {StatusBar} from 'react-native'; -import {NavigationContainer} from '@react-navigation/native'; -import {createStackNavigator} from '@react-navigation/stack'; -import {Provider} from 'react-redux'; -import {store} from './models'; +import { StatusBar } from 'react-native'; +import { NavigationContainer } from '@react-navigation/native'; +import { createStackNavigator } from '@react-navigation/stack'; +import { Provider } from 'react-redux'; +import { store } from './models'; import AuthLoadingScreen from './pages/AuthLoading'; -import {stackPageData} from './routes'; +import { stackPageData } from './routes'; +import { QueryClient, QueryClientProvider } from 'react-query' const Stack = createStackNavigator(); +const queryClient = new QueryClient() export default () => { return ( - - - {token => ( - - - {stackPageData.map((props, index) => { - return ( - + + + {token => ( + + + {stackPageData.map((props, index) => { + return ( + null // }} // component={Home} - /> - ); - })} - - - )} - + /> + ); + })} + + + )} + + ); }; diff --git a/HelloWorld/src/hooks/users.js b/HelloWorld/src/hooks/users.js new file mode 100644 index 00000000..cfc368b4 --- /dev/null +++ b/HelloWorld/src/hooks/users.js @@ -0,0 +1,67 @@ +import { Alert } from 'react-native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { userLogin, userAuth } from '../services/users'; +import { useQuery, useMutation } from 'react-query' +import Global from '../global'; + +// 登录 +export const login = ({ config = {}, update, formData, remember }) => { + const mutation = useMutation({ + mutationFn: userLogin, + onSuccess: async (data) => { + if (data?.token && data?.data) { + await AsyncStorage.setItem('token', data.token); + if (remember) { + await AsyncStorage.setItem('cachLoginName', formData.loginName); + await AsyncStorage.setItem('cachPassword', formData.password); + } + await AsyncStorage.setItem('userData', JSON.stringify(data.data)); + update({ token: data.token, userData: data.data }); + if (Global.navigation) { + Global.navigation.replace('Home'); + } + } else if (data && data.message) { + Alert.alert(`Login failed - ${data.error}`, data.message); + } + }, + ...config + }) + return mutation +} + +// 验证token +export const authToken = ({ token, update }) => { + const mutation = useMutation({ + mutationFn: userAuth, + onMutate: async () => { + let host = await AsyncStorage.getItem('apihost'); + if (!host && conf.hosts[0]) { + await AsyncStorage.setItem('apihost', JSON.stringify(conf.hosts[0])); + await update({ apihost: conf.hosts[0] }); + } + if (!token) { + await AsyncStorage.removeItem('userData'); + await AsyncStorage.removeItem('token'); + } + }, + onSuccess: async (data) => { + if (data?.token) { + await update({ authState: true, token: data.token }); + } else { + await update({ authState: true, token: null }); + } + } + }) + return mutation +} + +// 退出 +export const logout = ({ update }) => { + AsyncStorage.removeItem('token'); + AsyncStorage.removeItem('userData'); + update({ token: null, userData: null }); + if (Global.navigation) { + Global.navigation.navigate?.('SignIn'); + } +} + diff --git a/HelloWorld/src/models/global.js b/HelloWorld/src/models/global.js index 64b2da22..d587dc6d 100644 --- a/HelloWorld/src/models/global.js +++ b/HelloWorld/src/models/global.js @@ -1,5 +1,5 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; -import {userAuth} from '../services/users'; +import { userAuth } from '../services/users'; import conf from '../config'; export default { @@ -10,29 +10,10 @@ export default { authState: false, token: null, apihost: null, + userData: null, }, reducers: { - update: (state, payload) => ({...state, ...payload}), + update: (state, payload) => ({ ...state, ...payload }), }, - effects: dispatch => ({ - async authToken(_, {global}) { - let host = await AsyncStorage.getItem('apihost'); - if (!host && conf.hosts[0]) { - await AsyncStorage.setItem('apihost', JSON.stringify(conf.hosts[0])); - await this.update({apihost: conf.hosts[0]}); - } - - if (!global.token) { - await AsyncStorage.removeItem('userData'); - await AsyncStorage.removeItem('token'); - } - - const data = await userAuth(); - if (data && data.token) { - await this.update({authState: true, token: data.token}); - } else { - await this.update({authState: true, token: null}); - } - }, - }), + effects: dispatch => ({}), }; diff --git a/HelloWorld/src/models/index.js b/HelloWorld/src/models/index.js index 641adad8..a77c2800 100644 --- a/HelloWorld/src/models/index.js +++ b/HelloWorld/src/models/index.js @@ -1,14 +1,12 @@ import {init} from '@rematch/core'; import createLoadingPlugin from '@rematch/loading'; import * as global from './global'; -import * as users from './users'; const loadingPlugin = createLoadingPlugin({}); export const store = init({ models: { global: global.default, - users: users.default, }, plugins: [ loadingPlugin, diff --git a/HelloWorld/src/models/users.js b/HelloWorld/src/models/users.js deleted file mode 100644 index 4ebfb30b..00000000 --- a/HelloWorld/src/models/users.js +++ /dev/null @@ -1,52 +0,0 @@ -import {Alert} from 'react-native'; -import AsyncStorage from '@react-native-async-storage/async-storage'; -import {userLogin} from '../services/users'; -import Global from '../global'; - -export default { - state: { - userData: null, - remember: false, // Whether to remember password - formData: { - username: 'admin', - password: 'admin!', - }, - }, - reducers: { - update: (state, payload) => ({...state, ...payload}), - updateForm: (state, payload) => ({ - ...state, - formData: {...state.formData, ...payload}, - }), - }, - effects: dispatch => ({ - // 登录 - async login(_, {users, global}) { - const data = await userLogin(users.formData); - if (data && data.token && data.data) { - await AsyncStorage.setItem('token', data.token); - // Cache username and password - if (users.remember) { - await AsyncStorage.setItem('cachLoginName', users.formData.loginName); - await AsyncStorage.setItem('cachPassword', users.formData.password); - } - await AsyncStorage.setItem('userData', JSON.stringify(data.data)); - await dispatch.global.update({token: data.token}); - await this.update({userData: data.data}); - if (Global.navigation) { - // Global.navigation.navigate('Home'); - Global.navigation.replace('Home'); - } - } else if (data && data.message) { - Alert.alert(`Login failed - ${data.error}`, data.message); - } - }, - async logout() { - await AsyncStorage.removeItem('token'); - await AsyncStorage.removeItem('userData'); - dispatch.global.update({token: null}); - dispatch.users.update({userData: null}); - Global.navigation.navigate('SignIn'); - }, - }), -}; diff --git a/HelloWorld/src/pages/AuthLoading/index.js b/HelloWorld/src/pages/AuthLoading/index.js index 3c1bd5a4..e8f90209 100644 --- a/HelloWorld/src/pages/AuthLoading/index.js +++ b/HelloWorld/src/pages/AuthLoading/index.js @@ -1,52 +1,55 @@ -import React from 'react'; -import {Text, StatusBar, StyleSheet, SafeAreaView} from 'react-native'; -import {connect} from 'react-redux'; -import {Flex, Loader, H3, Icon} from '@uiw/react-native'; +import React, { useEffect } from 'react'; +import { Text, StatusBar, StyleSheet, SafeAreaView } from 'react-native'; +import { connect } from 'react-redux'; +import { Flex, Loader, H3, Icon } from '@uiw/react-native'; import Global from '../../global'; -import {logoLight} from '../../components/icons/signin'; +import { logoLight } from '../../components/icons/signin'; import Footer from '../../components/Footer'; +import { authToken } from '../../hooks/users' -class AuthLoadingScreen extends React.Component { - componentDidMount() { - const {navigation, authToken} = this.props; +const AuthLoadingScreen = ({ + navigation, + update, + token, + authState, + children +}) => { + const { mutate, isLoading } = authToken({ update, token }) + useEffect(() => { if (navigation && Global) { Global.navigation = navigation; } - authToken(); + mutate(); + }, []) + + if (children && typeof children === 'function' && authState) { + return children(token); } - render() { - const {token, loading, authState, children} = this.props; - if (children && typeof children === 'function' && authState) { - return children(token); - } - return ( - - - - - -

My APP

-
- - Verify login...} /> - -