From d075d60d19f4eebd2192378518e965ddc749371d Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Wed, 16 Jul 2025 12:11:20 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8(frontend)=20notify=20all=20partici?= =?UTF-8?q?pants=20when=20recording/transcription=20stops?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Broadcast limit-reached notifications to all room participants, not just owner, to ensure everyone knows recording has stopped due to duration limits. --- .../notifications/MainNotificationToast.tsx | 24 +++++++++++-------- .../components/ToastAnyRecording.tsx | 6 ++++- .../notifications/components/ToastJoined.tsx | 3 +++ .../components/ToastMessageReceived.tsx | 2 +- .../notifications/components/ToastMuted.tsx | 3 +++ .../components/ToastProvider.tsx | 2 +- .../notifications/components/ToastRaised.tsx | 2 ++ .../notifications/components/ToastRegion.tsx | 2 ++ .../src/locales/de/notifications.json | 6 +++-- .../src/locales/en/notifications.json | 6 +++-- .../src/locales/fr/notifications.json | 6 +++-- .../src/locales/nl/notifications.json | 6 +++-- 12 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/frontend/src/features/notifications/MainNotificationToast.tsx b/src/frontend/src/features/notifications/MainNotificationToast.tsx index 2210e8fd..de13b22d 100644 --- a/src/frontend/src/features/notifications/MainNotificationToast.tsx +++ b/src/frontend/src/features/notifications/MainNotificationToast.tsx @@ -72,29 +72,33 @@ export const MainNotificationToast = () => { ) => { const notification = decodeNotificationDataReceived(payload) - if (!participant || !notification) return + if (!notification) return switch (notification.type) { case NotificationType.ParticipantMuted: - toastQueue.add( - { - participant, - type: NotificationType.ParticipantMuted, - }, - { timeout: NotificationDuration.ALERT } - ) + if (participant) { + toastQueue.add( + { + participant, + type: NotificationType.ParticipantMuted, + }, + { timeout: NotificationDuration.ALERT } + ) + } + break case NotificationType.ReactionReceived: - if (notification.data?.emoji) + if (notification.data?.emoji && participant) handleEmoji(notification.data.emoji, participant) break case NotificationType.TranscriptionStarted: case NotificationType.TranscriptionStopped: case NotificationType.ScreenRecordingStarted: case NotificationType.ScreenRecordingStopped: + case NotificationType.TranscriptionLimitReached: + case NotificationType.ScreenRecordingLimitReached: toastQueue.add( { - participant, type: notification.type, }, { timeout: NotificationDuration.ALERT } diff --git a/src/frontend/src/features/notifications/components/ToastAnyRecording.tsx b/src/frontend/src/features/notifications/components/ToastAnyRecording.tsx index c29c7645..817a3bf9 100644 --- a/src/frontend/src/features/notifications/components/ToastAnyRecording.tsx +++ b/src/frontend/src/features/notifications/components/ToastAnyRecording.tsx @@ -19,10 +19,14 @@ export function ToastAnyRecording({ state, ...props }: ToastProps) { return 'transcript.started' case NotificationType.TranscriptionStopped: return 'transcript.stopped' + case NotificationType.TranscriptionLimitReached: + return 'transcript.limitReached' case NotificationType.ScreenRecordingStarted: return 'screenRecording.started' case NotificationType.ScreenRecordingStopped: return 'screenRecording.stopped' + case NotificationType.ScreenRecordingLimitReached: + return 'screenRecording.limitReached' default: return } @@ -40,7 +44,7 @@ export function ToastAnyRecording({ state, ...props }: ToastProps) { gap={0} > {t(key, { - name: participant.name, + name: participant?.name, })} diff --git a/src/frontend/src/features/notifications/components/ToastJoined.tsx b/src/frontend/src/features/notifications/components/ToastJoined.tsx index eee9d277..85c0f849 100644 --- a/src/frontend/src/features/notifications/components/ToastJoined.tsx +++ b/src/frontend/src/features/notifications/components/ToastJoined.tsx @@ -29,6 +29,9 @@ export function ToastJoined({ state, ...props }: ToastProps) { ) const layoutContext = useMaybeLayoutContext() const participant = props.toast.content.participant + + if (!participant) return + const trackReference = { participant, publication: participant.getTrackPublication(Source.Camera), diff --git a/src/frontend/src/features/notifications/components/ToastMessageReceived.tsx b/src/frontend/src/features/notifications/components/ToastMessageReceived.tsx index 4fbf242c..46000beb 100644 --- a/src/frontend/src/features/notifications/components/ToastMessageReceived.tsx +++ b/src/frontend/src/features/notifications/components/ToastMessageReceived.tsx @@ -27,7 +27,7 @@ export function ToastMessageReceived({ state, ...props }: ToastProps) { } }, [isChatOpen, toast, state]) - if (isChatOpen) return null + if (isChatOpen || !participant) return null return ( diff --git a/src/frontend/src/features/notifications/components/ToastMuted.tsx b/src/frontend/src/features/notifications/components/ToastMuted.tsx index 86ce3247..232d38aa 100644 --- a/src/frontend/src/features/notifications/components/ToastMuted.tsx +++ b/src/frontend/src/features/notifications/components/ToastMuted.tsx @@ -10,6 +10,9 @@ export function ToastMuted({ state, ...props }: ToastProps) { const ref = useRef(null) const { toastProps, contentProps } = useToast(props, state, ref) const participant = props.toast.content.participant + + if (!participant) return + return ( case NotificationType.RecordingSaving: diff --git a/src/frontend/src/locales/de/notifications.json b/src/frontend/src/locales/de/notifications.json index fb8d37c7..f1060ec2 100644 --- a/src/frontend/src/locales/de/notifications.json +++ b/src/frontend/src/locales/de/notifications.json @@ -24,11 +24,13 @@ }, "transcript": { "started": "{{name}} hat die Transkription des Treffens gestartet.", - "stopped": "{{name}} hat die Transkription des Treffens gestoppt." + "stopped": "{{name}} hat die Transkription des Treffens gestoppt.", + "limitReached": "Die Transkription hat die maximal zulässige Dauer überschritten und wird automatisch gespeichert." }, "screenRecording": { "started": "{{name}} hat die Aufzeichnung des Treffens gestartet.", - "stopped": "{{name}} hat die Aufzeichnung des Treffens gestoppt." + "stopped": "{{name}} hat die Aufzeichnung des Treffens gestoppt.", + "limitReached": "Die Aufzeichnung hat die maximal zulässige Dauer überschritten und wird automatisch gespeichert." }, "recordingSave": { "transcript": { diff --git a/src/frontend/src/locales/en/notifications.json b/src/frontend/src/locales/en/notifications.json index c38c446b..16908fd2 100644 --- a/src/frontend/src/locales/en/notifications.json +++ b/src/frontend/src/locales/en/notifications.json @@ -24,11 +24,13 @@ }, "transcript": { "started": "{{name}} started the meeting transcription.", - "stopped": "{{name}} stopped the meeting transcription." + "stopped": "{{name}} stopped the meeting transcription.", + "limitReached": "The transcription has exceeded the maximum allowed duration and will be automatically saved." }, "screenRecording": { "started": "{{name}} started the meeting recording.", - "stopped": "{{name}} stopped the meeting recording." + "stopped": "{{name}} stopped the meeting recording.", + "limitReached": "The recording has exceeded the maximum allowed duration and will be automatically saved." }, "recordingSave": { "transcript": { diff --git a/src/frontend/src/locales/fr/notifications.json b/src/frontend/src/locales/fr/notifications.json index 2339500f..8f292077 100644 --- a/src/frontend/src/locales/fr/notifications.json +++ b/src/frontend/src/locales/fr/notifications.json @@ -24,11 +24,13 @@ }, "transcript": { "started": "{{name}} a démarré la transcription de la réunion.", - "stopped": "{{name}} a arrêté 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." }, "screenRecording": { "started": "{{name}} a démarré l'enregistrement de la réunion.", - "stopped": "{{name}} a arrêté 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é." }, "recordingSave": { "transcript": { diff --git a/src/frontend/src/locales/nl/notifications.json b/src/frontend/src/locales/nl/notifications.json index ebaaebbc..4b1cd073 100644 --- a/src/frontend/src/locales/nl/notifications.json +++ b/src/frontend/src/locales/nl/notifications.json @@ -24,11 +24,13 @@ }, "transcript": { "started": "{{name}} is de transcriptie van de vergadering gestart.", - "stopped": "{{name}} heeft de transcriptie van de vergadering gestopt." + "stopped": "{{name}} heeft de transcriptie van de vergadering gestopt.", + "limitReached": "De transcriptie heeft de maximaal toegestane duur overschreden en wordt automatisch opgeslagen." }, "screenRecording": { "started": "{{name}} is begonnen met het opnemen van de vergadering.", - "stopped": "{{name}} is gestopt 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." }, "recordingSave": { "transcript": {