mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-31 04:37:57 +00:00
✨(frontend) notify user when their meeting role changes
Show a notification to the user whenever their role in the meeting changes, so they immediately see when they have been promoted or demoted.
This commit is contained in:
@@ -168,6 +168,31 @@ export const MainNotificationToast = () => {
|
|||||||
}
|
}
|
||||||
}, [room, triggerNotificationSoundIfRoomIsSmall])
|
}, [room, triggerNotificationSoundIfRoomIsSmall])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleAttributeChanged = (
|
||||||
|
changedAttributes: Record<string, string>,
|
||||||
|
participant: Participant
|
||||||
|
) => {
|
||||||
|
if (!participant.isLocal || !('room_role' in changedAttributes)) return
|
||||||
|
const newRole = changedAttributes['room_role']
|
||||||
|
toastQueue.add(
|
||||||
|
{
|
||||||
|
participant,
|
||||||
|
type: NotificationType.RoleChanged,
|
||||||
|
newRole: newRole,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timeout: NotificationDuration.ROLE_CHANGED,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
room.on(RoomEvent.ParticipantAttributesChanged, handleAttributeChanged)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
room.off(RoomEvent.ParticipantAttributesChanged, handleAttributeChanged)
|
||||||
|
}
|
||||||
|
}, [room])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const removeParticipantNotifications = (participant: Participant) => {
|
const removeParticipantNotifications = (participant: Participant) => {
|
||||||
toastQueue.visibleToasts.forEach((toast) => {
|
toastQueue.visibleToasts.forEach((toast) => {
|
||||||
|
|||||||
@@ -14,4 +14,5 @@ export const NotificationDuration = {
|
|||||||
RECORDING_SAVING: ToastDuration.EXTRA_LONG,
|
RECORDING_SAVING: ToastDuration.EXTRA_LONG,
|
||||||
REACTION_RECEIVED: ToastDuration.SHORT,
|
REACTION_RECEIVED: ToastDuration.SHORT,
|
||||||
RECORDING_REQUESTED: ToastDuration.LONG,
|
RECORDING_REQUESTED: ToastDuration.LONG,
|
||||||
|
ROLE_CHANGED: ToastDuration.LONG,
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ export enum NotificationType {
|
|||||||
ScreenRecordingLimitReached = 'screenRecordingLimitReached',
|
ScreenRecordingLimitReached = 'screenRecordingLimitReached',
|
||||||
RecordingSaving = 'recordingSaving',
|
RecordingSaving = 'recordingSaving',
|
||||||
PermissionsRemoved = 'permissionsRemoved',
|
PermissionsRemoved = 'permissionsRemoved',
|
||||||
|
RoleChanged = 'roleChanged',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { ToastRecordingSaving } from './ToastRecordingSaving'
|
|||||||
import { ToastPermissionsRemoved } from './ToastPermissionsRemoved'
|
import { ToastPermissionsRemoved } from './ToastPermissionsRemoved'
|
||||||
import { ToastRecordingRequest } from './ToastRecordingRequest'
|
import { ToastRecordingRequest } from './ToastRecordingRequest'
|
||||||
import { ToastAutoMuteLargeRoom } from './ToastAutoMuteLargeRoom'
|
import { ToastAutoMuteLargeRoom } from './ToastAutoMuteLargeRoom'
|
||||||
|
import { ToastRoleChanged } from '@/features/notifications/components/ToastRoleChanged'
|
||||||
|
|
||||||
interface ToastRegionProps extends AriaToastRegionProps {
|
interface ToastRegionProps extends AriaToastRegionProps {
|
||||||
state: ToastState<ToastData>
|
state: ToastState<ToastData>
|
||||||
@@ -70,6 +71,9 @@ const renderToast = (
|
|||||||
<ToastRecordingSaving key={toast.key} toast={toast} state={state} />
|
<ToastRecordingSaving key={toast.key} toast={toast} state={state} />
|
||||||
)
|
)
|
||||||
|
|
||||||
|
case NotificationType.RoleChanged:
|
||||||
|
return <ToastRoleChanged key={toast.key} toast={toast} state={state} />
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return <Toast key={toast.key} toast={toast} state={state} />
|
return <Toast key={toast.key} toast={toast} state={state} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { useToast } from 'react-aria'
|
||||||
|
import { useRef } from 'react'
|
||||||
|
|
||||||
|
import { type ToastProps } from './Toast'
|
||||||
|
import { HStack } from '@/styled-system/jsx'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { StyledToastContainer } from './StyledToastContainer'
|
||||||
|
|
||||||
|
export function ToastRoleChanged({ state, ...props }: Readonly<ToastProps>) {
|
||||||
|
const { t } = useTranslation('notifications', { keyPrefix: 'roleChanged' })
|
||||||
|
const ref = useRef(null)
|
||||||
|
const { toastProps, contentProps } = useToast(props, state, ref)
|
||||||
|
const newRole = t(`roles.${props.toast.content.newRole}`)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledToastContainer {...toastProps} ref={ref}>
|
||||||
|
<HStack
|
||||||
|
justify="center"
|
||||||
|
alignItems="center"
|
||||||
|
{...contentProps}
|
||||||
|
padding={14}
|
||||||
|
gap={0}
|
||||||
|
>
|
||||||
|
{t('body', { role: newRole })}
|
||||||
|
</HStack>
|
||||||
|
</StyledToastContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -54,5 +54,13 @@
|
|||||||
"default": "Deine Aufzeichnung wird gespeichert! Du erhältst eine E-Mail, sobald sie bereit ist."
|
"default": "Deine Aufzeichnung wird gespeichert! Du erhältst eine E-Mail, sobald sie bereit ist."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"roleChanged": {
|
||||||
|
"body": "Deine Rolle wurde geändert. Du bist jetzt {{role}}.",
|
||||||
|
"roles": {
|
||||||
|
"owner": "Host",
|
||||||
|
"administrator": "Co-host",
|
||||||
|
"member": "Mitglied"
|
||||||
|
}
|
||||||
|
},
|
||||||
"openMenu": "Menü öffnen"
|
"openMenu": "Menü öffnen"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,5 +54,13 @@
|
|||||||
"default": "Your recording is being saved! We’ll send a notification to your 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."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"roleChanged": {
|
||||||
|
"body": "Your role has changed. You are now {{role}}.",
|
||||||
|
"roles": {
|
||||||
|
"owner": "Host",
|
||||||
|
"administrator": "Co-host",
|
||||||
|
"member": "Member"
|
||||||
|
}
|
||||||
|
},
|
||||||
"openMenu": "Open menu"
|
"openMenu": "Open menu"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,5 +54,13 @@
|
|||||||
"default": "Nous finalisons votre enregistrement ! Vous recevrez un e-mail dès qu’il sera prêt."
|
"default": "Nous finalisons votre enregistrement ! Vous recevrez un e-mail dès qu’il sera prêt."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"roleChanged": {
|
||||||
|
"body": "Votre rôle a changé, vous êtes maitenant {{role}}.",
|
||||||
|
"roles": {
|
||||||
|
"owner": "Organisateur",
|
||||||
|
"administrator": "Co-organisateur",
|
||||||
|
"member": "Membre"
|
||||||
|
}
|
||||||
|
},
|
||||||
"openMenu": "Ouvrir le menu"
|
"openMenu": "Ouvrir le menu"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,5 +54,13 @@
|
|||||||
"default": "We zijn uw opname aan het voltooien! U ontvangt een e-mail zodra deze klaar is."
|
"default": "We zijn uw opname aan het voltooien! U ontvangt een e-mail zodra deze klaar is."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"roleChanged": {
|
||||||
|
"body": "Je rol is gewijzigd. Je bent nu {{role}}.",
|
||||||
|
"roles": {
|
||||||
|
"owner": "Host",
|
||||||
|
"administrator": "Co-host",
|
||||||
|
"member": "Lid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"openMenu": "Menu openen"
|
"openMenu": "Menu openen"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user