Просмотр исходного кода

feat(remotecontrol): Prevent multiple remote control sessions (#1875)

master
hristoterezov 7 лет назад
Родитель
Сommit
378a8d014e

+ 21
- 1
conference.js Просмотреть файл

11
 
11
 
12
 import { reload, reportError } from './modules/util/helpers';
12
 import { reload, reportError } from './modules/util/helpers';
13
 
13
 
14
+import * as RemoteControlEvents
15
+    from './service/remotecontrol/RemoteControlEvents';
14
 import UIEvents from './service/UI/UIEvents';
16
 import UIEvents from './service/UI/UIEvents';
15
 import UIUtil from './modules/UI/util/UIUtil';
17
 import UIUtil from './modules/UI/util/UIUtil';
16
 import * as JitsiMeetConferenceEvents from './ConferenceEvents';
18
 import * as JitsiMeetConferenceEvents from './ConferenceEvents';
1813
             ConferenceEvents.LOCK_STATE_CHANGED,
1815
             ConferenceEvents.LOCK_STATE_CHANGED,
1814
             (...args) => APP.store.dispatch(lockStateChanged(room, ...args)));
1816
             (...args) => APP.store.dispatch(lockStateChanged(room, ...args)));
1815
 
1817
 
1818
+        APP.remoteControl.on(RemoteControlEvents.ACTIVE_CHANGED, isActive => {
1819
+            room.setLocalParticipantProperty(
1820
+                "remoteControlSessionStatus",
1821
+                isActive
1822
+            );
1823
+            APP.UI.setLocalRemoteControlActiveChanged();
1824
+        });
1825
+
1816
         room.on(ConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
1826
         room.on(ConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
1817
                 (participant, name, oldValue, newValue) => {
1827
                 (participant, name, oldValue, newValue) => {
1818
-            if (name === "raisedHand") {
1828
+            switch (name) {
1829
+            case 'raisedHand':
1819
                 APP.UI.setRaisedHandStatus(participant, newValue);
1830
                 APP.UI.setRaisedHandStatus(participant, newValue);
1831
+                break;
1832
+            case 'remoteControlSessionStatus':
1833
+                APP.UI.setRemoteControlActiveStatus(
1834
+                    participant.getId(),
1835
+                    newValue);
1836
+                break;
1837
+            default:
1838
+            // ignore
1820
             }
1839
             }
1821
         });
1840
         });
1822
 
1841
 
2361
             APP.UI.setLocalRaisedHandStatus(raisedHand);
2380
             APP.UI.setLocalRaisedHandStatus(raisedHand);
2362
         }
2381
         }
2363
     },
2382
     },
2383
+
2364
     /**
2384
     /**
2365
      * Log event to callstats and analytics.
2385
      * Log event to callstats and analytics.
2366
      * @param {string} name the event name
2386
      * @param {string} name the event name

+ 20
- 0
modules/UI/UI.js Просмотреть файл

1230
 UI.setRemoteThumbnailsVisibility
1230
 UI.setRemoteThumbnailsVisibility
1231
     = shouldHide => Filmstrip.setRemoteVideoVisibility(shouldHide);
1231
     = shouldHide => Filmstrip.setRemoteVideoVisibility(shouldHide);
1232
 
1232
 
1233
+/**
1234
+ * Sets the remote control active status for a remote participant.
1235
+ *
1236
+ * @param {string} participantID - The id of the remote participant.
1237
+ * @param {boolean} isActive - The new remote control active status.
1238
+ * @returns {void}
1239
+ */
1240
+UI.setRemoteControlActiveStatus = function(participantID, isActive) {
1241
+    VideoLayout.setRemoteControlActiveStatus(participantID, isActive);
1242
+};
1243
+
1244
+/**
1245
+ * Sets the remote control active status for the local participant.
1246
+ *
1247
+ * @returns {void}
1248
+ */
1249
+UI.setLocalRemoteControlActiveChanged = function() {
1250
+    VideoLayout.setLocalRemoteControlActiveChanged();
1251
+};
1252
+
1233
 const UIListeners = new Map([
1253
 const UIListeners = new Map([
1234
     [
1254
     [
1235
         UIEvents.ETHERPAD_CLICKED,
1255
         UIEvents.ETHERPAD_CLICKED,

+ 30
- 25
modules/UI/videolayout/RemoteVideo.js Просмотреть файл

51
     this.flipX = false;
51
     this.flipX = false;
52
     this.isLocal = false;
52
     this.isLocal = false;
53
     this.popupMenuIsHovered = false;
53
     this.popupMenuIsHovered = false;
54
+    this._isRemoteControlSessionActive = false;
54
     /**
55
     /**
55
      * The flag is set to <tt>true</tt> after the 'onplay' event has been
56
      * The flag is set to <tt>true</tt> after the 'onplay' event has been
56
      * triggered on the current video element. It goes back to <tt>false</tt>
57
      * triggered on the current video element. It goes back to <tt>false</tt>
87
 
88
 
88
     this.initBrowserSpecificProperties();
89
     this.initBrowserSpecificProperties();
89
 
90
 
90
-    if (APP.conference.isModerator || this._supportsRemoteControl) {
91
-        this.addRemoteVideoMenu();
92
-    }
91
+    this.addRemoteVideoMenu();
93
 
92
 
94
     this.VideoLayout.resizeThumbnails(false, true);
93
     this.VideoLayout.resizeThumbnails(false, true);
95
 
94
 
135
     let remoteControlState = null;
134
     let remoteControlState = null;
136
     let onRemoteControlToggle;
135
     let onRemoteControlToggle;
137
 
136
 
138
-    if (this._supportsRemoteControl) {
137
+    if (this._supportsRemoteControl
138
+        && ((!APP.remoteControl.active && !this._isRemoteControlSessionActive)
139
+            || APP.remoteControl.controller.activeParticipant === this.id)) {
139
         if (controller.getRequestedParticipant() === this.id) {
140
         if (controller.getRequestedParticipant() === this.id) {
140
             onRemoteControlToggle = () => {};
141
             onRemoteControlToggle = () => {};
141
             remoteControlState = REMOTE_CONTROL_MENU_STATES.REQUESTING;
142
             remoteControlState = REMOTE_CONTROL_MENU_STATES.REQUESTING;
179
 };
180
 };
180
 
181
 
181
 RemoteVideo.prototype._onRemoteVideoMenuDisplay = function () {
182
 RemoteVideo.prototype._onRemoteVideoMenuDisplay = function () {
182
-    this.updateRemoteVideoMenu(this.isAudioMuted, true);
183
+    this.updateRemoteVideoMenu();
184
+};
185
+
186
+/**
187
+ * Sets the remote control active status for the remote video.
188
+ *
189
+ * @param {boolean} isActive - The new remote control active status.
190
+ * @returns {void}
191
+ */
192
+RemoteVideo.prototype.setRemoteControlActiveStatus = function(isActive) {
193
+    this._isRemoteControlSessionActive = isActive;
194
+    this.updateRemoteVideoMenu();
183
 };
195
 };
184
 
196
 
185
 /**
197
 /**
192
         return;
204
         return;
193
     }
205
     }
194
     this._supportsRemoteControl = isSupported;
206
     this._supportsRemoteControl = isSupported;
195
-    if(!isSupported) {
196
-        return;
197
-    }
198
-
199
-    if(!this.hasRemoteVideoMenu) {
200
-        //create menu
201
-        this.addRemoteVideoMenu();
202
-    } else {
203
-        //update the content
204
-        this.updateRemoteVideoMenu(this.isAudioMuted, true);
205
-    }
206
-
207
+    this.updateRemoteVideoMenu();
207
 };
208
 };
208
 
209
 
209
 /**
210
 /**
215
         if(result === null) {
216
         if(result === null) {
216
             return;
217
             return;
217
         }
218
         }
218
-        this.updateRemoteVideoMenu(this.isAudioMuted, true);
219
+        this.updateRemoteVideoMenu();
219
         APP.UI.messageHandler.notify(
220
         APP.UI.messageHandler.notify(
220
             "dialog.remoteControlTitle",
221
             "dialog.remoteControlTitle",
221
             (result === false) ? "dialog.remoteControlDeniedMessage"
222
             (result === false) ? "dialog.remoteControlDeniedMessage"
232
         }
233
         }
233
     }, error => {
234
     }, error => {
234
         logger.error(error);
235
         logger.error(error);
235
-        this.updateRemoteVideoMenu(this.isAudioMuted, true);
236
+        this.updateRemoteVideoMenu();
236
         APP.UI.messageHandler.notify(
237
         APP.UI.messageHandler.notify(
237
             "dialog.remoteControlTitle",
238
             "dialog.remoteControlTitle",
238
             "dialog.remoteControlErrorMessage",
239
             "dialog.remoteControlErrorMessage",
240
                 || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME}
241
                 || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME}
241
         );
242
         );
242
     });
243
     });
243
-    this.updateRemoteVideoMenu(this.isAudioMuted, true);
244
+    this.updateRemoteVideoMenu();
244
 };
245
 };
245
 
246
 
246
 /**
247
 /**
249
 RemoteVideo.prototype._stopRemoteControl = function () {
250
 RemoteVideo.prototype._stopRemoteControl = function () {
250
     // send message about stopping
251
     // send message about stopping
251
     APP.remoteControl.controller.stop();
252
     APP.remoteControl.controller.stop();
252
-    this.updateRemoteVideoMenu(this.isAudioMuted, true);
253
+    this.updateRemoteVideoMenu();
253
 };
254
 };
254
 
255
 
255
 /**
256
 /**
286
  * Updates the remote video menu.
287
  * Updates the remote video menu.
287
  *
288
  *
288
  * @param isMuted the new muted state to update to
289
  * @param isMuted the new muted state to update to
289
- * @param force to work even if popover is not visible
290
  */
290
  */
291
-RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted) {
291
+RemoteVideo.prototype.updateRemoteVideoMenu = function (
292
+    isMuted = this.isAudioMuted
293
+) {
292
     this.isAudioMuted = isMuted;
294
     this.isAudioMuted = isMuted;
293
 
295
 
294
     this._generatePopupContent();
296
     this._generatePopupContent();
323
  * Adds the remote video menu element for the given <tt>id</tt> in the
325
  * Adds the remote video menu element for the given <tt>id</tt> in the
324
  * given <tt>parentElement</tt>.
326
  * given <tt>parentElement</tt>.
325
  *
327
  *
326
- * @param id the id indicating the video for which we're adding a menu.
327
- * @param parentElement the parent element where this menu will be added
328
  */
328
  */
329
 RemoteVideo.prototype.addRemoteVideoMenu = function () {
329
 RemoteVideo.prototype.addRemoteVideoMenu = function () {
330
     if (interfaceConfig.filmStripOnly) {
330
     if (interfaceConfig.filmStripOnly) {
576
 
576
 
577
     if (!isVideo) {
577
     if (!isVideo) {
578
         this._audioStreamElement = streamElement;
578
         this._audioStreamElement = streamElement;
579
+
580
+        // If the remote video menu was created before the audio stream was
581
+        // attached we need to update the menu in order to show the volume
582
+        // slider.
583
+        this.updateRemoteVideoMenu();
579
     }
584
     }
580
 };
585
 };
581
 
586
 

+ 22
- 3
modules/UI/videolayout/VideoLayout.js Просмотреть файл

642
                 return;
642
                 return;
643
 
643
 
644
             remoteVideo.showAudioIndicator(isMuted);
644
             remoteVideo.showAudioIndicator(isMuted);
645
-            if (APP.conference.isModerator) {
646
-                remoteVideo.updateRemoteVideoMenu(isMuted);
647
-            }
645
+            remoteVideo.updateRemoteVideoMenu(isMuted);
648
         }
646
         }
649
     },
647
     },
650
 
648
 
1165
      */
1163
      */
1166
     getRemoteVideosCount() {
1164
     getRemoteVideosCount() {
1167
         return Object.keys(remoteVideos).length;
1165
         return Object.keys(remoteVideos).length;
1166
+    },
1167
+    /**
1168
+     * Sets the remote control active status for a remote participant.
1169
+     *
1170
+     * @param {string} participantID - The id of the remote participant.
1171
+     * @param {boolean} isActive - The new remote control active status.
1172
+     * @returns {void}
1173
+     */
1174
+    setRemoteControlActiveStatus(participantID, isActive) {
1175
+        remoteVideos[participantID].setRemoteControlActiveStatus(isActive);
1176
+    },
1177
+
1178
+    /**
1179
+     * Sets the remote control active status for the local participant.
1180
+     *
1181
+     * @returns {void}
1182
+     */
1183
+    setLocalRemoteControlActiveChanged() {
1184
+        Object.values(remoteVideos).forEach(
1185
+            remoteVideo => remoteVideo.updateRemoteVideoMenu()
1186
+        );
1168
     }
1187
     }
1169
 };
1188
 };
1170
 
1189
 

+ 18
- 1
modules/remotecontrol/Controller.js Просмотреть файл

8
     PERMISSIONS_ACTIONS,
8
     PERMISSIONS_ACTIONS,
9
     REMOTE_CONTROL_MESSAGE_NAME
9
     REMOTE_CONTROL_MESSAGE_NAME
10
 } from '../../service/remotecontrol/Constants';
10
 } from '../../service/remotecontrol/Constants';
11
+import * as RemoteControlEvents
12
+    from '../../service/remotecontrol/RemoteControlEvents';
11
 import UIEvents from '../../service/UI/UIEvents';
13
 import UIEvents from '../../service/UI/UIEvents';
12
 
14
 
13
 import RemoteControlParticipant from './RemoteControlParticipant';
15
 import RemoteControlParticipant from './RemoteControlParticipant';
86
             = this._onLargeVideoIdChanged.bind(this);
88
             = this._onLargeVideoIdChanged.bind(this);
87
     }
89
     }
88
 
90
 
91
+    /**
92
+     * Returns the current active participant's id.
93
+     *
94
+     * @returns {string|null} - The id of the current active participant.
95
+     */
96
+    get activeParticipant(): string | null {
97
+        return this._requestedParticipant || this._controlledParticipant;
98
+    }
99
+
89
     /**
100
     /**
90
      * Requests permissions from the remote control receiver side.
101
      * Requests permissions from the remote control receiver side.
91
      *
102
      *
100
         if (!this._enabled) {
111
         if (!this._enabled) {
101
             return Promise.reject(new Error('Remote control is disabled!'));
112
             return Promise.reject(new Error('Remote control is disabled!'));
102
         }
113
         }
103
-
114
+        this.emit(RemoteControlEvents.ACTIVE_CHANGED, true);
104
         this._area = eventCaptureArea;// $("#largeVideoWrapper")
115
         this._area = eventCaptureArea;// $("#largeVideoWrapper")
105
         logger.log(`Requsting remote control permissions from: ${userId}`);
116
         logger.log(`Requsting remote control permissions from: ${userId}`);
106
 
117
 
125
                     result = this._handleReply(participant, event);
136
                     result = this._handleReply(participant, event);
126
                 } catch (e) {
137
                 } catch (e) {
127
                     clearRequest();
138
                     clearRequest();
139
+                    this.emit(RemoteControlEvents.ACTIVE_CHANGED, false);
128
                     reject(e);
140
                     reject(e);
129
                 }
141
                 }
130
                 if (result !== null) {
142
                 if (result !== null) {
131
                     clearRequest();
143
                     clearRequest();
144
+                    if (result === false) {
145
+                        this.emit(RemoteControlEvents.ACTIVE_CHANGED, false);
146
+                    }
132
                     resolve(result);
147
                     resolve(result);
133
                 }
148
                 }
134
             };
149
             };
135
             onUserLeft = id => {
150
             onUserLeft = id => {
136
                 if (id === this._requestedParticipant) {
151
                 if (id === this._requestedParticipant) {
137
                     clearRequest();
152
                     clearRequest();
153
+                    this.emit(RemoteControlEvents.ACTIVE_CHANGED, false);
138
                     resolve(null);
154
                     resolve(null);
139
                 }
155
                 }
140
             };
156
             };
316
         this.pause();
332
         this.pause();
317
         this._controlledParticipant = null;
333
         this._controlledParticipant = null;
318
         this._area = undefined;
334
         this._area = undefined;
335
+        this.emit(RemoteControlEvents.ACTIVE_CHANGED, false);
319
         APP.UI.messageHandler.notify(
336
         APP.UI.messageHandler.notify(
320
             'dialog.remoteControlTitle',
337
             'dialog.remoteControlTitle',
321
             'dialog.remoteControlStopMessage'
338
             'dialog.remoteControlStopMessage'

+ 5
- 0
modules/remotecontrol/Receiver.js Просмотреть файл

13
     REMOTE_CONTROL_MESSAGE_NAME,
13
     REMOTE_CONTROL_MESSAGE_NAME,
14
     REQUESTS
14
     REQUESTS
15
 } from '../../service/remotecontrol/Constants';
15
 } from '../../service/remotecontrol/Constants';
16
+import * as RemoteControlEvents
17
+    from '../../service/remotecontrol/RemoteControlEvents';
16
 import {
18
 import {
17
     Transport,
19
     Transport,
18
     PostMessageTransportBackend
20
     PostMessageTransportBackend
132
             name: REMOTE_CONTROL_MESSAGE_NAME,
134
             name: REMOTE_CONTROL_MESSAGE_NAME,
133
             type: EVENTS.stop
135
             type: EVENTS.stop
134
         });
136
         });
137
+        this.emit(RemoteControlEvents.ACTIVE_CHANGED, false);
135
         if (!dontNotify) {
138
         if (!dontNotify) {
136
             APP.UI.messageHandler.notify(
139
             APP.UI.messageHandler.notify(
137
                 'dialog.remoteControlTitle',
140
                 'dialog.remoteControlTitle',
177
                     && message.action === PERMISSIONS_ACTIONS.request) {
180
                     && message.action === PERMISSIONS_ACTIONS.request) {
178
                 const userId = participant.getId();
181
                 const userId = participant.getId();
179
 
182
 
183
+                this.emit(RemoteControlEvents.ACTIVE_CHANGED, true);
180
                 APP.store.dispatch(
184
                 APP.store.dispatch(
181
                     openRemoteControlAuthorizationDialog(userId));
185
                     openRemoteControlAuthorizationDialog(userId));
182
             } else if (this._controller === participant.getId()) {
186
             } else if (this._controller === participant.getId()) {
200
      * @returns {void}
204
      * @returns {void}
201
      */
205
      */
202
     deny(userId: string) {
206
     deny(userId: string) {
207
+        this.emit(RemoteControlEvents.ACTIVE_CHANGED, false);
203
         this.sendRemoteControlEndpointMessage(userId, {
208
         this.sendRemoteControlEndpointMessage(userId, {
204
             type: EVENTS.permissions,
209
             type: EVENTS.permissions,
205
             action: PERMISSIONS_ACTIONS.deny
210
             action: PERMISSIONS_ACTIONS.deny

+ 37
- 1
modules/remotecontrol/RemoteControl.js Просмотреть файл

1
 /* @flow */
1
 /* @flow */
2
 
2
 
3
+import EventEmitter from 'events';
3
 import { getLogger } from 'jitsi-meet-logger';
4
 import { getLogger } from 'jitsi-meet-logger';
4
 
5
 
5
 import { DISCO_REMOTE_CONTROL_FEATURE }
6
 import { DISCO_REMOTE_CONTROL_FEATURE }
6
     from '../../service/remotecontrol/Constants';
7
     from '../../service/remotecontrol/Constants';
8
+import * as RemoteControlEvents
9
+    from '../../service/remotecontrol/RemoteControlEvents';
7
 
10
 
8
 import Controller from './Controller';
11
 import Controller from './Controller';
9
 import Receiver from './Receiver';
12
 import Receiver from './Receiver';
16
 /**
19
 /**
17
  * Implements the remote control functionality.
20
  * Implements the remote control functionality.
18
  */
21
  */
19
-class RemoteControl {
22
+class RemoteControl extends EventEmitter {
23
+    _active: boolean;
20
     _initialized: boolean;
24
     _initialized: boolean;
21
     controller: Controller;
25
     controller: Controller;
22
     receiver: Receiver;
26
     receiver: Receiver;
25
      * Constructs new instance. Creates controller and receiver properties.
29
      * Constructs new instance. Creates controller and receiver properties.
26
      */
30
      */
27
     constructor() {
31
     constructor() {
32
+        super();
28
         this.controller = new Controller();
33
         this.controller = new Controller();
34
+        this._active = false;
29
         this._initialized = false;
35
         this._initialized = false;
36
+
37
+        this.controller.on(RemoteControlEvents.ACTIVE_CHANGED, active => {
38
+            this.active = active;
39
+        });
40
+    }
41
+
42
+    /**
43
+     * Sets the remote control session active status.
44
+     *
45
+     * @param {boolean} isActive - True - if the controller or the receiver is
46
+     * currently in remote control session and false otherwise.
47
+     * @returns {void}
48
+     */
49
+    set active(isActive: boolean) {
50
+        this._active = isActive;
51
+        this.emit(RemoteControlEvents.ACTIVE_CHANGED, isActive);
52
+    }
53
+
54
+    /**
55
+     * Returns the remote control session active status.
56
+     *
57
+     * @returns {boolean} - True - if the controller or the receiver is
58
+     * currently in remote control session and false otherwise.
59
+     */
60
+    get active(): boolean {
61
+        return this._active;
30
     }
62
     }
31
 
63
 
32
     /**
64
     /**
45
         this._initialized = true;
77
         this._initialized = true;
46
         this.controller.enable(true);
78
         this.controller.enable(true);
47
         this.receiver = new Receiver();
79
         this.receiver = new Receiver();
80
+
81
+        this.receiver.on(RemoteControlEvents.ACTIVE_CHANGED, active => {
82
+            this.active = active;
83
+        });
48
     }
84
     }
49
 
85
 
50
     /**
86
     /**

+ 3
- 1
modules/remotecontrol/RemoteControlParticipant.js Просмотреть файл

1
 /* @flow */
1
 /* @flow */
2
 
2
 
3
+import EventEmitter from 'events';
3
 import { getLogger } from 'jitsi-meet-logger';
4
 import { getLogger } from 'jitsi-meet-logger';
4
 
5
 
5
 import {
6
 import {
13
 /**
14
 /**
14
  * Implements common logic for Receiver class and Controller class.
15
  * Implements common logic for Receiver class and Controller class.
15
  */
16
  */
16
-export default class RemoteControlParticipant {
17
+export default class RemoteControlParticipant extends EventEmitter {
17
     _enabled: boolean;
18
     _enabled: boolean;
18
 
19
 
19
     /**
20
     /**
20
      * Creates new instance.
21
      * Creates new instance.
21
      */
22
      */
22
     constructor() {
23
     constructor() {
24
+        super();
23
         this._enabled = false;
25
         this._enabled = false;
24
     }
26
     }
25
 
27
 

+ 53
- 27
react/features/remote-video-menu/components/RemoteVideoMenuTriggerButton.js Просмотреть файл

99
      * @returns {ReactElement}
99
      * @returns {ReactElement}
100
      */
100
      */
101
     render() {
101
     render() {
102
+        const content = this._renderRemoteVideoMenu();
103
+
104
+        if (!content) {
105
+            return null;
106
+        }
107
+
102
         return (
108
         return (
103
             <AKInlineDialog
109
             <AKInlineDialog
104
-                content = { this._renderRemoteVideoMenu() }
110
+                content = { content }
105
                 isOpen = { this.state.showRemoteMenu }
111
                 isOpen = { this.state.showRemoteMenu }
106
                 onClose = { this._onRemoteMenuClose }
112
                 onClose = { this._onRemoteMenuClose }
107
                 position = { interfaceConfig.VERTICAL_FILMSTRIP
113
                 position = { interfaceConfig.VERTICAL_FILMSTRIP
162
             participantID
168
             participantID
163
         } = this.props;
169
         } = this.props;
164
 
170
 
165
-        return (
166
-            <RemoteVideoMenu id = { participantID }>
167
-                { isModerator
168
-                    ? <MuteButton
169
-                        isAudioMuted = { isAudioMuted }
170
-                        onClick = { this._onRemoteMenuClose }
171
-                        participantID = { participantID } />
172
-                    : null }
173
-                { isModerator
174
-                    ? <KickButton
175
-                        onClick = { this._onRemoteMenuClose }
176
-                        participantID = { participantID } />
177
-                    : null }
178
-                { remoteControlState
179
-                    ? <RemoteControlButton
180
-                        onClick = { onRemoteControlToggle }
181
-                        participantID = { participantID }
182
-                        remoteControlState = { remoteControlState } />
183
-                    : null }
184
-                { onVolumeChange
185
-                    ? <VolumeSlider
186
-                        initialValue = { initialVolumeValue }
187
-                        onChange = { onVolumeChange } />
188
-                    : null }
189
-            </RemoteVideoMenu>
190
-        );
171
+        const buttons = [];
172
+
173
+        if (isModerator) {
174
+            buttons.push(
175
+                <MuteButton
176
+                    isAudioMuted = { isAudioMuted }
177
+                    key = 'mute'
178
+                    onClick = { this._onRemoteMenuClose }
179
+                    participantID = { participantID } />
180
+            );
181
+            buttons.push(
182
+                <KickButton
183
+                    key = 'kick'
184
+                    onClick = { this._onRemoteMenuClose }
185
+                    participantID = { participantID } />
186
+            );
187
+        }
188
+
189
+        if (remoteControlState) {
190
+            buttons.push(
191
+                <RemoteControlButton
192
+                    key = 'remote-control'
193
+                    onClick = { onRemoteControlToggle }
194
+                    participantID = { participantID }
195
+                    remoteControlState = { remoteControlState } />
196
+            );
197
+        }
198
+
199
+        if (onVolumeChange && isModerator) {
200
+            buttons.push(
201
+                <VolumeSlider
202
+                    initialValue = { initialVolumeValue }
203
+                    key = 'volume-slider'
204
+                    onChange = { onVolumeChange } />
205
+            );
206
+        }
207
+
208
+        if (buttons.length > 0) {
209
+            return (
210
+                <RemoteVideoMenu id = { participantID }>
211
+                    { buttons }
212
+                </RemoteVideoMenu>
213
+            );
214
+        }
215
+
216
+        return null;
191
     }
217
     }
192
 }
218
 }
193
 
219
 

+ 8
- 0
service/remotecontrol/RemoteControlEvents.js Просмотреть файл

1
+/**
2
+ * Events fired from the remote control module through the EventEmitter.
3
+ */
4
+
5
+/**
6
+ * Notifies about remote control active session status changes.
7
+ */
8
+export const ACTIVE_CHANGED = 'active-changed';

Загрузка…
Отмена
Сохранить