From 3da3641a19b77ed038bd71712f570ea3f87068fb Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Wed, 11 Sep 2024 23:26:40 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20(frontend)=20Add=20start/stop=20?= =?UTF-8?q?audio=20recording=20menu=20item?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Functional but not mergeable—remote participants need to be informed when recording starts, including the egress ID to prevent collisions. Quick and dirty implementation. --- .../features/rooms/livekit/api/recordRoom.ts | 19 ++++++- .../controls/Options/OptionsMenuItems.tsx | 2 + .../controls/Options/RecordingMenuItem.tsx | 51 +++++++++++++++++++ src/frontend/src/stores/egress.tsx | 9 ++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/frontend/src/features/rooms/livekit/components/controls/Options/RecordingMenuItem.tsx create mode 100644 src/frontend/src/stores/egress.tsx diff --git a/src/frontend/src/features/rooms/livekit/api/recordRoom.ts b/src/frontend/src/features/rooms/livekit/api/recordRoom.ts index 6c405c4d..c463c5d0 100644 --- a/src/frontend/src/features/rooms/livekit/api/recordRoom.ts +++ b/src/frontend/src/features/rooms/livekit/api/recordRoom.ts @@ -35,5 +35,22 @@ export const useRecordRoom = () => { } ) } - return { recordRoom } + + const stopRecordingRoom = (egressId: string) => { + if (!data || !data?.livekit) { + throw new Error('Room data is not available') + } + return fetchServerApi( + buildServerApiUrl(data.livekit.url, '/twirp/livekit.Egress/StopEgress'), + data.livekit.token, + { + method: 'POST', + body: JSON.stringify({ + egressId, + }), + } + ) + } + + return { recordRoom, stopRecordingRoom } } diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsMenuItems.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsMenuItems.tsx index 63b45855..490f98cc 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsMenuItems.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsMenuItems.tsx @@ -8,6 +8,7 @@ import { MenuItem, Menu as RACMenu } from 'react-aria-components' import { useTranslation } from 'react-i18next' import { Dispatch, SetStateAction } from 'react' import { DialogState } from '@/features/rooms/livekit/components/controls/Options/OptionsButton' +import { RecordingMenuItem } from './RecordingMenuItem.tsx' // @todo try refactoring it to use MenuList component export const OptionsMenuItems = ({ @@ -47,6 +48,7 @@ export const OptionsMenuItems = ({ {t('options.items.settings')} + ) } diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Options/RecordingMenuItem.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Options/RecordingMenuItem.tsx new file mode 100644 index 00000000..89720cb2 --- /dev/null +++ b/src/frontend/src/features/rooms/livekit/components/controls/Options/RecordingMenuItem.tsx @@ -0,0 +1,51 @@ +import { MenuItem } from 'react-aria-components' +import { menuItemRecipe } from '@/primitives/menuItemRecipe.ts' +import { RiPauseCircleLine, RiRecordCircleLine } from '@remixicon/react' +import { useRecordRoom } from '@/features/rooms/livekit/api/recordRoom.ts' +import { useState } from 'react' +import { egressStore } from '@/stores/egress.tsx' +import { useSnapshot } from 'valtio' + +export const RecordingMenuItem = () => { + const { recordRoom, stopRecordingRoom } = useRecordRoom() + + const egressSnap = useSnapshot(egressStore) + const egressId = egressSnap.egressId + + const [isPending, setIsPending] = useState(false) + + const handleAction = async () => { + if (egressId) { + setIsPending(true) + const response = await stopRecordingRoom(egressId) + console.log(response) + egressStore.egressId = undefined + setIsPending(false) + } else { + setIsPending(true) + const response = await recordRoom() + egressStore.egressId = response['egress_id'] as string + setIsPending(false) + } + } + + return ( + + {egressId ? ( + <> + + Stop recording room + + ) : ( + <> + + Record room + + )} + + ) +} diff --git a/src/frontend/src/stores/egress.tsx b/src/frontend/src/stores/egress.tsx new file mode 100644 index 00000000..64786d8b --- /dev/null +++ b/src/frontend/src/stores/egress.tsx @@ -0,0 +1,9 @@ +import { proxy } from 'valtio' + +type State = { + egressId: string | undefined +} + +export const egressStore = proxy({ + egressId: undefined, +})