♻️(frontend) simplify raised hand notification
Listen to metadata changed events instead of messaging the whole room. Less code, might be less clean, to be discussed.
This commit is contained in:
committed by
aleb_the_flash
parent
cd9e7c8a1f
commit
c50a749293
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useRoomContext } from '@livekit/components-react'
|
import { useRoomContext } from '@livekit/components-react'
|
||||||
import { Participant, RemoteParticipant, RoomEvent } from 'livekit-client'
|
import { Participant, RoomEvent } from 'livekit-client'
|
||||||
import { ToastProvider, toastQueue } from './components/ToastProvider'
|
import { ToastProvider, toastQueue } from './components/ToastProvider'
|
||||||
import { NotificationType } from './NotificationType'
|
import { NotificationType } from './NotificationType'
|
||||||
import { Div } from '@/primitives'
|
import { Div } from '@/primitives'
|
||||||
@@ -50,31 +50,32 @@ export const MainNotificationToast = () => {
|
|||||||
}
|
}
|
||||||
}, [room])
|
}, [room])
|
||||||
|
|
||||||
// fixme - close all related toasters when hands are lowered remotely
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const decoder = new TextDecoder()
|
|
||||||
|
|
||||||
const handleNotificationReceived = (
|
const handleNotificationReceived = (
|
||||||
payload: Uint8Array,
|
prevMetadataStr: string | undefined,
|
||||||
participant?: RemoteParticipant
|
participant: Participant
|
||||||
) => {
|
) => {
|
||||||
if (!participant) {
|
if (!participant) return
|
||||||
return
|
if (isMobileBrowser()) return
|
||||||
}
|
if (participant.isLocal) return
|
||||||
if (isMobileBrowser()) {
|
|
||||||
return
|
const prevMetadata = JSON.parse(prevMetadataStr || '{}')
|
||||||
}
|
const metadata = JSON.parse(participant.metadata || '{}')
|
||||||
const notification = decoder.decode(payload)
|
|
||||||
|
if (prevMetadata.raised == metadata.raised) return
|
||||||
|
|
||||||
const existingToast = toastQueue.visibleToasts.find(
|
const existingToast = toastQueue.visibleToasts.find(
|
||||||
(toast) =>
|
(toast) =>
|
||||||
toast.content.participant === participant &&
|
toast.content.participant === participant &&
|
||||||
toast.content.type === NotificationType.Raised
|
toast.content.type === NotificationType.Raised
|
||||||
)
|
)
|
||||||
if (existingToast && notification === NotificationType.Lowered) {
|
|
||||||
|
if (existingToast && prevMetadata.raised && !metadata.raised) {
|
||||||
toastQueue.close(existingToast.key)
|
toastQueue.close(existingToast.key)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!existingToast && notification === NotificationType.Raised) {
|
|
||||||
|
if (!existingToast && !prevMetadata.raised && metadata.raised) {
|
||||||
triggerNotificationSound(NotificationType.Raised)
|
triggerNotificationSound(NotificationType.Raised)
|
||||||
toastQueue.add(
|
toastQueue.add(
|
||||||
{
|
{
|
||||||
@@ -86,10 +87,10 @@ export const MainNotificationToast = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
room.on(RoomEvent.DataReceived, handleNotificationReceived)
|
room.on(RoomEvent.ParticipantMetadataChanged, handleNotificationReceived)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
room.off(RoomEvent.DataReceived, handleNotificationReceived)
|
room.off(RoomEvent.ParticipantMetadataChanged, handleNotificationReceived)
|
||||||
}
|
}
|
||||||
}, [room, triggerNotificationSound])
|
}, [room, triggerNotificationSound])
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { ToggleButton } from '@/primitives'
|
|||||||
import { css } from '@/styled-system/css'
|
import { css } from '@/styled-system/css'
|
||||||
import { useRoomContext } from '@livekit/components-react'
|
import { useRoomContext } from '@livekit/components-react'
|
||||||
import { useRaisedHand } from '@/features/rooms/livekit/hooks/useRaisedHand'
|
import { useRaisedHand } from '@/features/rooms/livekit/hooks/useRaisedHand'
|
||||||
import { NotificationType } from '@/features/notifications/NotificationType'
|
|
||||||
|
|
||||||
export const HandToggle = () => {
|
export const HandToggle = () => {
|
||||||
const { t } = useTranslation('rooms', { keyPrefix: 'controls.hand' })
|
const { t } = useTranslation('rooms', { keyPrefix: 'controls.hand' })
|
||||||
@@ -16,17 +15,6 @@ export const HandToggle = () => {
|
|||||||
|
|
||||||
const tooltipLabel = isHandRaised ? 'lower' : 'raise'
|
const tooltipLabel = isHandRaised ? 'lower' : 'raise'
|
||||||
|
|
||||||
const notifyOtherParticipants = (isHandRaised: boolean) => {
|
|
||||||
room.localParticipant.publishData(
|
|
||||||
new TextEncoder().encode(
|
|
||||||
!isHandRaised ? NotificationType.Raised : NotificationType.Lowered
|
|
||||||
),
|
|
||||||
{
|
|
||||||
reliable: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
@@ -40,10 +28,7 @@ export const HandToggle = () => {
|
|||||||
aria-label={t(tooltipLabel)}
|
aria-label={t(tooltipLabel)}
|
||||||
tooltip={t(tooltipLabel)}
|
tooltip={t(tooltipLabel)}
|
||||||
isSelected={isHandRaised}
|
isSelected={isHandRaised}
|
||||||
onPress={() => {
|
onPress={() => toggleRaisedHand()}
|
||||||
notifyOtherParticipants(isHandRaised)
|
|
||||||
toggleRaisedHand()
|
|
||||||
}}
|
|
||||||
data-attr={`controls-hand-${tooltipLabel}`}
|
data-attr={`controls-hand-${tooltipLabel}`}
|
||||||
>
|
>
|
||||||
<RiHand />
|
<RiHand />
|
||||||
|
|||||||
Reference in New Issue
Block a user