import React from 'react'; import PropTypes from 'prop-types'; import { Text, View, StyleSheet, Keyboard, Alert } from 'react-native'; import { connect } from 'react-redux'; import { dequal } from 'dequal'; import sharedStyles from './Styles'; import Button from '../containers/Button'; import I18n from '../i18n'; import * as HeaderButton from '../containers/HeaderButton'; import { themes } from '../constants/colors'; import { withTheme } from '../theme'; import FormContainer, { FormContainerInner } from '../containers/FormContainer'; import TextInput from '../containers/TextInput'; import { loginRequest as loginRequestAction } from '../actions/login'; import LoginServices from '../containers/LoginServices'; const styles = StyleSheet.create({ registerDisabled: { ...sharedStyles.textRegular, ...sharedStyles.textAlignCenter, fontSize: 16 }, title: { ...sharedStyles.textBold, fontSize: 22 }, inputContainer: { marginVertical: 16 }, bottomContainer: { flexDirection: 'column', alignItems: 'center', marginBottom: 32 }, bottomContainerText: { ...sharedStyles.textRegular, fontSize: 13 }, bottomContainerTextBold: { ...sharedStyles.textSemibold, fontSize: 13 }, loginButton: { marginTop: 16 } }); class LoginView extends React.Component { static navigationOptions = ({ route, navigation }) => ({ title: route.params?.title ?? 'Rocket.Chat', headerRight: () => }) static propTypes = { navigation: PropTypes.object, route: PropTypes.object, Site_Name: PropTypes.string, Accounts_RegistrationForm: PropTypes.string, Accounts_RegistrationForm_LinkReplacementText: PropTypes.string, Accounts_EmailOrUsernamePlaceholder: PropTypes.string, Accounts_PasswordPlaceholder: PropTypes.string, Accounts_PasswordReset: PropTypes.bool, Accounts_ShowFormLogin: PropTypes.bool, isFetching: PropTypes.bool, error: PropTypes.object, failure: PropTypes.bool, theme: PropTypes.string, loginRequest: PropTypes.func, inviteLinkToken: PropTypes.string } constructor(props) { super(props); this.state = { user: props.route.params?.username ?? '', password: '' }; } UNSAFE_componentWillReceiveProps(nextProps) { const { error } = this.props; if (nextProps.failure && !dequal(error, nextProps.error)) { Alert.alert(I18n.t('Oops'), I18n.t('Login_error')); } } get showRegistrationButton() { const { Accounts_RegistrationForm, inviteLinkToken } = this.props; return Accounts_RegistrationForm === 'Public' || (Accounts_RegistrationForm === 'Secret URL' && inviteLinkToken?.length); } login = () => { const { navigation, Site_Name } = this.props; navigation.navigate('LoginView', { title: Site_Name }); } register = () => { const { navigation, Site_Name } = this.props; navigation.navigate('RegisterView', { title: Site_Name }); } forgotPassword = () => { const { navigation, Site_Name } = this.props; navigation.navigate('ForgotPasswordView', { title: Site_Name }); } valid = () => { const { user, password } = this.state; return user.trim() && password.trim(); } submit = () => { if (!this.valid()) { return; } const { user, password } = this.state; const { loginRequest } = this.props; Keyboard.dismiss(); loginRequest({ user, password }); } renderUserForm = () => { const { user } = this.state; const { Accounts_EmailOrUsernamePlaceholder, Accounts_PasswordPlaceholder, Accounts_PasswordReset, Accounts_RegistrationForm_LinkReplacementText, isFetching, theme, Accounts_ShowFormLogin } = this.props; if (!Accounts_ShowFormLogin) { return null; } return ( <> {I18n.t('Login')} this.setState({ user: value })} onSubmitEditing={() => { this.passwordInput.focus(); }} testID='login-view-email' textContentType='username' autoCompleteType='username' theme={theme} value={user} /> { this.passwordInput = e; }} placeholder={Accounts_PasswordPlaceholder || I18n.t('Password')} returnKeyType='send' secureTextEntry onSubmitEditing={this.submit} onChangeText={value => this.setState({ password: value })} testID='login-view-password' textContentType='password' autoCompleteType='password' theme={theme} />