Przeglądaj źródła

fix(moderation) display green mic icon only for active speaker (#9744)

master
Avram Tudor 3 lat temu
rodzic
commit
6d3a4b920b
No account linked to committer's email address

+ 4
- 2
css/_base.scss Wyświetl plik

@@ -51,8 +51,10 @@ body {
51 51
     }
52 52
 }
53 53
 
54
-.jitsi-icon svg {
55
-    fill: white;
54
+.jitsi-icon {
55
+    &-default svg {
56
+        fill: white;
57
+    }
56 58
 }
57 59
 
58 60
 .disabled .jitsi-icon svg {

+ 3
- 1
react/features/base/icons/components/Icon.js Wyświetl plik

@@ -153,6 +153,8 @@ export default function Icon(props: Props) {
153 153
         }
154 154
     }, [ onClick, onKeyPress ]);
155 155
 
156
+    const jitsiIconClassName = calculatedColor ? 'jitsi-icon' : 'jitsi-icon jitsi-icon-default';
157
+
156 158
     return (
157 159
         <Container
158 160
             { ...rest }
@@ -163,7 +165,7 @@ export default function Icon(props: Props) {
163 165
             aria-haspopup = { ariaHasPopup }
164 166
             aria-label = { ariaLabel }
165 167
             aria-pressed = { ariaPressed }
166
-            className = { `jitsi-icon ${className || ''}` }
168
+            className = { `${jitsiIconClassName} ${className || ''}` }
167 169
             id = { containerId }
168 170
             onClick = { onClick }
169 171
             onKeyDown = { onKeyDown }

+ 7
- 56
react/features/participants-pane/components/web/ParticipantItem.js Wyświetl plik

@@ -4,17 +4,16 @@ import React, { type Node } from 'react';
4 4
 
5 5
 import { Avatar } from '../../../base/avatar';
6 6
 import {
7
-    Icon,
8
-    IconCameraEmpty,
9
-    IconCameraEmptyDisabled,
10
-    IconMicrophoneEmpty,
11
-    IconMicrophoneEmptySlash
12
-} from '../../../base/icons';
13
-import { ACTION_TRIGGER, MEDIA_STATE, type ActionTrigger, type MediaState } from '../../constants';
7
+    ACTION_TRIGGER,
8
+    AudioStateIcons,
9
+    MEDIA_STATE,
10
+    type ActionTrigger,
11
+    type MediaState,
12
+    VideoStateIcons
13
+} from '../../constants';
14 14
 
15 15
 import { RaisedHandIndicator } from './RaisedHandIndicator';
16 16
 import {
17
-    ColoredIcon,
18 17
     ParticipantActionsHover,
19 18
     ParticipantActionsPermanent,
20 19
     ParticipantContainer,
@@ -32,54 +31,6 @@ const Actions = {
32 31
     [ACTION_TRIGGER.PERMANENT]: ParticipantActionsPermanent
33 32
 };
34 33
 
35
-/**
36
- * Icon mapping for possible participant audio states.
37
- */
38
-const AudioStateIcons: {[MediaState]: React$Element<any> | null} = {
39
-    [MEDIA_STATE.FORCE_MUTED]: (
40
-        <ColoredIcon color = '#E04757'>
41
-            <Icon
42
-                size = { 16 }
43
-                src = { IconMicrophoneEmptySlash } />
44
-        </ColoredIcon>
45
-    ),
46
-    [MEDIA_STATE.MUTED]: (
47
-        <Icon
48
-            size = { 16 }
49
-            src = { IconMicrophoneEmptySlash } />
50
-    ),
51
-    [MEDIA_STATE.UNMUTED]: (
52
-        <ColoredIcon color = '#1EC26A'>
53
-            <Icon
54
-                size = { 16 }
55
-                src = { IconMicrophoneEmpty } />
56
-        </ColoredIcon>
57
-    ),
58
-    [MEDIA_STATE.NONE]: null
59
-};
60
-
61
-/**
62
- * Icon mapping for possible participant video states.
63
- */
64
-const VideoStateIcons = {
65
-    [MEDIA_STATE.FORCE_MUTED]: (
66
-        <Icon
67
-            size = { 16 }
68
-            src = { IconCameraEmptyDisabled } />
69
-    ),
70
-    [MEDIA_STATE.MUTED]: (
71
-        <Icon
72
-            size = { 16 }
73
-            src = { IconCameraEmptyDisabled } />
74
-    ),
75
-    [MEDIA_STATE.UNMUTED]: (
76
-        <Icon
77
-            size = { 16 }
78
-            src = { IconCameraEmpty } />
79
-    ),
80
-    [MEDIA_STATE.NONE]: null
81
-};
82
-
83 34
 type Props = {
84 35
 
85 36
     /**

+ 0
- 6
react/features/participants-pane/components/web/styled.js Wyświetl plik

@@ -190,12 +190,6 @@ export const Heading = styled.div`
190 190
   margin: 8px 0 ${props => props.theme.panePadding}px;
191 191
 `;
192 192
 
193
-export const ColoredIcon = styled.div`
194
-  & > div > svg {
195
-    fill: ${props => props.color || '#fff'};
196
-  }
197
-`;
198
-
199 193
 export const ParticipantActionButton = styled(Button)`
200 194
   height: ${props => props.theme.participantActionButtonHeight}px;
201 195
   padding: 6px 10px;

+ 9
- 2
react/features/participants-pane/constants.js Wyświetl plik

@@ -25,17 +25,19 @@ export const ACTION_TRIGGER: {HOVER: ActionTrigger, PERMANENT: ActionTrigger} =
25 25
     PERMANENT: 'Permanent'
26 26
 };
27 27
 
28
-export type MediaState = 'Muted' | 'ForceMuted' | 'Unmuted' | 'None';
28
+export type MediaState = 'DominantSpeaker' | 'Muted' | 'ForceMuted' | 'Unmuted' | 'None';
29 29
 
30 30
 /**
31 31
  * Enum of possible participant media states.
32 32
  */
33 33
 export const MEDIA_STATE: {
34
+    DOMINANT_SPEAKER: MediaState,
34 35
     MUTED: MediaState,
35 36
     FORCE_MUTED: MediaState,
36 37
     UNMUTED: MediaState,
37 38
     NONE: MediaState,
38 39
 } = {
40
+    DOMINANT_SPEAKER: 'DominantSpeaker',
39 41
     MUTED: 'Muted',
40 42
     FORCE_MUTED: 'ForceMuted',
41 43
     UNMUTED: 'Unmuted',
@@ -61,6 +63,12 @@ export const QUICK_ACTION_BUTTON: {
61 63
  * Icon mapping for possible participant audio states.
62 64
  */
63 65
 export const AudioStateIcons: {[MediaState]: React$Element<any> | null} = {
66
+    [MEDIA_STATE.DOMINANT_SPEAKER]: (
67
+        <Icon
68
+            color = '#1EC26A'
69
+            size = { 16 }
70
+            src = { IconMicrophoneEmpty } />
71
+    ),
64 72
     [MEDIA_STATE.FORCE_MUTED]: (
65 73
         <Icon
66 74
             color = '#E04757'
@@ -74,7 +82,6 @@ export const AudioStateIcons: {[MediaState]: React$Element<any> | null} = {
74 82
     ),
75 83
     [MEDIA_STATE.UNMUTED]: (
76 84
         <Icon
77
-            color = '#1EC26A'
78 85
             size = { 16 }
79 86
             src = { IconMicrophoneEmpty } />
80 87
     ),

+ 7
- 0
react/features/participants-pane/functions.js Wyświetl plik

@@ -8,6 +8,7 @@ import {
8 8
 import { getFeatureFlag, INVITE_ENABLED } from '../base/flags';
9 9
 import { MEDIA_TYPE, type MediaType } from '../base/media/constants';
10 10
 import {
11
+    getDominantSpeakerParticipant,
11 12
     getParticipantCount,
12 13
     isLocalParticipantModerator,
13 14
     isParticipantModerator
@@ -74,6 +75,12 @@ export function isForceMuted(participant: Object, mediaType: MediaType, state: O
74 75
  * @returns {MediaState}
75 76
  */
76 77
 export function getParticipantAudioMediaState(participant: Object, muted: Boolean, state: Object) {
78
+    const dominantSpeaker = getDominantSpeakerParticipant(state);
79
+
80
+    if (participant === dominantSpeaker) {
81
+        return MEDIA_STATE.DOMINANT_SPEAKER;
82
+    }
83
+
77 84
     if (muted) {
78 85
         if (isForceMuted(participant, MEDIA_TYPE.AUDIO, state)) {
79 86
             return MEDIA_STATE.FORCE_MUTED;

Ładowanie…
Anuluj
Zapisz