fix(AddPeopleDialog): Improve contact invite form
- Disables the invite buttons while invites are ongoing - Adds a keyboard shortcut (Enter) to send out invites - Closes AddPeopleDialog upon successful invites sent - Fixes the SecurityDialog closing when trying to set E2EE key via Enter shortcut - Removes superfluous separator from SecurityDialog
This commit is contained in:
parent
0494200383
commit
093254d948
|
@ -208,6 +208,12 @@
|
|||
padding: 8px 16px;
|
||||
background: #0376DA;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
& > a {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stream {
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
font-size: 14px;
|
||||
color: #6FB1EA;
|
||||
}
|
||||
|
||||
&>a+a {
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,7 @@ class E2EESection extends Component<Props, State> {
|
|||
disabled = { !editing }
|
||||
name = 'e2eeKey'
|
||||
onChange = { this._onKeyChange }
|
||||
onKeyDown = { this._onKeyDown }
|
||||
placeholder = { t('dialog.e2eeNoKey') }
|
||||
ref = { this.fieldRef }
|
||||
type = 'password'
|
||||
|
@ -137,6 +138,20 @@ class E2EESection extends Component<Props, State> {
|
|||
this.setState({ key: event.target.value.trim() });
|
||||
}
|
||||
|
||||
_onKeyDown: (Object) => void;
|
||||
|
||||
/**
|
||||
* Handler for the keydown event on the form, preventing the closing of the dialog.
|
||||
*
|
||||
* @param {Object} event - The DOM event triggered by keydown events.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onKeyDown(event) {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
_onSet: () => void;
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,6 +41,11 @@ export const REMOVE_PENDING_INVITE_REQUESTS
|
|||
*/
|
||||
export const SET_CALLEE_INFO_VISIBLE = 'SET_CALLEE_INFO_VISIBLE';
|
||||
|
||||
/**
|
||||
* The type of redux action to signal that the {@code AddPeopleDialog} should close.
|
||||
*/
|
||||
export const HIDE_ADD_PEOPLE_DIALOG = 'HIDE_ADD_PEOPLE_DIALOG';
|
||||
|
||||
/**
|
||||
* The type of the action which signals an error occurred while requesting dial-
|
||||
* in numbers.
|
||||
|
|
|
@ -9,6 +9,7 @@ import { inviteVideoRooms } from '../videosipgw';
|
|||
import {
|
||||
ADD_PENDING_INVITE_REQUEST,
|
||||
BEGIN_ADD_PEOPLE,
|
||||
HIDE_ADD_PEOPLE_DIALOG,
|
||||
REMOVE_PENDING_INVITE_REQUESTS,
|
||||
SET_CALLEE_INFO_VISIBLE,
|
||||
UPDATE_DIAL_IN_NUMBERS_FAILED,
|
||||
|
@ -36,6 +37,20 @@ export function beginAddPeople() {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a (redux) action to signal that the {@code AddPeopleDialog}
|
||||
* should close.
|
||||
*
|
||||
* @returns {{
|
||||
* type: HIDE_ADD_PEOPLE_DIALOG
|
||||
* }}
|
||||
*/
|
||||
export function hideAddPeopleDialog() {
|
||||
return {
|
||||
type: HIDE_ADD_PEOPLE_DIALOG
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invites (i.e. Sends invites to) an array of invitees (which may be a
|
||||
|
|
|
@ -10,6 +10,7 @@ import { Icon, IconPhone } from '../../../../base/icons';
|
|||
import { getLocalParticipant } from '../../../../base/participants';
|
||||
import { MultiSelectAutocomplete } from '../../../../base/react';
|
||||
import { connect } from '../../../../base/redux';
|
||||
import { hideAddPeopleDialog } from '../../../actions';
|
||||
import AbstractAddPeopleDialog, {
|
||||
type Props as AbstractProps,
|
||||
type State,
|
||||
|
@ -72,6 +73,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
|
|||
this._parseQueryResults = this._parseQueryResults.bind(this);
|
||||
this._setMultiSelectElement = this._setMultiSelectElement.bind(this);
|
||||
this._renderFooterText = this._renderFooterText.bind(this);
|
||||
this._onKeyDown = this._onKeyDown.bind(this);
|
||||
|
||||
this._resourceClient = {
|
||||
makeQuery: this._query,
|
||||
|
@ -135,7 +137,9 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className = 'add-people-form-wrap'>
|
||||
<div
|
||||
className = 'add-people-form-wrap'
|
||||
onKeyDown = { this._onKeyDown }>
|
||||
{ this._renderErrorMessage() }
|
||||
<MultiSelectAutocomplete
|
||||
footer = { footerText }
|
||||
|
@ -217,11 +221,30 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
|
|||
this._multiselect.setSelectedItems(itemsToSelect);
|
||||
}
|
||||
} else {
|
||||
// Do nothing.
|
||||
this.props.dispatch(hideAddPeopleDialog());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_onKeyDown: (Object) => void;
|
||||
|
||||
/**
|
||||
* Handles 'Enter' key in the form to trigger the invite.
|
||||
*
|
||||
* @param {Object} event - The key event.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onKeyDown(event) {
|
||||
const { inviteItems } = this.state;
|
||||
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
if (!this._isAddDisabled() && inviteItems.length) {
|
||||
this._onSubmit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_parseQueryResults: (?Array<Object>) => Array<Object>;
|
||||
|
||||
/**
|
||||
|
@ -380,7 +403,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className = 'invite-more-dialog invite-buttons'>
|
||||
<div className = { `invite-more-dialog invite-buttons${this._isAddDisabled() ? ' disabled' : ''}` }>
|
||||
<a
|
||||
className = 'invite-more-dialog invite-buttons-cancel'
|
||||
onClick = { this._onClearItems }>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// @flow
|
||||
|
||||
import { openDialog } from '../base/dialog';
|
||||
import { hideDialog, openDialog } from '../base/dialog';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
import { BEGIN_ADD_PEOPLE } from './actionTypes';
|
||||
import { BEGIN_ADD_PEOPLE, HIDE_ADD_PEOPLE_DIALOG } from './actionTypes';
|
||||
import { AddPeopleDialog } from './components';
|
||||
import './middleware.any';
|
||||
|
||||
|
@ -17,6 +17,8 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
switch (action.type) {
|
||||
case BEGIN_ADD_PEOPLE:
|
||||
return _beginAddPeople(store, next, action);
|
||||
case HIDE_ADD_PEOPLE_DIALOG:
|
||||
return _hideAddPeopleDialog(store, next, action);
|
||||
}
|
||||
|
||||
return next(action);
|
||||
|
@ -42,3 +44,22 @@ function _beginAddPeople({ dispatch }, next, action) {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the feature invite that the action {@link HIDE_ADD_PEOPLE_DIALOG} is being
|
||||
* dispatched within a specific redux {@code store}.
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified {@code action}
|
||||
* is being dispatched.
|
||||
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
|
||||
* specified {@code action} to the specified {@code store}.
|
||||
* @param {Action} action - The redux action {@code HIDE_ADD_PEOPLE_DIALOG} which is
|
||||
* being dispatched in the specified {@code store}.
|
||||
* @private
|
||||
* @returns {*} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _hideAddPeopleDialog({ dispatch }, next, action) {
|
||||
dispatch(hideDialog(AddPeopleDialog));
|
||||
|
||||
return next(action);
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ class LobbySection extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id = 'lobby-section'>
|
||||
{ t('lobby.enableDialogText') }
|
||||
<div className = 'control-row'>
|
||||
|
@ -97,6 +98,8 @@ class LobbySection extends PureComponent<Props, State> {
|
|||
value = { this.state.lobbyEnabled } />
|
||||
</div>
|
||||
</div>
|
||||
<div className = 'separator-line' />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,6 @@ function SecurityDialog({
|
|||
width = { 'small' }>
|
||||
<div className = 'security-dialog'>
|
||||
<LobbySection />
|
||||
<div className = 'separator-line' />
|
||||
<PasswordSection
|
||||
canEditPassword = { _canEditPassword }
|
||||
conference = { _conference }
|
||||
|
|
Loading…
Reference in New Issue