Przeglądaj źródła

WiP(invite-ui): Initial move of invite UI to invite button (#1950)

* WiP(invite-ui): Initial move of invite UI to invite button

* Adjusts styling to fit both horizontal and vertical filmstrip

* Removes comment and functions not needed

* [squash] Addressing various review comments

* [squash] Move invite options to a separate config

* [squash] Adjust invite button styles until we fix the whole UI theme

* [squash] Fix the remote videos scroll

* [squash]:Do not show popup menu when 1 option is available

* [squash]: Disable the invite button in filmstrip mode

* feat(connection-indicator): implement automatic hiding on good connection (#2009)

* ref(connection-stats): use PropTypes package

* feat(connection-stats): display a summary of the connection quality

* feat(connection-indicator): show empty bars for interrupted connection

* feat(connection-indicator): change background color based on status

* feat(connection-indicator): implement automatic hiding on good connection

* fix(connection-indicator): explicitly set font size

Currently non-react code will set an icon size on ConnectionIndicator.
This doesn't work on initial call join in vertical filmstrip after
some changes to support hiding the indicator. The chosen fix is
passing in the icon size to mirror what would happe with full
filmstrip reactification.

* ref(connection-stats): rename statuses

* feat(connection-indicator): make hiding behavior configurable

The original implementation made the auto hiding of the indicator
configured in interfaceConfig.

* fix(connection-indicator): readd class expected by torture tests

* fix(connection-indicator): change connection quality display styling

Bold the connection summary in the stats popover so it stands out.
Change the summaries so there are only three--strong, nonoptimal,
poor.

* fix(connection-indicator): gray background on lost connection

* feat(icons): add new gsm bars icon

* feat(connection-indicator): use new 3-bar icon

* ref(icons): remove icon-connection and icon-connection-lost

Both have been replaced by icon-gsm-bars so they are not
being referenced anymore. Mobile looks to have connect-lost
as a separate icon in font-icons/jitsi.json.

* fix(defaultToolbarButtons): Fixes unresolved InfoDialogButton component problem

* [squash]: Makes invite button fit the container

* [squash]:Addressing invite truncate, remote menu position and comment

* [squash]:Fix z-index in horizontal mode, z-index in lonely call

* [squash]: Fix filmstripOnly property, remove important from css
master
yanas 7 lat temu
rodzic
commit
86fcfcc535

+ 0
- 7
conference.js Wyświetl plik

895
         let user = room.getParticipantById(id);
895
         let user = room.getParticipantById(id);
896
         return user && user.isModerator();
896
         return user && user.isModerator();
897
     },
897
     },
898
-    /**
899
-     * Check if SIP is supported.
900
-     * @returns {boolean}
901
-     */
902
-    sipGatewayEnabled() {
903
-        return room.isSIPCallingSupported();
904
-    },
905
     get membersCount() {
898
     get membersCount() {
906
         return room.getParticipants().length + 1;
899
         return room.getParticipants().length + 1;
907
     },
900
     },

+ 50
- 5
css/_filmstrip.scss Wyświetl plik

48
     &__videos {
48
     &__videos {
49
         @extend %align-right;
49
         @extend %align-right;
50
         position:relative;
50
         position:relative;
51
-        height:196px;
52
         padding: 0;
51
         padding: 0;
53
         /* The filmstrip should not be covered by the left toolbar. */
52
         /* The filmstrip should not be covered by the left toolbar. */
54
         bottom: 0;
53
         bottom: 0;
55
         width:auto;
54
         width:auto;
56
         transition: bottom 2s;
55
         transition: bottom 2s;
57
         overflow: visible !important;
56
         overflow: visible !important;
58
-        /*!!! Removes the gap between the local video container and the remote
59
-        videos. */
60
-        font-size: 0pt;
61
 
57
 
62
         &#remoteVideos {
58
         &#remoteVideos {
63
             border: $thumbnailsBorder solid transparent;
59
             border: $thumbnailsBorder solid transparent;
64
             padding-left: $defaultToolbarSize + 5;
60
             padding-left: $defaultToolbarSize + 5;
65
-       }
61
+        }
62
+
63
+        /**
64
+         * The local video identifier.
65
+         */
66
+        &#filmstripLocalVideo {
67
+            bottom: 32px;
68
+            flex-direction: column;
69
+
70
+            /**
71
+             * The invite button style.
72
+             */
73
+            .filmstrip__invite {
74
+                padding-bottom: 5px;
75
+                margin-left: 2px;
76
+            }
77
+
78
+            /**
79
+             * The invite button group style.
80
+             * TOFIX: use AtlasKit.ButtonGroup if it starts supporting different
81
+             * flex grow options for the buttons.
82
+             */
83
+            .invite-button-group {
84
+                display: inline-flex;
85
+                justify-content: space-between;
86
+                width: 100%;
87
+
88
+                & button {
89
+                    background: $toolbarBackground;
90
+                    flex-grow: 1;
91
+                    flex-shrink: 1;
92
+                    overflow: hidden;
93
+                }
94
+
95
+                & > * {
96
+                    color: $toolbarButtonColor;
97
+                    flex-grow: 0;
98
+                    flex-shrink: 0;
99
+                    margin-left: 2px;
100
+                }
101
+
102
+                /**
103
+                 * Making sure any svg-s in an invite button group will be
104
+                 * colored the way we want.
105
+                 */
106
+                & path {
107
+                    fill: $toolbarButtonColor;
108
+                }
109
+            }
110
+        }
66
 
111
 
67
         &.hidden {
112
         &.hidden {
68
             bottom: -196px;
113
             bottom: -196px;

+ 20
- 19
css/_vertical_filmstrip_overrides.scss Wyświetl plik

24
          */
24
          */
25
         z-index: #{$tooltipsZ + 1};
25
         z-index: #{$tooltipsZ + 1};
26
 
26
 
27
-        &.hide-videos {
28
-            z-index: #{$tooltipsZ - 1};
29
-        }
30
-
31
         /**
27
         /**
32
          * Hide videos by making them slight to the right.
28
          * Hide videos by making them slight to the right.
33
          */
29
          */
50
             }
46
             }
51
         }
47
         }
52
 
48
 
49
+        /**
50
+         * Re-styles the local Video and invite button to better fit the
51
+         * vertical filmstrip layout.
52
+         */
53
         #filmstripLocalVideo {
53
         #filmstripLocalVideo {
54
+            bottom: 5px;
55
+            flex-direction: column-reverse;
54
             height: auto;
56
             height: auto;
55
-            justify-content: flex-end;
57
+            justify-content: flex-start;
58
+
59
+            .filmstrip__invite {
60
+                padding-bottom: 0px;
61
+                padding-top: 5px;
62
+                z-index: $dropdownZ;
63
+            }
56
         }
64
         }
57
 
65
 
58
         /**
66
         /**
69
             flex: 1;
77
             flex: 1;
70
             flex-direction: column;
78
             flex-direction: column;
71
             height: auto;
79
             height: auto;
72
-            overflow-x: hidden !important;
80
+            justify-content: flex-end;
73
 
81
 
74
-            .remote-videos-container {
75
-                flex-direction: column;
82
+            #filmstripRemoteVideosContainer {
83
+                flex-direction: column-reverse;
84
+                overflow-x: hidden;
76
             }
85
             }
77
         }
86
         }
78
 
87
 
101
         }
110
         }
102
 
111
 
103
         #remoteVideos {
112
         #remoteVideos {
104
-            flex-direction: column-reverse;
113
+            flex-direction: column;
105
             flex-grow: 1;
114
             flex-grow: 1;
106
         }
115
         }
107
 
116
 
153
      * be hidden.
162
      * be hidden.
154
      * The class opening is for when the filmstrip is transitioning from hidden
163
      * The class opening is for when the filmstrip is transitioning from hidden
155
      * to visible.
164
      * to visible.
156
-     * The class with-remote-videos is for when the filmstrip has remote videos
157
-     * displayed, as opposed to 1-on-1 mode where they might be hidden.
158
-     * The class without-remote-videos is for when the filmstrip is visible
159
-     * but it has no videos to display.
160
      */
165
      */
161
     .video-state-indicator.moveToCorner {
166
     .video-state-indicator.moveToCorner {
162
         transition: right 0.5s;
167
         transition: right 0.5s;
163
 
168
 
164
-        &.with-filmstrip.with-remote-videos {
169
+        &.with-filmstrip {
165
             &#recordingLabel {
170
             &#recordingLabel {
166
                 right: 200px;
171
                 right: 200px;
167
             }
172
             }
171
             }
176
             }
172
         }
177
         }
173
 
178
 
174
-        &.with-filmstrip.without-remote-videos {
175
-            transition-delay: 0.5s;
176
-        }
177
-
178
-        &.with-filmstrip.with-remote-videos.opening {
179
+        &.with-filmstrip.opening {
179
             transition: 0.9s;
180
             transition: 0.9s;
180
             transition-timing-function: ease-in-out;
181
             transition-timing-function: ease-in-out;
181
         }
182
         }

+ 7
- 1
interface_config.js Wyświetl plik

35
         //main toolbar
35
         //main toolbar
36
         'microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'fodeviceselection', 'hangup', // jshint ignore:line
36
         'microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'fodeviceselection', 'hangup', // jshint ignore:line
37
         //extended toolbar
37
         //extended toolbar
38
-        'profile', 'addtocall', 'contacts', 'info', 'chat', 'recording', 'etherpad', 'sharedvideo', 'dialout', 'settings', 'raisehand', 'videoquality', 'filmstrip'], // jshint ignore:line
38
+        'profile', 'contacts', 'info', 'chat', 'recording', 'etherpad', 'sharedvideo', 'settings', 'raisehand', 'videoquality', 'filmstrip'], // jshint ignore:line
39
     /**
39
     /**
40
      * Main Toolbar Buttons
40
      * Main Toolbar Buttons
41
      * All of them should be in TOOLBAR_BUTTONS
41
      * All of them should be in TOOLBAR_BUTTONS
42
      */
42
      */
43
     MAIN_TOOLBAR_BUTTONS: ['microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'fodeviceselection', 'hangup'], // jshint ignore:line
43
     MAIN_TOOLBAR_BUTTONS: ['microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'fodeviceselection', 'hangup'], // jshint ignore:line
44
     SETTINGS_SECTIONS: ['language', 'devices', 'moderator'],
44
     SETTINGS_SECTIONS: ['language', 'devices', 'moderator'],
45
+    INVITE_OPTIONS: ['invite', 'dialout', 'addtocall'],
45
     // Determines how the video would fit the screen. 'both' would fit the whole
46
     // Determines how the video would fit the screen. 'both' would fit the whole
46
     // screen, 'height' would fit the original video height to the height of the
47
     // screen, 'height' would fit the original video height to the height of the
47
     // screen, 'width' would fit the original video width to the width of the
48
     // screen, 'width' would fit the original video width to the width of the
124
      * @type {number}
125
      * @type {number}
125
      */
126
      */
126
     CONNECTION_INDICATOR_AUTO_HIDE_TIMEOUT: 5000
127
     CONNECTION_INDICATOR_AUTO_HIDE_TIMEOUT: 5000
128
+
129
+    /**
130
+     * The name of the application connected to the "Add people" search service.
131
+     */
132
+    // ADD_PEOPLE_APP_NAME: ""
127
 };
133
 };

+ 2
- 1
lang/main.json Wyświetl plik

446
         "hidePassword": "Hide password",
446
         "hidePassword": "Hide password",
447
         "inviteTo": "Invite people to __conferenceName__",
447
         "inviteTo": "Invite people to __conferenceName__",
448
         "invitedYouTo": "__userName__ has invited you to the __inviteURL__ conference",
448
         "invitedYouTo": "__userName__ has invited you to the __inviteURL__ conference",
449
+        "invitePeople": "Invite people",
449
         "locked": "This call is locked. New callers must have the link and enter the password to join.",
450
         "locked": "This call is locked. New callers must have the link and enter the password to join.",
450
         "showPassword": "Show password",
451
         "showPassword": "Show password",
451
         "unlocked": "This call is unlocked. Any new caller with the link may join the call."
452
         "unlocked": "This call is unlocked. Any new caller with the link may join the call."
467
     },
468
     },
468
     "dialOut": {
469
     "dialOut": {
469
         "dial": "Dial",
470
         "dial": "Dial",
470
-        "dialOut": "Call a phone number",
471
+        "dialOut": "Call a #",
471
         "statusMessage": "is now __status__",
472
         "statusMessage": "is now __status__",
472
         "enterPhone": "Enter phone number",
473
         "enterPhone": "Enter phone number",
473
         "phoneNotAllowed": "Oh, we don't support that destination yet! Sorry!"
474
         "phoneNotAllowed": "Oh, we don't support that destination yet! Sorry!"

+ 0
- 2
modules/UI/UI.js Wyświetl plik

37
     showDialPadButton,
37
     showDialPadButton,
38
     showEtherpadButton,
38
     showEtherpadButton,
39
     showSharedVideoButton,
39
     showSharedVideoButton,
40
-    showDialOutButton,
41
     showToolbox
40
     showToolbox
42
 } from '../../react/features/toolbox';
41
 } from '../../react/features/toolbox';
43
 import {
42
 import {
474
 UI.updateLocalRole = isModerator => {
473
 UI.updateLocalRole = isModerator => {
475
     VideoLayout.showModeratorIndicator();
474
     VideoLayout.showModeratorIndicator();
476
 
475
 
477
-    APP.store.dispatch(showDialOutButton(isModerator));
478
     APP.store.dispatch(showSharedVideoButton());
476
     APP.store.dispatch(showSharedVideoButton());
479
 
477
 
480
     Recording.showRecordingButton(isModerator);
478
     Recording.showRecordingButton(isModerator);

+ 6
- 13
modules/UI/videolayout/Filmstrip.js Wyświetl plik

193
         }
193
         }
194
     },
194
     },
195
 
195
 
196
-    /**
197
-     * Returns the width of filmstip
198
-     * @returns {number} width
199
-     */
200
-    getFilmstripWidth() {
201
-        return this.filmstrip.innerWidth()
202
-            - parseInt(this.filmstrip.css('paddingLeft'), 10)
203
-            - parseInt(this.filmstrip.css('paddingRight'), 10);
204
-    },
205
-
206
     /**
196
     /**
207
      * Calculates the size for thumbnails: local and remote one
197
      * Calculates the size for thumbnails: local and remote one
208
      * @returns {*|{localVideo, remoteVideo}}
198
      * @returns {*|{localVideo, remoteVideo}}
433
             promises.push(new Promise((resolve) => {
423
             promises.push(new Promise((resolve) => {
434
                 // Let CSS take care of height in vertical filmstrip mode.
424
                 // Let CSS take care of height in vertical filmstrip mode.
435
                 if (interfaceConfig.VERTICAL_FILMSTRIP) {
425
                 if (interfaceConfig.VERTICAL_FILMSTRIP) {
436
-                    resolve();
426
+                    $('#filmstripLocalVideo').animate({
427
+                        // adds 4 px because of small video 2px border
428
+                        width: local.thumbWidth + 4
429
+                    }, this._getAnimateOptions(animate, resolve));
437
                 } else {
430
                 } else {
438
                     this.filmstrip.animate({
431
                     this.filmstrip.animate({
439
-                        // adds 2 px because of small video 1px border
440
-                        height: remote.thumbHeight + 2
432
+                        // adds 4 px because of small video 2px border
433
+                        height: remote.thumbHeight + 4
441
                     }, this._getAnimateOptions(animate, resolve));
434
                     }, this._getAnimateOptions(animate, resolve));
442
                 }
435
                 }
443
             }));
436
             }));

+ 1
- 1
modules/UI/videolayout/LocalVideo.js Wyświetl plik

29
     this.isLocal = true;
29
     this.isLocal = true;
30
     this.emitter = emitter;
30
     this.emitter = emitter;
31
     this.statsPopoverLocation = interfaceConfig.VERTICAL_FILMSTRIP
31
     this.statsPopoverLocation = interfaceConfig.VERTICAL_FILMSTRIP
32
-        ? 'left bottom' : 'top center';
32
+        ? 'left top' : 'top center';
33
 
33
 
34
     Object.defineProperty(this, 'id', {
34
     Object.defineProperty(this, 'id', {
35
         get: function () {
35
         get: function () {

+ 1
- 1
modules/UI/videolayout/RemoteVideo.js Wyświetl plik

43
     this.hasRemoteVideoMenu = false;
43
     this.hasRemoteVideoMenu = false;
44
     this._supportsRemoteControl = false;
44
     this._supportsRemoteControl = false;
45
     this.statsPopoverLocation = interfaceConfig.VERTICAL_FILMSTRIP
45
     this.statsPopoverLocation = interfaceConfig.VERTICAL_FILMSTRIP
46
-        ? 'left top' : 'top center';
46
+        ? 'left bottom' : 'top center';
47
     this.addRemoteVideoContainer();
47
     this.addRemoteVideoContainer();
48
     this.updateIndicators();
48
     this.updateIndicators();
49
     this.setDisplayName();
49
     this.setDisplayName();

+ 11
- 0
react/features/base/conference/actionTypes.js Wyświetl plik

151
  * }
151
  * }
152
  */
152
  */
153
 export const SET_ROOM = Symbol('SET_ROOM');
153
 export const SET_ROOM = Symbol('SET_ROOM');
154
+
155
+/**
156
+ * The type of (redux) action, which indicates if a SIP gateway is enabled on
157
+ * the server.
158
+ *
159
+ * {
160
+ *     type: SET_SIP_GATEWAY_ENABLED
161
+ *     isSIPGatewayEnabled: boolean
162
+ * }
163
+ */
164
+export const SET_SIP_GATEWAY_ENABLED = Symbol('SET_SIP_GATEWAY_ENABLED');

+ 19
- 1
react/features/base/conference/reducer.js Wyświetl plik

14
     SET_AUDIO_ONLY,
14
     SET_AUDIO_ONLY,
15
     SET_PASSWORD,
15
     SET_PASSWORD,
16
     SET_RECEIVE_VIDEO_QUALITY,
16
     SET_RECEIVE_VIDEO_QUALITY,
17
-    SET_ROOM
17
+    SET_ROOM,
18
+    SET_SIP_GATEWAY_ENABLED
18
 } from './actionTypes';
19
 } from './actionTypes';
19
 import { VIDEO_QUALITY_LEVELS } from './constants';
20
 import { VIDEO_QUALITY_LEVELS } from './constants';
20
 import { isRoomValid } from './functions';
21
 import { isRoomValid } from './functions';
60
 
61
 
61
     case SET_ROOM:
62
     case SET_ROOM:
62
         return _setRoom(state, action);
63
         return _setRoom(state, action);
64
+
65
+    case SET_SIP_GATEWAY_ENABLED:
66
+        return _setSIPGatewayEnabled(state, action);
63
     }
67
     }
64
 
68
 
65
     return state;
69
     return state;
363
      */
367
      */
364
     return set(state, 'room', room);
368
     return set(state, 'room', room);
365
 }
369
 }
370
+
371
+/**
372
+ * Reduces a specific Redux action SET_SIP_GATEWAY_ENABLED of the feature
373
+ * base/conference.
374
+ *
375
+ * @param {Object} state - The Redux state of the feature base/conference.
376
+ * @param {Action} action - The Redux action SET_SIP_GATEWAY_ENABLED to reduce.
377
+ * @private
378
+ * @returns {Object} The new state of the feature base/conference after the
379
+ * reduction of the specified action.
380
+ */
381
+function _setSIPGatewayEnabled(state, action) {
382
+    return set(state, 'isSIPGatewayEnabled', action.isSIPGatewayEnabled);
383
+}

+ 1
- 1
react/features/conference/components/Conference.web.js Wyświetl plik

74
             <div id = 'videoconference_page'>
74
             <div id = 'videoconference_page'>
75
                 <div id = 'videospace'>
75
                 <div id = 'videospace'>
76
                     <LargeVideo />
76
                     <LargeVideo />
77
-                    <Filmstrip displayToolbox = { filmStripOnly } />
77
+                    <Filmstrip filmstripOnly = { filmStripOnly } />
78
                 </div>
78
                 </div>
79
 
79
 
80
                 { filmStripOnly ? null : <Toolbox /> }
80
                 { filmStripOnly ? null : <Toolbox /> }

+ 0
- 14
react/features/dial-out/actions.js Wyświetl plik

1
-import { openDialog } from '../../features/base/dialog';
2
-
3
 import {
1
 import {
4
     DIAL_OUT_CANCELED,
2
     DIAL_OUT_CANCELED,
5
     DIAL_OUT_CODES_UPDATED,
3
     DIAL_OUT_CODES_UPDATED,
7
     PHONE_NUMBER_CHECKED
5
     PHONE_NUMBER_CHECKED
8
 } from './actionTypes';
6
 } from './actionTypes';
9
 
7
 
10
-import { DialOutDialog } from './components';
11
-
12
 declare var $: Function;
8
 declare var $: Function;
13
 declare var config: Object;
9
 declare var config: Object;
14
 
10
 
76
     };
72
     };
77
 }
73
 }
78
 
74
 
79
-
80
-/**
81
- * Opens the dial-out dialog.
82
- *
83
- * @returns {Function}
84
- */
85
-export function openDialOutDialog() {
86
-    return openDialog(DialOutDialog);
87
-}
88
-
89
 /**
75
 /**
90
  * Sends an ajax request for dial-out country codes.
76
  * Sends an ajax request for dial-out country codes.
91
  *
77
  *

+ 7
- 4
react/features/filmstrip/components/Filmstrip.web.js Wyświetl plik

5
 import React, { Component } from 'react';
5
 import React, { Component } from 'react';
6
 import { connect } from 'react-redux';
6
 import { connect } from 'react-redux';
7
 
7
 
8
+import { InviteButton } from '../../invite';
8
 import { Toolbox } from '../../toolbox';
9
 import { Toolbox } from '../../toolbox';
9
 
10
 
10
 import { setFilmstripHovered } from '../actions';
11
 import { setFilmstripHovered } from '../actions';
48
         dispatch: PropTypes.func,
49
         dispatch: PropTypes.func,
49
 
50
 
50
         /**
51
         /**
51
-         * Whether or not the toolbox should be displayed within the filmstrip.
52
+         * Whether or not the conference is in filmstripOnly mode.
52
          */
53
          */
53
-        displayToolbox: PropTypes.bool
54
+        filmstripOnly: PropTypes.bool
54
     };
55
     };
55
 
56
 
56
     /**
57
     /**
100
 
101
 
101
         return (
102
         return (
102
             <div className = { filmstripClassNames }>
103
             <div className = { filmstripClassNames }>
103
-                { this.props.displayToolbox ? <Toolbox /> : null }
104
+                { this.props.filmstripOnly ? <Toolbox /> : null }
104
                 <div
105
                 <div
105
                     className = 'filmstrip__videos'
106
                     className = 'filmstrip__videos'
106
                     id = 'remoteVideos'>
107
                     id = 'remoteVideos'>
108
                         className = 'filmstrip__videos'
109
                         className = 'filmstrip__videos'
109
                         id = 'filmstripLocalVideo'
110
                         id = 'filmstripLocalVideo'
110
                         onMouseOut = { this._onMouseOut }
111
                         onMouseOut = { this._onMouseOut }
111
-                        onMouseOver = { this._onMouseOver } />
112
+                        onMouseOver = { this._onMouseOver }>
113
+                        { this.props.filmstripOnly ? null : <InviteButton /> }
114
+                    </div>
112
                     <div
115
                     <div
113
                         className = 'filmstrip__videos'
116
                         className = 'filmstrip__videos'
114
                         id = 'filmstripRemoteVideos'>
117
                         id = 'filmstripRemoteVideos'>

+ 1
- 10
react/features/invite/actions.js Wyświetl plik

5
     UPDATE_DIAL_IN_NUMBERS_FAILED,
5
     UPDATE_DIAL_IN_NUMBERS_FAILED,
6
     UPDATE_DIAL_IN_NUMBERS_SUCCESS
6
     UPDATE_DIAL_IN_NUMBERS_SUCCESS
7
 } from './actionTypes';
7
 } from './actionTypes';
8
-import { AddPeopleDialog, InviteDialog } from './components';
8
+import { InviteDialog } from './components';
9
 
9
 
10
 declare var $: Function;
10
 declare var $: Function;
11
 
11
 
18
     return openDialog(InviteDialog);
18
     return openDialog(InviteDialog);
19
 }
19
 }
20
 
20
 
21
-/**
22
- * Opens the Add People Dialog.
23
- *
24
- * @returns {Function}
25
- */
26
-export function openAddPeopleDialog() {
27
-    return openDialog(AddPeopleDialog);
28
-}
29
-
30
 /**
21
 /**
31
  * Opens the inline conference info dialog.
22
  * Opens the inline conference info dialog.
32
  *
23
  *

+ 1
- 0
react/features/invite/components/InviteButton.native.js Wyświetl plik

1
+

+ 231
- 0
react/features/invite/components/InviteButton.web.js Wyświetl plik

1
+import PropTypes from 'prop-types';
2
+import React, { Component } from 'react';
3
+import { connect } from 'react-redux';
4
+import Button from '@atlaskit/button';
5
+import DropdownMenu from '@atlaskit/dropdown-menu';
6
+
7
+import { translate } from '../../base/i18n';
8
+import { getLocalParticipant, PARTICIPANT_ROLE } from '../../base/participants';
9
+
10
+import { openDialog } from '../../base/dialog';
11
+import { AddPeopleDialog, InviteDialog } from '.';
12
+import { DialOutDialog } from '../../dial-out';
13
+import { isInviteOptionEnabled, getInviteOptionPosition } from '../functions';
14
+
15
+declare var interfaceConfig: Object;
16
+
17
+const SHARE_LINK_OPTION = 'invite';
18
+const DIAL_OUT_OPTION = 'dialout';
19
+const ADD_TO_CALL_OPTION = 'addtocall';
20
+
21
+/**
22
+ * The button that provides different invite options.
23
+ */
24
+class InviteButton extends Component {
25
+    /**
26
+     * {@code InviteButton}'s property types.
27
+     *
28
+     * @static
29
+     */
30
+    static propTypes = {
31
+        /**
32
+         * Indicates if the "Add to call" feature is available.
33
+         */
34
+        _isAddToCallAvailable: PropTypes.bool,
35
+
36
+        /**
37
+         * Indicates if the "Dial out" feature is available.
38
+         */
39
+        _isDialOutAvailable: PropTypes.bool,
40
+
41
+        /**
42
+         * The function opening the dialog.
43
+         */
44
+        openDialog: PropTypes.func,
45
+
46
+        /**
47
+         * Invoked to obtain translated strings.
48
+         */
49
+        t: PropTypes.func
50
+    };
51
+
52
+    /**
53
+     * Initializes a new {@code InviteButton} instance.
54
+     *
55
+     * @param {Object} props - The read-only properties with which the new
56
+     * instance is to be initialized.
57
+     */
58
+    constructor(props) {
59
+        super(props);
60
+
61
+        this._onInviteClick = this._onInviteClick.bind(this);
62
+        this._onInviteOptionSelected = this._onInviteOptionSelected.bind(this);
63
+        this._updateInviteItems = this._updateInviteItems.bind(this);
64
+
65
+        this._updateInviteItems(this.props);
66
+    }
67
+
68
+    /**
69
+     * Implements React's {@link Component#componentWillReceiveProps()}.
70
+     *
71
+     * @inheritdoc
72
+     * @param {Object} nextProps - The read-only props which this Component will
73
+     * receive.
74
+     * @returns {void}
75
+     */
76
+    componentWillReceiveProps(nextProps) {
77
+        if (this.props._isDialOutAvailable !== nextProps._isDialOutAvailable
78
+            || this.props._isAddToCallAvailable
79
+                !== nextProps._isAddToCallAvailable) {
80
+            this._updateInviteItems(nextProps);
81
+        }
82
+    }
83
+
84
+    /**
85
+     * Renders the content of this component.
86
+     *
87
+     * @returns {ReactElement}
88
+     */
89
+    render() {
90
+        const { t } = this.props;
91
+
92
+        const { VERTICAL_FILMSTRIP } = interfaceConfig;
93
+
94
+        return (
95
+            <div className = 'filmstrip__invite'>
96
+                <div className = 'invite-button-group'>
97
+                    <Button
98
+                        onClick = { this._onInviteClick }
99
+                        shouldFitContainer = { true }>
100
+                        { t('invite.invitePeople') }
101
+                    </Button>
102
+                    { this.props._isDialOutAvailable
103
+                        || this.props._isAddToCallAvailable
104
+                        ? <DropdownMenu
105
+                            items = { this.state.inviteOptions }
106
+                            onItemActivated = { this._onInviteOptionSelected }
107
+                            position = { VERTICAL_FILMSTRIP
108
+                                ? 'bottom right'
109
+                                : 'top right' }
110
+                            shouldFlip = { true }
111
+                            triggerType = 'button' />
112
+                        : null }
113
+                </div>
114
+            </div>
115
+        );
116
+    }
117
+
118
+    /**
119
+     * Handles the click of the invite button.
120
+     *
121
+     * @private
122
+     * @returns {void}
123
+     */
124
+    _onInviteClick() {
125
+        this.props.openDialog(InviteDialog);
126
+    }
127
+
128
+    /**
129
+     * Handles selection of the invite options.
130
+     *
131
+     * @param { Object } option - The invite option that has been selected from
132
+     * the dropdown menu.
133
+     * @private
134
+     * @returns {void}
135
+     */
136
+    _onInviteOptionSelected(option) {
137
+        this.state.inviteOptions[0].items.forEach(item => {
138
+            if (item.content === option.item.content) {
139
+                item.action();
140
+            }
141
+        });
142
+    }
143
+
144
+    /**
145
+     * Updates the invite items list depending on the availability of the
146
+     * features.
147
+     *
148
+     * @param {Object} props - The read-only properties of the component.
149
+     * @private
150
+     * @returns {void}
151
+     */
152
+    _updateInviteItems(props) {
153
+        const { t } = this.props;
154
+
155
+        const inviteItems = [];
156
+
157
+        inviteItems.splice(
158
+            getInviteOptionPosition(SHARE_LINK_OPTION),
159
+            0,
160
+            {
161
+                content: t('toolbar.invite'),
162
+                action: () => this.props.openDialog(InviteDialog)
163
+            }
164
+        );
165
+
166
+        if (props._isDialOutAvailable) {
167
+            inviteItems.splice(
168
+                getInviteOptionPosition(DIAL_OUT_OPTION),
169
+                0,
170
+                {
171
+                    content: t('dialOut.dialOut'),
172
+                    action: () => this.props.openDialog(DialOutDialog)
173
+                }
174
+            );
175
+        }
176
+
177
+        if (props._isAddToCallAvailable) {
178
+            inviteItems.splice(
179
+                getInviteOptionPosition(ADD_TO_CALL_OPTION),
180
+                0,
181
+                {
182
+                    content: interfaceConfig.ADD_PEOPLE_APP_NAME,
183
+                    action: () => this.props.openDialog(AddPeopleDialog)
184
+                }
185
+            );
186
+        }
187
+
188
+        this.state = {
189
+            /**
190
+             * The list of invite options.
191
+             */
192
+            inviteOptions: [
193
+                {
194
+                    items: inviteItems
195
+                }
196
+            ]
197
+        };
198
+    }
199
+}
200
+
201
+/**
202
+ * Maps (parts of) the Redux state to the associated {@code InviteButton}'s
203
+ * props.
204
+ *
205
+ * @param {Object} state - The Redux state.
206
+ * @private
207
+ * @returns {{
208
+ *     _isAddToCallAvailable: boolean,
209
+ *     _isDialOutAvailable: boolean
210
+ * }}
211
+ */
212
+function _mapStateToProps(state) {
213
+    const { enableUserRolesBasedOnToken } = state['features/base/config'];
214
+
215
+    const { conference } = state['features/base/conference'];
216
+
217
+    const { isGuest } = state['features/jwt'];
218
+
219
+    return {
220
+        _isAddToCallAvailable: !isGuest
221
+            && isInviteOptionEnabled(ADD_TO_CALL_OPTION),
222
+        _isDialOutAvailable:
223
+            getLocalParticipant(state).role === PARTICIPANT_ROLE.MODERATOR
224
+            && conference && conference.isSIPCallingSupported()
225
+            && isInviteOptionEnabled(DIAL_OUT_OPTION)
226
+            && (!enableUserRolesBasedOnToken || !isGuest)
227
+    };
228
+}
229
+
230
+export default translate(connect(
231
+    _mapStateToProps, { openDialog })(InviteButton));

+ 1
- 0
react/features/invite/components/index.js Wyświetl plik

1
 export { default as AddPeopleDialog } from './AddPeopleDialog';
1
 export { default as AddPeopleDialog } from './AddPeopleDialog';
2
 export { default as InfoDialogButton } from './InfoDialogButton';
2
 export { default as InfoDialogButton } from './InfoDialogButton';
3
+export { default as InviteButton } from './InviteButton';
3
 export { default as InviteDialog } from './InviteDialog';
4
 export { default as InviteDialog } from './InviteDialog';

+ 25
- 0
react/features/invite/functions.js Wyświetl plik

1
 declare var $: Function;
1
 declare var $: Function;
2
+declare var interfaceConfig: Object;
2
 
3
 
3
 /**
4
 /**
4
  * Sends an ajax request to a directory service.
5
  * Sends an ajax request to a directory service.
76
         }
77
         }
77
     }
78
     }
78
 }
79
 }
80
+
81
+/**
82
+ * Indicates if an invite option is enabled in the configuration.
83
+ *
84
+ * @param {string} name - The name of the option defined in
85
+ * interfaceConfig.INVITE_OPTIONS.
86
+ * @returns {boolean} - True to indicate that the given invite option is
87
+ * enabled, false - otherwise.
88
+ */
89
+export function isInviteOptionEnabled(name) {
90
+    return interfaceConfig.INVITE_OPTIONS.indexOf(name) !== -1;
91
+}
92
+
93
+/**
94
+ * Get the position of the invite option in the interfaceConfig.INVITE_OPTIONS
95
+ * list.
96
+ *
97
+ * @param {string} optionName - The invite option name.
98
+ * @private
99
+ * @returns {number} - The position of the option in the list.
100
+ */
101
+export function getInviteOptionPosition(optionName) {
102
+    return interfaceConfig.INVITE_OPTIONS.indexOf(optionName);
103
+}

+ 3
- 22
react/features/recording/components/RecordingLabel.web.js Wyświetl plik

3
 import { connect } from 'react-redux';
3
 import { connect } from 'react-redux';
4
 
4
 
5
 import { translate } from '../../base/i18n';
5
 import { translate } from '../../base/i18n';
6
-import { shouldRemoteVideosBeVisible } from '../../filmstrip';
7
 
6
 
8
 /**
7
 /**
9
  * Implements a React {@link Component} which displays the current state of
8
  * Implements a React {@link Component} which displays the current state of
38
          */
37
          */
39
         _labelDisplayConfiguration: PropTypes.object,
38
         _labelDisplayConfiguration: PropTypes.object,
40
 
39
 
41
-        /**
42
-         * Whether or not remote videos within the filmstrip are currently
43
-         * visible. Depending on the visibility state, coupled with filmstrip
44
-         * visibility, CSS classes will be set to allow for adjusting of
45
-         * {@code RecordingLabel} positioning.
46
-         */
47
-        _remoteVideosVisible: PropTypes.bool,
48
-
49
         /**
40
         /**
50
          * Invoked to obtain translated string.
41
          * Invoked to obtain translated string.
51
          */
42
          */
106
             centered ? '' : 'moveToCorner',
97
             centered ? '' : 'moveToCorner',
107
             this.state.filmstripBecomingVisible ? 'opening' : '',
98
             this.state.filmstripBecomingVisible ? 'opening' : '',
108
             this.props._filmstripVisible
99
             this.props._filmstripVisible
109
-                ? 'with-filmstrip' : 'without-filmstrip',
110
-            this.props._remoteVideosVisible
111
-                ? 'with-remote-videos' : 'without-remote-videos'
100
+                ? 'with-filmstrip' : 'without-filmstrip'
112
         ].join(' ');
101
         ].join(' ');
113
 
102
 
114
         return (
103
         return (
137
  * @private
126
  * @private
138
  * @returns {{
127
  * @returns {{
139
  *     _filmstripVisible: boolean,
128
  *     _filmstripVisible: boolean,
140
- *     _labelDisplayConfiguration: Object,
141
- *     _remoteVideosVisible: boolean,
129
+ *     _labelDisplayConfiguration: Object
142
  * }}
130
  * }}
143
  */
131
  */
144
 function _mapStateToProps(state) {
132
 function _mapStateToProps(state) {
159
          *
147
          *
160
          * @type {Object}
148
          * @type {Object}
161
          */
149
          */
162
-        _labelDisplayConfiguration: labelDisplayConfiguration,
163
-
164
-        /**
165
-         * Whether or not remote videos are displayed in the filmstrip.
166
-         *
167
-         * @type {boolean}
168
-         */
169
-        _remoteVideosVisible: shouldRemoteVideosBeVisible(state)
150
+        _labelDisplayConfiguration: labelDisplayConfiguration
170
     };
151
     };
171
 }
152
 }
172
 
153
 

+ 1
- 1
react/features/remote-video-menu/components/RemoteVideoMenuTriggerButton.js Wyświetl plik

107
                 content = { content }
107
                 content = { content }
108
                 onPopoverOpen = { this._onShowRemoteMenu }
108
                 onPopoverOpen = { this._onShowRemoteMenu }
109
                 position = { interfaceConfig.VERTICAL_FILMSTRIP
109
                 position = { interfaceConfig.VERTICAL_FILMSTRIP
110
-                    ? 'left middle' : 'top center' }>
110
+                    ? 'left bottom' : 'top center' }>
111
                 <span
111
                 <span
112
                     className = 'popover-trigger remote-video-menu-trigger'>
112
                     className = 'popover-trigger remote-video-menu-trigger'>
113
                     <i
113
                     <i

+ 0
- 23
react/features/toolbox/actions.web.js Wyświetl plik

324
     };
324
     };
325
 }
325
 }
326
 
326
 
327
-/**
328
- * Shows the dial out button if it's required and appropriate
329
- * flag is passed.
330
- *
331
- * @param {boolean} show - Flag showing whether to show button or not.
332
- * @returns {Function}
333
- */
334
-export function showDialOutButton(show: boolean): Function {
335
-    return (dispatch: Dispatch<*>, getState: Function) => {
336
-        const buttonName = 'dialout';
337
-
338
-        if (show
339
-                && APP.conference.sipGatewayEnabled()
340
-                && isButtonEnabled(buttonName)
341
-                && (!config.enableUserRolesBasedOnToken
342
-                    || !getState()['features/jwt'].isGuest)) {
343
-            dispatch(setToolbarButton(buttonName, {
344
-                hidden: false
345
-            }));
346
-        }
347
-    };
348
-}
349
-
350
 /**
327
 /**
351
  * Shows the toolbox for specified timeout.
328
  * Shows the toolbox for specified timeout.
352
  *
329
  *

+ 366
- 384
react/features/toolbox/defaultToolbarButtons.web.js Wyświetl plik

1
 /* @flow */
1
 /* @flow */
2
 
2
 
3
 import React from 'react';
3
 import React from 'react';
4
+import _ from 'lodash';
4
 
5
 
5
 import { ParticipantCounter } from '../contact-list';
6
 import { ParticipantCounter } from '../contact-list';
6
 import { openDeviceSelectionDialog } from '../device-selection';
7
 import { openDeviceSelectionDialog } from '../device-selection';
7
-import { openDialOutDialog } from '../dial-out';
8
 
8
 
9
 import {
9
 import {
10
     InfoDialogButton,
10
     InfoDialogButton,
11
-    openAddPeopleDialog,
12
     openInviteDialog
11
     openInviteDialog
13
 } from '../invite';
12
 } from '../invite';
13
+
14
 import { VideoQualityButton } from '../video-quality';
14
 import { VideoQualityButton } from '../video-quality';
15
 
15
 
16
 import UIEvents from '../../../service/UI/UIEvents';
16
 import UIEvents from '../../../service/UI/UIEvents';
21
 declare var interfaceConfig: Object;
21
 declare var interfaceConfig: Object;
22
 declare var JitsiMeetJS: Object;
22
 declare var JitsiMeetJS: Object;
23
 
23
 
24
+let buttons: Object = {};
25
+
24
 /**
26
 /**
25
- * All toolbar buttons' descriptors.
27
+ * Returns a map of all button descriptors and according properties.
28
+ *
29
+ * @returns {*} - The maps of default button descriptors.
26
  */
30
  */
27
-const buttons: Object = {
28
-    addtocall: {
29
-        classNames: [ 'button', 'icon-add' ],
30
-        enabled: true,
31
-        id: 'toolbar_button_add',
32
-        isDisplayed: () => !APP.store.getState()['features/jwt'].isGuest,
33
-        onClick(dispatch) {
34
-            JitsiMeetJS.analytics.sendEvent('toolbar.add.clicked');
35
-
36
-            dispatch(openAddPeopleDialog());
37
-        },
38
-        tooltipKey: 'toolbar.addPeople'
39
-    },
40
-
41
-    /**
42
-     * The descriptor of the camera toolbar button.
43
-     */
44
-    camera: {
45
-        classNames: [ 'button', 'icon-camera' ],
46
-        enabled: true,
47
-        isDisplayed: () => true,
48
-        id: 'toolbar_button_camera',
49
-        onClick() {
50
-            const newVideoMutedState = !APP.conference.isLocalVideoMuted();
51
-
52
-            if (newVideoMutedState) {
53
-                JitsiMeetJS.analytics.sendEvent('toolbar.video.enabled');
54
-            } else {
55
-                JitsiMeetJS.analytics.sendEvent('toolbar.video.disabled');
56
-            }
57
-            APP.UI.emitEvent(UIEvents.VIDEO_MUTED, newVideoMutedState);
58
-        },
59
-        popups: [
60
-            {
61
-                dataAttr: 'audioOnly.featureToggleDisabled',
62
-                dataInterpolate: { feature: 'video mute' },
63
-                id: 'unmuteWhileAudioOnly'
64
-            }
65
-        ],
66
-        shortcut: 'V',
67
-        shortcutAttr: 'toggleVideoPopover',
68
-        shortcutFunc() {
69
-            if (APP.conference.isAudioOnly()) {
70
-                APP.UI.emitEvent(UIEvents.VIDEO_UNMUTING_WHILE_AUDIO_ONLY);
71
-
72
-                return;
73
-            }
74
-
75
-            JitsiMeetJS.analytics.sendEvent('shortcut.videomute.toggled');
76
-            APP.conference.toggleVideoMuted();
77
-        },
78
-        shortcutDescription: 'keyboardShortcuts.videoMute',
79
-        tooltipKey: 'toolbar.videomute'
80
-    },
81
-
82
-    /**
83
-     * The descriptor of the chat toolbar button.
84
-     */
85
-    chat: {
86
-        classNames: [ 'button', 'icon-chat' ],
87
-        enabled: true,
88
-        html: <span className = 'badge-round'>
89
-            <span id = 'unreadMessages' />
90
-        </span>,
91
-        id: 'toolbar_button_chat',
92
-        onClick() {
93
-            JitsiMeetJS.analytics.sendEvent('toolbar.chat.toggled');
94
-            APP.UI.emitEvent(UIEvents.TOGGLE_CHAT);
95
-        },
96
-        shortcut: 'C',
97
-        shortcutAttr: 'toggleChatPopover',
98
-        shortcutFunc() {
99
-            JitsiMeetJS.analytics.sendEvent('shortcut.chat.toggled');
100
-            APP.UI.toggleChat();
101
-        },
102
-        shortcutDescription: 'keyboardShortcuts.toggleChat',
103
-        sideContainerId: 'chat_container',
104
-        tooltipKey: 'toolbar.chat'
105
-    },
106
-
107
-    /**
108
-     * The descriptor of the contact list toolbar button.
109
-     */
110
-    contacts: {
111
-        childComponent: ParticipantCounter,
112
-        classNames: [ 'button', 'icon-contactList' ],
113
-        enabled: true,
114
-        id: 'toolbar_contact_list',
115
-        onClick() {
116
-            JitsiMeetJS.analytics.sendEvent(
117
-                'toolbar.contacts.toggled');
118
-            APP.UI.emitEvent(UIEvents.TOGGLE_CONTACT_LIST);
119
-        },
120
-        sideContainerId: 'contacts_container',
121
-        tooltipKey: 'bottomtoolbar.contactlist'
122
-    },
123
-
124
-    /**
125
-     * The descriptor of the desktop sharing toolbar button.
126
-     */
127
-    desktop: {
128
-        classNames: [ 'button', 'icon-share-desktop' ],
129
-        enabled: true,
130
-        id: 'toolbar_button_desktopsharing',
131
-        onClick() {
132
-            if (APP.conference.isSharingScreen) {
133
-                JitsiMeetJS.analytics.sendEvent('toolbar.screen.disabled');
134
-            } else {
135
-                JitsiMeetJS.analytics.sendEvent('toolbar.screen.enabled');
136
-            }
137
-            APP.UI.emitEvent(UIEvents.TOGGLE_SCREENSHARING);
31
+function getDefaultButtons() {
32
+    if (!_.isEmpty(buttons)) {
33
+        return buttons;
34
+    }
35
+
36
+    buttons = {
37
+        /**
38
+         * The descriptor of the camera toolbar button.
39
+         */
40
+        camera: {
41
+            classNames: [ 'button', 'icon-camera' ],
42
+            enabled: true,
43
+            isDisplayed: () => true,
44
+            id: 'toolbar_button_camera',
45
+            onClick() {
46
+                const newVideoMutedState = !APP.conference.isLocalVideoMuted();
47
+
48
+                if (newVideoMutedState) {
49
+                    JitsiMeetJS.analytics.sendEvent('toolbar.video.enabled');
50
+                } else {
51
+                    JitsiMeetJS.analytics.sendEvent('toolbar.video.disabled');
52
+                }
53
+                APP.UI.emitEvent(UIEvents.VIDEO_MUTED, newVideoMutedState);
54
+            },
55
+            popups: [
56
+                {
57
+                    dataAttr: 'audioOnly.featureToggleDisabled',
58
+                    dataInterpolate: { feature: 'video mute' },
59
+                    id: 'unmuteWhileAudioOnly'
60
+                }
61
+            ],
62
+            shortcut: 'V',
63
+            shortcutAttr: 'toggleVideoPopover',
64
+            shortcutFunc() {
65
+                if (APP.conference.isAudioOnly()) {
66
+                    APP.UI.emitEvent(UIEvents.VIDEO_UNMUTING_WHILE_AUDIO_ONLY);
67
+
68
+                    return;
69
+                }
70
+
71
+                JitsiMeetJS.analytics.sendEvent('shortcut.videomute.toggled');
72
+                APP.conference.toggleVideoMuted();
73
+            },
74
+            shortcutDescription: 'keyboardShortcuts.videoMute',
75
+            tooltipKey: 'toolbar.videomute'
138
         },
76
         },
139
-        popups: [
140
-            {
141
-                dataAttr: 'audioOnly.featureToggleDisabled',
142
-                dataInterpolate: { feature: 'screen sharing' },
143
-                id: 'screenshareWhileAudioOnly'
144
-            }
145
-        ],
146
-        shortcut: 'D',
147
-        shortcutAttr: 'toggleDesktopSharingPopover',
148
-        shortcutFunc() {
149
-            JitsiMeetJS.analytics.sendEvent('shortcut.screen.toggled');
150
-
151
-            // eslint-disable-next-line no-empty-function
152
-            APP.conference.toggleScreenSharing().catch(() => {});
77
+
78
+        /**
79
+         * The descriptor of the chat toolbar button.
80
+         */
81
+        chat: {
82
+            classNames: [ 'button', 'icon-chat' ],
83
+            enabled: true,
84
+            html: <span className = 'badge-round'>
85
+                <span id = 'unreadMessages' /></span>,
86
+            id: 'toolbar_button_chat',
87
+            onClick() {
88
+                JitsiMeetJS.analytics.sendEvent('toolbar.chat.toggled');
89
+                APP.UI.emitEvent(UIEvents.TOGGLE_CHAT);
90
+            },
91
+            shortcut: 'C',
92
+            shortcutAttr: 'toggleChatPopover',
93
+            shortcutFunc() {
94
+                JitsiMeetJS.analytics.sendEvent('shortcut.chat.toggled');
95
+                APP.UI.toggleChat();
96
+            },
97
+            shortcutDescription: 'keyboardShortcuts.toggleChat',
98
+            sideContainerId: 'chat_container',
99
+            tooltipKey: 'toolbar.chat'
153
         },
100
         },
154
-        shortcutDescription: 'keyboardShortcuts.toggleScreensharing',
155
-        tooltipKey: 'toolbar.sharescreen'
156
-    },
157
-
158
-    /**
159
-     * The descriptor of the dial out toolbar button.
160
-     */
161
-    dialout: {
162
-        classNames: [ 'button', 'icon-telephone' ],
163
-        enabled: true,
164
-
165
-        // Will be displayed once the SIP calls functionality is detected.
166
-        hidden: true,
167
-        id: 'toolbar_button_dial_out',
168
-        onClick(dispatch) {
169
-            JitsiMeetJS.analytics.sendEvent('toolbar.sip.clicked');
170
-
171
-            dispatch(openDialOutDialog());
101
+
102
+        /**
103
+         * The descriptor of the contact list toolbar button.
104
+         */
105
+        contacts: {
106
+            childComponent: ParticipantCounter,
107
+            classNames: [ 'button', 'icon-contactList' ],
108
+            enabled: true,
109
+            id: 'toolbar_contact_list',
110
+            onClick() {
111
+                JitsiMeetJS.analytics.sendEvent(
112
+                    'toolbar.contacts.toggled');
113
+                APP.UI.emitEvent(UIEvents.TOGGLE_CONTACT_LIST);
114
+            },
115
+            sideContainerId: 'contacts_container',
116
+            tooltipKey: 'bottomtoolbar.contactlist'
172
         },
117
         },
173
-        tooltipKey: 'dialOut.dialOut'
174
-    },
175
-
176
-    /**
177
-     * The descriptor of the device selection toolbar button.
178
-     */
179
-    fodeviceselection: {
180
-        classNames: [ 'button', 'icon-settings' ],
181
-        enabled: true,
182
-        isDisplayed() {
183
-            return interfaceConfig.filmStripOnly;
118
+
119
+        /**
120
+         * The descriptor of the desktop sharing toolbar button.
121
+         */
122
+        desktop: {
123
+            classNames: [ 'button', 'icon-share-desktop' ],
124
+            enabled: true,
125
+            id: 'toolbar_button_desktopsharing',
126
+            onClick() {
127
+                if (APP.conference.isSharingScreen) {
128
+                    JitsiMeetJS.analytics.sendEvent('toolbar.screen.disabled');
129
+                } else {
130
+                    JitsiMeetJS.analytics.sendEvent('toolbar.screen.enabled');
131
+                }
132
+                APP.UI.emitEvent(UIEvents.TOGGLE_SCREENSHARING);
133
+            },
134
+            popups: [
135
+                {
136
+                    dataAttr: 'audioOnly.featureToggleDisabled',
137
+                    dataInterpolate: { feature: 'screen sharing' },
138
+                    id: 'screenshareWhileAudioOnly'
139
+                }
140
+            ],
141
+            shortcut: 'D',
142
+            shortcutAttr: 'toggleDesktopSharingPopover',
143
+            shortcutFunc() {
144
+                JitsiMeetJS.analytics.sendEvent('shortcut.screen.toggled');
145
+
146
+                // eslint-disable-next-line no-empty-function
147
+                APP.conference.toggleScreenSharing().catch(() => {});
148
+            },
149
+            shortcutDescription: 'keyboardShortcuts.toggleScreensharing',
150
+            tooltipKey: 'toolbar.sharescreen'
184
         },
151
         },
185
-        id: 'toolbar_button_fodeviceselection',
186
-        onClick(dispatch) {
187
-            JitsiMeetJS.analytics.sendEvent(
188
-                'toolbar.fodeviceselection.toggled');
189
 
152
 
190
-            dispatch(openDeviceSelectionDialog());
153
+        /**
154
+         * The descriptor of the device selection toolbar button.
155
+         */
156
+        fodeviceselection: {
157
+            classNames: [ 'button', 'icon-settings' ],
158
+            enabled: true,
159
+            isDisplayed() {
160
+                return interfaceConfig.filmStripOnly;
161
+            },
162
+            id: 'toolbar_button_fodeviceselection',
163
+            onClick(dispatch: Function) {
164
+                JitsiMeetJS.analytics.sendEvent(
165
+                    'toolbar.fodeviceselection.toggled');
166
+
167
+                dispatch(openDeviceSelectionDialog());
168
+            },
169
+            sideContainerId: 'settings_container',
170
+            tooltipKey: 'toolbar.Settings'
191
         },
171
         },
192
-        sideContainerId: 'settings_container',
193
-        tooltipKey: 'toolbar.Settings'
194
-    },
195
-
196
-    /**
197
-     * The descriptor of the dialpad toolbar button.
198
-     */
199
-    dialpad: {
200
-        classNames: [ 'button', 'icon-dialpad' ],
201
-        enabled: true,
202
-
203
-        // TODO: remove it after UI.updateDTMFSupport fix
204
-        hidden: true,
205
-        id: 'toolbar_button_dialpad',
206
-        onClick() {
207
-            JitsiMeetJS.analytics.sendEvent('toolbar.sip.dialpad.clicked');
172
+
173
+        /**
174
+         * The descriptor of the dialpad toolbar button.
175
+         */
176
+        dialpad: {
177
+            classNames: [ 'button', 'icon-dialpad' ],
178
+            enabled: true,
179
+
180
+            // TODO: remove it after UI.updateDTMFSupport fix
181
+            hidden: true,
182
+            id: 'toolbar_button_dialpad',
183
+            onClick() {
184
+                JitsiMeetJS.analytics.sendEvent('toolbar.sip.dialpad.clicked');
185
+            },
186
+            tooltipKey: 'toolbar.dialpad'
208
         },
187
         },
209
-        tooltipKey: 'toolbar.dialpad'
210
-    },
211
-
212
-    /**
213
-     * The descriptor of the etherpad toolbar button.
214
-     */
215
-    etherpad: {
216
-        classNames: [ 'button', 'icon-share-doc' ],
217
-        enabled: true,
218
-        hidden: true,
219
-        id: 'toolbar_button_etherpad',
220
-        onClick() {
221
-            JitsiMeetJS.analytics.sendEvent('toolbar.etherpad.clicked');
222
-            APP.UI.emitEvent(UIEvents.ETHERPAD_CLICKED);
188
+
189
+        /**
190
+         * The descriptor of the etherpad toolbar button.
191
+         */
192
+        etherpad: {
193
+            classNames: [ 'button', 'icon-share-doc' ],
194
+            enabled: true,
195
+            hidden: true,
196
+            id: 'toolbar_button_etherpad',
197
+            onClick() {
198
+                JitsiMeetJS.analytics.sendEvent('toolbar.etherpad.clicked');
199
+                APP.UI.emitEvent(UIEvents.ETHERPAD_CLICKED);
200
+            },
201
+            tooltipKey: 'toolbar.etherpad'
223
         },
202
         },
224
-        tooltipKey: 'toolbar.etherpad'
225
-    },
226
-
227
-    /**
228
-     * The descriptor of the toolbar button which toggles full-screen mode.
229
-     */
230
-    fullscreen: {
231
-        classNames: [ 'button', 'icon-full-screen' ],
232
-        enabled: true,
233
-        id: 'toolbar_button_fullScreen',
234
-        onClick() {
235
-            JitsiMeetJS.analytics.sendEvent('toolbar.fullscreen.enabled');
236
-
237
-            APP.UI.emitEvent(UIEvents.TOGGLE_FULLSCREEN);
203
+
204
+        /**
205
+         * The descriptor of the toolbar button which toggles full-screen mode.
206
+         */
207
+        fullscreen: {
208
+            classNames: [ 'button', 'icon-full-screen' ],
209
+            enabled: true,
210
+            id: 'toolbar_button_fullScreen',
211
+            onClick() {
212
+                JitsiMeetJS.analytics.sendEvent('toolbar.fullscreen.enabled');
213
+
214
+                APP.UI.emitEvent(UIEvents.TOGGLE_FULLSCREEN);
215
+            },
216
+            shortcut: 'S',
217
+            shortcutAttr: 'toggleFullscreenPopover',
218
+            shortcutDescription: 'keyboardShortcuts.fullScreen',
219
+            shortcutFunc() {
220
+                JitsiMeetJS.analytics.sendEvent('shortcut.fullscreen.toggled');
221
+                APP.UI.toggleFullScreen();
222
+            },
223
+            tooltipKey: 'toolbar.fullscreen'
238
         },
224
         },
239
-        shortcut: 'S',
240
-        shortcutAttr: 'toggleFullscreenPopover',
241
-        shortcutDescription: 'keyboardShortcuts.fullScreen',
242
-        shortcutFunc() {
243
-            JitsiMeetJS.analytics.sendEvent('shortcut.fullscreen.toggled');
244
-            APP.UI.toggleFullScreen();
225
+
226
+        /**
227
+         * The descriptor of the toolbar button which hangs up the
228
+         * call/conference.
229
+         */
230
+        hangup: {
231
+            classNames: [ 'button', 'icon-hangup', 'button_hangup' ],
232
+            enabled: true,
233
+            isDisplayed: () => true,
234
+            id: 'toolbar_button_hangup',
235
+            onClick() {
236
+                JitsiMeetJS.analytics.sendEvent('toolbar.hangup');
237
+                APP.UI.emitEvent(UIEvents.HANGUP);
238
+            },
239
+            tooltipKey: 'toolbar.hangup'
245
         },
240
         },
246
-        tooltipKey: 'toolbar.fullscreen'
247
-    },
248
-
249
-    /**
250
-     * The descriptor of the toolbar button which hangs up the call/conference.
251
-     */
252
-    hangup: {
253
-        classNames: [ 'button', 'icon-hangup', 'button_hangup' ],
254
-        enabled: true,
255
-        isDisplayed: () => true,
256
-        id: 'toolbar_button_hangup',
257
-        onClick() {
258
-            JitsiMeetJS.analytics.sendEvent('toolbar.hangup');
259
-            APP.UI.emitEvent(UIEvents.HANGUP);
241
+
242
+        /**
243
+         * The descriptor of the toolbar button which opens a dialog for the
244
+         * conference URL and inviting others.
245
+         */
246
+        info: {
247
+            component: InfoDialogButton
260
         },
248
         },
261
-        tooltipKey: 'toolbar.hangup'
262
-    },
263
-
264
-    /**
265
-     * The descriptor of the toolbar button which opens a dialog for the
266
-     * conference URL and inviting others.
267
-     */
268
-    info: {
269
-        component: InfoDialogButton
270
-    },
271
-
272
-    /**
273
-     * The descriptor of the toolbar button which shows the invite user dialog.
274
-     */
275
-    invite: {
276
-        classNames: [ 'button', 'icon-link' ],
277
-        enabled: true,
278
-        id: 'toolbar_button_link',
279
-        onClick(dispatch) {
280
-            JitsiMeetJS.analytics.sendEvent('toolbar.invite.clicked');
281
-
282
-            dispatch(openInviteDialog());
249
+
250
+        /**
251
+         * The descriptor of the toolbar button which shows the invite user
252
+         * dialog.
253
+         */
254
+        invite: {
255
+            classNames: [ 'button', 'icon-link' ],
256
+            enabled: true,
257
+            id: 'toolbar_button_link',
258
+            onClick(dispatch: Function) {
259
+                JitsiMeetJS.analytics.sendEvent('toolbar.invite.clicked');
260
+
261
+                dispatch(openInviteDialog());
262
+            },
263
+            tooltipKey: 'toolbar.invite'
283
         },
264
         },
284
-        tooltipKey: 'toolbar.invite'
285
-    },
286
-
287
-    /**
288
-     * The descriptor of the microphone toolbar button.
289
-     */
290
-    microphone: {
291
-        classNames: [ 'button', 'icon-microphone' ],
292
-        enabled: true,
293
-        isDisplayed: () => true,
294
-        id: 'toolbar_button_mute',
295
-        onClick() {
296
-            const sharedVideoManager = APP.UI.getSharedVideoManager();
297
-
298
-            if (APP.conference.isLocalAudioMuted()) {
299
-                // If there's a shared video with the volume "on" and we aren't
300
-                // the video owner, we warn the user
301
-                // that currently it's not possible to unmute.
302
-                if (sharedVideoManager
303
-                    && sharedVideoManager.isSharedVideoVolumeOn()
304
-                    && !sharedVideoManager.isSharedVideoOwner()) {
305
-                    APP.UI.showCustomToolbarPopup(
306
-                        '#unableToUnmutePopup', true, 5000);
265
+
266
+        /**
267
+         * The descriptor of the microphone toolbar button.
268
+         */
269
+        microphone: {
270
+            classNames: [ 'button', 'icon-microphone' ],
271
+            enabled: true,
272
+            isDisplayed: () => true,
273
+            id: 'toolbar_button_mute',
274
+            onClick() {
275
+                const sharedVideoManager = APP.UI.getSharedVideoManager();
276
+
277
+                if (APP.conference.isLocalAudioMuted()) {
278
+                    // If there's a shared video with the volume "on" and we
279
+                    // aren't the video owner, we warn the user
280
+                    // that currently it's not possible to unmute.
281
+                    if (sharedVideoManager
282
+                        && sharedVideoManager.isSharedVideoVolumeOn()
283
+                        && !sharedVideoManager.isSharedVideoOwner()) {
284
+                        APP.UI.showCustomToolbarPopup(
285
+                            '#unableToUnmutePopup', true, 5000);
286
+                    } else {
287
+                        JitsiMeetJS.analytics
288
+                            .sendEvent('toolbar.audio.unmuted');
289
+                        APP.UI.emitEvent(UIEvents.AUDIO_MUTED, false, true);
290
+                    }
307
                 } else {
291
                 } else {
308
-                    JitsiMeetJS.analytics.sendEvent('toolbar.audio.unmuted');
309
-                    APP.UI.emitEvent(UIEvents.AUDIO_MUTED, false, true);
292
+                    JitsiMeetJS.analytics.sendEvent('toolbar.audio.muted');
293
+                    APP.UI.emitEvent(UIEvents.AUDIO_MUTED, true, true);
310
                 }
294
                 }
311
-            } else {
312
-                JitsiMeetJS.analytics.sendEvent('toolbar.audio.muted');
313
-                APP.UI.emitEvent(UIEvents.AUDIO_MUTED, true, true);
314
-            }
315
-        },
316
-        popups: [
317
-            {
318
-                dataAttr: 'toolbar.micMutedPopup',
319
-                id: 'micMutedPopup'
320
             },
295
             },
321
-            {
322
-                dataAttr: 'toolbar.unableToUnmutePopup',
323
-                id: 'unableToUnmutePopup'
296
+            popups: [
297
+                {
298
+                    dataAttr: 'toolbar.micMutedPopup',
299
+                    id: 'micMutedPopup'
300
+                },
301
+                {
302
+                    dataAttr: 'toolbar.unableToUnmutePopup',
303
+                    id: 'unableToUnmutePopup'
304
+                },
305
+                {
306
+                    dataAttr: 'toolbar.talkWhileMutedPopup',
307
+                    id: 'talkWhileMutedPopup'
308
+                }
309
+            ],
310
+            shortcut: 'M',
311
+            shortcutAttr: 'mutePopover',
312
+            shortcutFunc() {
313
+                JitsiMeetJS.analytics.sendEvent('shortcut.audiomute.toggled');
314
+                APP.conference.toggleAudioMuted();
324
             },
315
             },
325
-            {
326
-                dataAttr: 'toolbar.talkWhileMutedPopup',
327
-                id: 'talkWhileMutedPopup'
328
-            }
329
-        ],
330
-        shortcut: 'M',
331
-        shortcutAttr: 'mutePopover',
332
-        shortcutFunc() {
333
-            JitsiMeetJS.analytics.sendEvent('shortcut.audiomute.toggled');
334
-            APP.conference.toggleAudioMuted();
316
+            shortcutDescription: 'keyboardShortcuts.mute',
317
+            tooltipKey: 'toolbar.mute'
335
         },
318
         },
336
-        shortcutDescription: 'keyboardShortcuts.mute',
337
-        tooltipKey: 'toolbar.mute'
338
-    },
339
-
340
-    /**
341
-     * The descriptor of the profile toolbar button.
342
-     */
343
-    profile: {
344
-        component: ProfileButton,
345
-        sideContainerId: 'profile_container'
346
-    },
347
-
348
-    /**
349
-     * The descriptor of the "Raise hand" toolbar button.
350
-     */
351
-    raisehand: {
352
-        classNames: [ 'button', 'icon-raised-hand' ],
353
-        enabled: true,
354
-        id: 'toolbar_button_raisehand',
355
-        onClick() {
356
-            JitsiMeetJS.analytics.sendEvent('toolbar.raiseHand.clicked');
357
-            APP.conference.maybeToggleRaisedHand();
319
+
320
+        /**
321
+         * The descriptor of the profile toolbar button.
322
+         */
323
+        profile: {
324
+            component: ProfileButton,
325
+            sideContainerId: 'profile_container'
358
         },
326
         },
359
-        shortcut: 'R',
360
-        shortcutAttr: 'raiseHandPopover',
361
-        shortcutDescription: 'keyboardShortcuts.raiseHand',
362
-        shortcutFunc() {
363
-            JitsiMeetJS.analytics.sendEvent('shortcut.raisehand.clicked');
364
-            APP.conference.maybeToggleRaisedHand();
327
+
328
+        /**
329
+         * The descriptor of the "Raise hand" toolbar button.
330
+         */
331
+        raisehand: {
332
+            classNames: [ 'button', 'icon-raised-hand' ],
333
+            enabled: true,
334
+            id: 'toolbar_button_raisehand',
335
+            onClick() {
336
+                JitsiMeetJS.analytics.sendEvent('toolbar.raiseHand.clicked');
337
+                APP.conference.maybeToggleRaisedHand();
338
+            },
339
+            shortcut: 'R',
340
+            shortcutAttr: 'raiseHandPopover',
341
+            shortcutDescription: 'keyboardShortcuts.raiseHand',
342
+            shortcutFunc() {
343
+                JitsiMeetJS.analytics.sendEvent('shortcut.raisehand.clicked');
344
+                APP.conference.maybeToggleRaisedHand();
345
+            },
346
+            tooltipKey: 'toolbar.raiseHand'
365
         },
347
         },
366
-        tooltipKey: 'toolbar.raiseHand'
367
-    },
368
-
369
-    /**
370
-     * The descriptor of the recording toolbar button. Requires additional
371
-     * initialization in the recording module.
372
-     */
373
-    recording: {
374
-        classNames: [ 'button' ],
375
-        enabled: true,
376
-
377
-        // will be displayed once the recording functionality is detected
378
-        hidden: true,
379
-        id: 'toolbar_button_record',
380
-        tooltipKey: 'liveStreaming.buttonTooltip'
381
-    },
382
-
383
-    /**
384
-     * The descriptor of the settings toolbar button.
385
-     */
386
-    settings: {
387
-        classNames: [ 'button', 'icon-settings' ],
388
-        enabled: true,
389
-        id: 'toolbar_button_settings',
390
-        onClick() {
391
-            JitsiMeetJS.analytics.sendEvent('toolbar.settings.toggled');
392
-            APP.UI.emitEvent(UIEvents.TOGGLE_SETTINGS);
348
+
349
+        /**
350
+         * The descriptor of the recording toolbar button. Requires additional
351
+         * initialization in the recording module.
352
+         */
353
+        recording: {
354
+            classNames: [ 'button' ],
355
+            enabled: true,
356
+
357
+            // will be displayed once the recording functionality is detected
358
+            hidden: true,
359
+            id: 'toolbar_button_record',
360
+            tooltipKey: 'liveStreaming.buttonTooltip'
393
         },
361
         },
394
-        sideContainerId: 'settings_container',
395
-        tooltipKey: 'toolbar.Settings'
396
-    },
397
-
398
-    /**
399
-     * The descriptor of the "Share YouTube video" toolbar button.
400
-     */
401
-    sharedvideo: {
402
-        classNames: [ 'button', 'icon-shared-video' ],
403
-        enabled: true,
404
-        id: 'toolbar_button_sharedvideo',
405
-        onClick() {
406
-            JitsiMeetJS.analytics.sendEvent('toolbar.sharedvideo.clicked');
407
-            APP.UI.emitEvent(UIEvents.SHARED_VIDEO_CLICKED);
362
+
363
+        /**
364
+         * The descriptor of the settings toolbar button.
365
+         */
366
+        settings: {
367
+            classNames: [ 'button', 'icon-settings' ],
368
+            enabled: true,
369
+            id: 'toolbar_button_settings',
370
+            onClick() {
371
+                JitsiMeetJS.analytics.sendEvent('toolbar.settings.toggled');
372
+                APP.UI.emitEvent(UIEvents.TOGGLE_SETTINGS);
373
+            },
374
+            sideContainerId: 'settings_container',
375
+            tooltipKey: 'toolbar.Settings'
408
         },
376
         },
409
-        popups: [
410
-            {
411
-                dataAttr: 'toolbar.sharedVideoMutedPopup',
412
-                id: 'sharedVideoMutedPopup'
413
-            }
414
-        ],
415
-        tooltipKey: 'toolbar.sharedvideo'
416
-    },
417
-
418
-    videoquality: {
419
-        component: VideoQualityButton
420
-    }
421
-};
422
 
377
 
378
+        /**
379
+         * The descriptor of the "Share YouTube video" toolbar button.
380
+         */
381
+        sharedvideo: {
382
+            classNames: [ 'button', 'icon-shared-video' ],
383
+            enabled: true,
384
+            id: 'toolbar_button_sharedvideo',
385
+            onClick() {
386
+                JitsiMeetJS.analytics.sendEvent('toolbar.sharedvideo.clicked');
387
+                APP.UI.emitEvent(UIEvents.SHARED_VIDEO_CLICKED);
388
+            },
389
+            popups: [
390
+                {
391
+                    dataAttr: 'toolbar.sharedVideoMutedPopup',
392
+                    id: 'sharedVideoMutedPopup'
393
+                }
394
+            ],
395
+            tooltipKey: 'toolbar.sharedvideo'
396
+        },
423
 
397
 
424
-Object.keys(buttons).forEach(name => {
425
-    const button = buttons[name];
398
+        videoquality: {
399
+            component: VideoQualityButton
400
+        }
401
+    };
426
 
402
 
427
-    if (!button.isDisplayed) {
428
-        button.isDisplayed = () => !interfaceConfig.filmStripOnly;
429
-    }
430
-});
403
+    Object.keys(buttons).forEach(name => {
404
+        const button = buttons[name];
405
+
406
+        if (!button.isDisplayed) {
407
+            button.isDisplayed = () => !interfaceConfig.filmStripOnly;
408
+        }
409
+    });
410
+
411
+    return buttons;
412
+}
431
 
413
 
432
-export default buttons;
414
+export default getDefaultButtons;

+ 3
- 2
react/features/toolbox/functions.web.js Wyświetl plik

1
 import SideContainerToggler
1
 import SideContainerToggler
2
     from '../../../modules/UI/side_pannels/SideContainerToggler';
2
     from '../../../modules/UI/side_pannels/SideContainerToggler';
3
 
3
 
4
-import defaultToolbarButtons from './defaultToolbarButtons';
4
+import getDefaultButtons from './defaultToolbarButtons';
5
 
5
 
6
 declare var interfaceConfig: Object;
6
 declare var interfaceConfig: Object;
7
 
7
 
27
         toolbarButtons
27
         toolbarButtons
28
             = interfaceConfig.TOOLBAR_BUTTONS.reduce(
28
             = interfaceConfig.TOOLBAR_BUTTONS.reduce(
29
                 (acc, buttonName) => {
29
                 (acc, buttonName) => {
30
-                    let button = defaultToolbarButtons[buttonName];
30
+                    const buttons = getDefaultButtons();
31
+                    let button = buttons ? buttons[buttonName] : null;
31
                     const currentButtonHandlers = buttonHandlers[buttonName];
32
                     const currentButtonHandlers = buttonHandlers[buttonName];
32
 
33
 
33
                     if (button) {
34
                     if (button) {

+ 3
- 2
react/features/toolbox/reducer.js Wyświetl plik

15
     SET_TOOLBOX_TIMEOUT_MS,
15
     SET_TOOLBOX_TIMEOUT_MS,
16
     SET_TOOLBOX_VISIBLE
16
     SET_TOOLBOX_VISIBLE
17
 } from './actionTypes';
17
 } from './actionTypes';
18
-import defaultToolbarButtons from './defaultToolbarButtons';
18
+import getDefaultButtons from './defaultToolbarButtons';
19
 
19
 
20
 declare var interfaceConfig: Object;
20
 declare var interfaceConfig: Object;
21
 
21
 
209
  * @returns {Object}
209
  * @returns {Object}
210
  */
210
  */
211
 function _setButton(state, { button, buttonName }): Object {
211
 function _setButton(state, { button, buttonName }): Object {
212
-    const buttonDefinition = defaultToolbarButtons[buttonName];
212
+    const buttons = getDefaultButtons();
213
+    const buttonDefinition = buttons ? buttons[buttonName] : null;
213
 
214
 
214
     // We don't need to update if the button shouldn't be displayed
215
     // We don't need to update if the button shouldn't be displayed
215
     if (!buttonDefinition || !buttonDefinition.isDisplayed()) {
216
     if (!buttonDefinition || !buttonDefinition.isDisplayed()) {

+ 1
- 14
react/features/video-quality/components/VideoQualityLabel.web.js Wyświetl plik

5
 
5
 
6
 import { VIDEO_QUALITY_LEVELS } from '../../base/conference';
6
 import { VIDEO_QUALITY_LEVELS } from '../../base/conference';
7
 import { translate } from '../../base/i18n';
7
 import { translate } from '../../base/i18n';
8
-import { shouldRemoteVideosBeVisible } from '../../filmstrip';
9
 
8
 
10
 const { HIGH, STANDARD, LOW } = VIDEO_QUALITY_LEVELS;
9
 const { HIGH, STANDARD, LOW } = VIDEO_QUALITY_LEVELS;
11
 
10
 
59
          */
58
          */
60
         _filmstripVisible: PropTypes.bool,
59
         _filmstripVisible: PropTypes.bool,
61
 
60
 
62
-        /**
63
-         * Whether or note remote videos are visible in the filmstrip,
64
-         * regardless of count. Used to determine display classes to set.
65
-         */
66
-        _remoteVideosVisible: PropTypes.bool,
67
-
68
         /**
61
         /**
69
          * The current video resolution (height) to display a label for.
62
          * The current video resolution (height) to display a label for.
70
          */
63
          */
123
             _audioOnly,
116
             _audioOnly,
124
             _conferenceStarted,
117
             _conferenceStarted,
125
             _filmstripVisible,
118
             _filmstripVisible,
126
-            _remoteVideosVisible,
127
             _resolution,
119
             _resolution,
128
             t
120
             t
129
         } = this.props;
121
         } = this.props;
140
         const baseClasses = 'video-state-indicator moveToCorner';
132
         const baseClasses = 'video-state-indicator moveToCorner';
141
         const filmstrip
133
         const filmstrip
142
             = _filmstripVisible ? 'with-filmstrip' : 'without-filmstrip';
134
             = _filmstripVisible ? 'with-filmstrip' : 'without-filmstrip';
143
-        const remoteVideosVisible = _remoteVideosVisible
144
-            ? 'with-remote-videos'
145
-            : 'without-remote-videos';
146
         const opening = this.state.togglingToVisible ? 'opening' : '';
135
         const opening = this.state.togglingToVisible ? 'opening' : '';
147
         const classNames
136
         const classNames
148
-            = `${baseClasses} ${filmstrip} ${remoteVideosVisible} ${opening}`;
137
+            = `${baseClasses} ${filmstrip} ${opening}`;
149
         const tooltipKey
138
         const tooltipKey
150
             = `videoStatus.labelTooltip${_audioOnly ? 'AudioOnly' : 'Video'}`;
139
             = `videoStatus.labelTooltip${_audioOnly ? 'AudioOnly' : 'Video'}`;
151
 
140
 
206
  *     _audioOnly: boolean,
195
  *     _audioOnly: boolean,
207
  *     _conferenceStarted: boolean,
196
  *     _conferenceStarted: boolean,
208
  *     _filmstripVisible: true,
197
  *     _filmstripVisible: true,
209
- *     _remoteVideosVisible: boolean,
210
  *     _resolution: number
198
  *     _resolution: number
211
  * }}
199
  * }}
212
  */
200
  */
219
         _audioOnly: audioOnly,
207
         _audioOnly: audioOnly,
220
         _conferenceStarted: Boolean(conference),
208
         _conferenceStarted: Boolean(conference),
221
         _filmstripVisible: visible,
209
         _filmstripVisible: visible,
222
-        _remoteVideosVisible: shouldRemoteVideosBeVisible(state),
223
         _resolution: resolution
210
         _resolution: resolution
224
     };
211
     };
225
 }
212
 }

Ładowanie…
Anuluj
Zapisz