💩(frontend) mute remote participants
Messy code file organization, but functions are okay. Functional, but not well-designed and likely hard to maintain. Shipping it, creating technical debt here. Will be reused for interactions with LiveKit server API.
This commit is contained in:
committed by
aleb_the_flash
parent
c8cc9909ba
commit
e06e9d1496
@@ -0,0 +1,5 @@
|
||||
export const buildServerApiUrl = (origin: string, path: string) => {
|
||||
const sanitizedOrigin = origin.replace(/\/$/, '')
|
||||
const sanitizedPath = path.replace(/^\//, '')
|
||||
return `${sanitizedOrigin}/${sanitizedPath}`
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ApiError } from '@/api/ApiError'
|
||||
|
||||
export const fetchServerApi = async <T = Record<string, unknown>>(
|
||||
url: string,
|
||||
token: string,
|
||||
options?: RequestInit
|
||||
): Promise<T> => {
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
...options?.headers,
|
||||
},
|
||||
})
|
||||
const result = await response.json()
|
||||
if (!response.ok) {
|
||||
throw new ApiError(response.status, result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Participant, Track } from 'livekit-client'
|
||||
import Source = Track.Source
|
||||
import { fetchServerApi } from './fetchServerApi'
|
||||
import { buildServerApiUrl } from './buildServerApiUrl'
|
||||
import { useRoomData } from '../hooks/useRoomData'
|
||||
|
||||
export const useMuteParticipant = () => {
|
||||
const data = useRoomData()
|
||||
|
||||
const muteParticipant = (participant: Participant) => {
|
||||
if (!data || !data?.livekit) {
|
||||
throw new Error('Room data is not available')
|
||||
}
|
||||
const trackSid = participant.getTrackPublication(
|
||||
Source.Microphone
|
||||
)?.trackSid
|
||||
|
||||
if (!trackSid) {
|
||||
throw new Error('Missing audio track')
|
||||
}
|
||||
return fetchServerApi(
|
||||
buildServerApiUrl(
|
||||
data.livekit.url,
|
||||
'twirp/livekit.RoomService/MutePublishedTrack'
|
||||
),
|
||||
data.livekit.token,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
room: data.livekit.room,
|
||||
identity: participant.identity,
|
||||
muted: true,
|
||||
track_sid: trackSid,
|
||||
}),
|
||||
}
|
||||
)
|
||||
}
|
||||
return { muteParticipant }
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import { RiMicOffLine } from '@remixicon/react'
|
||||
import { TooltipWrapper } from '@/primitives/TooltipWrapper.tsx'
|
||||
import { Button, Dialog, P } from '@/primitives'
|
||||
import { useState } from 'react'
|
||||
import { useMuteParticipant } from '@/features/rooms/livekit/api/muteParticipant'
|
||||
|
||||
const MuteAlertDialog = ({
|
||||
isOpen,
|
||||
@@ -52,6 +53,7 @@ type MicIndicatorProps = {
|
||||
|
||||
const MicIndicator = ({ participant }: MicIndicatorProps) => {
|
||||
const { t } = useTranslation('rooms')
|
||||
const { muteParticipant } = useMuteParticipant()
|
||||
const { isMuted } = useTrackMutedIndicator({
|
||||
participant: participant,
|
||||
source: Source.Microphone,
|
||||
@@ -98,7 +100,9 @@ const MicIndicator = ({ participant }: MicIndicatorProps) => {
|
||||
</TooltipWrapper>
|
||||
<MuteAlertDialog
|
||||
isOpen={isAlertOpen}
|
||||
onSubmit={() => setIsAlertOpen(false)}
|
||||
onSubmit={() =>
|
||||
muteParticipant(participant).then(() => setIsAlertOpen(false))
|
||||
}
|
||||
onClose={() => setIsAlertOpen(false)}
|
||||
name={name}
|
||||
/>
|
||||
|
||||
12
src/frontend/src/features/rooms/livekit/hooks/useRoomData.ts
Normal file
12
src/frontend/src/features/rooms/livekit/hooks/useRoomData.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ApiRoom } from '@/features/rooms/api/ApiRoom'
|
||||
import { useRoomContext } from '@livekit/components-react'
|
||||
import { useParams } from 'wouter'
|
||||
import { keys } from '@/api/queryKeys'
|
||||
import { queryClient } from '@/api/queryClient'
|
||||
|
||||
export const useRoomData = (): ApiRoom | undefined => {
|
||||
const room = useRoomContext()
|
||||
const { roomId } = useParams()
|
||||
const queryKey = [keys.room, roomId, room.localParticipant.name]
|
||||
return queryClient.getQueryData<ApiRoom>(queryKey)
|
||||
}
|
||||
Reference in New Issue
Block a user