Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: Migrate LoginView to TypeScript #3423

Merged
merged 15 commits into from
Oct 20, 2021
56 changes: 34 additions & 22 deletions app/containers/TextInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {
KeyboardTypeOptions,
NativeSyntheticEvent,
ReturnKeyTypeOptions,
StyleProp,
StyleSheet,
Text,
TextInputAndroidProps,
TextInputIOSProps,
TextInputSubmitEditingEventData,
View,
ViewStyle
} from 'react-native';
import Touchable from 'react-native-platform-touchable';

import sharedStyles from '../views/Styles';
Expand Down Expand Up @@ -51,22 +63,29 @@ const styles = StyleSheet.create({
});

interface IRCTextInputProps {
label: string;
error: {
label?: string;
value?: string;
keyboardType?: KeyboardTypeOptions;
returnKeyType?: ReturnKeyTypeOptions;
onChangeText?: Function;
onSubmitEditing?: (e: NativeSyntheticEvent<TextInputSubmitEditingEventData>) => void;
gerzonc marked this conversation as resolved.
Show resolved Hide resolved
error?: {
error: any;
reason: any;
};
loading: boolean;
secureTextEntry: boolean;
containerStyle: any;
inputStyle: object;
inputRef: any;
testID: string;
iconLeft: string;
iconRight: string;
loading?: boolean;
secureTextEntry?: boolean;
containerStyle?: StyleProp<ViewStyle>;
inputStyle?: object;
inputRef?: React.Ref<unknown>;
testID?: string;
iconLeft?: string;
iconRight?: string;
placeholder: string;
left: JSX.Element;
onIconRightPress(): void;
left?: JSX.Element;
textContentType?: TextInputIOSProps['textContentType'];
autoCompleteType?: TextInputAndroidProps['autoCompleteType'];
onIconRightPress?(): void;
theme: string;
}

Expand Down Expand Up @@ -148,17 +167,10 @@ export default class RCTextInput extends React.PureComponent<IRCTextInputProps,
return (
<View style={[styles.inputContainer, containerStyle]}>
{label ? (
<Text
contentDescription={null}
// @ts-ignore
accessibilityLabel={null}
style={[styles.label, { color: themes[theme].titleText }, error.error && { color: dangerColor }]}>
{label}
</Text>
<Text style={[styles.label, { color: themes[theme].titleText }, error?.error && { color: dangerColor }]}>{label}</Text>
) : null}
<View style={styles.wrap}>
<TextInput
/* @ts-ignore*/
style={[
styles.input,
iconLeft && styles.inputIconLeft,
Expand All @@ -168,7 +180,7 @@ export default class RCTextInput extends React.PureComponent<IRCTextInputProps,
borderColor: themes[theme].separatorColor,
color: themes[theme].titleText
},
error.error && {
error?.error && {
color: dangerColor,
borderColor: dangerColor
},
Expand Down
61 changes: 32 additions & 29 deletions app/views/LoginView.js → app/views/LoginView.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Alert, Keyboard, StyleSheet, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { dequal } from 'dequal';
import { StackNavigationProp } from '@react-navigation/stack';
import { RouteProp } from '@react-navigation/core';

import Button from '../containers/Button';
import I18n from '../i18n';
Expand Down Expand Up @@ -46,39 +47,41 @@ const styles = StyleSheet.create({
}
});

class LoginView extends React.Component {
static navigationOptions = ({ route, navigation }) => ({
title: route.params?.title ?? 'Rocket.Chat',
interface IProps {
navigation: StackNavigationProp<any>;
route: RouteProp<any, 'RegisterView'>;
Site_Name: string;
Accounts_RegistrationForm: string;
Accounts_RegistrationForm_LinkReplacementText: string;
Accounts_EmailOrUsernamePlaceholder: string;
Accounts_PasswordPlaceholder: string;
Accounts_PasswordReset: boolean;
Accounts_ShowFormLogin: boolean;
isFetching: boolean;
error: object;
failure: boolean;
theme: string;
loginRequest: Function;
inviteLinkToken: string;
}

class LoginView extends React.Component<IProps, any> {
private passwordInput: any;

static navigationOptions = ({ route, navigation }: Partial<IProps>) => ({
title: route?.params?.title ?? 'Rocket.Chat',
headerRight: () => <HeaderButton.Legal testID='login-view-more' navigation={navigation} />
});

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) {
constructor(props: IProps) {
super(props);
this.state = {
user: props.route.params?.username ?? '',
password: ''
};
}

UNSAFE_componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps: IProps) {
const { error } = this.props;
if (nextProps.failure && !dequal(error, nextProps.error)) {
Alert.alert(I18n.t('Oops'), I18n.t('Login_error'));
Expand Down Expand Up @@ -146,7 +149,7 @@ class LoginView extends React.Component {
placeholder={Accounts_EmailOrUsernamePlaceholder || I18n.t('Username_or_email')}
keyboardType='email-address'
returnKeyType='next'
onChangeText={value => this.setState({ user: value })}
onChangeText={(value: string) => this.setState({ user: value })}
onSubmitEditing={() => {
this.passwordInput.focus();
}}
Expand All @@ -166,7 +169,7 @@ class LoginView extends React.Component {
returnKeyType='send'
secureTextEntry
onSubmitEditing={this.submit}
onChangeText={value => this.setState({ password: value })}
onChangeText={(value: string) => this.setState({ password: value })}
testID='login-view-password'
textContentType='password'
autoCompleteType='password'
Expand Down Expand Up @@ -227,7 +230,7 @@ class LoginView extends React.Component {
}
}

const mapStateToProps = state => ({
const mapStateToProps = (state: any) => ({
server: state.server.server,
Site_Name: state.settings.Site_Name,
Accounts_ShowFormLogin: state.settings.Accounts_ShowFormLogin,
Expand All @@ -242,8 +245,8 @@ const mapStateToProps = state => ({
inviteLinkToken: state.inviteLinks.token
});

const mapDispatchToProps = dispatch => ({
loginRequest: params => dispatch(loginRequestAction(params))
const mapDispatchToProps = (dispatch: any) => ({
loginRequest: (params: any) => dispatch(loginRequestAction(params))
});

export default connect(mapStateToProps, mapDispatchToProps)(withTheme(LoginView));