mirror of
https://github.com/suitenumerique/meet.git
synced 2026-09-04 06:35:38 +00:00
🐛(frontend) restore automatic lower-hand on speaking
Following the re-rendering optimization refactoring, the automatic lower-hand feature broke: the way `isSpeaking` was read no longer made sense once we limited how often components in the app re-render. Fix the detection so the raised hand is again lowered automatically when the participant starts speaking, without relying on frequent re-renders.
This commit is contained in:
@@ -22,6 +22,7 @@ and this project adheres to
|
||||
|
||||
- 🐛(backend) allow any printable ASCII characters in user sub field #1673
|
||||
- 🐛(frontend) keep the sending resolution picked while the camera is off #1667
|
||||
- 🐛(frontend) restore automatic lower-hand on speaking
|
||||
|
||||
## [1.30.0] - 2026-09-01
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import { RiHand } from '@remixicon/react'
|
||||
import { ToggleButton } from '@/primitives'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { useRoomContext } from '@livekit/components-react'
|
||||
import { useIsSpeaking, useRoomContext } from '@livekit/components-react'
|
||||
import { useRaisedHand } from '@/features/rooms/livekit/hooks/useRaisedHand'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import {
|
||||
@@ -25,11 +25,11 @@ export const HandToggle = ({
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'controls.hand' })
|
||||
|
||||
const room = useRoomContext()
|
||||
const { isHandRaised, toggleRaisedHand } = useRaisedHand({
|
||||
const { isHandRaised, toggleRaisedHand, lowerHand } = useRaisedHand({
|
||||
participant: room.localParticipant,
|
||||
})
|
||||
|
||||
const isSpeaking = room.localParticipant.isSpeaking
|
||||
const isSpeaking = useIsSpeaking(room.localParticipant)
|
||||
const speakingTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
const [hasShownToast, setHasShownToast] = useState(false)
|
||||
|
||||
@@ -57,9 +57,10 @@ export const HandToggle = ({
|
||||
|
||||
if (shouldShowToast && !speakingTimerRef.current) {
|
||||
speakingTimerRef.current = setTimeout(() => {
|
||||
speakingTimerRef.current = null
|
||||
setHasShownToast(true)
|
||||
const onClose = () => {
|
||||
if (isHandRaised) toggleRaisedHand()
|
||||
lowerHand()
|
||||
resetToastState()
|
||||
}
|
||||
showLowerHandToast(room.localParticipant, onClose)
|
||||
@@ -70,7 +71,17 @@ export const HandToggle = ({
|
||||
speakingTimerRef.current = null
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isSpeaking, isHandRaised, hasShownToast, toggleRaisedHand])
|
||||
}, [isSpeaking, isHandRaised, hasShownToast, lowerHand])
|
||||
|
||||
// Clear any pending timer on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (speakingTimerRef.current) {
|
||||
clearTimeout(speakingTimerRef.current)
|
||||
speakingTimerRef.current = null
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
const tooltipLabel = isHandRaised ? 'lower' : 'raise'
|
||||
|
||||
|
||||
@@ -86,5 +86,16 @@ export function useRaisedHand({ participant }: useRaisedHandProps) {
|
||||
}
|
||||
}
|
||||
|
||||
return { isHandRaised, toggleRaisedHand }
|
||||
const lowerHand = async () => {
|
||||
if (!isLocal(participant)) return
|
||||
try {
|
||||
await raiseHand(false)
|
||||
} catch (e) {
|
||||
reportError('generic_failure', e, {
|
||||
context: 'lower_raised_hand',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return { isHandRaised, toggleRaisedHand, lowerHand }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user