Pārlūkot izejas kodu

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
master
Mihai Uscat 4 gadus atpakaļ
vecāks
revīzija
093254d948

+ 6
- 0
css/modals/invite/_invite_more.scss Parādīt failu

@@ -208,6 +208,12 @@
208 208
                 padding: 8px 16px;
209 209
                 background: #0376DA;
210 210
             }
211
+
212
+            &.disabled {
213
+                & > a {
214
+                    pointer-events: none;
215
+                }
216
+            }
211 217
         }
212 218
 
213 219
         &.stream {

+ 1
- 5
css/modals/security/_security.scss Parādīt failu

@@ -21,15 +21,11 @@
21 21
                         font-size: 14px;
22 22
                         color: #6FB1EA;
23 23
                     }
24
-
25
-                    &>a+a {
26
-                        margin-left: 24px;
27
-                    }
28 24
                 }
29 25
             }
30 26
         }
31 27
 
32
-        &> :first-child:not(:last-child) {
28
+        & > :first-child:not(:last-child) {
33 29
             margin-right: 24px;
34 30
         }
35 31
 

+ 15
- 0
react/features/e2ee/components/E2EESection.js Parādīt failu

@@ -109,6 +109,7 @@ class E2EESection extends Component<Props, State> {
109 109
                         disabled = { !editing }
110 110
                         name = 'e2eeKey'
111 111
                         onChange = { this._onKeyChange }
112
+                        onKeyDown = { this._onKeyDown }
112 113
                         placeholder = { t('dialog.e2eeNoKey') }
113 114
                         ref = { this.fieldRef }
114 115
                         type = 'password'
@@ -137,6 +138,20 @@ class E2EESection extends Component<Props, State> {
137 138
         this.setState({ key: event.target.value.trim() });
138 139
     }
139 140
 
141
+    _onKeyDown: (Object) => void;
142
+
143
+    /**
144
+     * Handler for the keydown event on the form, preventing the closing of the dialog.
145
+     *
146
+     * @param {Object} event - The DOM event triggered by keydown events.
147
+     * @returns {void}
148
+     */
149
+    _onKeyDown(event) {
150
+        if (event.key === 'Enter') {
151
+            event.preventDefault();
152
+        }
153
+    }
154
+
140 155
     _onSet: () => void;
141 156
 
142 157
     /**

+ 5
- 0
react/features/invite/actionTypes.js Parādīt failu

@@ -41,6 +41,11 @@ export const REMOVE_PENDING_INVITE_REQUESTS
41 41
  */
42 42
 export const SET_CALLEE_INFO_VISIBLE = 'SET_CALLEE_INFO_VISIBLE';
43 43
 
44
+/**
45
+ * The type of redux action to signal that the {@code AddPeopleDialog} should close.
46
+ */
47
+export const HIDE_ADD_PEOPLE_DIALOG = 'HIDE_ADD_PEOPLE_DIALOG';
48
+
44 49
 /**
45 50
  * The type of the action which signals an error occurred while requesting dial-
46 51
  * in numbers.

+ 15
- 0
react/features/invite/actions.any.js Parādīt failu

@@ -9,6 +9,7 @@ import { inviteVideoRooms } from '../videosipgw';
9 9
 import {
10 10
     ADD_PENDING_INVITE_REQUEST,
11 11
     BEGIN_ADD_PEOPLE,
12
+    HIDE_ADD_PEOPLE_DIALOG,
12 13
     REMOVE_PENDING_INVITE_REQUESTS,
13 14
     SET_CALLEE_INFO_VISIBLE,
14 15
     UPDATE_DIAL_IN_NUMBERS_FAILED,
@@ -36,6 +37,20 @@ export function beginAddPeople() {
36 37
     };
37 38
 }
38 39
 
40
+/**
41
+ * Creates a (redux) action to signal that the {@code AddPeopleDialog}
42
+ * should close.
43
+ *
44
+ * @returns {{
45
+ *     type: HIDE_ADD_PEOPLE_DIALOG
46
+ * }}
47
+ */
48
+export function hideAddPeopleDialog() {
49
+    return {
50
+        type: HIDE_ADD_PEOPLE_DIALOG
51
+    };
52
+}
53
+
39 54
 
40 55
 /**
41 56
  * Invites (i.e. Sends invites to) an array of invitees (which may be a

+ 26
- 3
react/features/invite/components/add-people-dialog/web/InviteContactsForm.js Parādīt failu

@@ -10,6 +10,7 @@ import { Icon, IconPhone } from '../../../../base/icons';
10 10
 import { getLocalParticipant } from '../../../../base/participants';
11 11
 import { MultiSelectAutocomplete } from '../../../../base/react';
12 12
 import { connect } from '../../../../base/redux';
13
+import { hideAddPeopleDialog } from '../../../actions';
13 14
 import AbstractAddPeopleDialog, {
14 15
     type Props as AbstractProps,
15 16
     type State,
@@ -72,6 +73,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
72 73
         this._parseQueryResults = this._parseQueryResults.bind(this);
73 74
         this._setMultiSelectElement = this._setMultiSelectElement.bind(this);
74 75
         this._renderFooterText = this._renderFooterText.bind(this);
76
+        this._onKeyDown = this._onKeyDown.bind(this);
75 77
 
76 78
         this._resourceClient = {
77 79
             makeQuery: this._query,
@@ -135,7 +137,9 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
135 137
         }
136 138
 
137 139
         return (
138
-            <div className = 'add-people-form-wrap'>
140
+            <div
141
+                className = 'add-people-form-wrap'
142
+                onKeyDown = { this._onKeyDown }>
139 143
                 { this._renderErrorMessage() }
140 144
                 <MultiSelectAutocomplete
141 145
                     footer = { footerText }
@@ -217,11 +221,30 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
217 221
                         this._multiselect.setSelectedItems(itemsToSelect);
218 222
                     }
219 223
                 } else {
220
-                    // Do nothing.
224
+                    this.props.dispatch(hideAddPeopleDialog());
221 225
                 }
222 226
             });
223 227
     }
224 228
 
229
+    _onKeyDown: (Object) => void;
230
+
231
+    /**
232
+     * Handles 'Enter' key in the form to trigger the invite.
233
+     *
234
+     * @param {Object} event - The key event.
235
+     * @returns {void}
236
+     */
237
+    _onKeyDown(event) {
238
+        const { inviteItems } = this.state;
239
+
240
+        if (event.key === 'Enter') {
241
+            event.preventDefault();
242
+            if (!this._isAddDisabled() && inviteItems.length) {
243
+                this._onSubmit();
244
+            }
245
+        }
246
+    }
247
+
225 248
     _parseQueryResults: (?Array<Object>) => Array<Object>;
226 249
 
227 250
     /**
@@ -380,7 +403,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
380 403
         }
381 404
 
382 405
         return (
383
-            <div className = 'invite-more-dialog invite-buttons'>
406
+            <div className = { `invite-more-dialog invite-buttons${this._isAddDisabled() ? ' disabled' : ''}` }>
384 407
                 <a
385 408
                     className = 'invite-more-dialog invite-buttons-cancel'
386 409
                     onClick = { this._onClearItems }>

+ 23
- 2
react/features/invite/middleware.web.js Parādīt failu

@@ -1,9 +1,9 @@
1 1
 // @flow
2 2
 
3
-import { openDialog } from '../base/dialog';
3
+import { hideDialog, openDialog } from '../base/dialog';
4 4
 import { MiddlewareRegistry } from '../base/redux';
5 5
 
6
-import { BEGIN_ADD_PEOPLE } from './actionTypes';
6
+import { BEGIN_ADD_PEOPLE, HIDE_ADD_PEOPLE_DIALOG } from './actionTypes';
7 7
 import { AddPeopleDialog } from './components';
8 8
 import './middleware.any';
9 9
 
@@ -17,6 +17,8 @@ MiddlewareRegistry.register(store => next => action => {
17 17
     switch (action.type) {
18 18
     case BEGIN_ADD_PEOPLE:
19 19
         return _beginAddPeople(store, next, action);
20
+    case HIDE_ADD_PEOPLE_DIALOG:
21
+        return _hideAddPeopleDialog(store, next, action);
20 22
     }
21 23
 
22 24
     return next(action);
@@ -42,3 +44,22 @@ function _beginAddPeople({ dispatch }, next, action) {
42 44
 
43 45
     return result;
44 46
 }
47
+
48
+/**
49
+ * Notifies the feature invite that the action {@link HIDE_ADD_PEOPLE_DIALOG} is being
50
+ * dispatched within a specific redux {@code store}.
51
+ *
52
+ * @param {Store} store - The redux store in which the specified {@code action}
53
+ * is being dispatched.
54
+ * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
55
+ * specified {@code action} to the specified {@code store}.
56
+ * @param {Action} action - The redux action {@code HIDE_ADD_PEOPLE_DIALOG} which is
57
+ * being dispatched in the specified {@code store}.
58
+ * @private
59
+ * @returns {*} The value returned by {@code next(action)}.
60
+ */
61
+function _hideAddPeopleDialog({ dispatch }, next, action) {
62
+    dispatch(hideDialog(AddPeopleDialog));
63
+
64
+    return next(action);
65
+}

+ 13
- 10
react/features/lobby/components/web/LobbySection.js Parādīt failu

@@ -86,17 +86,20 @@ class LobbySection extends PureComponent<Props, State> {
86 86
         }
87 87
 
88 88
         return (
89
-            <div id = 'lobby-section'>
90
-                { t('lobby.enableDialogText') }
91
-                <div className = 'control-row'>
92
-                    <label>
93
-                        { t('lobby.toggleLabel') }
94
-                    </label>
95
-                    <Switch
96
-                        onValueChange = { this._onToggleLobby }
97
-                        value = { this.state.lobbyEnabled } />
89
+            <>
90
+                <div id = 'lobby-section'>
91
+                    { t('lobby.enableDialogText') }
92
+                    <div className = 'control-row'>
93
+                        <label>
94
+                            { t('lobby.toggleLabel') }
95
+                        </label>
96
+                        <Switch
97
+                            onValueChange = { this._onToggleLobby }
98
+                            value = { this.state.lobbyEnabled } />
99
+                    </div>
98 100
                 </div>
99
-            </div>
101
+                <div className = 'separator-line' />
102
+            </>
100 103
         );
101 104
     }
102 105
 

+ 0
- 1
react/features/security/components/security-dialog/SecurityDialog.js Parādīt failu

@@ -89,7 +89,6 @@ function SecurityDialog({
89 89
             width = { 'small' }>
90 90
             <div className = 'security-dialog'>
91 91
                 <LobbySection />
92
-                <div className = 'separator-line' />
93 92
                 <PasswordSection
94 93
                     canEditPassword = { _canEditPassword }
95 94
                     conference = { _conference }

Notiek ielāde…
Atcelt
Saglabāt