🩹(frontend) avoid having the two recording modes concurrently

Implement mutual exclusivity between transcript and screen recording modes
to prevent both from being active simultaneously. Add validation logic to
ensure users can only enable one recording type at a time.
This commit is contained in:
lebaudantoine
2025-04-07 21:33:38 +02:00
committed by aleb_the_flash
parent 468d09dc3b
commit c08c3efdbb
4 changed files with 52 additions and 19 deletions

View File

@@ -14,9 +14,13 @@ import { RoomEvent } from 'livekit-client'
import { useTranslation } from 'react-i18next'
import { NotificationPayload } from '@/features/notifications/NotificationPayload'
import { NotificationType } from '@/features/notifications/NotificationType'
import { useSnapshot } from 'valtio/index'
import { RecordingStatus, recordingStore } from '@/stores/recording'
import { CRISP_HELP_ARTICLE_RECORDING } from '@/utils/constants'
import { useIsRecordingTransitioning } from '../hooks/useIsRecordingTransitioning'
import {
useIsScreenRecordingStarted,
useIsTranscriptStarted,
} from '../hooks/useIsRecordingStarted'
export const ScreenRecording = () => {
const [isLoading, setIsLoading] = useState(false)
@@ -27,9 +31,11 @@ export const ScreenRecording = () => {
const { mutateAsync: startRecordingRoom } = useStartRecording()
const { mutateAsync: stopRecordingRoom } = useStopRecording()
const recordingSnap = useSnapshot(recordingStore)
const isScreenRecordingStarted = useIsScreenRecordingStarted()
const isTranscriptStarted = useIsTranscriptStarted()
const room = useRoomContext()
const isRecordingTransitioning = useIsRecordingTransitioning()
useEffect(() => {
const handleRecordingStatusChanged = () => {
@@ -52,7 +58,7 @@ export const ScreenRecording = () => {
})
}
const handleTranscript = async () => {
const handleScreenRecording = async () => {
if (!roomId) {
console.warn('No room ID found')
return
@@ -78,11 +84,8 @@ export const ScreenRecording = () => {
}
const isDisabled = useMemo(
() =>
isLoading ||
recordingSnap.status == RecordingStatus.SCREEN_RECORDING_STARTING ||
recordingSnap.status == RecordingStatus.SCREEN_RECORDING_STOPPING,
[isLoading, recordingSnap]
() => isLoading || isRecordingTransitioning || isTranscriptStarted,
[isLoading, isRecordingTransitioning, isTranscriptStarted]
)
return (
@@ -103,7 +106,7 @@ export const ScreenRecording = () => {
})}
/>
{room.isRecording ? (
{isScreenRecordingStarted ? (
<>
<Text>{t('stop.heading')}</Text>
<Text
@@ -120,7 +123,7 @@ export const ScreenRecording = () => {
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleTranscript()}
onPress={() => handleScreenRecording()}
data-attr="stop-transcript"
size="sm"
variant="tertiary"
@@ -149,7 +152,7 @@ export const ScreenRecording = () => {
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleTranscript()}
onPress={() => handleScreenRecording()}
data-attr="start-transcript"
size="sm"
variant="tertiary"

View File

@@ -14,13 +14,17 @@ import { RoomEvent } from 'livekit-client'
import { useTranslation } from 'react-i18next'
import { NotificationPayload } from '@/features/notifications/NotificationPayload'
import { NotificationType } from '@/features/notifications/NotificationType'
import { useSnapshot } from 'valtio/index'
import { RecordingStatus, recordingStore } from '@/stores/recording'
import { useHasRecordingAccess } from '../hooks/useHasScreenRecordingAccess'
import {
BETA_USERS_FORM_URL,
CRISP_HELP_ARTICLE_TRANSCRIPT,
} from '@/utils/constants'
import { useIsRecordingTransitioning } from '../hooks/useIsRecordingTransitioning'
import {
useIsScreenRecordingStarted,
useIsTranscriptStarted,
} from '../hooks/useIsRecordingStarted'
export const Transcript = () => {
const [isLoading, setIsLoading] = useState(false)
@@ -35,7 +39,9 @@ export const Transcript = () => {
const { mutateAsync: startRecordingRoom } = useStartRecording()
const { mutateAsync: stopRecordingRoom } = useStopRecording()
const recordingSnap = useSnapshot(recordingStore)
const isScreenRecordingStarted = useIsScreenRecordingStarted()
const isTranscriptStarted = useIsTranscriptStarted()
const isRecordingTransitioning = useIsRecordingTransitioning()
const room = useRoomContext()
@@ -83,11 +89,8 @@ export const Transcript = () => {
}
const isDisabled = useMemo(
() =>
isLoading ||
recordingSnap.status === RecordingStatus.TRANSCRIPT_STARTING ||
recordingSnap.status === RecordingStatus.TRANSCRIPT_STOPPING,
[isLoading, recordingSnap]
() => isLoading || isRecordingTransitioning || isScreenRecordingStarted,
[isLoading, isRecordingTransitioning, isScreenRecordingStarted]
)
return (
@@ -136,7 +139,7 @@ export const Transcript = () => {
</>
) : (
<>
{room.isRecording ? (
{isTranscriptStarted ? (
<>
<Text>{t('stop.heading')}</Text>
<Text

View File

@@ -0,0 +1,12 @@
import { useSnapshot } from 'valtio'
import { RecordingStatus, recordingStore } from '@/stores/recording'
export const useIsScreenRecordingStarted = () => {
const recordingSnap = useSnapshot(recordingStore)
return recordingSnap.status == RecordingStatus.SCREEN_RECORDING_STARTED
}
export const useIsTranscriptStarted = () => {
const recordingSnap = useSnapshot(recordingStore)
return recordingSnap.status == RecordingStatus.TRANSCRIPT_STARTED
}

View File

@@ -0,0 +1,15 @@
import { useSnapshot } from 'valtio'
import { RecordingStatus, recordingStore } from '@/stores/recording'
export const useIsRecordingTransitioning = () => {
const recordingSnap = useSnapshot(recordingStore)
const transitionalStates = [
RecordingStatus.TRANSCRIPT_STARTING,
RecordingStatus.TRANSCRIPT_STOPPING,
RecordingStatus.SCREEN_RECORDING_STARTING,
RecordingStatus.SCREEN_RECORDING_STOPPING,
]
return transitionalStates.includes(recordingSnap.status)
}