Browse Source

feat(prejoin): Add 'skip prejoin' button

master
Vlad Piersec 5 years ago
parent
commit
035f720a50

+ 1
- 7
css/_prejoin.scss View File

36
     }
36
     }
37
 
37
 
38
     &-checkbox-container {
38
     &-checkbox-container {
39
-        align-items: center;
40
-        color: #fff;
41
-        display: none;
42
-        font-size: 13px;
43
-        justify-content: center;
44
-        line-height: 20px;
45
-        margin-top: 16px;
39
+        margin-bottom: 14px;
46
         width: 100%;
40
         width: 100%;
47
     }
41
     }
48
 }
42
 }

+ 63
- 0
css/_premeeting-screens.scss View File

216
         width: 100%;
216
         width: 100%;
217
     }
217
     }
218
 }
218
 }
219
+
220
+@mixin flex-centered() {
221
+    align-items: center;
222
+    display: flex;
223
+    justify-content: center;
224
+}
225
+
226
+@mixin icon-container($bg, $fill) {
227
+    .toggle-button-icon-container {
228
+        background: $bg;
229
+
230
+        svg {
231
+            fill: $fill
232
+        }
233
+    }
234
+}
235
+
236
+.toggle-button {
237
+    border-radius: 3px;
238
+    cursor: pointer;
239
+    color: #fff;
240
+    font-size: 13px;
241
+    height: 40px;
242
+    margin: 0 auto;
243
+    width: 320px;
244
+
245
+    @include flex-centered();
246
+
247
+    svg {
248
+        fill: transparent;
249
+    }
250
+
251
+    &:hover {
252
+        background: #1C2025;
253
+
254
+        @include icon-container(#A4B8D1, #1C2025);
255
+    }
256
+
257
+    &-container {
258
+        position: relative;
259
+
260
+        @include flex-centered();
261
+    }
262
+
263
+    &-icon-container {
264
+        border-radius: 50%;
265
+        left: -22px;
266
+        padding: 2px;
267
+        position: absolute;
268
+    }
269
+
270
+    &--toggled {
271
+        background: #75757A;
272
+
273
+        &:hover {
274
+            background: #75757A;
275
+
276
+            @include icon-container(#A4B8D1, #75757A);
277
+        }
278
+
279
+        @include icon-container(#A4B8D1, #75757A);
280
+    }
281
+}

+ 6
- 0
react/features/base/premeeting/components/web/PreMeetingScreen.js View File

39
      */
39
      */
40
     title: string,
40
     title: string,
41
 
41
 
42
+    /**
43
+     * The 'Skip prejoin' button to be rendered (if any).
44
+     */
45
+     skipPrejoinButton?: React$Node,
46
+
42
     /**
47
     /**
43
      * True if the preview overlay should be muted, false otherwise.
48
      * True if the preview overlay should be muted, false otherwise.
44
      */
49
      */
97
                         <AudioSettingsButton visible = { true } />
102
                         <AudioSettingsButton visible = { true } />
98
                         <VideoSettingsButton visible = { true } />
103
                         <VideoSettingsButton visible = { true } />
99
                     </div>
104
                     </div>
105
+                    { this.props.skipPrejoinButton }
100
                     { this.props.footer }
106
                     { this.props.footer }
101
                 </div>
107
                 </div>
102
             </div>
108
             </div>

+ 52
- 0
react/features/base/premeeting/components/web/ToggleButton.js View File

1
+// @flow
2
+
3
+import React from 'react';
4
+
5
+import { Icon, IconCheck } from '../../../icons';
6
+
7
+const mainClass = 'toggle-button';
8
+
9
+type Props = {
10
+
11
+    /**
12
+     * Text of the button.
13
+     */
14
+    children: React$Node,
15
+
16
+    /**
17
+     * If the button is toggled or not.
18
+     */
19
+    isToggled?: boolean,
20
+
21
+    /**
22
+     * OnClick button handler.
23
+     */
24
+    onClick: Function
25
+}
26
+
27
+/**
28
+ * Button used as a toggle.
29
+ *
30
+ * @returns {ReactElement}
31
+ */
32
+function ToggleButton({ children, isToggled, onClick }: Props) {
33
+    const className = isToggled ? `${mainClass} ${mainClass}--toggled` : mainClass;
34
+
35
+    return (
36
+        <div
37
+            className = { className }
38
+            onClick = { onClick }>
39
+            <div className = 'toggle-button-container'>
40
+                <div className = 'toggle-button-icon-container'>
41
+                    <Icon
42
+                        className = 'toggle-button-icon'
43
+                        size = { 10 }
44
+                        src = { IconCheck } />
45
+                </div>
46
+                <span>{children}</span>
47
+            </div>
48
+        </div>
49
+    );
50
+}
51
+
52
+export default ToggleButton;

+ 1
- 0
react/features/base/premeeting/components/web/index.js View File

3
 export { default as ActionButton } from './ActionButton';
3
 export { default as ActionButton } from './ActionButton';
4
 export { default as InputField } from './InputField';
4
 export { default as InputField } from './InputField';
5
 export { default as PreMeetingScreen } from './PreMeetingScreen';
5
 export { default as PreMeetingScreen } from './PreMeetingScreen';
6
+export { default as ToggleButton } from './ToggleButton';

+ 35
- 16
react/features/prejoin/components/Prejoin.js View File

7
 import { translate } from '../../base/i18n';
7
 import { translate } from '../../base/i18n';
8
 import { Icon, IconPhone, IconVolumeOff } from '../../base/icons';
8
 import { Icon, IconPhone, IconVolumeOff } from '../../base/icons';
9
 import { isVideoMutedByUser } from '../../base/media';
9
 import { isVideoMutedByUser } from '../../base/media';
10
-import { ActionButton, InputField, PreMeetingScreen } from '../../base/premeeting';
10
+import { ActionButton, InputField, PreMeetingScreen, ToggleButton } from '../../base/premeeting';
11
 import { connect } from '../../base/redux';
11
 import { connect } from '../../base/redux';
12
 import { getDisplayName, updateSettings } from '../../base/settings';
12
 import { getDisplayName, updateSettings } from '../../base/settings';
13
 import { getLocalJitsiVideoTrack } from '../../base/tracks';
13
 import { getLocalJitsiVideoTrack } from '../../base/tracks';
21
     isDeviceStatusVisible,
21
     isDeviceStatusVisible,
22
     isDisplayNameRequired,
22
     isDisplayNameRequired,
23
     isJoinByPhoneButtonVisible,
23
     isJoinByPhoneButtonVisible,
24
-    isJoinByPhoneDialogVisible
24
+    isJoinByPhoneDialogVisible,
25
+    isPrejoinSkipped
25
 } from '../functions';
26
 } from '../functions';
26
 
27
 
27
 import JoinByPhoneDialog from './dialogs/JoinByPhoneDialog';
28
 import JoinByPhoneDialog from './dialogs/JoinByPhoneDialog';
29
 
30
 
30
 type Props = {
31
 type Props = {
31
 
32
 
33
+    /**
34
+     * Flag signaling if the 'skip prejoin' button is toggled or not.
35
+     */
36
+    buttonIsToggled: boolean,
37
+
32
     /**
38
     /**
33
      * Flag signaling if the device status is visible or not.
39
      * Flag signaling if the device status is visible or not.
34
      */
40
      */
145
 
151
 
146
         this._closeDialog = this._closeDialog.bind(this);
152
         this._closeDialog = this._closeDialog.bind(this);
147
         this._showDialog = this._showDialog.bind(this);
153
         this._showDialog = this._showDialog.bind(this);
148
-        this._onCheckboxChange = this._onCheckboxChange.bind(this);
154
+        this._onToggleButtonClick = this._onToggleButtonClick.bind(this);
149
         this._onDropdownClose = this._onDropdownClose.bind(this);
155
         this._onDropdownClose = this._onDropdownClose.bind(this);
150
         this._onOptionsClick = this._onOptionsClick.bind(this);
156
         this._onOptionsClick = this._onOptionsClick.bind(this);
151
         this._setName = this._setName.bind(this);
157
         this._setName = this._setName.bind(this);
152
     }
158
     }
153
 
159
 
154
-    _onCheckboxChange: () => void;
160
+    _onToggleButtonClick: () => void;
155
 
161
 
156
     /**
162
     /**
157
-     * Handler for the checkbox.
163
+     * Handler for the toggle button.
158
      *
164
      *
159
      * @param {Object} e - The synthetic event.
165
      * @param {Object} e - The synthetic event.
160
      * @returns {void}
166
      * @returns {void}
161
      */
167
      */
162
-    _onCheckboxChange(e) {
163
-        this.props.setSkipPrejoin(e.target.checked);
168
+    _onToggleButtonClick() {
169
+        this.props.setSkipPrejoin(!this.props.buttonIsToggled);
164
     }
170
     }
165
 
171
 
166
     _onDropdownClose: () => void;
172
     _onDropdownClose: () => void;
250
             videoTrack
256
             videoTrack
251
         } = this.props;
257
         } = this.props;
252
 
258
 
253
-        const { _closeDialog, _onCheckboxChange, _onDropdownClose, _onOptionsClick, _setName, _showDialog } = this;
259
+        const { _closeDialog, _onDropdownClose, _onOptionsClick, _setName, _showDialog } = this;
254
         const { showJoinByPhoneButtons } = this.state;
260
         const { showJoinByPhoneButtons } = this.state;
255
 
261
 
256
         return (
262
         return (
259
                 name = { name }
265
                 name = { name }
260
                 showAvatar = { showAvatar }
266
                 showAvatar = { showAvatar }
261
                 showConferenceInfo = { showJoinActions }
267
                 showConferenceInfo = { showJoinActions }
268
+                skipPrejoinButton = { this._renderSkipPrejoinButton() }
262
                 title = { t('prejoin.joinMeeting') }
269
                 title = { t('prejoin.joinMeeting') }
263
                 videoMuted = { !showCameraPreview }
270
                 videoMuted = { !showCameraPreview }
264
                 videoTrack = { videoTrack }>
271
                 videoTrack = { videoTrack }>
306
                                 </InlineDialog>
313
                                 </InlineDialog>
307
                             </div>
314
                             </div>
308
                         </div>
315
                         </div>
309
-
310
-                        <div className = 'prejoin-checkbox-container'>
311
-                            <input
312
-                                className = 'prejoin-checkbox'
313
-                                onChange = { _onCheckboxChange }
314
-                                type = 'checkbox' />
315
-                            <span>{t('prejoin.doNotShow')}</span>
316
-                        </div>
317
                     </div>
316
                     </div>
318
                 )}
317
                 )}
319
                 { showDialog && (
318
                 { showDialog && (
333
     _renderFooter() {
332
     _renderFooter() {
334
         return this.props.deviceStatusVisible && <DeviceStatus />;
333
         return this.props.deviceStatusVisible && <DeviceStatus />;
335
     }
334
     }
335
+
336
+    /**
337
+     * Renders the 'skip prejoin' button.
338
+     *
339
+     * @returns {React$Element}
340
+     */
341
+    _renderSkipPrejoinButton() {
342
+        const { buttonIsToggled, t } = this.props;
343
+
344
+        return (
345
+            <div className = 'prejoin-checkbox-container'>
346
+                <ToggleButton
347
+                    isToggled = { buttonIsToggled }
348
+                    onClick = { this._onToggleButtonClick }>
349
+                    {t('prejoin.doNotShow')}
350
+                </ToggleButton>
351
+            </div>
352
+        );
353
+    }
336
 }
354
 }
337
 
355
 
338
 /**
356
 /**
346
     const joinButtonDisabled = isDisplayNameRequired(state) && !name;
364
     const joinButtonDisabled = isDisplayNameRequired(state) && !name;
347
 
365
 
348
     return {
366
     return {
367
+        buttonIsToggled: isPrejoinSkipped(state),
349
         joinButtonDisabled,
368
         joinButtonDisabled,
350
         name,
369
         name,
351
         deviceStatusVisible: isDeviceStatusVisible(state),
370
         deviceStatusVisible: isDeviceStatusVisible(state),

+ 10
- 0
react/features/prejoin/functions.js View File

36
         || state['features/base/config'].requireDisplayName;
36
         || state['features/base/config'].requireDisplayName;
37
 }
37
 }
38
 
38
 
39
+/**
40
+ * Selector for determining if the user has chosen to skip prejoin page.
41
+ *
42
+ * @param {Object} state - The state of the app.
43
+ * @returns {boolean}
44
+ */
45
+export function isPrejoinSkipped(state: Object) {
46
+    return state['features/prejoin'].userSelectedSkipPrejoin;
47
+}
48
+
39
 /**
49
 /**
40
  * Returns the text for the prejoin status bar.
50
  * Returns the text for the prejoin status bar.
41
  *
51
  *

Loading…
Cancel
Save