Commit ddb75ea2 by Giang Tran

update code

parent 1d08f5bb
...@@ -132,8 +132,8 @@ android { ...@@ -132,8 +132,8 @@ android {
applicationId "com.dcv.invest" applicationId "com.dcv.invest"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 20 versionCode 23
versionName "2.4" versionName "2.7"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
} }
splits { splits {
......
...@@ -905,7 +905,7 @@ ...@@ -905,7 +905,7 @@
CODE_SIGN_ENTITLEMENTS = Invest/InvestDebug.entitlements; CODE_SIGN_ENTITLEMENTS = Invest/InvestDebug.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 16; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = MXZ24GRH48; DEVELOPMENT_TEAM = MXZ24GRH48;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
...@@ -914,7 +914,7 @@ ...@@ -914,7 +914,7 @@
); );
INFOPLIST_FILE = Invest/Info.plist; INFOPLIST_FILE = Invest/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.3.2; MARKETING_VERSION = 2.3.4;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"$(inherited)", "$(inherited)",
"-ObjC", "-ObjC",
...@@ -939,11 +939,11 @@ ...@@ -939,11 +939,11 @@
CODE_SIGN_ENTITLEMENTS = Invest/Invest.entitlements; CODE_SIGN_ENTITLEMENTS = Invest/Invest.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 16; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = MXZ24GRH48; DEVELOPMENT_TEAM = MXZ24GRH48;
INFOPLIST_FILE = Invest/Info.plist; INFOPLIST_FILE = Invest/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.3.2; MARKETING_VERSION = 2.3.4;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"$(inherited)", "$(inherited)",
"-ObjC", "-ObjC",
......
...@@ -61,13 +61,13 @@ ...@@ -61,13 +61,13 @@
</dict> </dict>
</dict> </dict>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>Accect connect camera</string> <string>Cho phép truy cp vào máy nh và thư vin để ti nh lên ng dng</string>
<key>NSFaceIDUsageDescription</key> <key>NSFaceIDUsageDescription</key>
<string>Enabling Face ID allows you quick and secure access to your account.</string> <string>Enabling Face ID allows you quick and secure access to your account.</string>
<key>NSLocationWhenInUseUsageDescription</key> <key>NSLocationWhenInUseUsageDescription</key>
<string></string> <string></string>
<key>NSPhotoLibraryUsageDescription</key> <key>NSPhotoLibraryUsageDescription</key>
<string>To upload images</string> <string>Upload nh lên ng dng</string>
<key>UIAppFonts</key> <key>UIAppFonts</key>
<array> <array>
<string>AntDesign.ttf</string> <string>AntDesign.ttf</string>
......
import React, {useState, useEffect} from 'react'; import React, {useState, useEffect} from 'react';
import { import {
View, View,
Text, Text,
StyleSheet, StyleSheet,
Image, Image,
TouchableOpacity, TouchableOpacity,
KeyboardAvoidingView, KeyboardAvoidingView,
Platform, Platform,
Alert, Alert,
} from 'react-native'; } from 'react-native';
import InputIcon from '../../components/Input/InputIcon'; import InputIcon from '../../components/Input/InputIcon';
import {getFontXD, HEIGHTXD, WIDTHXD} from '../../Config/Functions'; import {getFontXD, HEIGHTXD, WIDTHXD} from '../../Config/Functions';
import R from '../../assets/R'; import R from '../../assets/R';
import {useNavigation} from '@react-navigation/native'; import {useNavigation} from '@react-navigation/native';
import { import {
TABNAVIGATOR, TABNAVIGATOR,
FORGOTPASSWORD, FORGOTPASSWORD,
CONFIRMEMAIL, CONFIRMEMAIL,
} from '../../routers/ScreenNames'; } from '../../routers/ScreenNames';
import {checkFormatArray, encryptRSAString} from '../../Config/Functions'; import {checkFormatArray, encryptRSAString} from '../../Config/Functions';
import {loginApi} from '../../apis/Functions/users'; import {loginApi} from '../../apis/Functions/users';
...@@ -38,254 +38,262 @@ import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; ...@@ -38,254 +38,262 @@ import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import DeviceInfo from 'react-native-device-info'; import DeviceInfo from 'react-native-device-info';
const Login = (props) => { const Login = (props) => {
const {navigation} = props; const {navigation} = props;
const [email, setEmail] = useState(''); const [email, setEmail] = useState('');
const [pass, setPass] = useState(''); const [pass, setPass] = useState('');
const [biometryType, setBiometryType] = useState(null); const [biometryType, setBiometryType] = useState(null);
const [isShowBiometryLogin, setIsShowBiometryLogin] = useState(false); const [isShowBiometryLogin, setIsShowBiometryLogin] = useState(false);
const navigate = useNavigation(); const navigate = useNavigation();
const optionalConfigObject = { const optionalConfigObject = {
title: 'Authentication Required', // Android title: 'Authentication Required', // Android
color: '#e00606', // Android, color: '#e00606', // Android,
fallbackLabel: '', // iOS (if empty, then label is hidden) fallbackLabel: '', // iOS (if empty, then label is hidden)
}; };
const getTokenDevice = async () => { const getTokenDevice = async () => {
let fcmToken = await AsyncStorage.getItem(KEY.FIREBASE); let fcmToken = await AsyncStorage.getItem(KEY.FIREBASE);
if (!fcmToken) { if (!fcmToken) {
fcmToken = await messaging().getToken(); fcmToken = await messaging().getToken();
if (fcmToken) { if (fcmToken) {
AsyncStorage.setItem(KEY.FIREBASE, fcmToken); AsyncStorage.setItem(KEY.FIREBASE, fcmToken);
} }
} }
}; };
const getLoginByBiometry = async () => { const getLoginByBiometry = async () => {
let loginByBiometry = await AsyncStorage.getItem(KEY.IS_LOGIN_BY_BIOMETRY); let loginByBiometry = await AsyncStorage.getItem(KEY.IS_LOGIN_BY_BIOMETRY);
if (loginByBiometry) { if (loginByBiometry) {
loginByBiometry = JSON.parse(loginByBiometry) loginByBiometry = JSON.parse(loginByBiometry);
setIsShowBiometryLogin(loginByBiometry.isLoginByBiometry); setIsShowBiometryLogin(loginByBiometry.isLoginByBiometry);
loginByBiometry.isLoginByBiometry && Keychain.getSupportedBiometryType({}).then((biometryType) => { loginByBiometry.isLoginByBiometry &&
setBiometryType(biometryType); Keychain.getSupportedBiometryType({}).then((biometryType) => {
}); setBiometryType(biometryType);
} });
}; }
useEffect(() => { };
props.hideLoading(); useEffect(() => {
getAccount(); props.hideLoading();
getTokenDevice(); getAccount();
getLoginByBiometry(); getTokenDevice();
}, []); getLoginByBiometry();
}, []);
const getAccount = async () => { const getAccount = async () => {
const jsonValue = await AsyncStorage.getItem(KEY.ACCOUNT); const jsonValue = await AsyncStorage.getItem(KEY.ACCOUNT);
const account = JSON.parse(jsonValue); const account = JSON.parse(jsonValue);
if (account) { if (account) {
onSubmitLogin(account.email, account.pass); onSubmitLogin(account.email, account.pass);
} }
}; };
const getCredentialInfo = async () => { const getCredentialInfo = async () => {
try { try {
const appBundleId = await DeviceInfo.getBundleId(); // only used for android as default for service on iOS is bundleId const appBundleId = await DeviceInfo.getBundleId(); // only used for android as default for service on iOS is bundleId
// Retrieve the credentials // Retrieve the credentials
const options = { const options = {
service: Platform.OS === 'ios' ? undefined : appBundleId, service: Platform.OS === 'ios' ? undefined : appBundleId,
forceAuth: true, forceAuth: true,
authenticationPrompt: { authenticationPrompt: {
title: 'Authentication needed', title: 'Authentication needed',
cancel: 'Cancel', cancel: 'Cancel',
}, },
}; };
const credentials = await Keychain.getGenericPassword(options); const credentials = await Keychain.getGenericPassword(options);
if (credentials) { if (credentials) {
console.log( console.log('Credentials successfully loaded for user ', credentials);
'Credentials successfully loaded for user ', credentials, onSubmitLogin(credentials.username, credentials.password);
); } else {
onSubmitLogin(credentials.username, credentials.password); showAlert(
TYPE.ERROR,
} else { I18n.t('Notification'),
showAlert( I18n.t('HaveNotCredential', {
TYPE.ERROR, type:
I18n.t('Notification'), biometryType == 'FaceID'
I18n.t('HaveNotCredential', {type: biometryType == 'FaceID' ? I18n.t('FaceId') : I18n.t('Fingerprint')}), ? I18n.t('FaceId')
); : I18n.t('Fingerprint'),
console.log('No credentials stored'); }),
} );
} catch (error) { console.log('No credentials stored');
console.log('Keychain couldn\'t be accessed!', error); }
} } catch (error) {
}; console.log("Keychain couldn't be accessed!", error);
const onSubmitLogin = async (email, pass) => { }
const titles = [ };
I18n.t('Username').toLowerCase(), const onSubmitLogin = async (email, pass) => {
I18n.t('Password').toLowerCase(), const titles = [
]; I18n.t('Username').toLowerCase(),
const index = checkFormatArray([email, pass]); I18n.t('Password').toLowerCase(),
];
const index = checkFormatArray([email, pass]);
if (index === true) { if (index === true) {
firebase = await AsyncStorage.getItem(KEY.FIREBASE); firebase = await AsyncStorage.getItem(KEY.FIREBASE);
props.showLoading(); props.showLoading();
const res = await loginApi({ const res = await loginApi({
email, email,
password: encryptRSAString(pass), password: encryptRSAString(pass),
platform: Platform.OS, platform: Platform.OS,
device_token: firebase, device_token: firebase,
account_type: 'CUSTOMER', account_type: 'CUSTOMER',
}); });
props.hideLoading(); props.hideLoading();
if (res.data) { if (res.data) {
if (res.data.code == 200 && res.data.data) { if (res.data.code == 200 && res.data.data) {
const jsonValue = JSON.stringify({email, pass}); const jsonValue = JSON.stringify({email, pass});
AsyncStorage.setItem(KEY.TOKEN, res.data.data.token); AsyncStorage.setItem(KEY.TOKEN, res.data.data.token);
AsyncStorage.setItem(KEY.ACCOUNT, jsonValue); AsyncStorage.setItem(KEY.ACCOUNT, jsonValue);
props.saveUserToRedux(res.data.data); props.saveUserToRedux(res.data.data);
navigate.reset({ navigate.reset({
index: 1, index: 1,
routes: [{name: TABNAVIGATOR}], routes: [{name: TABNAVIGATOR}],
}); });
} else {
showAlert(TYPE.ERROR, I18n.t('Notification'), res.data.message);
}
} else {
showAlert(
TYPE.ERROR,
I18n.t('Notification'),
I18n.t('Systemmaintenance'),
);
}
} else { } else {
showAlert( showAlert(TYPE.ERROR, I18n.t('Notification'), res.data.message);
TYPE.WARN,
I18n.t('Notification'),
I18n.t('Please_fill_in') + titles[index],
);
} }
}; } else {
showAlert(
TYPE.ERROR,
I18n.t('Notification'),
I18n.t('Systemmaintenance'),
);
}
} else {
showAlert(
TYPE.WARN,
I18n.t('Notification'),
I18n.t('Please_fill_in') + titles[index],
);
}
};
return ( return (
<View <View
style={{ style={{
flex: 1, flex: 1,
paddingHorizontal: 20, paddingHorizontal: 20,
paddingTop: 20, paddingTop: 20,
backgroundColor: 'white', backgroundColor: 'white',
}}> }}>
<InputIcon <InputIcon
icon={R.images.iconUser3} icon={R.images.iconUser3}
title={'Email'} title={'Email'}
onChangeText={(val) => setEmail(val)} onChangeText={(val) => setEmail(val)}
value={email} value={email}
/> />
<InputIcon <InputIcon
icon={R.images.iconLock} icon={R.images.iconLock}
title={'Password'} title={'Password'}
isPassWord={true} isPassWord={true}
onChangeText={(val) => setPass(val)} onChangeText={(val) => setPass(val)}
value={pass} value={pass}
/> />
<TouchableOpacity <TouchableOpacity
onPress={() => navigate.navigate(CONFIRMEMAIL)} onPress={() => navigate.navigate(CONFIRMEMAIL)}
style={styles.forgotView}> style={styles.forgotView}>
<AppText i18nKey={'ForgotPassword'} style={styles.txtTitle}/> <AppText i18nKey={'ForgotPassword'} style={styles.txtTitle} />
</TouchableOpacity> </TouchableOpacity>
<View <View
style={{ style={{
marginVertical: 20, marginVertical: 20,
alignItems: 'center', alignItems: 'center',
}}>
<TouchableOpacity
onPress={() => onSubmitLogin(email, pass)}
style={styles.wrapLogin}>
<AppText i18nKey={'Login'} style={styles.txtLogin} />
<Image source={R.images.iconRight1} style={styles.imgIcon} />
</TouchableOpacity>
{isShowBiometryLogin ? (
<View style={{flexDirection: 'row', marginTop: WIDTHXD(70)}}>
{biometryType == 'FaceID' ? (
<TouchableOpacity
onPress={() => {
getCredentialInfo();
}}> }}>
<TouchableOpacity <Image
onPress={() => onSubmitLogin(email, pass)} source={R.images.iconFaceId}
style={styles.wrapLogin}> style={[styles.imgIconBiometry, {tintColor: R.colors.main}]}
<AppText i18nKey={'Login'} style={styles.txtLogin}/> />
<Image source={R.images.iconRight1} style={styles.imgIcon}/> </TouchableOpacity>
</TouchableOpacity> ) : (
{isShowBiometryLogin ? <TouchableOpacity
<View style={{flexDirection: 'row', marginTop: WIDTHXD(70)}}> onPress={() => {
{biometryType == 'FaceID' ? getCredentialInfo();
<TouchableOpacity }}>
onPress={() => { <Image
getCredentialInfo(); source={R.images.fingerprint}
}}> style={styles.imgIconBiometry}
<Image source={R.images.iconFaceId} style={[styles.imgIconBiometry, {tintColor: R.colors.main}]}/> />
</TouchableOpacity> </TouchableOpacity>
: )}
<TouchableOpacity </View>
onPress={() => { ) : null}
getCredentialInfo();
}}>
<Image source={R.images.fingerprint} style={styles.imgIconBiometry}/>
</TouchableOpacity>
}
</View>
: null}
<View style={styles.row}> <View style={styles.row}>
<AppText i18nKey={'Have_account'} style={styles.txtTitle}/> <AppText i18nKey={'Have_account'} style={styles.txtTitle} />
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
navigation.navigate('REGISTOR'); navigation.navigate('REGISTOR');
}}> }}>
<AppText i18nKey={'Register'} style={styles.txtRegistor}/> <AppText i18nKey={'Register'} style={styles.txtRegistor} />
</TouchableOpacity> </TouchableOpacity>
</View>
</View>
<View style={{height: 100}}/>
</View> </View>
); </View>
<View style={{height: 100}} />
</View>
);
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
forgotView: { forgotView: {
marginVertical: 20, marginVertical: 20,
alignItems: 'flex-end', alignItems: 'flex-end',
}, },
txtTitle: { txtTitle: {
fontSize: getFontXD(42), fontSize: getFontXD(42),
color: '#929292', color: '#929292',
}, },
txtLogin: { txtLogin: {
fontSize: getFontXD(48), fontSize: getFontXD(48),
color: 'white', color: 'white',
fontWeight: '700', fontWeight: '700',
}, },
wrapLogin: { wrapLogin: {
width: WIDTHXD(512), width: WIDTHXD(512),
height: HEIGHTXD(150), height: HEIGHTXD(150),
backgroundColor: '#1C6AF6', backgroundColor: '#1C6AF6',
borderRadius: 30, borderRadius: 30,
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
}, },
imgIcon: { imgIcon: {
width: WIDTHXD(72), width: WIDTHXD(72),
height: HEIGHTXD(72), height: HEIGHTXD(72),
marginLeft: 5, marginLeft: 5,
}, },
imgIconBiometry: { imgIconBiometry: {
width: WIDTHXD(120), width: WIDTHXD(120),
height: WIDTHXD(120), height: WIDTHXD(120),
}, },
row: { row: {
flexDirection: 'row', flexDirection: 'row',
marginTop: 30, marginTop: 30,
}, },
txtRegistor: { txtRegistor: {
marginLeft: WIDTHXD(10), marginLeft: WIDTHXD(10),
fontSize: getFontXD(42), fontSize: getFontXD(42),
color: '#1473E6', color: '#1473E6',
}, },
}); });
const mapStateToProps = (state) => { const mapStateToProps = (state) => {
return {}; return {};
}; };
export default connect(mapStateToProps, { export default connect(mapStateToProps, {
showLoading, showLoading,
hideLoading, hideLoading,
saveUserToRedux, saveUserToRedux,
})(Login); })(Login);
...@@ -38,13 +38,23 @@ const FirebaseNotification = (props) => { ...@@ -38,13 +38,23 @@ const FirebaseNotification = (props) => {
const unsubscribe = messaging().onMessage(async (remoteMessage) => { const unsubscribe = messaging().onMessage(async (remoteMessage) => {
console.log('A new FCM message arrived!', remoteMessage.data); console.log('A new FCM message arrived!', remoteMessage.data);
const {action_type, body, title, record_id} = remoteMessage.data; const {action_type, body, title, record_id} = remoteMessage.data;
props.showNotificaton({ if (action_type == 'REDIRECT') {
title, props.showNotificaton({
content: body, title,
screen: convertScreen(action_type), content: body,
id_record: record_id, screen: convertScreen(action_type),
link: remoteMessage.data?.redirect_to, id_record: record_id,
}); link: remoteMessage.data?.redirect_to,
});
} else {
props.showNotificaton({
title,
content: body,
screen: convertScreen(action_type),
id_record: record_id,
link: null,
});
}
if (action_type != 'CUSTOMER_NEWS') refetchDataUser(); if (action_type != 'CUSTOMER_NEWS') refetchDataUser();
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment