♻️(frontend) encapsulate recording maximum duration handling

Centralize the logic to compute, internationalize, and present the maximum
recording duration in a human-readable way, reducing duplication across the
codebase.
This commit is contained in:
lebaudantoine
2025-12-31 19:15:07 +01:00
committed by aleb_the_flash
parent 5e1705d259
commit f7d463f380
5 changed files with 33 additions and 20 deletions

View File

@@ -1,8 +1,7 @@
import { useTranslation } from 'react-i18next'
import { Button, Dialog, P } from '@/primitives'
import { HStack } from '@/styled-system/jsx'
import { useConfig } from '@/api/useConfig'
import humanizeDuration from 'humanize-duration'
import { useHumanizeRecordingMaxDuration } from '@/features/recording'
export const LimitReachedAlertDialog = ({
isOpen,
@@ -11,19 +10,19 @@ export const LimitReachedAlertDialog = ({
isOpen: boolean
onClose: () => void
}) => {
const { t, i18n } = useTranslation('rooms', {
const { t } = useTranslation('rooms', {
keyPrefix: 'recordingStateToast.limitReachedAlert',
})
const { data } = useConfig()
const maxDuration = useHumanizeRecordingMaxDuration()
return (
<Dialog isOpen={isOpen} role="alertdialog" title={t('title')}>
<P>
{t('description', {
duration_message: data?.recording?.max_duration
duration_message: maxDuration
? t('durationMessage', {
duration: humanizeDuration(data?.recording?.max_duration, {
language: i18n.language,
}),
duration: maxDuration,
})
: '',
})}

View File

@@ -8,6 +8,7 @@ import {
useHasFeatureWithoutAdminRights,
useStartRecording,
useStopRecording,
useHumanizeRecordingMaxDuration,
} from '@/features/recording'
import { useEffect, useMemo, useState } from 'react'
import { ConnectionState, RoomEvent } from 'livekit-client'
@@ -27,8 +28,6 @@ import posthog from 'posthog-js'
import { useSnapshot } from 'valtio/index'
import { Spinner } from '@/primitives/Spinner'
import { useConfig } from '@/api/useConfig'
import humanizeDuration from 'humanize-duration'
import i18n from 'i18next'
import { FeatureFlags } from '@/features/analytics/enums'
import { NoAccessView } from './NoAccessView'
import { HStack, VStack } from '@/styled-system/jsx'
@@ -36,6 +35,8 @@ import { Checkbox } from '@/primitives/Checkbox'
export const ScreenRecordingSidePanel = () => {
const { data } = useConfig()
const recordingMaxDuration = useHumanizeRecordingMaxDuration()
const [isLoading, setIsLoading] = useState(false)
const recordingSnap = useSnapshot(recordingStore)
const { t } = useTranslation('rooms', { keyPrefix: 'screenRecording' })
@@ -175,11 +176,9 @@ export const ScreenRecordingSidePanel = () => {
{t('heading')}
</H>
<Text variant="body" fullWidth>
{data?.recording?.max_duration
{recordingMaxDuration
? t('body', {
max_duration: humanizeDuration(data?.recording?.max_duration, {
language: i18n.language,
}),
max_duration: recordingMaxDuration,
})
: t('bodyWithoutMaxDuration')}{' '}
{data?.support?.help_article_recording && (

View File

@@ -9,6 +9,7 @@ import {
useStartRecording,
useStopRecording,
useHasFeatureWithoutAdminRights,
useHumanizeRecordingMaxDuration,
} from '../index'
import { useEffect, useMemo, useState } from 'react'
import { ConnectionState, RoomEvent } from 'livekit-client'
@@ -28,8 +29,6 @@ import posthog from 'posthog-js'
import { useSnapshot } from 'valtio/index'
import { Spinner } from '@/primitives/Spinner'
import { useConfig } from '@/api/useConfig'
import humanizeDuration from 'humanize-duration'
import i18n from 'i18next'
import { HStack, VStack } from '@/styled-system/jsx'
import { Checkbox } from '@/primitives/Checkbox.tsx'
@@ -42,6 +41,7 @@ import { NoAccessView } from './NoAccessView'
export const TranscriptSidePanel = () => {
const { data } = useConfig()
const recordingMaxDuration = useHumanizeRecordingMaxDuration()
const [isLoading, setIsLoading] = useState(false)
const { t } = useTranslation('rooms', { keyPrefix: 'transcript' })
@@ -203,11 +203,9 @@ export const TranscriptSidePanel = () => {
{t('heading')}
</H>
<Text variant="body" fullWidth>
{data?.recording?.max_duration
{recordingMaxDuration
? t('body', {
max_duration: humanizeDuration(data?.recording?.max_duration, {
language: i18n.language,
}),
max_duration: recordingMaxDuration,
})
: t('bodyWithoutMaxDuration')}{' '}
{data?.support?.help_article_transcript && (

View File

@@ -0,0 +1,16 @@
import { useMemo } from 'react'
import humanizeDuration from 'humanize-duration'
import i18n from 'i18next'
import { useConfig } from '@/api/useConfig'
export const useHumanizeRecordingMaxDuration = () => {
const { data } = useConfig()
return useMemo(() => {
if (!data?.recording?.max_duration) return
return humanizeDuration(data?.recording?.max_duration, {
language: i18n.language,
})
}, [data])
}

View File

@@ -3,6 +3,7 @@ export { useIsRecordingModeEnabled } from './hooks/useIsRecordingModeEnabled'
export { useHasRecordingAccess } from './hooks/useHasRecordingAccess'
export { useIsRecordingActive } from './hooks/useIsRecordingActive'
export { useHasFeatureWithoutAdminRights } from './hooks/useHasFeatureWithoutAdminRights'
export { useHumanizeRecordingMaxDuration } from './hooks/useHumanizeRecordingMaxDuration'
// api
export { useStartRecording } from './api/startRecording'