From 9f46038cadc8c8cf4df8dfcc982cd45ab513d700 Mon Sep 17 00:00:00 2001 From: Zishan Ahmad Date: Sat, 20 Apr 2024 18:07:13 +0530 Subject: [PATCH] feat: user role display functionality (#567) * removed TODO comments * added display of channel level roles * added check of admins * added admin role display * removed unnecessary comments --- packages/api/src/EmbeddedChatApi.ts | 20 +++++++ packages/react/src/components/EmbeddedChat.js | 11 +++- .../src/components/Message/MessageHeader.js | 60 +++++++++++++++---- packages/react/src/hooks/useFetchChatData.js | 11 +++- packages/react/src/store/memberStore.js | 2 + packages/react/src/store/userStore.js | 2 + 6 files changed, 90 insertions(+), 16 deletions(-) diff --git a/packages/api/src/EmbeddedChatApi.ts b/packages/api/src/EmbeddedChatApi.ts index 17cb1b90b..f5ba79612 100644 --- a/packages/api/src/EmbeddedChatApi.ts +++ b/packages/api/src/EmbeddedChatApi.ts @@ -543,6 +543,26 @@ export default class EmbeddedChatApi { } } + async getUsersInRole(role: string) { + try { + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; + const roles = await fetch( + `${this.host}/api/v1/roles.getUsersInRole?role=${role}`, + { + headers: { + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, + }, + method: "GET", + } + ); + return await roles.json(); + } catch (err) { + console.log(err); + } + } + async sendTypingStatus(username: string, typing: boolean) { try { this.rcClient.methodCall( diff --git a/packages/react/src/components/EmbeddedChat.js b/packages/react/src/components/EmbeddedChat.js index 185932add..1a8a29b0a 100644 --- a/packages/react/src/components/EmbeddedChat.js +++ b/packages/react/src/components/EmbeddedChat.js @@ -47,10 +47,19 @@ const EmbeddedChat = ({ const [fullScreen, setFullScreen] = useState(false); const setToastbarPosition = useToastStore((state) => state.setPosition); const setShowAvatar = useUserStore((state) => state.setShowAvatar); + const setShowRoles = useUserStore((state) => state.setShowRoles); useEffect(() => { setToastbarPosition(toastBarPosition); setShowAvatar(showAvatar); - }, [toastBarPosition, showAvatar, setShowAvatar, setToastbarPosition]); + setShowRoles(showRoles); + }, [ + toastBarPosition, + showAvatar, + setShowAvatar, + setToastbarPosition, + showRoles, + setShowRoles, + ]); const { onDrag, diff --git a/packages/react/src/components/Message/MessageHeader.js b/packages/react/src/components/Message/MessageHeader.js index 0eaf7b592..2da638248 100644 --- a/packages/react/src/components/Message/MessageHeader.js +++ b/packages/react/src/components/Message/MessageHeader.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { css } from '@emotion/react'; import { format } from 'date-fns'; -import { useUserStore } from '../../store'; +import { useMemberStore, useUserStore } from '../../store'; import { Icon } from '../Icon'; import useComponentOverrides from '../../theme/useComponentOverrides'; import { Box } from '../Box'; @@ -34,6 +34,21 @@ const MessageHeaderNameCss = css` color: #2f343d; `; +const MessageUserRoleCss = css` + background-color: #cbced1; + letter-spacing: 0rem; + font-size: 0.75rem; + padding: 0 0.25rem; + margin: 0 0.1rem; + border-radius: 2px; + font-weight: 700; + line-height: 1.25rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + color: #2f343d; +`; + const MessageHeaderUsernameCss = css` letter-spacing: 0rem; font-size: 0.875rem; @@ -61,6 +76,11 @@ const MessageHeaderTimestapCss = css` const MessageHeader = ({ message, isTimeStamped = true }) => { const { styleOverrides, classNames } = useComponentOverrides('MessageHeader'); const authenticatedUserId = useUserStore((state) => state.userId); + const showRoles = useUserStore((state) => state.showRoles); + + const channelLevelRoles = useMemberStore((state) => state.memberRoles); + const admins = useMemberStore((state) => state.admins); + const isPinned = message.pinned; const isStarred = message.starred && @@ -100,10 +120,6 @@ const MessageHeader = ({ message, isTimeStamped = true }) => { } }; - // const userRoles = roles[message.u.username] - // ? roles[message.u.username].roles - // : null; - if (!message.t) { return ( { > @{message.u.username} - {/* TODO {userRoles - ? userRoles.map((role, index) => ( - - {role.charAt(0).toUpperCase() + role.slice(1)} - - )) - : null} */} + {showRoles && ( + <> + {admins.includes(message?.u?.username) && ( + + Admin + + )} + + {channelLevelRoles[message.u.username]?.roles?.map( + (role, index) => ( + + {role} + + ) + )} + + )} + {isTimeStamped && ( { const setMemberRoles = useMemberStore((state) => state.setMemberRoles); const isChannelPrivate = useChannelStore((state) => state.isChannelPrivate); const setMessages = useMessageStore((state) => state.setMessages); + const setAdmins = useMemberStore((state) => state.setAdmins); const isUserAuthenticated = useUserStore( (state) => state.isUserAuthenticated ); @@ -42,14 +43,17 @@ const useFetchChatData = (showRoles) => { } if (!isUserAuthenticated) { - // fetch roles only when the user is authenticated return; } if (showRoles) { const { roles } = await RCInstance.getChannelRoles(isChannelPrivate); + const fetchedAdmins = await RCInstance.getUsersInRole('admin'); + const adminUsernames = fetchedAdmins.users.map( + (user) => user.username + ); + setAdmins(adminUsernames); - // convert roles array from the API into an object for better search const rolesObj = roles?.length > 0 ? roles.reduce( @@ -68,10 +72,11 @@ const useFetchChatData = (showRoles) => { isUserAuthenticated, RCInstance, ECOptions?.enableThreads, + isChannelPrivate, showRoles, setMessages, + setAdmins, setMemberRoles, - isChannelPrivate, ] ); diff --git a/packages/react/src/store/memberStore.js b/packages/react/src/store/memberStore.js index b731bc1db..b5ef88637 100644 --- a/packages/react/src/store/memberStore.js +++ b/packages/react/src/store/memberStore.js @@ -4,7 +4,9 @@ const useMemberStore = create((set) => ({ members: [], showMembers: false, memberRoles: {}, + admins: [], setMemberRoles: (memberRoles) => set((state) => ({ ...state, memberRoles })), + setAdmins: (admins) => set(() => ({ admins })), toggleShowMembers: () => set((state) => ({ showMembers: !state.showMembers })), setMembersHandler: (memberList) => set(() => ({ members: memberList })), diff --git a/packages/react/src/store/userStore.js b/packages/react/src/store/userStore.js index eb49570cb..08f83e07d 100644 --- a/packages/react/src/store/userStore.js +++ b/packages/react/src/store/userStore.js @@ -29,6 +29,8 @@ const useUserStore = create((set) => ({ setEmailorUser: (emailoruser) => set(() => ({ emailoruser })), showAvatar: false, setShowAvatar: (showAvatar) => set(() => ({ showAvatar })), + showRoles: false, + setShowRoles: (showRoles) => set(() => ({ showRoles })), roles: {}, setRoles: (roles) => set((state) => ({ ...state, roles })), }));