|
@@ -2,6 +2,7 @@
|
2
|
2
|
|
3
|
3
|
import React, { useCallback, useEffect, useState } from 'react';
|
4
|
4
|
|
|
5
|
+import { isSupported } from '../../../av-moderation/functions';
|
5
|
6
|
import { translate } from '../../../base/i18n';
|
6
|
7
|
import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet';
|
7
|
8
|
import { MEDIA_TYPE } from '../../../base/media';
|
|
@@ -9,6 +10,7 @@ import {
|
9
|
10
|
getLocalParticipant,
|
10
|
11
|
getParticipantByIdOrUndefined,
|
11
|
12
|
getParticipantDisplayName,
|
|
13
|
+ isLocalParticipantModerator,
|
12
|
14
|
isParticipantModerator
|
13
|
15
|
} from '../../../base/participants';
|
14
|
16
|
import { connect } from '../../../base/redux';
|
|
@@ -18,7 +20,7 @@ import {
|
18
|
20
|
isParticipantAudioMuted,
|
19
|
21
|
isParticipantVideoMuted
|
20
|
22
|
} from '../../../base/tracks';
|
21
|
|
-import { ACTION_TRIGGER, type MediaState, MEDIA_STATE } from '../../constants';
|
|
23
|
+import { ACTION_TRIGGER, type MediaState, MEDIA_STATE, QUICK_ACTION_BUTTON } from '../../constants';
|
22
|
24
|
import {
|
23
|
25
|
getParticipantAudioMediaState,
|
24
|
26
|
getParticipantVideoMediaState,
|
|
@@ -51,11 +53,21 @@ type Props = {
|
51
|
53
|
*/
|
52
|
54
|
_displayName: string,
|
53
|
55
|
|
|
56
|
+ /**
|
|
57
|
+ * Whether or not moderation is supported.
|
|
58
|
+ */
|
|
59
|
+ _isModerationSupported: boolean,
|
|
60
|
+
|
54
|
61
|
/**
|
55
|
62
|
* True if the participant is the local participant.
|
56
|
63
|
*/
|
57
|
64
|
_local: Boolean,
|
58
|
65
|
|
|
66
|
+ /**
|
|
67
|
+ * Whether or not the local participant is moderator.
|
|
68
|
+ */
|
|
69
|
+ _localModerator: boolean,
|
|
70
|
+
|
59
|
71
|
/**
|
60
|
72
|
* Shared video local participant owner.
|
61
|
73
|
*/
|
|
@@ -162,7 +174,9 @@ function MeetingParticipantItem({
|
162
|
174
|
_audioTrack,
|
163
|
175
|
_disableModeratorIndicator,
|
164
|
176
|
_displayName,
|
|
177
|
+ _isModerationSupported,
|
165
|
178
|
_local,
|
|
179
|
+ _localModerator,
|
166
|
180
|
_localVideoOwner,
|
167
|
181
|
_participant,
|
168
|
182
|
_participantID,
|
|
@@ -220,6 +234,10 @@ function MeetingParticipantItem({
|
220
|
234
|
askToUnmuteText = t('participantsPane.actions.allowVideo');
|
221
|
235
|
}
|
222
|
236
|
|
|
237
|
+ const buttonType = _isModerationSupported
|
|
238
|
+ ? _localModerator ? QUICK_ACTION_BUTTON.ASK_TO_UNMUTE : _quickActionButtonType
|
|
239
|
+ : '';
|
|
240
|
+
|
223
|
241
|
return (
|
224
|
242
|
<ParticipantItem
|
225
|
243
|
actionsTrigger = { ACTION_TRIGGER.HOVER }
|
|
@@ -241,7 +259,7 @@ function MeetingParticipantItem({
|
241
|
259
|
&& <>
|
242
|
260
|
<ParticipantQuickAction
|
243
|
261
|
askUnmuteText = { askToUnmuteText }
|
244
|
|
- buttonType = { _quickActionButtonType }
|
|
262
|
+ buttonType = { buttonType }
|
245
|
263
|
muteAudio = { muteAudio }
|
246
|
264
|
muteParticipantButtonText = { muteParticipantButtonText }
|
247
|
265
|
participantID = { _participantID } />
|
|
@@ -287,12 +305,16 @@ function _mapStateToProps(state, ownProps): Object {
|
287
|
305
|
|
288
|
306
|
const { disableModeratorIndicator } = state['features/base/config'];
|
289
|
307
|
|
|
308
|
+ const _localModerator = isLocalParticipantModerator(state);
|
|
309
|
+
|
290
|
310
|
return {
|
291
|
311
|
_audioMediaState,
|
292
|
312
|
_audioTrack,
|
293
|
313
|
_disableModeratorIndicator: disableModeratorIndicator,
|
294
|
314
|
_displayName: getParticipantDisplayName(state, participant?.id),
|
|
315
|
+ _isModerationSupported: isSupported()(state),
|
295
|
316
|
_local: Boolean(participant?.local),
|
|
317
|
+ _localModerator,
|
296
|
318
|
_localVideoOwner: Boolean(ownerId === localParticipantId),
|
297
|
319
|
_participant: participant,
|
298
|
320
|
_participantID: participant?.id,
|