Fix Android keyboard (#250)

This commit is contained in:
enahum 2017-02-14 11:30:28 -03:00 committed by Harrison Healey
parent 3fb12eed99
commit 239ecbcdba
5 changed files with 267 additions and 157 deletions

View file

@ -4,8 +4,10 @@
import React from 'react';
import {
KeyboardAvoidingView,
Platform,
StatusBar,
Text
Text,
View
} from 'react-native';
import {Constants} from 'service/constants';
@ -100,6 +102,15 @@ export default class Channel extends React.PureComponent {
this.props.actions.selectFirstAvailableTeam();
};
renderAndroid = (children) => {
const {theme} = this.props;
return (
<View style={{flex: 1, backgroundColor: theme.centerChannelBg}}>
{children}
</View>
);
};
render() {
const {
currentTeam,
@ -118,21 +129,42 @@ export default class Channel extends React.PureComponent {
teamId = currentTeam.id;
}
const status = (
<StatusBar
key='statusBar'
barStyle='light-content'
/>
);
const postList = (
<ChannelPostList
key='postList'
channel={currentChannel}
/>
);
const postTextBox = (
<PostTextbox
ref={this.attachPostTextbox}
key='postTextBox'
value={this.props.drafts[this.props.currentChannel.id]}
teamId={teamId}
channelId={currentChannel.id}
onChangeText={this.props.actions.handlePostDraftChanged}
/>
);
if (Platform.OS === 'android') {
return this.renderAndroid([status, postList, postTextBox]);
}
return (
<KeyboardAvoidingView
behavior='padding'
style={{flex: 1, backgroundColor: theme.centerChannelBg}}
keyboardVerticalOffset={65}
>
<StatusBar barStyle='light-content'/>
<ChannelPostList channel={currentChannel}/>
<PostTextbox
ref={this.attachPostTextbox}
value={this.props.drafts[this.props.currentChannel.id]}
teamId={teamId}
channelId={currentChannel.id}
onChangeText={this.props.actions.handlePostDraftChanged}
/>
{status}
{postList}
{postTextBox}
</KeyboardAvoidingView>
);
}

View file

@ -5,7 +5,9 @@ import React, {Component, PropTypes} from 'react';
import {injectIntl, intlShape} from 'react-intl';
import {
Image,
Keyboard,
KeyboardAvoidingView,
Platform,
Text,
TextInput,
TouchableWithoutFeedback,
@ -72,6 +74,7 @@ class Login extends Component {
preSignIn = () => {
this.setState({error: null});
Keyboard.dismiss();
if (!this.props.loginId) {
// it's slightly weird to be constructing the message ID, but it's a bit nicer than triply nested if statements
let msgId = 'login.no';
@ -156,75 +159,89 @@ class Login extends Component {
return '';
}
loginRef = (ref) => {
this.loginId = ref;
};
passwordRef = (ref) => {
this.passwd = ref;
};
passwordFocus = () => {
this.passwd.focus();
};
render() {
if (this.props.configRequest.status === RequestStatus.STARTED || this.props.licenseRequest.status === RequestStatus.STARTED) {
return <Loading/>;
}
const scene = (
<TouchableWithoutFeedback onPress={this.blur}>
<View style={[GlobalStyles.container, GlobalStyles.signupContainer]}>
<Image
source={logo}
/>
<Text style={GlobalStyles.header}>
{this.props.config.SiteName}
</Text>
<FormattedText
style={GlobalStyles.subheader}
id='web.root.signup_info'
defaultMessage='All team communication in one place, searchable and accessible anywhere'
/>
<ErrorText error={this.props.loginRequest.error || this.props.checkMfaRequest.error || this.state.error}/>
<TextInput
ref={this.loginRef}
value={this.props.loginId}
onChangeText={this.props.actions.handleLoginIdChanged}
style={GlobalStyles.inputBox}
placeholder={this.createLoginPlaceholder()}
autoCorrect={false}
autoCapitalize='none'
keyboardType='email-address'
returnKeyType='next'
underlineColorAndroid='transparent'
onSubmitEditing={this.passwordFocus}
/>
<TextInput
ref={this.passwordRef}
value={this.props.password}
onChangeText={this.props.actions.handlePasswordChanged}
style={GlobalStyles.inputBox}
placeholder={this.props.intl.formatMessage({id: 'login.password', defaultMessage: 'Password'})}
secureTextEntry={true}
autoCorrect={false}
autoCapitalize='none'
underlineColorAndroid='transparent'
returnKeyType='go'
onSubmitEditing={this.preSignIn}
/>
<Button
onPress={this.preSignIn}
containerStyle={GlobalStyles.signupButton}
>
<FormattedText
id='login.signIn'
defaultMessage='Sign in'
style={GlobalStyles.signupButtonText}
/>
</Button>
</View>
</TouchableWithoutFeedback>
);
if (Platform.OS === 'android') {
return scene;
}
return (
<KeyboardAvoidingView
behavior='padding'
style={{flex: 1}}
keyboardVerticalOffset={65}
>
<TouchableWithoutFeedback onPress={this.blur}>
<View style={[GlobalStyles.container, GlobalStyles.signupContainer]}>
<Image
source={logo}
/>
<Text style={GlobalStyles.header}>
{this.props.config.SiteName}
</Text>
<FormattedText
style={GlobalStyles.subheader}
id='web.root.signup_info'
defaultMessage='All team communication in one place, searchable and accessible anywhere'
/>
<ErrorText error={this.props.loginRequest.error || this.props.checkMfaRequest.error || this.state.error}/>
<TextInput
ref={(ref) => {
this.loginId = ref;
}}
value={this.props.loginId}
onChangeText={this.props.actions.handleLoginIdChanged}
style={GlobalStyles.inputBox}
placeholder={this.createLoginPlaceholder()}
autoCorrect={false}
autoCapitalize='none'
keyboardType='email-address'
returnKeyType='next'
underlineColorAndroid='transparent'
onSubmitEditing={() => {
this.passwd.focus();
}}
/>
<TextInput
ref={(ref) => {
this.passwd = ref;
}}
value={this.props.password}
onChangeText={this.props.actions.handlePasswordChanged}
style={GlobalStyles.inputBox}
placeholder={this.props.intl.formatMessage({id: 'login.password', defaultMessage: 'Password'})}
secureTextEntry={true}
autoCorrect={false}
autoCapitalize='none'
underlineColorAndroid='transparent'
returnKeyType='go'
onSubmitEditing={this.preSignIn}
/>
<Button
onPress={this.preSignIn}
containerStyle={GlobalStyles.signupButton}
>
<FormattedText
id='login.signIn'
defaultMessage='Sign in'
style={GlobalStyles.signupButtonText}
/>
</Button>
</View>
</TouchableWithoutFeedback>
{scene}
</KeyboardAvoidingView>
);
}

View file

@ -4,7 +4,9 @@
import React, {Component} from 'react';
import {
Image,
Keyboard,
KeyboardAvoidingView,
Platform,
TouchableWithoutFeedback,
View
} from 'react-native';
@ -54,11 +56,16 @@ export default class Mfa extends Component {
});
};
inputRef = (ref) => {
this.textInput = ref;
};
blur = () => {
this.textInput.refs.wrappedInstance.blur();
};
submit = () => {
Keyboard.dismiss();
if (!this.state.token) {
this.setState({
error: {
@ -73,51 +80,57 @@ export default class Mfa extends Component {
};
render() {
const scene = (
<TouchableWithoutFeedback onPress={this.blur}>
<View style={[GlobalStyles.container, GlobalStyles.signupContainer]}>
<Image
source={logo}
/>
<FormattedText
style={[GlobalStyles.header, GlobalStyles.label]}
id='login_mfa.enterToken'
defaultMessage="To complete the sign in process, please enter a token from your smartphone's authenticator"
/>
<ErrorText error={this.state.error}/>
<TextInputWithLocalizedPlaceholder
ref={this.inputRef}
value={this.state.token}
onChangeText={this.handleInput}
onSubmitEditing={this.submit}
style={GlobalStyles.inputBox}
autoCapitalize='none'
autoCorrect={false}
keyboardType='numeric'
placeholder={{id: 'login_mfa.token', defaultMessage: 'MFA Token'}}
returnKeyType='go'
underlineColorAndroid='transparent'
/>
<Button
onPress={this.submit}
loading={false}
containerStyle={GlobalStyles.signupButton}
>
<FormattedText
style={GlobalStyles.signupButtonText}
id='mobile.components.select_server_view.proceed'
defaultMessage='Proceed'
/>
</Button>
</View>
</TouchableWithoutFeedback>
);
if (Platform.OS === 'android') {
return scene;
}
return (
<KeyboardAvoidingView
behavior='padding'
style={{flex: 1}}
keyboardVerticalOffset={0}
>
<TouchableWithoutFeedback onPress={this.blur}>
<View style={[GlobalStyles.container, GlobalStyles.signupContainer]}>
<Image
source={logo}
/>
<FormattedText
style={[GlobalStyles.header, GlobalStyles.label]}
id='login_mfa.enterToken'
defaultMessage="To complete the sign in process, please enter a token from your smartphone's authenticator"
/>
<ErrorText error={this.state.error}/>
<TextInputWithLocalizedPlaceholder
ref={(ref) => {
this.textInput = ref;
}}
value={this.state.token}
onChangeText={this.handleInput}
onSubmitEditing={this.submit}
style={GlobalStyles.inputBox}
autoCapitalize='none'
autoCorrect={false}
keyboardType='numeric'
placeholder={{id: 'login_mfa.token', defaultMessage: 'MFA Token'}}
returnKeyType='go'
underlineColorAndroid='transparent'
/>
<Button
onPress={this.submit}
loading={false}
containerStyle={GlobalStyles.signupButton}
>
<FormattedText
style={GlobalStyles.signupButtonText}
id='mobile.components.select_server_view.proceed'
defaultMessage='Proceed'
/>
</Button>
</View>
</TouchableWithoutFeedback>
{scene}
</KeyboardAvoidingView>
);
}

View file

@ -4,7 +4,9 @@
import React, {Component} from 'react';
import {
Image,
Keyboard,
KeyboardAvoidingView,
Platform,
TouchableWithoutFeedback,
View
} from 'react-native';
@ -32,61 +34,72 @@ export default class SelectServer extends Component {
this.props.actions.getPing().then(() => {
if (this.props.server.status === RequestStatus.SUCCESS) {
Keyboard.dismiss();
this.props.actions.goToLogin();
}
});
};
inputRef = (ref) => {
this.textInput = ref;
};
blur = () => {
this.textInput.refs.wrappedInstance.blur();
};
render() {
const scene = (
<TouchableWithoutFeedback onPress={this.blur}>
<View style={[GlobalStyles.container, GlobalStyles.signupContainer]}>
<Image
source={logo}
/>
<FormattedText
style={[GlobalStyles.header, GlobalStyles.label]}
id='mobile.components.select_server_view.enterServerUrl'
defaultMessage='Enter Server URL'
/>
<TextInputWithLocalizedPlaceholder
ref={this.inputRef}
value={this.props.serverUrl}
onChangeText={this.props.actions.handleServerUrlChanged}
onSubmitEditing={this.onClick}
style={GlobalStyles.inputBox}
autoCapitalize='none'
autoCorrect={false}
keyboardType='url'
placeholder={{id: 'mobile.components.select_server_view.siteUrlPlaceholder', defaultMessage: 'https://mattermost.example.com'}}
returnKeyType='go'
underlineColorAndroid='transparent'
/>
<Button
onPress={this.onClick}
loading={this.props.server.loading}
containerStyle={GlobalStyles.signupButton}
>
<FormattedText
style={GlobalStyles.signupButtonText}
id='mobile.components.select_server_view.proceed'
defaultMessage='Proceed'
/>
</Button>
<ErrorText error={this.props.server.error}/>
</View>
</TouchableWithoutFeedback>
);
if (Platform.OS === 'android') {
return scene;
}
return (
<KeyboardAvoidingView
behavior='padding'
style={{flex: 1}}
keyboardVerticalOffset={0}
>
<TouchableWithoutFeedback onPress={this.blur}>
<View style={[GlobalStyles.container, GlobalStyles.signupContainer]}>
<Image
source={logo}
/>
<FormattedText
style={[GlobalStyles.header, GlobalStyles.label]}
id='mobile.components.select_server_view.enterServerUrl'
defaultMessage='Enter Server URL'
/>
<TextInputWithLocalizedPlaceholder
ref={(ref) => {
this.textInput = ref;
}}
value={this.props.serverUrl}
onChangeText={this.props.actions.handleServerUrlChanged}
onSubmitEditing={this.onClick}
style={GlobalStyles.inputBox}
autoCapitalize='none'
autoCorrect={false}
keyboardType='url'
placeholder={{id: 'mobile.components.select_server_view.siteUrlPlaceholder', defaultMessage: 'https://mattermost.example.com'}}
returnKeyType='go'
underlineColorAndroid='transparent'
/>
<Button
onPress={this.onClick}
loading={this.props.server.loading}
containerStyle={GlobalStyles.signupButton}
>
<FormattedText
style={GlobalStyles.signupButtonText}
id='mobile.components.select_server_view.proceed'
defaultMessage='Proceed'
/>
</Button>
<ErrorText error={this.props.server.error}/>
</View>
</TouchableWithoutFeedback>
{scene}
</KeyboardAvoidingView>
);
}

View file

@ -4,8 +4,10 @@
import React from 'react';
import {
KeyboardAvoidingView,
Platform,
StatusBar,
StyleSheet
StyleSheet,
View
} from 'react-native';
import PostList from 'app/components/post_list';
@ -36,25 +38,58 @@ export default class Thread extends React.Component {
handleDraftChanged = (value) => {
this.props.actions.handleCommentDraftChanged(this.props.rootId, value);
}
};
renderAndroid = (children) => {
const style = getStyle(this.props.theme);
return (
<View style={style.container}>
{children}
</View>
);
};
render() {
const style = getStyle(this.props.theme);
const status = (
<StatusBar
key='statusBar'
barStyle='light-content'
/>
);
const postList = (
<PostList
key='postList'
posts={this.props.posts}
/>
);
const postTextBox = (
<PostTextbox
key='postTextBox'
rootId={this.props.rootId}
value={this.props.draft}
teamId={this.props.teamId}
channelId={this.props.channelId}
onChangeText={this.handleDraftChanged}
/>
);
if (Platform.OS === 'android') {
return this.renderAndroid([status, postList, postTextBox]);
}
return (
<KeyboardAvoidingView
behavior='padding'
style={style.container}
keyboardVerticalOffset={65}
>
<StatusBar barStyle='light-content'/>
<PostList posts={this.props.posts}/>
<PostTextbox
rootId={this.props.rootId}
value={this.props.draft}
teamId={this.props.teamId}
channelId={this.props.channelId}
onChangeText={this.handleDraftChanged}
/>
{status}
{postList}
{postTextBox}
</KeyboardAvoidingView>
);
}