feat: add room lock pwd error message

This commit is contained in:
Bettenbuk Zoltan 2019-07-10 10:19:00 +02:00 committed by Zoltan Bettenbuk
parent 598b6f0598
commit a53a86ee7a
4 changed files with 80 additions and 4 deletions

View File

@ -189,6 +189,7 @@
"gracefulShutdown": "Our service is currently down for maintenance. Please try again later.", "gracefulShutdown": "Our service is currently down for maintenance. Please try again later.",
"hungUp": "You hung up", "hungUp": "You hung up",
"IamHost": "I am the host", "IamHost": "I am the host",
"incorrectRoomLockPassword": "Incorrect password",
"incorrectPassword": "Incorrect username or password", "incorrectPassword": "Incorrect username or password",
"inlineInstallationMsg": "You need to install our desktop sharing extension.", "inlineInstallationMsg": "You need to install our desktop sharing extension.",
"inlineInstallExtension": "Install now", "inlineInstallExtension": "Install now",

View File

@ -30,6 +30,16 @@ type Props = BaseProps & {
*/ */
contentKey: string, contentKey: string,
/**
* An optional initial value to initiate the field with.
*/
initialValue?: ?string,
/**
* A message key to be shown for the user (e.g. an error that is defined after submitting the form).
*/
messageKey?: string,
t: Function, t: Function,
textInputProps: ?Object, textInputProps: ?Object,
@ -62,7 +72,7 @@ class InputDialog extends BaseDialog<Props, State> {
super(props); super(props);
this.state = { this.state = {
fieldValue: undefined fieldValue: props.initialValue
}; };
this._onChangeText = this._onChangeText.bind(this); this._onChangeText = this._onChangeText.bind(this);
@ -75,7 +85,7 @@ class InputDialog extends BaseDialog<Props, State> {
* @inheritdoc * @inheritdoc
*/ */
_renderContent() { _renderContent() {
const { _dialogStyles, okDisabled, t } = this.props; const { _dialogStyles, messageKey, okDisabled, t } = this.props;
return ( return (
<View> <View>
@ -93,6 +103,13 @@ class InputDialog extends BaseDialog<Props, State> {
underlineColorAndroid = { FIELD_UNDERLINE } underlineColorAndroid = { FIELD_UNDERLINE }
value = { this.state.fieldValue } value = { this.state.fieldValue }
{ ...this.props.textInputProps } /> { ...this.props.textInputProps } />
{ messageKey && (<Text
style = { [
styles.formMessage,
_dialogStyles.text
] }>
{ t(messageKey) }
</Text>) }
</View> </View>
<View style = { brandedDialog.buttonWrapper }> <View style = { brandedDialog.buttonWrapper }>
<TouchableOpacity <TouchableOpacity

View File

@ -115,6 +115,12 @@ export const inputDialog = createStyleSheet({
fieldWrapper: { fieldWrapper: {
...brandedDialog.mainWrapper, ...brandedDialog.mainWrapper,
paddingBottom: BoxModel.padding * 2 paddingBottom: BoxModel.padding * 2
},
formMessage: {
alignSelf: 'flex-start',
fontStyle: 'italic',
margin: BoxModel.margin
} }
}); });

View File

@ -14,6 +14,11 @@ import { _cancelPasswordRequiredPrompt } from '../actions';
*/ */
type Props = { type Props = {
/**
* The previously entered password, if any.
*/
_password: ?string,
/** /**
* The {@code JitsiConference} which requires a password. * The {@code JitsiConference} which requires a password.
* *
@ -27,11 +32,19 @@ type Props = {
dispatch: Dispatch<any> dispatch: Dispatch<any>
}; };
type State = {
/**
* The previously entered password, if any.
*/
password: ?string
}
/** /**
* Implements a React {@code Component} which prompts the user when a password * Implements a React {@code Component} which prompts the user when a password
* is required to join a conference. * is required to join a conference.
*/ */
class PasswordRequiredPrompt extends Component<Props> { class PasswordRequiredPrompt extends Component<Props, State> {
/** /**
* Initializes a new {@code PasswordRequiredPrompt} instance. * Initializes a new {@code PasswordRequiredPrompt} instance.
* *
@ -41,11 +54,34 @@ class PasswordRequiredPrompt extends Component<Props> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
this.state = {
password: props._password
};
// Bind event handlers so they are only bound once per instance. // Bind event handlers so they are only bound once per instance.
this._onCancel = this._onCancel.bind(this); this._onCancel = this._onCancel.bind(this);
this._onSubmit = this._onSubmit.bind(this); this._onSubmit = this._onSubmit.bind(this);
} }
/**
* Implements {@code Component#componentDidUpdate}.
*
* @inheritdoc
*/
componentDidUpdate() {
const { _password } = this.props;
// The previous password in Redux gets cleared after the dialog appears and it ends up breaking the dialog
// logic. We move the prop into state and only update it if it has an actual value, avoiding loosing the
// previously received value when Redux updates.
if (_password && _password !== this.state.password) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
password: _password
});
}
}
/** /**
* Implements React's {@link Component#render()}. * Implements React's {@link Component#render()}.
* *
@ -53,9 +89,13 @@ class PasswordRequiredPrompt extends Component<Props> {
* @returns {ReactElement} * @returns {ReactElement}
*/ */
render() { render() {
const { password } = this.state;
return ( return (
<InputDialog <InputDialog
contentKey = 'dialog.passwordLabel' contentKey = 'dialog.passwordLabel'
initialValue = { password }
messageKey = { password ? 'dialog.incorrectRoomLockPassword' : undefined }
onCancel = { this._onCancel } onCancel = { this._onCancel }
onSubmit = { this._onSubmit } onSubmit = { this._onSubmit }
textInputProps = {{ textInputProps = {{
@ -100,4 +140,16 @@ class PasswordRequiredPrompt extends Component<Props> {
} }
} }
export default connect()(PasswordRequiredPrompt); /**
* Maps part of the Redux state to the props of this component.
*
* @param {Object} state - The Redux state.
* @returns {Props}
*/
function _mapStateToProps(state) {
return {
_password: state['features/base/conference'].password
};
}
export default connect(_mapStateToProps)(PasswordRequiredPrompt);