diff --git a/src/frontend/src/features/notifications/MainNotificationToast.tsx b/src/frontend/src/features/notifications/MainNotificationToast.tsx index 67724148..89e8e4be 100644 --- a/src/frontend/src/features/notifications/MainNotificationToast.tsx +++ b/src/frontend/src/features/notifications/MainNotificationToast.tsx @@ -104,6 +104,16 @@ export const MainNotificationToast = () => { { timeout: NotificationDuration.ALERT } ) break + case NotificationType.TranscriptionRequested: + case NotificationType.ScreenRecordingRequested: + toastQueue.add( + { + participant, + type: notification.type, + }, + { timeout: NotificationDuration.RECORDING_REQUESTED } + ) + break case NotificationType.PermissionsRemoved: { const removedSources = notification?.data?.removedSources if (!removedSources?.length) break diff --git a/src/frontend/src/features/notifications/NotificationDuration.ts b/src/frontend/src/features/notifications/NotificationDuration.ts index 23886db0..de51a059 100644 --- a/src/frontend/src/features/notifications/NotificationDuration.ts +++ b/src/frontend/src/features/notifications/NotificationDuration.ts @@ -13,4 +13,5 @@ export const NotificationDuration = { LOWER_HAND: ToastDuration.EXTRA_LONG, RECORDING_SAVING: ToastDuration.EXTRA_LONG, REACTION_RECEIVED: ToastDuration.SHORT, + RECORDING_REQUESTED: ToastDuration.LONG, } as const diff --git a/src/frontend/src/features/notifications/NotificationType.ts b/src/frontend/src/features/notifications/NotificationType.ts index 58ea6622..7eadc929 100644 --- a/src/frontend/src/features/notifications/NotificationType.ts +++ b/src/frontend/src/features/notifications/NotificationType.ts @@ -9,8 +9,10 @@ export enum NotificationType { TranscriptionStarted = 'transcriptionStarted', TranscriptionStopped = 'transcriptionStopped', TranscriptionLimitReached = 'transcriptionLimitReached', + TranscriptionRequested = 'transcriptionRequested', ScreenRecordingStarted = 'screenRecordingStarted', ScreenRecordingStopped = 'screenRecordingStopped', + ScreenRecordingRequested = 'screenRecordingRequested', ScreenRecordingLimitReached = 'screenRecordingLimitReached', RecordingSaving = 'recordingSaving', PermissionsRemoved = 'permissionsRemoved', diff --git a/src/frontend/src/features/notifications/components/ToastRecordingRequest.tsx b/src/frontend/src/features/notifications/components/ToastRecordingRequest.tsx new file mode 100644 index 00000000..1d88ebb1 --- /dev/null +++ b/src/frontend/src/features/notifications/components/ToastRecordingRequest.tsx @@ -0,0 +1,83 @@ +import { useToast } from '@react-aria/toast' +import { useMemo, useRef } from 'react' + +import { StyledToastContainer, ToastProps } from './Toast' +import { HStack } from '@/styled-system/jsx' +import { useTranslation } from 'react-i18next' +import { NotificationType } from '../NotificationType' +import { Button } from '@/primitives' +import { css } from '@/styled-system/css' +import { useSidePanel } from '@/features/rooms/livekit/hooks/useSidePanel' + +export function ToastRecordingRequest({ + state, + ...props +}: Readonly) { + const { t } = useTranslation('notifications') + const ref = useRef(null) + const { toastProps, contentProps } = useToast(props, state, ref) + const participant = props.toast.content.participant + const type = props.toast.content.type + + const { + isTranscriptOpen, + openTranscript, + isScreenRecordingOpen, + openScreenRecording, + } = useSidePanel() + + const options = useMemo(() => { + switch (type) { + case NotificationType.TranscriptionRequested: + return { + key: 'transcript.requested', + isMenuOpen: isTranscriptOpen, + openMenu: openTranscript, + } + case NotificationType.ScreenRecordingRequested: + return { + key: 'screenRecording.requested', + isMenuOpen: isScreenRecordingOpen, + openMenu: openScreenRecording, + } + default: + return + } + }, [ + type, + isTranscriptOpen, + isScreenRecordingOpen, + openTranscript, + openScreenRecording, + ]) + + if (!options) return + + return ( + + + {t(options.key, { + name: participant?.name, + })} + {!options.isMenuOpen && ( + + )} + + + ) +} diff --git a/src/frontend/src/features/notifications/components/ToastRegion.tsx b/src/frontend/src/features/notifications/components/ToastRegion.tsx index 24c724a0..64a3a321 100644 --- a/src/frontend/src/features/notifications/components/ToastRegion.tsx +++ b/src/frontend/src/features/notifications/components/ToastRegion.tsx @@ -12,6 +12,7 @@ import { ToastLowerHand } from './ToastLowerHand' import { ToastAnyRecording } from './ToastAnyRecording' import { ToastRecordingSaving } from './ToastRecordingSaving' import { ToastPermissionsRemoved } from './ToastPermissionsRemoved' +import { ToastRecordingRequest } from './ToastRecordingRequest' interface ToastRegionProps extends AriaToastRegionProps { state: ToastState @@ -52,6 +53,12 @@ const renderToast = ( case NotificationType.ScreenRecordingLimitReached: return + case NotificationType.TranscriptionRequested: + case NotificationType.ScreenRecordingRequested: + return ( + + ) + case NotificationType.RecordingSaving: return ( diff --git a/src/frontend/src/features/recording/components/NoAccessView.tsx b/src/frontend/src/features/recording/components/NoAccessView.tsx index 3ce279a2..48790346 100644 --- a/src/frontend/src/features/recording/components/NoAccessView.tsx +++ b/src/frontend/src/features/recording/components/NoAccessView.tsx @@ -2,14 +2,25 @@ import { A, Div, H, Text } from '@/primitives' import { css } from '@/styled-system/css' import { useTranslation } from 'react-i18next' import { LoginPrompt } from './LoginPrompt' +import { RequestRecording } from './RequestRecording' import { useUser } from '@/features/auth' -import { VStack } from '@/styled-system/jsx' +import { HStack, VStack } from '@/styled-system/jsx' + +const Divider = ({ label }: { label: string }) => ( + +
+ {label} +
+ +) interface NoAccessViewProps { i18nKeyPrefix: string i18nKey: string helpArticle?: string imagePath: string + handleRequest: () => Promise + isActive: boolean } export const NoAccessView = ({ @@ -17,6 +28,8 @@ export const NoAccessView = ({ i18nKey, helpArticle, imagePath, + handleRequest, + isActive, }: NoAccessViewProps) => { const { isLoggedIn } = useUser() const { t } = useTranslation('rooms', { keyPrefix: i18nKeyPrefix }) @@ -34,20 +47,18 @@ export const NoAccessView = ({ src={imagePath} alt="" className={css({ - minHeight: '309px', - height: '309px', + minHeight: '250px', + height: '250px', marginBottom: '1rem', - '@media (max-height: 700px)': { + marginTop: '-16px', + '@media (max-height: 900px)': { height: 'auto', minHeight: 'auto', - maxHeight: '45%', - marginBottom: '0.3rem', + maxHeight: '25%', + marginBottom: '0.75rem', }, - '@media (max-height: 530px)': { - height: 'auto', - minHeight: 'auto', - maxHeight: '40%', - marginBottom: '0.1rem', + '@media (max-height: 770px)': { + display: 'none', }, })} /> @@ -82,6 +93,17 @@ export const NoAccessView = ({ body={t(`${i18nKey}.login.body`)} /> )} + {!isLoggedIn && !isActive && ( + + )} + {!isActive && ( + + )}
) } diff --git a/src/frontend/src/features/recording/components/RequestRecording.tsx b/src/frontend/src/features/recording/components/RequestRecording.tsx new file mode 100644 index 00000000..9cef50c4 --- /dev/null +++ b/src/frontend/src/features/recording/components/RequestRecording.tsx @@ -0,0 +1,87 @@ +import { Button, H, Text } from '@/primitives' +import { css } from '@/styled-system/css' +import { HStack } from '@/styled-system/jsx' +import { useEffect, useRef, useState } from 'react' +import { Spinner } from '@/primitives/Spinner.tsx' +import { NotificationDuration } from '@/features/notifications/NotificationDuration' + +interface RequestRecordingProps { + heading: string + body: string + buttonLabel: string + handleRequest: () => Promise +} + +export const RequestRecording = ({ + heading, + body, + buttonLabel, + handleRequest, +}: RequestRecordingProps) => { + const [isDisabled, setIsDisabled] = useState(false) + const timeoutRef = useRef() + + useEffect(() => { + return () => { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current) + } + } + }, []) + + const onPress = async () => { + setIsDisabled(true) + + try { + await handleRequest() + } catch { + setIsDisabled(false) + return + } + + timeoutRef.current = setTimeout(() => { + setIsDisabled(false) + }, NotificationDuration.RECORDING_REQUESTED) + } + + return ( +
+ + person_raised_hand + + {heading} + + + + {body} + +
+ +
+
+ ) +} diff --git a/src/frontend/src/features/recording/components/ScreenRecordingSidePanel.tsx b/src/frontend/src/features/recording/components/ScreenRecordingSidePanel.tsx index 04dab7e8..8523abbd 100644 --- a/src/frontend/src/features/recording/components/ScreenRecordingSidePanel.tsx +++ b/src/frontend/src/features/recording/components/ScreenRecordingSidePanel.tsx @@ -57,6 +57,13 @@ export const ScreenRecordingSidePanel = () => { const room = useRoomContext() const { openTranscript } = useSidePanel() + const handleRequestScreenRecording = async () => { + await notifyParticipants({ + type: NotificationType.ScreenRecordingRequested, + }) + posthog.capture('screen-recording-requested', {}) + } + const handleScreenRecording = async () => { if (!roomId) { console.warn('No room ID found') @@ -105,6 +112,8 @@ export const ScreenRecordingSidePanel = () => { i18nKey="notAdminOrOwner" helpArticle={data?.support?.help_article_recording} imagePath="/assets/intro-slider/4.png" + handleRequest={handleRequestScreenRecording} + isActive={statuses.isActive} /> ) } diff --git a/src/frontend/src/features/recording/components/TranscriptSidePanel.tsx b/src/frontend/src/features/recording/components/TranscriptSidePanel.tsx index 82661635..84ac9d9e 100644 --- a/src/frontend/src/features/recording/components/TranscriptSidePanel.tsx +++ b/src/frontend/src/features/recording/components/TranscriptSidePanel.tsx @@ -69,6 +69,13 @@ export const TranscriptSidePanel = () => { const room = useRoomContext() const { openScreenRecording } = useSidePanel() + const handleRequestTranscription = async () => { + await notifyParticipants({ + type: NotificationType.TranscriptionRequested, + }) + posthog.capture('transcript-requested', {}) + } + const handleTranscript = async () => { if (!roomId) { console.warn('No room ID found') @@ -124,6 +131,8 @@ export const TranscriptSidePanel = () => { i18nKey="notAdminOrOwner" helpArticle={data?.support?.help_article_transcript} imagePath="/assets/intro-slider/3.png" + handleRequest={handleRequestTranscription} + isActive={statuses.isActive} /> ) } @@ -135,6 +144,8 @@ export const TranscriptSidePanel = () => { i18nKey="premium" helpArticle={data?.support?.help_article_transcript} imagePath="/assets/intro-slider/3.png" + handleRequest={handleRequestTranscription} + isActive={statuses.isActive} /> ) } diff --git a/src/frontend/src/locales/de/notifications.json b/src/frontend/src/locales/de/notifications.json index 99df3c1b..049c00f7 100644 --- a/src/frontend/src/locales/de/notifications.json +++ b/src/frontend/src/locales/de/notifications.json @@ -30,12 +30,14 @@ "transcript": { "started": "{{name}} hat die Transkription des Treffens gestartet.", "stopped": "{{name}} hat die Transkription des Treffens gestoppt.", - "limitReached": "Die Transkription hat die maximal zulässige Dauer überschritten und wird automatisch gespeichert." + "limitReached": "Die Transkription hat die maximal zulässige Dauer überschritten und wird automatisch gespeichert.", + "requested": "{{name}} will die Transkription starten." }, "screenRecording": { "started": "{{name}} hat die Aufzeichnung des Treffens gestartet.", "stopped": "{{name}} hat die Aufzeichnung des Treffens gestoppt.", - "limitReached": "Die Aufzeichnung hat die maximal zulässige Dauer überschritten und wird automatisch gespeichert." + "limitReached": "Die Aufzeichnung hat die maximal zulässige Dauer überschritten und wird automatisch gespeichert.", + "requested": "{{name}} will die Aufnahme starten." }, "recordingSave": { "transcript": { @@ -46,5 +48,6 @@ "message": "Wir finalisieren Ihre Aufnahme! Sie erhalten eine E-Mail an {{email}}, sobald sie fertig ist.", "default": "Wir finalisieren Ihre Aufnahme! Sie erhalten eine E-Mail, sobald sie fertig ist." } - } + }, + "openMenu": "Menü öffnen" } diff --git a/src/frontend/src/locales/de/rooms.json b/src/frontend/src/locales/de/rooms.json index 8b2a5c48..ce9bc9c8 100644 --- a/src/frontend/src/locales/de/rooms.json +++ b/src/frontend/src/locales/de/rooms.json @@ -332,18 +332,30 @@ "heading": "Zugriff eingeschränkt", "body": "Aus Sicherheitsgründen kann nur der Ersteller oder ein Administrator des Meetings eine Transkription (Beta) starten.", "linkMore": "Mehr erfahren", + "dividerLabel": "ODER", "login": { "heading": "Anmeldung erforderlich", "body": "Nur der Ersteller des Meetings oder ein Administrator kann die Transkription starten. Melden Sie sich an, um Ihre Berechtigungen zu überprüfen." + }, + "request": { + "heading": "Anfrage an Moderator", + "body": "Der Moderator wird benachrichtigt und kann die Transkription starten.", + "buttonLabel": "Anfordern" } }, "premium": { "heading": "Premium-Funktion", "body": "Diese Funktion ist öffentlichen Bediensteten vorbehalten. Wenn Ihre E-Mail-Adresse nicht autorisiert ist, kontaktieren Sie bitte den Support, um Zugriff zu erhalten.", "linkMore": "Mehr erfahren", + "dividerLabel": "ODER", "login": { "heading": "Anmeldung erforderlich", "body": "Nur der Ersteller des Meetings oder ein Administrator kann die Transkription starten. Melden Sie sich an, um Ihre Berechtigungen zu überprüfen." + }, + "request": { + "heading": "Anfrage an Moderator", + "body": "Der Moderator wird benachrichtigt und kann die Transkription starten.", + "buttonLabel": "Anfordern" } } }, @@ -370,9 +382,15 @@ "heading": "Zugriff eingeschränkt", "body": "Aus Sicherheitsgründen kann nur der Ersteller oder ein Administrator des Meetings eine Videoaufnahme (Beta) starten.", "linkMore": "Mehr erfahren", + "dividerLabel": "ODER", "login": { "heading": "Anmeldung erforderlich", "body": "Nur der Ersteller der Besprechung oder ein Administrator kann die Aufzeichnung starten. Melden Sie sich an, um Ihre Berechtigungen zu überprüfen." + }, + "request": { + "heading": "Aufnahme anfordern", + "body": "Der Moderator wird benachrichtigt und kann die Aufnahme für Sie starten.", + "buttonLabel": "Anfrage senden" } }, "durationMessage": "(begrenzt auf {{max_duration}})" diff --git a/src/frontend/src/locales/en/notifications.json b/src/frontend/src/locales/en/notifications.json index c9de8dfc..2e0a264c 100644 --- a/src/frontend/src/locales/en/notifications.json +++ b/src/frontend/src/locales/en/notifications.json @@ -30,12 +30,14 @@ "transcript": { "started": "{{name}} started the meeting transcription.", "stopped": "{{name}} stopped the meeting transcription.", - "limitReached": "The transcription has exceeded the maximum allowed duration and will be automatically saved." + "limitReached": "The transcription has exceeded the maximum allowed duration and will be automatically saved.", + "requested": "{{name}} wants to start the meeting transcription." }, "screenRecording": { "started": "{{name}} started the meeting recording.", "stopped": "{{name}} stopped the meeting recording.", - "limitReached": "The recording has exceeded the maximum allowed duration and will be automatically saved." + "limitReached": "The recording has exceeded the maximum allowed duration and will be automatically saved.", + "requested": "{{name}} wants to start the meeting recording." }, "recordingSave": { "transcript": { @@ -46,5 +48,6 @@ "message": "Your recording is being saved! We’ll send a notification to {{email}} as soon as it’s ready.", "default": "Your recording is being saved! We’ll send a notification to your email as soon as it’s ready." } - } + }, + "openMenu": "Open menu" } diff --git a/src/frontend/src/locales/en/rooms.json b/src/frontend/src/locales/en/rooms.json index 101a9717..3de1c040 100644 --- a/src/frontend/src/locales/en/rooms.json +++ b/src/frontend/src/locales/en/rooms.json @@ -332,18 +332,30 @@ "heading": "Restricted Access", "body": "For security reasons, only the meeting creator or an admin can start a transcription (beta).", "linkMore": "Learn more", + "dividerLabel": "OR", "login": { "heading": "Login Required", "body": "Only the meeting creator or an admin can start a transcription. Log in to verify your permissions." + }, + "request": { + "heading": "Request Transcription", + "body": "The host will be notified and can enable transcription for you.", + "buttonLabel": "Request" } }, "premium": { "heading": "Premium feature", "body": "This feature is reserved for public agents. If your email address is not authorized, please contact support to get access.", "linkMore": "Learn more", + "dividerLabel": "OR", "login": { "heading": "You are not logged in!", "body": "You must be logged in to use this feature. Please log in, then try again." + }, + "request": { + "heading": "Request Transcription", + "body": "The host will be notified and can enable transcription for you.", + "buttonLabel": "Request" } } }, @@ -370,9 +382,15 @@ "heading": "Restricted Access", "body": "For security reasons, only the meeting creator or an admin can start a recording (beta).", "linkMore": "Learn more", + "dividerLabel": "OR", "login": { "heading": "Login Required", "body": "Only the meeting creator or an admin can start screen recording. Log in to verify your permissions." + }, + "request": { + "heading": "Request Recording", + "body": "The host will be notified and can enable recording for you.", + "buttonLabel": "Request" } }, "durationMessage": "(limited to {{max_duration}}) " diff --git a/src/frontend/src/locales/fr/notifications.json b/src/frontend/src/locales/fr/notifications.json index bfec3048..0b3bd8e4 100644 --- a/src/frontend/src/locales/fr/notifications.json +++ b/src/frontend/src/locales/fr/notifications.json @@ -30,12 +30,14 @@ "transcript": { "started": "{{name}} a démarré la transcription de la réunion.", "stopped": "{{name}} a arrêté la transcription de la réunion.", - "limitReached": "La transcription a dépassé la durée maximale autorisée, elle va être automatiquement sauvegardée." + "limitReached": "La transcription a dépassé la durée maximale autorisée, elle va être automatiquement sauvegardée.", + "requested": "{{name}} a demandé à démarrer la transcription." }, "screenRecording": { "started": "{{name}} a démarré l'enregistrement de la réunion.", "stopped": "{{name}} a arrêté l'enregistrement de la réunion.", - "limitReached": "L'enregistrement a dépassé la durée maximale autorisée, il va être automatiquement sauvegardé." + "limitReached": "L'enregistrement a dépassé la durée maximale autorisée, il va être automatiquement sauvegardé.", + "requested": "{{name}} a demandé à démarrer l'enregistrement." }, "recordingSave": { "transcript": { @@ -46,5 +48,6 @@ "message": "Nous finalisons votre enregistrement ! Vous recevrez un e-mail à {{email}} dès qu’il sera prêt.", "default": "Nous finalisons votre enregistrement ! Vous recevrez un e-mail dès qu’il sera prêt." } - } + }, + "openMenu": "Ouvrir le menu" } diff --git a/src/frontend/src/locales/fr/rooms.json b/src/frontend/src/locales/fr/rooms.json index 31d2e6d3..68fb810e 100644 --- a/src/frontend/src/locales/fr/rooms.json +++ b/src/frontend/src/locales/fr/rooms.json @@ -332,18 +332,30 @@ "heading": "Accès restreint", "body": "Pour des raisons de sécurité, seul le créateur ou un administrateur de la réunion peut lancer une transcription (beta).", "linkMore": "En savoir plus", + "dividerLabel": "OU", "login": { "heading": "Connexion requise", "body": "Seul le créateur de la réunion ou un administrateur peut démarrer la transcription. Connectez-vous pour vérifier vos autorisations." + }, + "request": { + "heading": "Demander à l'organisateur", + "body": "L'hôte recevra une notification et pourra démarrer la transcription pour vous.", + "buttonLabel": "Demander" } }, "premium": { "heading": "Fonctionnalité premium", "body": "Cette fonctionnalité est réservée aux agents publics. Si votre adresse email n’est pas autorisée, contactez le support pour obtenir l'accès.", "linkMore": "En savoir plus", + "dividerLabel": "OU", "login": { "heading": "Vous n'êtes pas connecté !", "body": "Vous devez être connecté pour utiliser cette fonctionnalité. Connectez-vous, puis réessayez." + }, + "request": { + "heading": "Demander à l'organisateur", + "body": "L'hôte recevra une notification et pourra démarrer la transcription pour vous.", + "buttonLabel": "Demander" } } }, @@ -370,9 +382,15 @@ "heading": "Accès restreint", "body": "Pour des raisons de sécurité, seul le créateur ou un administrateur de la réunion peut lancer un enregistrement (beta).", "linkMore": "En savoir plus", + "dividerLabel": "OU", "login": { "heading": "Connexion requise", "body": "Seul le créateur de la réunion ou un administrateur peut démarrer l'enregistrement. Connectez-vous pour vérifier vos autorisations." + }, + "request": { + "heading": "Demander à l'organisateur", + "body": "L'hôte recevra une notification et pourra démarrer l'enregistrement pour vous.", + "buttonLabel": "Demander" } }, "durationMessage": "(limité à {{max_duration}}) " diff --git a/src/frontend/src/locales/nl/notifications.json b/src/frontend/src/locales/nl/notifications.json index 76c27469..116fe94f 100644 --- a/src/frontend/src/locales/nl/notifications.json +++ b/src/frontend/src/locales/nl/notifications.json @@ -30,12 +30,14 @@ "transcript": { "started": "{{name}} is de transcriptie van de vergadering gestart.", "stopped": "{{name}} heeft de transcriptie van de vergadering gestopt.", - "limitReached": "De transcriptie heeft de maximaal toegestane duur overschreden en wordt automatisch opgeslagen." + "limitReached": "De transcriptie heeft de maximaal toegestane duur overschreden en wordt automatisch opgeslagen.", + "requested": "{{name}} wil graag de transcriptie starten." }, "screenRecording": { "started": "{{name}} is begonnen met het opnemen van de vergadering.", "stopped": "{{name}} is gestopt met het opnemen van de vergadering.", - "limitReached": "De opname heeft de maximaal toegestane duur overschreden en wordt automatisch opgeslagen." + "limitReached": "De opname heeft de maximaal toegestane duur overschreden en wordt automatisch opgeslagen.", + "requested": "{{name}} wil graag de opname starten." }, "recordingSave": { "transcript": { @@ -46,5 +48,6 @@ "message": "We zijn uw opname aan het voltooien! U ontvangt een e-mail op {{email}} zodra deze klaar is.", "default": "We zijn uw opname aan het voltooien! U ontvangt een e-mail zodra deze klaar is." } - } + }, + "openMenu": "Menu openen" } diff --git a/src/frontend/src/locales/nl/rooms.json b/src/frontend/src/locales/nl/rooms.json index 26851cd6..c4d5f9c2 100644 --- a/src/frontend/src/locales/nl/rooms.json +++ b/src/frontend/src/locales/nl/rooms.json @@ -332,18 +332,30 @@ "heading": "Toegang beperkt", "body": "Om veiligheidsredenen kan alleen de maker of een beheerder van de vergadering een transcriptie starten (beta).", "linkMore": "Meer informatie", + "dividerLabel": "OF", "login": { "heading": "Inloggen vereist", "body": "Alleen de maker van de vergadering of een beheerder kan de transcriptie starten. Log in om uw machtigingen te controleren." + }, + "request": { + "heading": "Transcriptie aanvragen", + "body": "De host wordt op de hoogte gebracht en kan de transcriptie voor u inschakelen.", + "buttonLabel": "Aanvragen" } }, "premium": { "heading": "Premiumfunctie", "body": "Deze functie is voorbehouden aan openbare medewerkers. Als uw e-mailadres niet is toegestaan, neem dan contact op met de support om toegang te krijgen.", "linkMore": "Meer informatie", + "dividerLabel": "OF", "login": { "heading": "Inloggen vereist", "body": "Alleen de maker van de vergadering of een beheerder kan de transcriptie starten. Log in om uw machtigingen te controleren." + }, + "request": { + "heading": "Transcriptie aanvragen", + "body": "De host wordt op de hoogte gebracht en kan de transcriptie voor u inschakelen.", + "buttonLabel": "Aanvragen" } } }, @@ -370,9 +382,15 @@ "heading": "Toegang beperkt", "body": "Om veiligheidsredenen kan alleen de maker of een beheerder van de vergadering een opname starten (beta).", "linkMore": "Meer informatie", + "dividerLabel": "OF", "login": { "heading": "Inloggen vereist", "body": "Alleen de maker van de vergadering of een beheerder kan de opname starten. Log in om uw machtigingen te controleren." + }, + "request": { + "heading": "Opname aanvragen", + "body": "De host wordt op de hoogte gebracht en kan de opname voor u inschakelen.", + "buttonLabel": "Aanvragen" } }, "durationMessage": "(beperkt tot {{max_duration}})"