From 4793f2fa8fc87a0bbe3e511a47f1720270227573 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Wed, 27 Aug 2025 15:25:18 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20display=20host=20status?= =?UTF-8?q?=20to=20meeting=20participants?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add host identification display for participants using boolean flag from LiveKit token attributes. Currently passes simple boolean but will be refactored to distinguish owner/admin/member roles and host/co-host with different privileges. Security note: attributes are not fully secure as participants can update their own metadata, potentially faking admin status. However, consequences are limited to user confusion without destructive capabilities. Metadata updates currently needed for name changes and hand raising functionality. Plan to remove canUpdateOwnMetadata permission to strengthen security while preserving essential user interaction capabilities. --- .../Participants/ParticipantListItem.tsx | 48 +++++++++++-------- .../rooms/utils/getParticipantIsRoomAdmin.ts | 12 +++++ src/frontend/src/locales/de/rooms.json | 1 + src/frontend/src/locales/en/rooms.json | 1 + src/frontend/src/locales/fr/rooms.json | 1 + src/frontend/src/locales/nl/rooms.json | 1 + 6 files changed, 43 insertions(+), 21 deletions(-) create mode 100644 src/frontend/src/features/rooms/utils/getParticipantIsRoomAdmin.ts diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Participants/ParticipantListItem.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Participants/ParticipantListItem.tsx index 63232694..ba8344b7 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/Participants/ParticipantListItem.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/Participants/ParticipantListItem.tsx @@ -1,10 +1,11 @@ import { css } from '@/styled-system/css' -import { HStack } from '@/styled-system/jsx' +import { HStack, VStack } from '@/styled-system/jsx' import { Text } from '@/primitives/Text' import { useTranslation } from 'react-i18next' import { Avatar } from '@/components/Avatar' import { getParticipantColor } from '@/features/rooms/utils/getParticipantColor' +import { getParticipantIsRoomAdmin } from '@/features/rooms/utils/getParticipantIsRoomAdmin' import { Participant, Track } from 'livekit-client' import { isLocal } from '@/utils/livekit' import { @@ -102,36 +103,41 @@ export const ParticipantListItem = ({ > - - + - {name} - - {isLocal(participant) && ( - ({t('participants.you')}) + {name} + {isLocal(participant) && ( + + ({t('participants.you')}) + + )} + + {getParticipantIsRoomAdmin(participant) && ( + {t('participants.host')} )} - + diff --git a/src/frontend/src/features/rooms/utils/getParticipantIsRoomAdmin.ts b/src/frontend/src/features/rooms/utils/getParticipantIsRoomAdmin.ts new file mode 100644 index 00000000..a0ee52b5 --- /dev/null +++ b/src/frontend/src/features/rooms/utils/getParticipantIsRoomAdmin.ts @@ -0,0 +1,12 @@ +import { Participant } from 'livekit-client' + +export const getParticipantIsRoomAdmin = ( + participant: Participant +): boolean => { + const attributes = participant.attributes + + if (!attributes) { + return false + } + return attributes?.room_admin === 'true' +} diff --git a/src/frontend/src/locales/de/rooms.json b/src/frontend/src/locales/de/rooms.json index a6bed7ef..1a8db979 100644 --- a/src/frontend/src/locales/de/rooms.json +++ b/src/frontend/src/locales/de/rooms.json @@ -426,6 +426,7 @@ "participants": { "subheading": "Im Raum", "you": "Du", + "host": "Host", "contributors": "Mitwirkende", "collapsable": { "open": "{{name}}-Liste öffnen", diff --git a/src/frontend/src/locales/en/rooms.json b/src/frontend/src/locales/en/rooms.json index 652ec1d2..fd401d7c 100644 --- a/src/frontend/src/locales/en/rooms.json +++ b/src/frontend/src/locales/en/rooms.json @@ -426,6 +426,7 @@ "participants": { "subheading": "In room", "you": "You", + "host": "Host", "contributors": "Contributors", "collapsable": { "open": "Open {{name}} list", diff --git a/src/frontend/src/locales/fr/rooms.json b/src/frontend/src/locales/fr/rooms.json index 72e75d85..ebc1bd48 100644 --- a/src/frontend/src/locales/fr/rooms.json +++ b/src/frontend/src/locales/fr/rooms.json @@ -427,6 +427,7 @@ "subheading": "Dans la réunion", "you": "Vous", "contributors": "Contributeurs", + "host": "Organisateur de la réunion", "collapsable": { "open": "Ouvrir la liste {{name}}", "close": "Fermer la liste {{name}}" diff --git a/src/frontend/src/locales/nl/rooms.json b/src/frontend/src/locales/nl/rooms.json index 42877d2b..b44d56a1 100644 --- a/src/frontend/src/locales/nl/rooms.json +++ b/src/frontend/src/locales/nl/rooms.json @@ -426,6 +426,7 @@ "participants": { "subheading": "In de ruimte", "you": "U", + "host": "Host", "contributors": "Deelnemers", "collapsable": { "open": "Open {{name}} lijst",