🚸(frontend) inform user when recording is saving

Saving a recording can take a bit of time, display a clear message to
inform user it can takes few minutes.
This commit is contained in:
lebaudantoine
2025-04-10 20:08:28 +02:00
committed by aleb_the_flash
parent f0742a0978
commit a079ceef71
8 changed files with 166 additions and 92 deletions

View File

@@ -14,20 +14,18 @@ import { RoomEvent } from 'livekit-client'
import { useTranslation } from 'react-i18next'
import { RecordingStatus, recordingStore } from '@/stores/recording'
import { CRISP_HELP_ARTICLE_RECORDING } from '@/utils/constants'
import {
useIsRecordingTransitioning,
useIsScreenRecordingStarted,
useIsTranscriptStarted,
} from '@/features/recording'
import { useIsRecordingTransitioning } from '@/features/recording'
import {
useNotifyParticipants,
NotificationType,
} from '@/features/notifications'
import posthog from 'posthog-js'
import { useSnapshot } from 'valtio/index'
export const ScreenRecordingSidePanel = () => {
const [isLoading, setIsLoading] = useState(false)
const recordingSnap = useSnapshot(recordingStore)
const { t } = useTranslation('rooms', { keyPrefix: 'screenRecording' })
const { notifyParticipants } = useNotifyParticipants()
@@ -37,8 +35,16 @@ export const ScreenRecordingSidePanel = () => {
const { mutateAsync: startRecordingRoom } = useStartRecording()
const { mutateAsync: stopRecordingRoom } = useStopRecording()
const isScreenRecordingStarted = useIsScreenRecordingStarted()
const isTranscriptStarted = useIsTranscriptStarted()
const statuses = useMemo(() => {
return {
isAnotherModeStarted:
recordingSnap.status == RecordingStatus.TRANSCRIPT_STARTED,
isStarted:
recordingSnap.status == RecordingStatus.SCREEN_RECORDING_STARTED,
isStopping:
recordingSnap.status == RecordingStatus.SCREEN_RECORDING_STOPPING,
}
}, [recordingSnap])
const room = useRoomContext()
const isRecordingTransitioning = useIsRecordingTransitioning()
@@ -84,8 +90,9 @@ export const ScreenRecordingSidePanel = () => {
}
const isDisabled = useMemo(
() => isLoading || isRecordingTransitioning || isTranscriptStarted,
[isLoading, isRecordingTransitioning, isTranscriptStarted]
() =>
isLoading || isRecordingTransitioning || statuses.isAnotherModeStarted,
[isLoading, isRecordingTransitioning, statuses]
)
return (
@@ -106,7 +113,7 @@ export const ScreenRecordingSidePanel = () => {
})}
/>
{isScreenRecordingStarted ? (
{statuses.isStarted ? (
<>
<H lvl={3} margin={false}>
{t('stop.heading')}
@@ -135,34 +142,57 @@ export const ScreenRecordingSidePanel = () => {
</>
) : (
<>
<H lvl={3} margin={false}>
{t('start.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
})}
>
{t('start.body')} <br />{' '}
<A href={CRISP_HELP_ARTICLE_RECORDING} target="_blank">
{t('start.linkMore')}
</A>
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleScreenRecording()}
data-attr="start-screen-recording"
size="sm"
variant="tertiary"
>
{t('start.button')}
</Button>
{statuses.isStopping ? (
<>
<H lvl={3} margin={false}>
{t('stopping.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
})}
>
{t('stopping.body')}
</Text>
</>
) : (
<>
<H lvl={3} margin={false}>
{t('start.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
})}
>
{t('start.body')} <br />{' '}
<A href={CRISP_HELP_ARTICLE_RECORDING} target="_blank">
{t('start.linkMore')}
</A>
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleScreenRecording()}
data-attr="start-screen-recording"
size="sm"
variant="tertiary"
>
{t('start.button')}
</Button>
</>
)}
</>
)}
</Div>

View File

@@ -6,12 +6,10 @@ import { useRoomId } from '@/features/rooms/livekit/hooks/useRoomId'
import { useRoomContext } from '@livekit/components-react'
import {
RecordingMode,
useHasRecordingAccess,
useIsRecordingTransitioning,
useStartRecording,
useStopRecording,
useIsScreenRecordingStarted,
useIsTranscriptStarted,
useIsRecordingTransitioning,
useHasRecordingAccess,
} from '../index'
import { useEffect, useMemo, useState } from 'react'
import { RoomEvent } from 'livekit-client'
@@ -23,15 +21,18 @@ import {
} from '@/utils/constants'
import { FeatureFlags } from '@/features/analytics/enums'
import {
useNotifyParticipants,
NotificationType,
useNotifyParticipants,
} from '@/features/notifications'
import posthog from 'posthog-js'
import { useSnapshot } from 'valtio/index'
export const TranscriptSidePanel = () => {
const [isLoading, setIsLoading] = useState(false)
const { t } = useTranslation('rooms', { keyPrefix: 'transcript' })
const recordingSnap = useSnapshot(recordingStore)
const { notifyParticipants } = useNotifyParticipants()
const hasTranscriptAccess = useHasRecordingAccess(
@@ -43,8 +44,15 @@ export const TranscriptSidePanel = () => {
const { mutateAsync: startRecordingRoom } = useStartRecording()
const { mutateAsync: stopRecordingRoom } = useStopRecording()
const isScreenRecordingStarted = useIsScreenRecordingStarted()
const isTranscriptStarted = useIsTranscriptStarted()
const statuses = useMemo(() => {
return {
isAnotherModeStarted:
recordingSnap.status == RecordingStatus.SCREEN_RECORDING_STARTED,
isStarted: recordingSnap.status == RecordingStatus.TRANSCRIPT_STARTED,
isStopping: recordingSnap.status == RecordingStatus.TRANSCRIPT_STOPPING,
}
}, [recordingSnap])
const isRecordingTransitioning = useIsRecordingTransitioning()
const room = useRoomContext()
@@ -87,8 +95,9 @@ export const TranscriptSidePanel = () => {
}
const isDisabled = useMemo(
() => isLoading || isRecordingTransitioning || isScreenRecordingStarted,
[isLoading, isRecordingTransitioning, isScreenRecordingStarted]
() =>
isLoading || isRecordingTransitioning || statuses.isAnotherModeStarted,
[isLoading, isRecordingTransitioning, statuses]
)
return (
@@ -137,7 +146,7 @@ export const TranscriptSidePanel = () => {
</>
) : (
<>
{isTranscriptStarted ? (
{statuses.isStarted ? (
<>
<H lvl={3} margin={false}>
{t('stop.heading')}
@@ -166,34 +175,57 @@ export const TranscriptSidePanel = () => {
</>
) : (
<>
<H lvl={3} margin={false}>
{t('start.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
})}
>
{t('start.body')} <br />{' '}
<A href={CRISP_HELP_ARTICLE_TRANSCRIPT} target="_blank">
{t('start.linkMore')}
</A>
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleTranscript()}
data-attr="start-transcript"
size="sm"
variant="tertiary"
>
{t('start.button')}
</Button>
{statuses.isStopping ? (
<>
<H lvl={3} margin={false}>
{t('stopping.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
})}
>
{t('stopping.body')}
</Text>
</>
) : (
<>
<H lvl={3} margin={false}>
{t('start.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
})}
>
{t('start.body')} <br />{' '}
<A href={CRISP_HELP_ARTICLE_TRANSCRIPT} target="_blank">
{t('start.linkMore')}
</A>
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleTranscript()}
data-attr="start-transcript"
size="sm"
variant="tertiary"
>
{t('start.button')}
</Button>
</>
)}
</>
)}
</>

View File

@@ -1,12 +0,0 @@
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

@@ -1,9 +1,5 @@
// hooks
export { useIsRecordingModeEnabled } from './hooks/useIsRecordingModeEnabled'
export {
useIsScreenRecordingStarted,
useIsTranscriptStarted,
} from './hooks/useIsRecordingStarted'
export { useIsRecordingTransitioning } from './hooks/useIsRecordingTransitioning'
export { useHasRecordingAccess } from './hooks/useHasRecordingAccess'

View File

@@ -207,6 +207,10 @@
"body": "",
"button": ""
},
"stopping": {
"heading": "",
"body": ""
},
"beta": {
"heading": "",
"body": "",

View File

@@ -212,6 +212,10 @@
"body": "The transcription of your meeting is in progress. You will receive the result by email once the meeting is finished.",
"button": "Stop transcription"
},
"stopping": {
"heading": "Saving your data…",
"body": "This process may take a few minutes. Thank you for your patience."
},
"beta": {
"heading": "Become a beta tester",
"body": "Record your meeting for later. You will receive a summary by email once the meeting is finished.",
@@ -225,6 +229,10 @@
"button": "Start recording",
"linkMore": "Learn more"
},
"stopping": {
"heading": "Saving your data…",
"body": "This process may take a few minutes. Thank you for your patience."
},
"stop": {
"heading": "Recording in progress…",
"body": "You will receive the result by email once the recording is complete.",

View File

@@ -212,6 +212,10 @@
"body": "La transcription de votre réunion est en cours. Vous recevrez le resultat par email une fois la réunion terminée.",
"button": "Arrêter la transcription"
},
"stopping": {
"heading": "Sauvegarde de vos données…",
"body": "Cette opération peut durer quelques minutes. Merci de votre patience."
},
"beta": {
"heading": "Devenez beta testeur",
"body": "Enregistrer votre réunion pour plus tard. Vous recevrez un compte-rendu par email une fois la réunion terminée.",
@@ -225,6 +229,10 @@
"button": "Démarrer l'enregistrement",
"linkMore": "En savoir plus"
},
"stopping": {
"heading": "Sauvegarde de vos données…",
"body": "Cette opération peut durer quelques minutes. Merci de votre patience."
},
"stop": {
"heading": "Enregistrement en cours …",
"body": "Vous recevrez le resultat par email une fois l'enregistrement terminé.",

View File

@@ -212,6 +212,10 @@
"body": "De transcriptie van uw vergadering is bezig. U ontvangt het resultaat per e-mail zodra de vergadering is afgelopen.",
"button": "Transcriptie stoppen"
},
"stopping": {
"heading": "Uw gegevens worden opgeslagen…",
"body": "Dit proces kan enkele minuten duren. Bedankt voor uw geduld."
},
"beta": {
"heading": "Word betatester",
"body": "Neem uw vergadering op voor later. U ontvangt een samenvatting per e-mail zodra de vergadering is afgelopen.",
@@ -225,6 +229,10 @@
"button": "Opname starten",
"linkMore": "Meer informatie"
},
"stopping": {
"heading": "Uw gegevens worden opgeslagen…",
"body": "Dit proces kan enkele minuten duren. Bedankt voor uw geduld."
},
"stop": {
"heading": "Opname bezig …",
"body": "Je ontvangt het resultaat per e-mail zodra de opname is voltooid.",