diff --git a/src/frontend/src/features/recording/components/LimitDescription.tsx b/src/frontend/src/features/recording/components/LimitDescription.tsx
new file mode 100644
index 00000000..b4d2232f
--- /dev/null
+++ b/src/frontend/src/features/recording/components/LimitDescription.tsx
@@ -0,0 +1,43 @@
+import { useTranslation } from 'react-i18next'
+
+import { A, Text } from '@/primitives'
+import { useConfig } from '@/api/useConfig'
+import { useHumanizeDuration } from '@/hooks/useHumanizeDuration'
+import { useMemo } from 'react'
+
+export const LimitDescription = ({
+ keyPrefix,
+ supportArticleLink,
+}: {
+ keyPrefix?: 'transcript' | 'screenRecording'
+ supportArticleLink?: string
+}) => {
+ const { data } = useConfig()
+ const { t } = useTranslation('rooms', { keyPrefix })
+
+ const formatter = useHumanizeDuration()
+
+ const maxRecordingDuration = useMemo(
+ () => formatter(data?.recording?.max_duration),
+ [data?.recording?.max_duration, formatter]
+ )
+
+ return (
+
+ {maxRecordingDuration
+ ? t('body', { max_duration: maxRecordingDuration })
+ : t('bodyWithoutMaxDuration')}{' '}
+ {supportArticleLink && (
+
+ {t('linkMore')}
+
+ )}
+
+ )
+}
diff --git a/src/frontend/src/features/recording/components/LimitReachedAlertDialog.tsx b/src/frontend/src/features/recording/components/LimitReachedAlertDialog.tsx
index ad2481e5..3f901558 100644
--- a/src/frontend/src/features/recording/components/LimitReachedAlertDialog.tsx
+++ b/src/frontend/src/features/recording/components/LimitReachedAlertDialog.tsx
@@ -1,64 +1,81 @@
import { useTranslation } from 'react-i18next'
import { Button, Dialog, P } from '@/primitives'
import { HStack } from '@/styled-system/jsx'
-import { useHumanizeRecordingMaxDuration } from '@/features/recording'
-import { useEffect, useState } from 'react'
+import { useEffect, useMemo, useState } from 'react'
import { NotificationType } from '@/features/notifications'
-import { useIsAdminOrOwner } from '@/features/rooms/livekit/hooks/useIsAdminOrOwner'
+import { AdminOrOwnerOnly } from '@/features/rooms/components/AdminOrOwnerOnly'
import { RoomEvent } from 'livekit-client'
import { decodeNotificationDataReceived } from '@/features/notifications/utils'
import { useRoomContext } from '@livekit/components-react'
+import { useHumanizeDuration } from '@/hooks/useHumanizeDuration'
+import { useConfig } from '@/api/useConfig'
-export const LimitReachedAlertDialog = () => {
- const [isAlertOpen, setIsAlertOpen] = useState(false)
-
+// Isolated into its own component so the `useHumanizeDuration` hook (and the
+// `humanize-duration` library it pulls in) is only loaded when the modal is
+// actually opened.
+const LimitDescription = () => {
+ const { data } = useConfig()
const { t } = useTranslation('rooms', {
keyPrefix: 'recordingStateToast.limitReachedAlert',
})
+ const formatter = useHumanizeDuration()
+ const formattedDuration = useMemo(
+ () => formatter(data?.recording?.max_duration),
+ [formatter, data?.recording?.max_duration]
+ )
+
+ return (
+
+ {t('description', {
+ duration_message: formattedDuration
+ ? t('durationMessage', {
+ duration: formattedDuration,
+ })
+ : '',
+ })}
+
+ )
+}
+
+const LimitReachedAlertDialogContent = () => {
+ const [isOpen, setIsOpen] = useState(false)
+ const { t } = useTranslation('rooms', {
+ keyPrefix: 'recordingStateToast.limitReachedAlert',
+ })
const room = useRoomContext()
- const isAdminOrOwner = useIsAdminOrOwner()
- const maxDuration = useHumanizeRecordingMaxDuration()
useEffect(() => {
- const handleDataReceived = (payload: Uint8Array) => {
- if (!isAdminOrOwner) return
-
+ const handleLimitNotification = (payload: Uint8Array) => {
const notification = decodeNotificationDataReceived(payload)
-
if (
notification?.type === NotificationType.TranscriptionLimitReached ||
notification?.type === NotificationType.ScreenRecordingLimitReached
) {
- setIsAlertOpen(true)
+ setIsOpen(true)
}
}
-
- room.on(RoomEvent.DataReceived, handleDataReceived)
+ room.on(RoomEvent.DataReceived, handleLimitNotification)
return () => {
- room.off(RoomEvent.DataReceived, handleDataReceived)
+ room.off(RoomEvent.DataReceived, handleLimitNotification)
}
- }, [room, isAdminOrOwner])
-
- if (!isAdminOrOwner) return null
+ }, [room])
return (
-