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