✨(frontend) allow local participant to update her name
The user name is initially set by the backend when generating the LiveKit access token. By default, if the frontend has not provided a username, the backend uses the user's email address. This approach isn't ideal, as some users prefer using their first name. This update allows local participant to change their username in real-time during a session. However, these changes are not yet persisted for future meetings. This persistence feature will be added in upcoming commits.
This commit is contained in:
committed by
aleb_the_flash
parent
fe8ed43aae
commit
37eea16a50
@@ -3,6 +3,7 @@ import {
|
||||
RiFeedbackLine,
|
||||
RiQuestionLine,
|
||||
RiSettings3Line,
|
||||
RiUser5Line,
|
||||
} from '@remixicon/react'
|
||||
import { useState } from 'react'
|
||||
import { styled } from '@/styled-system/jsx'
|
||||
@@ -10,8 +11,10 @@ import {
|
||||
Menu as RACMenu,
|
||||
MenuItem as RACMenuItem,
|
||||
Popover as RACPopover,
|
||||
Separator as RACSeparator,
|
||||
} from 'react-aria-components'
|
||||
import { SettingsDialog } from '@/features/settings'
|
||||
import { UsernameDialog } from '../../dialogs/UsernameDialog'
|
||||
|
||||
// Styled components to be refactored
|
||||
const StyledMenu = styled(RACMenu, {
|
||||
@@ -60,13 +63,28 @@ const StyledPopover = styled(RACPopover, {
|
||||
},
|
||||
})
|
||||
|
||||
const StyledSeparator = styled(RACSeparator, {
|
||||
base: {
|
||||
height: '1px',
|
||||
background: '#9ca3af',
|
||||
margin: '2px 4px',
|
||||
},
|
||||
})
|
||||
|
||||
type DialogState = 'username' | 'settings' | null
|
||||
|
||||
export const OptionsMenu = () => {
|
||||
const { t } = useTranslation('rooms')
|
||||
const [isSettingsDialogOpen, setIsSettingsDialogOpen] = useState(false)
|
||||
const [dialogOpen, setDialogOpen] = useState<DialogState>(null)
|
||||
return (
|
||||
<>
|
||||
<StyledPopover>
|
||||
<StyledMenu>
|
||||
<StyledMenuItem onAction={() => setDialogOpen('username')}>
|
||||
<RiUser5Line size={18} />
|
||||
{t('options.items.username')}
|
||||
</StyledMenuItem>
|
||||
<StyledSeparator />
|
||||
<StyledMenuItem
|
||||
href="https://tchap.gouv.fr/#/room/!aGImQayAgBLjSBycpm:agent.dinum.tchap.gouv.fr?via=agent.dinum.tchap.gouv.fr"
|
||||
target="_blank"
|
||||
@@ -81,15 +99,19 @@ export const OptionsMenu = () => {
|
||||
<RiFeedbackLine size={18} />
|
||||
{t('options.items.feedbacks')}
|
||||
</StyledMenuItem>
|
||||
<StyledMenuItem onAction={() => setIsSettingsDialogOpen(true)}>
|
||||
<StyledMenuItem onAction={() => setDialogOpen('settings')}>
|
||||
<RiSettings3Line size={18} />
|
||||
{t('options.items.settings')}
|
||||
</StyledMenuItem>
|
||||
</StyledMenu>
|
||||
</StyledPopover>
|
||||
<UsernameDialog
|
||||
isOpen={dialogOpen === 'username'}
|
||||
onOpenChange={(v) => !v && setDialogOpen(null)}
|
||||
/>
|
||||
<SettingsDialog
|
||||
isOpen={isSettingsDialogOpen}
|
||||
onOpenChange={(v) => setIsSettingsDialogOpen(v)}
|
||||
isOpen={dialogOpen === 'settings'}
|
||||
onOpenChange={(v) => !v && setDialogOpen(null)}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Field, Form, Dialog, DialogProps } from '@/primitives'
|
||||
import { useRoomContext } from '@livekit/components-react'
|
||||
|
||||
export type UsernameDialogProps = Pick<DialogProps, 'isOpen' | 'onOpenChange'>
|
||||
|
||||
export const UsernameDialog = (props: UsernameDialogProps) => {
|
||||
const { t } = useTranslation('rooms')
|
||||
|
||||
const ctx = useRoomContext()
|
||||
return (
|
||||
<Dialog title={t('options.username.heading')} {...props}>
|
||||
<Form
|
||||
onSubmit={(data) => {
|
||||
ctx.localParticipant.setName(data.username as string)
|
||||
const { onOpenChange } = props
|
||||
if (onOpenChange) {
|
||||
onOpenChange(false)
|
||||
}
|
||||
}}
|
||||
submitLabel={t('options.username.submitLabel')}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
name="username"
|
||||
label={t('options.username.label')}
|
||||
description={t('options.username.description')}
|
||||
defaultValue={ctx.localParticipant.name}
|
||||
validate={(value) => {
|
||||
return !value ? (
|
||||
<p>{t('options.username.validationError')}</p>
|
||||
) : null
|
||||
}}
|
||||
/>
|
||||
</Form>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
@@ -36,7 +36,15 @@
|
||||
"items": {
|
||||
"feedbacks": "",
|
||||
"support": "",
|
||||
"settings": ""
|
||||
"settings": "",
|
||||
"username": ""
|
||||
},
|
||||
"username": {
|
||||
"heading": "",
|
||||
"label": "",
|
||||
"description": "",
|
||||
"validationError": "",
|
||||
"submitLabel": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,15 @@
|
||||
"items": {
|
||||
"feedbacks": "Give us feedbacks",
|
||||
"support": "Get Help on Tchap",
|
||||
"settings": "Settings"
|
||||
"settings": "Settings",
|
||||
"username": "Update Your Name"
|
||||
},
|
||||
"username": {
|
||||
"heading": "Update Your Name",
|
||||
"label": "Your Name",
|
||||
"description": "All other participants will see this name.",
|
||||
"validationError": "Name cannot be empty.",
|
||||
"submitLabel": "Save"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,15 @@
|
||||
"items": {
|
||||
"feedbacks": "Partager votre avis",
|
||||
"support": "Obtenir de l'aide sur Tchap",
|
||||
"settings": "Paramètres"
|
||||
"settings": "Paramètres",
|
||||
"username": "Choisir votre nom"
|
||||
},
|
||||
"username": {
|
||||
"heading": "Choisir votre nom",
|
||||
"label": "Votre Nom",
|
||||
"description": "Tous les autres participants verront ce nom.",
|
||||
"validationError": "Le nom ne peut pas être vide.",
|
||||
"submitLabel": "Enregistrer"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user