♻️(frontend) factorize notifyParticipants
Extract notifyParticipants in a proper hook to avoid duplication.
This commit is contained in:
committed by
aleb_the_flash
parent
ba9d22f6c8
commit
ff09c3d969
@@ -0,0 +1,37 @@
|
|||||||
|
import { useRoomContext } from '@livekit/components-react'
|
||||||
|
import { NotificationType } from '../NotificationType'
|
||||||
|
import { NotificationPayload } from '../NotificationPayload'
|
||||||
|
|
||||||
|
export const useNotifyParticipants = () => {
|
||||||
|
const room = useRoomContext()
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const notifyParticipants = async <T extends Record<string, any>>(options: {
|
||||||
|
type: NotificationType
|
||||||
|
destinationIdentities?: string[]
|
||||||
|
additionalData?: T
|
||||||
|
reliable?: boolean
|
||||||
|
}): Promise<void> => {
|
||||||
|
const {
|
||||||
|
type,
|
||||||
|
destinationIdentities,
|
||||||
|
additionalData = {} as T,
|
||||||
|
reliable = true,
|
||||||
|
} = options
|
||||||
|
|
||||||
|
const payload: NotificationPayload & T = {
|
||||||
|
type,
|
||||||
|
...additionalData,
|
||||||
|
}
|
||||||
|
|
||||||
|
const encoder = new TextEncoder()
|
||||||
|
const data = encoder.encode(JSON.stringify(payload))
|
||||||
|
|
||||||
|
await room.localParticipant.publishData(data, {
|
||||||
|
reliable,
|
||||||
|
destinationIdentities,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return { notifyParticipants }
|
||||||
|
}
|
||||||
2
src/frontend/src/features/notifications/index.ts
Normal file
2
src/frontend/src/features/notifications/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export { useNotifyParticipants } from './hooks/useNotifyParticipants'
|
||||||
|
export { NotificationType } from './NotificationType'
|
||||||
@@ -3,25 +3,15 @@ import Source = Track.Source
|
|||||||
import { fetchServerApi } from './fetchServerApi'
|
import { fetchServerApi } from './fetchServerApi'
|
||||||
import { buildServerApiUrl } from './buildServerApiUrl'
|
import { buildServerApiUrl } from './buildServerApiUrl'
|
||||||
import { useRoomData } from '../hooks/useRoomData'
|
import { useRoomData } from '../hooks/useRoomData'
|
||||||
import { useRoomContext } from '@livekit/components-react'
|
import {
|
||||||
import { NotificationType } from '@/features/notifications/NotificationType'
|
useNotifyParticipants,
|
||||||
import { NotificationPayload } from '@/features/notifications/NotificationPayload'
|
NotificationType,
|
||||||
|
} from '@/features/notifications'
|
||||||
|
|
||||||
export const useMuteParticipant = () => {
|
export const useMuteParticipant = () => {
|
||||||
const data = useRoomData()
|
const data = useRoomData()
|
||||||
const room = useRoomContext()
|
|
||||||
|
|
||||||
const notifyParticipant = async (participant: Participant) => {
|
const { notifyParticipants } = useNotifyParticipants()
|
||||||
const encoder = new TextEncoder()
|
|
||||||
const payload: NotificationPayload = {
|
|
||||||
type: NotificationType.ParticipantMuted,
|
|
||||||
}
|
|
||||||
const data = encoder.encode(JSON.stringify(payload))
|
|
||||||
await room.localParticipant.publishData(data, {
|
|
||||||
reliable: true,
|
|
||||||
destinationIdentities: [participant.identity],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const muteParticipant = async (participant: Participant) => {
|
const muteParticipant = async (participant: Participant) => {
|
||||||
if (!data || !data?.livekit) {
|
if (!data || !data?.livekit) {
|
||||||
@@ -53,7 +43,10 @@ export const useMuteParticipant = () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
await notifyParticipant(participant)
|
await notifyParticipants({
|
||||||
|
type: NotificationType.ParticipantMuted,
|
||||||
|
destinationIdentities: [participant.identity],
|
||||||
|
})
|
||||||
|
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import {
|
|||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { RoomEvent } from 'livekit-client'
|
import { RoomEvent } from 'livekit-client'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { NotificationPayload } from '@/features/notifications/NotificationPayload'
|
|
||||||
import { NotificationType } from '@/features/notifications/NotificationType'
|
|
||||||
import { RecordingStatus, recordingStore } from '@/stores/recording'
|
import { RecordingStatus, recordingStore } from '@/stores/recording'
|
||||||
import { CRISP_HELP_ARTICLE_RECORDING } from '@/utils/constants'
|
import { CRISP_HELP_ARTICLE_RECORDING } from '@/utils/constants'
|
||||||
import {
|
import {
|
||||||
@@ -22,10 +20,17 @@ import {
|
|||||||
useIsTranscriptStarted,
|
useIsTranscriptStarted,
|
||||||
} from '@/features/recording'
|
} from '@/features/recording'
|
||||||
|
|
||||||
|
import {
|
||||||
|
useNotifyParticipants,
|
||||||
|
NotificationType,
|
||||||
|
} from '@/features/notifications'
|
||||||
|
|
||||||
export const ScreenRecording = () => {
|
export const ScreenRecording = () => {
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const { t } = useTranslation('rooms', { keyPrefix: 'screenRecording' })
|
const { t } = useTranslation('rooms', { keyPrefix: 'screenRecording' })
|
||||||
|
|
||||||
|
const { notifyParticipants } = useNotifyParticipants()
|
||||||
|
|
||||||
const roomId = useRoomId()
|
const roomId = useRoomId()
|
||||||
|
|
||||||
const { mutateAsync: startRecordingRoom } = useStartRecording()
|
const { mutateAsync: startRecordingRoom } = useStartRecording()
|
||||||
@@ -47,17 +52,6 @@ export const ScreenRecording = () => {
|
|||||||
}
|
}
|
||||||
}, [room])
|
}, [room])
|
||||||
|
|
||||||
const notifyParticipant = async (status: NotificationType) => {
|
|
||||||
const encoder = new TextEncoder()
|
|
||||||
const payload: NotificationPayload = {
|
|
||||||
type: status,
|
|
||||||
}
|
|
||||||
const data = encoder.encode(JSON.stringify(payload))
|
|
||||||
await room.localParticipant.publishData(data, {
|
|
||||||
reliable: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleScreenRecording = async () => {
|
const handleScreenRecording = async () => {
|
||||||
if (!roomId) {
|
if (!roomId) {
|
||||||
console.warn('No room ID found')
|
console.warn('No room ID found')
|
||||||
@@ -67,15 +61,19 @@ export const ScreenRecording = () => {
|
|||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
if (room.isRecording) {
|
if (room.isRecording) {
|
||||||
await stopRecordingRoom({ id: roomId })
|
await stopRecordingRoom({ id: roomId })
|
||||||
await notifyParticipant(NotificationType.ScreenRecordingStopped)
|
|
||||||
recordingStore.status = RecordingStatus.SCREEN_RECORDING_STOPPING
|
recordingStore.status = RecordingStatus.SCREEN_RECORDING_STOPPING
|
||||||
|
await notifyParticipants({
|
||||||
|
type: NotificationType.ScreenRecordingStopped,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
await startRecordingRoom({
|
await startRecordingRoom({
|
||||||
id: roomId,
|
id: roomId,
|
||||||
mode: RecordingMode.ScreenRecording,
|
mode: RecordingMode.ScreenRecording,
|
||||||
})
|
})
|
||||||
await notifyParticipant(NotificationType.ScreenRecordingStarted)
|
|
||||||
recordingStore.status = RecordingStatus.SCREEN_RECORDING_STARTING
|
recordingStore.status = RecordingStatus.SCREEN_RECORDING_STARTING
|
||||||
|
await notifyParticipants({
|
||||||
|
type: NotificationType.ScreenRecordingStarted,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to handle transcript:', error)
|
console.error('Failed to handle transcript:', error)
|
||||||
|
|||||||
@@ -16,19 +16,23 @@ import {
|
|||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { RoomEvent } from 'livekit-client'
|
import { RoomEvent } from 'livekit-client'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { NotificationPayload } from '@/features/notifications/NotificationPayload'
|
|
||||||
import { NotificationType } from '@/features/notifications/NotificationType'
|
|
||||||
import { RecordingStatus, recordingStore } from '@/stores/recording'
|
import { RecordingStatus, recordingStore } from '@/stores/recording'
|
||||||
import {
|
import {
|
||||||
BETA_USERS_FORM_URL,
|
BETA_USERS_FORM_URL,
|
||||||
CRISP_HELP_ARTICLE_TRANSCRIPT,
|
CRISP_HELP_ARTICLE_TRANSCRIPT,
|
||||||
} from '@/utils/constants'
|
} from '@/utils/constants'
|
||||||
import { FeatureFlags } from '@/features/analytics/enums'
|
import { FeatureFlags } from '@/features/analytics/enums'
|
||||||
|
import {
|
||||||
|
useNotifyParticipants,
|
||||||
|
NotificationType,
|
||||||
|
} from '@/features/notifications'
|
||||||
|
|
||||||
export const Transcript = () => {
|
export const Transcript = () => {
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const { t } = useTranslation('rooms', { keyPrefix: 'transcript' })
|
const { t } = useTranslation('rooms', { keyPrefix: 'transcript' })
|
||||||
|
|
||||||
|
const { notifyParticipants } = useNotifyParticipants()
|
||||||
|
|
||||||
const hasTranscriptAccess = useHasRecordingAccess(
|
const hasTranscriptAccess = useHasRecordingAccess(
|
||||||
RecordingMode.Transcript,
|
RecordingMode.Transcript,
|
||||||
FeatureFlags.Transcript
|
FeatureFlags.Transcript
|
||||||
@@ -54,17 +58,6 @@ export const Transcript = () => {
|
|||||||
}
|
}
|
||||||
}, [room])
|
}, [room])
|
||||||
|
|
||||||
const notifyParticipant = async (status: NotificationType) => {
|
|
||||||
const encoder = new TextEncoder()
|
|
||||||
const payload: NotificationPayload = {
|
|
||||||
type: status,
|
|
||||||
}
|
|
||||||
const data = encoder.encode(JSON.stringify(payload))
|
|
||||||
await room.localParticipant.publishData(data, {
|
|
||||||
reliable: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleTranscript = async () => {
|
const handleTranscript = async () => {
|
||||||
if (!roomId) {
|
if (!roomId) {
|
||||||
console.warn('No room ID found')
|
console.warn('No room ID found')
|
||||||
@@ -74,12 +67,16 @@ export const Transcript = () => {
|
|||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
if (room.isRecording) {
|
if (room.isRecording) {
|
||||||
await stopRecordingRoom({ id: roomId })
|
await stopRecordingRoom({ id: roomId })
|
||||||
await notifyParticipant(NotificationType.TranscriptionStopped)
|
|
||||||
recordingStore.status = RecordingStatus.TRANSCRIPT_STOPPING
|
recordingStore.status = RecordingStatus.TRANSCRIPT_STOPPING
|
||||||
|
await notifyParticipants({
|
||||||
|
type: NotificationType.TranscriptionStopped,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
await startRecordingRoom({ id: roomId, mode: RecordingMode.Transcript })
|
await startRecordingRoom({ id: roomId, mode: RecordingMode.Transcript })
|
||||||
await notifyParticipant(NotificationType.TranscriptionStarted)
|
|
||||||
recordingStore.status = RecordingStatus.TRANSCRIPT_STARTING
|
recordingStore.status = RecordingStatus.TRANSCRIPT_STARTING
|
||||||
|
await notifyParticipants({
|
||||||
|
type: NotificationType.TranscriptionStarted,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to handle transcript:', error)
|
console.error('Failed to handle transcript:', error)
|
||||||
|
|||||||
Reference in New Issue
Block a user