feat(dialog) new native InputDialog
This commit is contained in:
parent
78b117cec6
commit
66b4c0cab0
|
@ -1,32 +1,25 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { View, Text, TextInput, TouchableOpacity } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import Dialog from 'react-native-dialog';
|
||||
|
||||
import { translate } from '../../../i18n';
|
||||
import { connect } from '../../../redux';
|
||||
import { StyleType } from '../../../styles';
|
||||
import { _abstractMapStateToProps } from '../../functions';
|
||||
import { type State as AbstractState } from '../AbstractDialog';
|
||||
import AbstractDialog, {
|
||||
type Props as AbstractProps,
|
||||
type State as AbstractState
|
||||
} from '../AbstractDialog';
|
||||
|
||||
import BaseDialog, { type Props as BaseProps } from './BaseDialog';
|
||||
import {
|
||||
FIELD_UNDERLINE,
|
||||
brandedDialog,
|
||||
inputDialog as styles
|
||||
} from './styles';
|
||||
import { FIELD_UNDERLINE, inputDialog as styles } from './styles';
|
||||
|
||||
type Props = BaseProps & {
|
||||
type Props = AbstractProps & {
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
* The dialog descriptionKey.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
/**
|
||||
* The untranslated i18n key for the field label on the dialog.
|
||||
*/
|
||||
contentKey: string,
|
||||
descriptionKey: string,
|
||||
|
||||
/**
|
||||
* An optional initial value to initiate the field with.
|
||||
|
@ -38,18 +31,28 @@ type Props = BaseProps & {
|
|||
*/
|
||||
messageKey?: string,
|
||||
|
||||
/**
|
||||
* The translate function.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* Props for the text input.
|
||||
*/
|
||||
textInputProps: ?Object,
|
||||
|
||||
/**
|
||||
* The untranslated i18n key for the dialog title.
|
||||
*/
|
||||
titleKey?: string,
|
||||
|
||||
/**
|
||||
* Validating of the input.
|
||||
*/
|
||||
validateInput: ?Function
|
||||
}
|
||||
|
||||
type State = {
|
||||
...AbstractState,
|
||||
type State = AbstractState & {
|
||||
|
||||
/**
|
||||
* The current value of the field.
|
||||
|
@ -60,7 +63,7 @@ type State = {
|
|||
/**
|
||||
* Implements a single field input dialog component.
|
||||
*/
|
||||
class InputDialog extends BaseDialog<Props, State> {
|
||||
class InputDialog<P: Props, S: State> extends AbstractDialog<P, S> {
|
||||
/**
|
||||
* Instantiates a new {@code InputDialog}.
|
||||
*
|
||||
|
@ -79,52 +82,55 @@ class InputDialog extends BaseDialog<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements {@code BaseDialog._renderContent}.
|
||||
* Implements {@code Component#render}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
_renderContent() {
|
||||
const { _dialogStyles, messageKey, okDisabled, t } = this.props;
|
||||
render() {
|
||||
const {
|
||||
descriptionKey,
|
||||
messageKey,
|
||||
t,
|
||||
titleKey
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View
|
||||
style = { [
|
||||
brandedDialog.mainWrapper,
|
||||
styles.fieldWrapper
|
||||
] }>
|
||||
<Text style = { _dialogStyles.fieldLabel }>
|
||||
{ t(this.props.contentKey) }
|
||||
</Text>
|
||||
<TextInput
|
||||
<Dialog.Container
|
||||
onBackdropPress = { this._onCancel }
|
||||
visible = { true }>
|
||||
{
|
||||
titleKey && (
|
||||
<Dialog.Title>
|
||||
{ t(titleKey) }
|
||||
</Dialog.Title>
|
||||
)
|
||||
}
|
||||
{
|
||||
descriptionKey && (
|
||||
<Dialog.Description>
|
||||
{ t(descriptionKey) }
|
||||
</Dialog.Description>
|
||||
)
|
||||
}
|
||||
<Dialog.Input
|
||||
autoFocus = { true }
|
||||
onChangeText = { this._onChangeText }
|
||||
style = { _dialogStyles.field }
|
||||
underlineColorAndroid = { FIELD_UNDERLINE }
|
||||
value = { this.state.fieldValue }
|
||||
{ ...this.props.textInputProps } />
|
||||
{ messageKey && (<Text
|
||||
style = { [
|
||||
styles.formMessage,
|
||||
_dialogStyles.text
|
||||
] }>
|
||||
{ t(messageKey) }
|
||||
</Text>) }
|
||||
</View>
|
||||
<View style = { brandedDialog.buttonWrapper }>
|
||||
<TouchableOpacity
|
||||
disabled = { okDisabled }
|
||||
onPress = { this._onSubmitValue }
|
||||
style = { [
|
||||
_dialogStyles.button,
|
||||
brandedDialog.buttonFarLeft,
|
||||
brandedDialog.buttonFarRight
|
||||
] }>
|
||||
<Text style = { _dialogStyles.buttonLabel }>
|
||||
{ t('dialog.Ok') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{
|
||||
messageKey && (
|
||||
<Dialog.Description
|
||||
style = { styles.formMessage }>
|
||||
{ t(messageKey) }
|
||||
</Dialog.Description>
|
||||
)
|
||||
}
|
||||
<Dialog.Button
|
||||
label = { t('dialog.Ok') }
|
||||
onPress = { this._onSubmitValue } />
|
||||
</Dialog.Container>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -140,9 +146,7 @@ class InputDialog extends BaseDialog<Props, State> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onChangeText(fieldValue) {
|
||||
|
||||
if (this.props.validateInput
|
||||
&& !this.props.validateInput(fieldValue)) {
|
||||
if (this.props.validateInput && !this.props.validateInput(fieldValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,15 +162,11 @@ export const inputDialog = {
|
|||
marginBottom: 0
|
||||
},
|
||||
|
||||
fieldWrapper: {
|
||||
...brandedDialog.mainWrapper,
|
||||
paddingBottom: BoxModel.padding * 2
|
||||
},
|
||||
|
||||
formMessage: {
|
||||
alignSelf: 'flex-start',
|
||||
fontStyle: 'italic',
|
||||
margin: BoxModel.margin
|
||||
fontWeight: 'bold',
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -18,8 +18,9 @@ class DisplayNamePrompt extends AbstractDisplayNamePrompt<*> {
|
|||
render() {
|
||||
return (
|
||||
<InputDialog
|
||||
contentKey = 'dialog.enterDisplayName'
|
||||
onSubmit = { this._onSetDisplayName } />
|
||||
descriptionKey = 'dialog.enterDisplayName'
|
||||
onSubmit = { this._onSetDisplayName }
|
||||
titleKey = 'dialog.displayNameRequired' />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,14 +92,15 @@ class PasswordRequiredPrompt extends Component<Props, State> {
|
|||
|
||||
return (
|
||||
<InputDialog
|
||||
contentKey = 'dialog.passwordLabel'
|
||||
descriptionKey = 'dialog.passwordLabel'
|
||||
initialValue = { password }
|
||||
messageKey = { password ? 'dialog.incorrectRoomLockPassword' : undefined }
|
||||
onCancel = { this._onCancel }
|
||||
onSubmit = { this._onSubmit }
|
||||
textInputProps = {{
|
||||
secureTextEntry: true
|
||||
}} />
|
||||
}}
|
||||
titleKey = 'dialog.password' />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import React from 'react';
|
|||
import { InputDialog } from '../../../base/dialog';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { ColorPalette } from '../../../base/styles';
|
||||
import AbstractSharedVideoDialog from '../AbstractSharedVideoDialog';
|
||||
|
||||
/**
|
||||
|
@ -56,15 +55,14 @@ class SharedVideoDialog extends AbstractSharedVideoDialog<*> {
|
|||
|
||||
return (
|
||||
<InputDialog
|
||||
contentKey = 'dialog.shareVideoTitle'
|
||||
messageKey = { error ? 'dialog.sharedVideoDialogError' : undefined }
|
||||
onSubmit = { this._onSubmitValue }
|
||||
textInputProps = {{
|
||||
autoCapitalize: 'none',
|
||||
autoCorrect: false,
|
||||
placeholder: t('dialog.sharedVideoLinkPlaceholder'),
|
||||
placeholderTextColor: ColorPalette.lightGrey
|
||||
}} />
|
||||
placeholder: t('dialog.sharedVideoLinkPlaceholder')
|
||||
}}
|
||||
titleKey = 'dialog.shareVideoTitle' />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue