diff --git a/css/_base.scss b/css/_base.scss index f0fa7b7c3..67ad368b7 100644 --- a/css/_base.scss +++ b/css/_base.scss @@ -51,8 +51,10 @@ body { } } -.jitsi-icon svg { - fill: white; +.jitsi-icon { + &-default svg { + fill: white; + } } .disabled .jitsi-icon svg { diff --git a/react/features/base/icons/components/Icon.js b/react/features/base/icons/components/Icon.js index 42fb9ce4a..4aa49fa99 100644 --- a/react/features/base/icons/components/Icon.js +++ b/react/features/base/icons/components/Icon.js @@ -153,6 +153,8 @@ export default function Icon(props: Props) { } }, [ onClick, onKeyPress ]); + const jitsiIconClassName = calculatedColor ? 'jitsi-icon' : 'jitsi-icon jitsi-icon-default'; + return ( | null} = { - [MEDIA_STATE.FORCE_MUTED]: ( - - - - ), - [MEDIA_STATE.MUTED]: ( - - ), - [MEDIA_STATE.UNMUTED]: ( - - - - ), - [MEDIA_STATE.NONE]: null -}; - -/** - * Icon mapping for possible participant video states. - */ -const VideoStateIcons = { - [MEDIA_STATE.FORCE_MUTED]: ( - - ), - [MEDIA_STATE.MUTED]: ( - - ), - [MEDIA_STATE.UNMUTED]: ( - - ), - [MEDIA_STATE.NONE]: null -}; - type Props = { /** diff --git a/react/features/participants-pane/components/web/styled.js b/react/features/participants-pane/components/web/styled.js index 5bbe47f82..b1152bbdb 100644 --- a/react/features/participants-pane/components/web/styled.js +++ b/react/features/participants-pane/components/web/styled.js @@ -190,12 +190,6 @@ export const Heading = styled.div` margin: 8px 0 ${props => props.theme.panePadding}px; `; -export const ColoredIcon = styled.div` - & > div > svg { - fill: ${props => props.color || '#fff'}; - } -`; - export const ParticipantActionButton = styled(Button)` height: ${props => props.theme.participantActionButtonHeight}px; padding: 6px 10px; diff --git a/react/features/participants-pane/constants.js b/react/features/participants-pane/constants.js index c9b5b91a8..db194ef5b 100644 --- a/react/features/participants-pane/constants.js +++ b/react/features/participants-pane/constants.js @@ -25,17 +25,19 @@ export const ACTION_TRIGGER: {HOVER: ActionTrigger, PERMANENT: ActionTrigger} = PERMANENT: 'Permanent' }; -export type MediaState = 'Muted' | 'ForceMuted' | 'Unmuted' | 'None'; +export type MediaState = 'DominantSpeaker' | 'Muted' | 'ForceMuted' | 'Unmuted' | 'None'; /** * Enum of possible participant media states. */ export const MEDIA_STATE: { + DOMINANT_SPEAKER: MediaState, MUTED: MediaState, FORCE_MUTED: MediaState, UNMUTED: MediaState, NONE: MediaState, } = { + DOMINANT_SPEAKER: 'DominantSpeaker', MUTED: 'Muted', FORCE_MUTED: 'ForceMuted', UNMUTED: 'Unmuted', @@ -61,6 +63,12 @@ export const QUICK_ACTION_BUTTON: { * Icon mapping for possible participant audio states. */ export const AudioStateIcons: {[MediaState]: React$Element | null} = { + [MEDIA_STATE.DOMINANT_SPEAKER]: ( + + ), [MEDIA_STATE.FORCE_MUTED]: ( | null} = { ), [MEDIA_STATE.UNMUTED]: ( ), diff --git a/react/features/participants-pane/functions.js b/react/features/participants-pane/functions.js index 6b3081050..5a112cca9 100644 --- a/react/features/participants-pane/functions.js +++ b/react/features/participants-pane/functions.js @@ -8,6 +8,7 @@ import { import { getFeatureFlag, INVITE_ENABLED } from '../base/flags'; import { MEDIA_TYPE, type MediaType } from '../base/media/constants'; import { + getDominantSpeakerParticipant, getParticipantCount, isLocalParticipantModerator, isParticipantModerator @@ -74,6 +75,12 @@ export function isForceMuted(participant: Object, mediaType: MediaType, state: O * @returns {MediaState} */ export function getParticipantAudioMediaState(participant: Object, muted: Boolean, state: Object) { + const dominantSpeaker = getDominantSpeakerParticipant(state); + + if (participant === dominantSpeaker) { + return MEDIA_STATE.DOMINANT_SPEAKER; + } + if (muted) { if (isForceMuted(participant, MEDIA_TYPE.AUDIO, state)) { return MEDIA_STATE.FORCE_MUTED;