🚸(frontend) enhance mic indicator in participant list
The Gmeet-inspired indicator was misleading for users, at least those not used to GSuite products. They didn't understand how to mute a participant. Plus, having the button disabled for the local participant, was creating confusion. To simplify the UX, have all the buttons enabled is simpler to understand. Empirical observations with a few number of users, should be enhance and challenge in the long run.
This commit is contained in:
committed by
aleb_the_flash
parent
aaf6b03a25
commit
c5ce32ef79
@@ -81,6 +81,11 @@ const config: Config = {
|
|||||||
'80%': { transform: 'rotate(20deg)' },
|
'80%': { transform: 'rotate(20deg)' },
|
||||||
'100%': { transform: 'rotate(0)' },
|
'100%': { transform: 'rotate(0)' },
|
||||||
},
|
},
|
||||||
|
pulse_mic: {
|
||||||
|
'0%': { color: 'primary', opacity: '1' },
|
||||||
|
'50%': { color: 'primary', opacity: '0.8' },
|
||||||
|
'100%': { color: 'primary', opacity: '1' },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
tokens: defineTokens({
|
tokens: defineTokens({
|
||||||
/* we take a few things from the panda preset but for now we clear out some stuff.
|
/* we take a few things from the panda preset but for now we clear out some stuff.
|
||||||
|
|||||||
@@ -13,7 +13,12 @@ import {
|
|||||||
useTrackMutedIndicator,
|
useTrackMutedIndicator,
|
||||||
} from '@livekit/components-react'
|
} from '@livekit/components-react'
|
||||||
import Source = Track.Source
|
import Source = Track.Source
|
||||||
import { RiMicOffLine } from '@remixicon/react'
|
import {
|
||||||
|
RiMicFill,
|
||||||
|
RiMicLine,
|
||||||
|
RiMicOffFill,
|
||||||
|
RiMicOffLine,
|
||||||
|
} from '@remixicon/react'
|
||||||
import { Button, Dialog, P } from '@/primitives'
|
import { Button, Dialog, P } from '@/primitives'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useMuteParticipant } from '@/features/rooms/livekit/api/muteParticipant'
|
import { useMuteParticipant } from '@/features/rooms/livekit/api/muteParticipant'
|
||||||
@@ -57,10 +62,7 @@ const MicIndicator = ({ participant }: MicIndicatorProps) => {
|
|||||||
source: Source.Microphone,
|
source: Source.Microphone,
|
||||||
})
|
})
|
||||||
const isSpeaking = useIsSpeaking(participant)
|
const isSpeaking = useIsSpeaking(participant)
|
||||||
const isDisabled = isLocal(participant) || (!isLocal(participant) && isMuted)
|
|
||||||
|
|
||||||
const [isAlertOpen, setIsAlertOpen] = useState(false)
|
const [isAlertOpen, setIsAlertOpen] = useState(false)
|
||||||
|
|
||||||
const name = participant.name || participant.identity
|
const name = participant.name || participant.identity
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -69,16 +71,28 @@ const MicIndicator = ({ participant }: MicIndicatorProps) => {
|
|||||||
square
|
square
|
||||||
invisible
|
invisible
|
||||||
size="sm"
|
size="sm"
|
||||||
tooltip={t('participants.muteParticipant', {
|
tooltip={
|
||||||
name,
|
isLocal(participant)
|
||||||
})}
|
? t('participants.muteYourself')
|
||||||
isDisabled={isDisabled}
|
: t('participants.muteParticipant', {
|
||||||
onPress={() => !isMuted && setIsAlertOpen(true)}
|
name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
isDisabled={isMuted}
|
||||||
|
onPress={() =>
|
||||||
|
!isMuted && isLocal(participant)
|
||||||
|
? muteParticipant(participant)
|
||||||
|
: setIsAlertOpen(true)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{isMuted ? (
|
{isMuted ? (
|
||||||
<RiMicOffLine color="gray" />
|
<RiMicOffFill color={'gray'} />
|
||||||
) : (
|
) : (
|
||||||
<ActiveSpeaker isSpeaking={isSpeaking} />
|
<RiMicFill
|
||||||
|
style={{
|
||||||
|
animation: isSpeaking ? 'pulse_mic 800ms infinite' : undefined,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
<MuteAlertDialog
|
<MuteAlertDialog
|
||||||
@@ -102,7 +116,6 @@ export const ParticipantListItem = ({
|
|||||||
}: ParticipantListItemProps) => {
|
}: ParticipantListItemProps) => {
|
||||||
const { t } = useTranslation('rooms')
|
const { t } = useTranslation('rooms')
|
||||||
const name = participant.name || participant.identity
|
const name = participant.name || participant.identity
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HStack
|
<HStack
|
||||||
role="listitem"
|
role="listitem"
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
"close": ""
|
"close": ""
|
||||||
},
|
},
|
||||||
"you": "",
|
"you": "",
|
||||||
|
"muteYourself": "",
|
||||||
"muteParticipant": "",
|
"muteParticipant": "",
|
||||||
"muteParticipantAlert": {
|
"muteParticipantAlert": {
|
||||||
"description": "",
|
"description": "",
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
"open": "Open {{name}} list",
|
"open": "Open {{name}} list",
|
||||||
"close": "Close {{name}} list"
|
"close": "Close {{name}} list"
|
||||||
},
|
},
|
||||||
|
"muteYourself": "Close your mic",
|
||||||
"muteParticipant": "Close the mic of {{name}}",
|
"muteParticipant": "Close the mic of {{name}}",
|
||||||
"muteParticipantAlert": {
|
"muteParticipantAlert": {
|
||||||
"description": "Mute {{name}} for all participants? {{name}} is the only person who can unmute themselves.",
|
"description": "Mute {{name}} for all participants? {{name}} is the only person who can unmute themselves.",
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
"open": "Ouvrir la liste {{name}}",
|
"open": "Ouvrir la liste {{name}}",
|
||||||
"close": "Fermer la liste {{name}}"
|
"close": "Fermer la liste {{name}}"
|
||||||
},
|
},
|
||||||
|
"muteYourself": "Couper votre micro",
|
||||||
"muteParticipant": "Couper le micro de {{name}}",
|
"muteParticipant": "Couper le micro de {{name}}",
|
||||||
"muteParticipantAlert": {
|
"muteParticipantAlert": {
|
||||||
"description": "Couper le micro de {{name}} pour tous les participants ? {{name}} est la seule personne habilitée à réactiver son micro",
|
"description": "Couper le micro de {{name}} pour tous les participants ? {{name}} est la seule personne habilitée à réactiver son micro",
|
||||||
|
|||||||
Reference in New Issue
Block a user