diff --git a/app/containers/TextInput.js b/app/containers/TextInput.js index 73f2ccabf0a3994e56ad3377810e606353fcadf3..c6b2899425bab0f0ab478324648ee781365bfba1 100644 --- a/app/containers/TextInput.js +++ b/app/containers/TextInput.js @@ -2,6 +2,8 @@ import React from 'react'; import { View, StyleSheet, Text, TextInput } from 'react-native'; import PropTypes from 'prop-types'; +import Icon from 'react-native-vector-icons/FontAwesome'; + import sharedStyles from '../views/Styles'; import { COLOR_DANGER } from '../constants/colors'; @@ -29,46 +31,57 @@ const styles = StyleSheet.create({ inputError: { color: COLOR_DANGER, borderColor: COLOR_DANGER + }, + wrap: { + flex: 1, + position: 'relative' + }, + icon: { + position: 'absolute', + right: 0, + padding: 10, + color: 'rgba(0,0,0,.45)' } }); + export default class RCTextInput extends React.PureComponent { static propTypes = { label: PropTypes.string, - value: PropTypes.string, error: PropTypes.object, - inputProps: PropTypes.object, - inputRef: PropTypes.func, - onChangeText: PropTypes.func, - onSubmitEditing: PropTypes.func + secureTextEntry: PropTypes.bool } - static defaultProps = { - label: 'Label', + showPassword: false, error: {} } + state = { + showPassword: false + } + + get icon() { return <Icon name={this.state.showPassword ? 'eye-slash' : 'eye'} style={styles.icon} size={20} onPress={this.tooglePassword} />; } + + tooglePassword = () => this.setState({ showPassword: !this.state.showPassword }) render() { const { - label, value, error, inputRef, onChangeText, onSubmitEditing, inputProps + label, error, secureTextEntry, ...inputProps } = this.props; + const { showPassword } = this.state; return ( <View style={styles.inputContainer}> - <Text style={[styles.label, error.error && styles.labelError]}> - {label} - </Text> - <TextInput - ref={inputRef} - style={[styles.input, error.error && styles.inputError]} - onChangeText={onChangeText} - onSubmitEditing={onSubmitEditing} - value={value} - autoCorrect={false} - returnKeyType='next' - autoCapitalize='none' - underlineColorAndroid='transparent' - {...inputProps} - /> + { label && <Text style={[styles.label, error.error && styles.labelError]}>{label}</Text> } + <View style={styles.wrap}> + <TextInput + style={[styles.input, error.error && styles.inputError]} + autoCorrect={false} + autoCapitalize='none' + underlineColorAndroid='transparent' + secureTextEntry={secureTextEntry && !showPassword} + {...inputProps} + /> + {secureTextEntry && this.icon} + </View> {error.error && <Text style={sharedStyles.error}>{error.reason}</Text>} </View> ); diff --git a/app/views/LoginView.js b/app/views/LoginView.js index 6aa06772c5c784e56b88ae154cfeee1ff66e7bc6..d6b7e3c9f2e4be2b1c0112bc7fb9bfbaecd4760e 100644 --- a/app/views/LoginView.js +++ b/app/views/LoginView.js @@ -1,7 +1,7 @@ import React from 'react'; import Spinner from 'react-native-loading-spinner-overlay'; import PropTypes from 'prop-types'; -import { Keyboard, Text, TextInput, View, ScrollView, TouchableOpacity, SafeAreaView, WebView, Platform, LayoutAnimation } from 'react-native'; +import { Keyboard, Text, View, ScrollView, TouchableOpacity, SafeAreaView, WebView, Platform, LayoutAnimation } from 'react-native'; import { connect } from 'react-redux'; import Icon from 'react-native-vector-icons/FontAwesome'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; @@ -10,6 +10,7 @@ import Modal from 'react-native-modal'; import { loginSubmit, open, close } from '../actions/login'; import KeyboardView from '../presentation/KeyboardView'; +import TextInput from '../containers/TextInput'; import styles from './Styles'; import scrollPersistTaps from '../utils/scrollPersistTaps'; @@ -65,7 +66,6 @@ export default class LoginView extends React.Component { username: '', password: '', modalVisible: false, - showPassword: false, oAuthUrl: '' }; this.redirectRegex = new RegExp(`(?=.*(${ this.props.server }))(?=.*(credentialToken))(?=.*(credentialSecret))`, 'g'); @@ -239,21 +239,20 @@ export default class LoginView extends React.Component { onSubmitEditing={() => { this.password.focus(); }} placeholder={this.props.Accounts_EmailOrUsernamePlaceholder || 'Email or username'} /> - <View style={styles.passInput}> - <TextInput - ref={(e) => { this.password = e; }} - style={styles.input_white} - onChangeText={password => this.setState({ password })} - secureTextEntry={!this.state.showPassword} - autoCorrect={false} - returnKeyType='done' - autoCapitalize='none' - underlineColorAndroid='transparent' - onSubmitEditing={this.submit} - placeholder={this.props.Accounts_PasswordPlaceholder || 'Password'} - /> - <Icon name='eye' style={styles.passIcon} size={20} onPress={() => { this.setState({ showPassword: !this.state.showPassword }); }}/> - </View> + + <TextInput + ref={(e) => { this.password = e; }} + style={styles.input_white} + onChangeText={password => this.setState({ password })} + secureTextEntry + autoCorrect={false} + returnKeyType='done' + autoCapitalize='none' + underlineColorAndroid='transparent' + onSubmitEditing={this.submit} + placeholder={this.props.Accounts_PasswordPlaceholder || 'Password'} + /> + {this.renderTOTP()} <TouchableOpacity diff --git a/app/views/RoomInfoEditView/index.js b/app/views/RoomInfoEditView/index.js index 3b8834f0649b6bffacc16cd73e54d39ef7fa3070..b8b30037a80b43dd693a19bf785b6830a565dece 100644 --- a/app/views/RoomInfoEditView/index.js +++ b/app/views/RoomInfoEditView/index.js @@ -262,7 +262,7 @@ export default class RoomInfoEditView extends React.Component { <SafeAreaView> <View style={sharedStyles.formContainer}> <RCTextInput - inputRef={(e) => { this.name = e; }} + ref={(e) => { this.name = e; }} label='Name' value={name} onChangeText={value => this.setState({ name: value })} @@ -270,7 +270,7 @@ export default class RoomInfoEditView extends React.Component { error={nameError} /> <RCTextInput - inputRef={(e) => { this.description = e; }} + ref={(e) => { this.description = e; }} label='Description' value={description} onChangeText={value => this.setState({ description: value })} @@ -278,7 +278,7 @@ export default class RoomInfoEditView extends React.Component { inputProps={{ multiline: true }} /> <RCTextInput - inputRef={(e) => { this.topic = e; }} + ref={(e) => { this.topic = e; }} label='Topic' value={topic} onChangeText={value => this.setState({ topic: value })} @@ -286,7 +286,7 @@ export default class RoomInfoEditView extends React.Component { inputProps={{ multiline: true }} /> <RCTextInput - inputRef={(e) => { this.announcement = e; }} + ref={(e) => { this.announcement = e; }} label='Announcement' value={announcement} onChangeText={value => this.setState({ announcement: value })} @@ -294,7 +294,7 @@ export default class RoomInfoEditView extends React.Component { inputProps={{ multiline: true }} /> <RCTextInput - inputRef={(e) => { this.joinCode = e; }} + ref={(e) => { this.joinCode = e; }} label='Password' value={joinCode} onChangeText={value => this.setState({ joinCode: value })} diff --git a/app/views/Styles.js b/app/views/Styles.js index f3b1c026d10ae64573d66900c0a1155dedf6478c..63c17bac648040eededef8ae1cbfe05d317f7ccb 100644 --- a/app/views/Styles.js +++ b/app/views/Styles.js @@ -32,16 +32,6 @@ export default StyleSheet.create({ justifyContent: 'center', flex: 1 }, - passInput: { - flex: 1, - position: 'relative' - }, - passIcon: { - position: 'absolute', - right: 0, - padding: 10, - color: 'rgba(0,0,0,.45)' - }, loginLogo: { width: Dimensions.get('window').width - 150, height: Dimensions.get('window').width - 150,