Browse Source

feat(prejoin): Add 'skip prejoin' button

master^2
Vlad Piersec 4 years ago
parent
commit
035f720a50

+ 1
- 7
css/_prejoin.scss View File

@@ -36,13 +36,7 @@
36 36
     }
37 37
 
38 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 40
         width: 100%;
47 41
     }
48 42
 }

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

@@ -216,3 +216,66 @@
216 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,6 +39,11 @@ type Props = {
39 39
      */
40 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 48
      * True if the preview overlay should be muted, false otherwise.
44 49
      */
@@ -97,6 +102,7 @@ export default class PreMeetingScreen extends PureComponent<Props> {
97 102
                         <AudioSettingsButton visible = { true } />
98 103
                         <VideoSettingsButton visible = { true } />
99 104
                     </div>
105
+                    { this.props.skipPrejoinButton }
100 106
                     { this.props.footer }
101 107
                 </div>
102 108
             </div>

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

@@ -0,0 +1,52 @@
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,3 +3,4 @@
3 3
 export { default as ActionButton } from './ActionButton';
4 4
 export { default as InputField } from './InputField';
5 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,7 +7,7 @@ import { getRoomName } from '../../base/conference';
7 7
 import { translate } from '../../base/i18n';
8 8
 import { Icon, IconPhone, IconVolumeOff } from '../../base/icons';
9 9
 import { isVideoMutedByUser } from '../../base/media';
10
-import { ActionButton, InputField, PreMeetingScreen } from '../../base/premeeting';
10
+import { ActionButton, InputField, PreMeetingScreen, ToggleButton } from '../../base/premeeting';
11 11
 import { connect } from '../../base/redux';
12 12
 import { getDisplayName, updateSettings } from '../../base/settings';
13 13
 import { getLocalJitsiVideoTrack } from '../../base/tracks';
@@ -21,7 +21,8 @@ import {
21 21
     isDeviceStatusVisible,
22 22
     isDisplayNameRequired,
23 23
     isJoinByPhoneButtonVisible,
24
-    isJoinByPhoneDialogVisible
24
+    isJoinByPhoneDialogVisible,
25
+    isPrejoinSkipped
25 26
 } from '../functions';
26 27
 
27 28
 import JoinByPhoneDialog from './dialogs/JoinByPhoneDialog';
@@ -29,6 +30,11 @@ import DeviceStatus from './preview/DeviceStatus';
29 30
 
30 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 39
      * Flag signaling if the device status is visible or not.
34 40
      */
@@ -145,22 +151,22 @@ class Prejoin extends Component<Props, State> {
145 151
 
146 152
         this._closeDialog = this._closeDialog.bind(this);
147 153
         this._showDialog = this._showDialog.bind(this);
148
-        this._onCheckboxChange = this._onCheckboxChange.bind(this);
154
+        this._onToggleButtonClick = this._onToggleButtonClick.bind(this);
149 155
         this._onDropdownClose = this._onDropdownClose.bind(this);
150 156
         this._onOptionsClick = this._onOptionsClick.bind(this);
151 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 165
      * @param {Object} e - The synthetic event.
160 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 172
     _onDropdownClose: () => void;
@@ -250,7 +256,7 @@ class Prejoin extends Component<Props, State> {
250 256
             videoTrack
251 257
         } = this.props;
252 258
 
253
-        const { _closeDialog, _onCheckboxChange, _onDropdownClose, _onOptionsClick, _setName, _showDialog } = this;
259
+        const { _closeDialog, _onDropdownClose, _onOptionsClick, _setName, _showDialog } = this;
254 260
         const { showJoinByPhoneButtons } = this.state;
255 261
 
256 262
         return (
@@ -259,6 +265,7 @@ class Prejoin extends Component<Props, State> {
259 265
                 name = { name }
260 266
                 showAvatar = { showAvatar }
261 267
                 showConferenceInfo = { showJoinActions }
268
+                skipPrejoinButton = { this._renderSkipPrejoinButton() }
262 269
                 title = { t('prejoin.joinMeeting') }
263 270
                 videoMuted = { !showCameraPreview }
264 271
                 videoTrack = { videoTrack }>
@@ -306,14 +313,6 @@ class Prejoin extends Component<Props, State> {
306 313
                                 </InlineDialog>
307 314
                             </div>
308 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 316
                     </div>
318 317
                 )}
319 318
                 { showDialog && (
@@ -333,6 +332,25 @@ class Prejoin extends Component<Props, State> {
333 332
     _renderFooter() {
334 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,6 +364,7 @@ function mapStateToProps(state): Object {
346 364
     const joinButtonDisabled = isDisplayNameRequired(state) && !name;
347 365
 
348 366
     return {
367
+        buttonIsToggled: isPrejoinSkipped(state),
349 368
         joinButtonDisabled,
350 369
         name,
351 370
         deviceStatusVisible: isDeviceStatusVisible(state),

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

@@ -36,6 +36,16 @@ export function isDisplayNameRequired(state: Object): boolean {
36 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 50
  * Returns the text for the prejoin status bar.
41 51
  *

Loading…
Cancel
Save