feat(display-name): convert prompt to react

Create a new component that uses Dialog. Reuse existing actions
for updating a participant's display name.
This commit is contained in:
Leonard Kim 2017-07-28 10:58:04 -07:00 committed by yanas
parent 1c1604bee7
commit 002e48b886
8 changed files with 166 additions and 47 deletions

View File

@ -29,6 +29,7 @@ import { setAudioMuted, setVideoMuted } from '../../react/features/base/media';
import { import {
openDeviceSelectionDialog openDeviceSelectionDialog
} from '../../react/features/device-selection'; } from '../../react/features/device-selection';
import { openDisplayNamePrompt } from '../../react/features/display-name';
import { import {
checkAutoEnableDesktopSharing, checkAutoEnableDesktopSharing,
dockToolbox, dockToolbox,
@ -867,53 +868,7 @@ UI.participantConnectionStatusChanged = function (id) {
* Prompt user for nickname. * Prompt user for nickname.
*/ */
UI.promptDisplayName = () => { UI.promptDisplayName = () => {
const labelKey = 'dialog.enterDisplayName'; APP.store.dispatch(openDisplayNamePrompt());
const message = (
`<div class="form-control">
<label data-i18n="${labelKey}" class="form-control__label"></label>
<input name="displayName" type="text"
data-i18n="[placeholder]defaultNickname"
class="input-control" autofocus>
</div>`
);
// Don't use a translation string, because we're too early in the call and
// the translation may not be initialised.
const buttons = { Ok: true };
const dialog = messageHandler.openDialog(
'dialog.displayNameRequired',
message,
true,
buttons,
(e, v, m, f) => {
e.preventDefault();
if (v) {
const displayName = f.displayName;
if (displayName) {
UI.inputDisplayNameHandler(displayName);
dialog.close();
return;
}
}
},
() => {
const form = $.prompt.getPrompt();
const input = form.find("input[name='displayName']");
const button = form.find("button");
input.focus();
button.attr("disabled", "disabled");
input.keyup(() => {
if (input.val()) {
button.removeAttr("disabled");
} else {
button.attr("disabled", "disabled");
}
});
}
);
}; };
/** /**

View File

@ -0,0 +1,12 @@
import { openDialog } from '../../features/base/dialog';
import { DisplayNamePrompt } from './components';
/**
* Signals to open a dialog with the {@code DisplayNamePrompt} component.
*
* @returns {Object}
*/
export function openDisplayNamePrompt() {
return openDialog(DisplayNamePrompt);
}

View File

@ -0,0 +1,150 @@
import AKFieldText from '@atlaskit/field-text';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Dialog } from '../../base/dialog';
import { translate } from '../../base/i18n';
import {
getLocalParticipant,
participantDisplayNameChanged
} from '../../base/participants';
/**
* Implements a React {@code Component} for displaying a dialog with an field
* for setting the local participant's display name.
*
* @extends Component
*/
class DisplayNamePrompt extends Component {
/**
* {@code DisplayNamePrompt} component's property types.
*
* @static
*/
static propTypes = {
/**
* The current ID for the local participant. Used for setting the
* display name on the associated participant.
*/
_localParticipantID: React.PropTypes.string,
/**
* Invoked to update the local participant's display name.
*/
dispatch: React.PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: React.PropTypes.func
};
/**
* Initializes a new {@code DisplayNamePrompt} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
this.state = {
/**
* The name to show in the display name text field.
*
* @type {string}
*/
displayName: ''
};
// Bind event handlers so they are only bound once for every instance.
this._onDisplayNameChange = this._onDisplayNameChange.bind(this);
this._onSubmit = this._onSubmit.bind(this);
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
return (
<Dialog
isModal = { true }
onSubmit = { this._onSubmit }
titleKey = 'dialog.displayNameRequired'
width = 'small'>
<AKFieldText
autoFocus = { true }
compact = { true }
label = { this.props.t('dialog.enterDisplayName') }
name = 'displayName'
onChange = { this._onDisplayNameChange }
shouldFitContainer = { true }
type = 'text'
value = { this.state.displayName } />
</Dialog>);
}
/**
* Updates the entered display name.
*
* @param {Object} event - The DOM event triggered from the entered display
* name value having changed.
* @private
* @returns {void}
*/
_onDisplayNameChange(event) {
this.setState({
displayName: event.target.value
});
}
/**
* Dispatches an action to update the local participant's display name. A
* name must be entered for the action to dispatch.
*
* @private
* @returns {void}
*/
_onSubmit() {
const { displayName } = this.state;
if (!displayName.trim()) {
return false;
}
const { dispatch, _localParticipantID } = this.props;
dispatch(
participantDisplayNameChanged(_localParticipantID, displayName));
return true;
}
}
/**
* Maps (parts of) the Redux state to the associated {@code DisplayNamePrompt}'s
* props.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _localParticipantID: string
* }}
*/
function _mapStateToProps(state) {
const { id } = getLocalParticipant(state);
return {
/**
* The current ID for the local participant.
*
* @type {string}
*/
_localParticipantID: id
};
}
export default translate(connect(_mapStateToProps)(DisplayNamePrompt));

View File

@ -1 +1,2 @@
export { default as DisplayName } from './DisplayName'; export { default as DisplayName } from './DisplayName';
export { default as DisplayNamePrompt } from './DisplayNamePrompt';

View File

@ -1 +1,2 @@
export * from './actions';
export * from './components'; export * from './components';