Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@ import { ChatRoomState } from './types'
export const INITIAL_CHAT_ROOM_STATE: ChatRoomState = {
id: undefined,
participants: undefined,
leftPanelContent: 0,
singleChatProfileDetails: {
pk: undefined,
name: undefined,
username: undefined,
imageUrl: undefined,
biography: undefined,
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ const ChatRoomProvider: FC<PropsWithChildren> = ({ children }) => {
if (!storeRef.current) {
storeRef.current = create<UseChatRoom>((set) => ({
...INITIAL_CHAT_ROOM_STATE,

setChatRoom: (state: ChatRoomState) => set(state),
resetChatRoom: () => set({ ...INITIAL_CHAT_ROOM_STATE }),
setLeftPanelContent: (content: number) => set({ leftPanelContent: content }),
setSingleChatProfileDetails: (details) => set({ singleChatProfileDetails: { ...details } }),
}))
}
return <ChatRoomContext.Provider value={storeRef.current}>{children}</ChatRoomContext.Provider>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
export type ChatRoomState = {
id?: string
participants?: (string | null | undefined)[]
leftPanelContent?: number
singleChatProfileDetails?: {
pk: number | undefined
name: string | null | undefined
username: string | null | undefined
imageUrl: string | null | undefined
biography?: string | null | undefined
}
}

type ChatRoomFunctions = {
Expand All @@ -9,6 +17,14 @@ type ChatRoomFunctions = {
replace?: boolean | undefined,
) => void
resetChatRoom: () => void
setLeftPanelContent: (content: number) => void
setSingleChatProfileDetails: (details: {
pk: number | undefined
name: string | undefined
username: string | undefined
imageUrl: string | undefined
biography?: string | undefined
}) => void
}

export type UseChatRoom = ChatRoomState & ChatRoomFunctions
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ export const RoomTitleFragment = graphql`
node {
profile {
id
pk
name
image(width: 100, height: 100) {
image(width: 128, height: 128) {
url
}
biography
urlPath {
path
}
}
role
}
Expand Down
17 changes: 13 additions & 4 deletions packages/components/modules/messages/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ export const useGroupNameAndAvatar = (
headerRef as GroupTitleFragment$key,
)
return {
pk: undefined,
path: undefined,
biography: undefined,
title: header?.title,
avatar: header?.image?.url,
}
}

const useRoomNameAndAvatar = (headerRef: RoomTitleFragment$key | null | undefined) => {
export const useSingleChatDetails = (headerRef: RoomTitleFragment$key | null | undefined) => {
const { currentProfile } = useCurrentProfile()
const header = useFragment<RoomTitleFragment$key>(RoomTitleFragment, headerRef)
if (!header?.participants) {
Expand All @@ -39,22 +42,28 @@ const useRoomNameAndAvatar = (headerRef: RoomTitleFragment$key | null | undefine
)
if (otherParticipant === undefined) {
return {
pk: undefined,
title: 'Deleted User',
avatar: undefined,
path: undefined,
biography: undefined,
}
}

return {
pk: otherParticipant?.node?.profile?.pk,
title: otherParticipant?.node?.profile?.name,
avatar: otherParticipant?.node?.profile?.image?.url,
path: otherParticipant?.node?.profile?.urlPath?.path,
biography: otherParticipant?.node?.profile?.biography,
}
}

export const useNameAndAvatar = (roomHeader: TitleFragment$data) => {
const roomNameAndAvatar = useRoomNameAndAvatar(roomHeader)
export const useChatroomDetails = (roomHeader: TitleFragment$data) => {
const singleChatDetails = useSingleChatDetails(roomHeader)
const groupNameAndAvatar = useGroupNameAndAvatar(roomHeader)
if (roomHeader.isGroup) return groupNameAndAvatar
return roomNameAndAvatar
return singleChatDetails
}

export const getParticipantCountString = (participantCount: number | null | undefined) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
TitleFragment,
UnreadMessagesCountFragment,
useArchiveChatRoomMutation,
useNameAndAvatar,
useChatroomDetails,
useUnreadChatMutation,
} from '../../../common'
import { StyledChatCard } from './styled'
Expand Down Expand Up @@ -52,7 +52,7 @@ const ChatRoomItem: FC<ChatRoomItemProps> = ({
const chatCardRef = useRef<HTMLDivElement>(null)

const { currentProfile } = useCurrentProfile()
const { title, avatar } = useNameAndAvatar(headerFragment)
const { title, avatar } = useChatroomDetails(headerFragment)

const { lastMessageTime } = lastMessageFragment
const lastMessage = lastMessageFragment.lastMessage?.content
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ const ChatRoomOptions: FC<ChatRoomOptionsProps> = ({
onArchiveClicked,
onDetailsClicked,
onLeaveClicked,
onContactDetailsClicked,
}) => (
<MenuList>
<MenuItem onClick={onArchiveClicked} disabled={isArchiveMutationInFlight}>
<Typography variant="body2">{isArchived ? 'Unarchive Chat' : 'Archive Chat'}</Typography>
</MenuItem>
{!isGroup && (
<MenuItem onClick={onContactDetailsClicked}>
<Typography variant="body2">Contact Details</Typography>
</MenuItem>
)}
{isGroup ? (
<>
<MenuItem onClick={onDetailsClicked}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface ChatRoomOptionsProps {
onArchiveClicked: () => void
onDetailsClicked: () => void
onLeaveClicked: () => void
onContactDetailsClicked: () => void
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useState } from 'react'
import { FC, useEffect, useState } from 'react'

import { useCurrentProfile } from '@baseapp-frontend/authentication'
import { AvatarWithPlaceholder } from '@baseapp-frontend/design-system/components/web/avatars'
Expand All @@ -20,10 +20,11 @@ import {
getParticipantCountString,
useArchiveChatRoomMutation,
useChatRoom,
useChatroomDetails,
useCheckIsAdmin,
useNameAndAvatar,
} from '../../../common'
import { RoomTitleFragment } from '../../../common/graphql/fragments/RoomTitle'
import { LEFT_PANEL_CONTENT } from '../../ChatRoomsComponent/constants'
import LeaveGroupDialog from '../../__shared__/LeaveGroupDialog'
import ChatRoomOptions from './ChatRoomOptions'
import { BackButtonContainer, ChatHeaderContainer, ChatTitleContainer } from './styled'
Expand All @@ -37,14 +38,28 @@ const ChatRoomHeader: FC<ChatRoomHeaderProps> = ({
roomId,
}) => {
const roomHeader = useFragment(TitleFragment, roomTitleRef)

const [open, setOpen] = useState(false)
const { currentProfile } = useCurrentProfile()

const isUpToMd = useResponsive('up', 'md')
const { resetChatRoom } = useChatRoom()
const { resetChatRoom, setSingleChatProfileDetails, setLeftPanelContent } = useChatRoom()

const { isGroup } = roomHeader
const { title, avatar } = useNameAndAvatar(roomHeader)
const { title, avatar, path, pk, biography } = useChatroomDetails(roomHeader)

useEffect(() => {
if (!isGroup) {
setSingleChatProfileDetails({
pk: pk ?? undefined,
name: title ?? '',
username: path ?? '',
imageUrl: avatar ?? '',
biography: biography ?? '',
})
}
}, [pk, title, path, avatar, biography])

const { participants } = useFragment<RoomTitleFragment$key>(RoomTitleFragment, roomHeader)
const { isSoleAdmin } = useCheckIsAdmin(participants as MembersListFragment$data['participants'])
const members = getParticipantCountString(participantsCount)
Expand Down Expand Up @@ -148,6 +163,10 @@ const ChatRoomHeader: FC<ChatRoomHeaderProps> = ({
popover.onClose()
setOpen(true)
}}
onContactDetailsClicked={() => {
popover.onClose()
setLeftPanelContent(LEFT_PANEL_CONTENT.profileSummary)
}}
/>
</Popover>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export const LEFT_PANEL_CONTENT = {
createGroupChat: 2,
editGroupChat: 3,
groupDetails: 4,
profileSummary: 5,
} as const
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { FC, useState } from 'react'
import { FC } from 'react'

import { useResponsive } from '@baseapp-frontend/design-system/hooks/web'

Expand All @@ -13,10 +13,11 @@ import ChatRoom from '../ChatRoom'
import DefaultGroupChatCreate from '../GroupChatCreate'
import DefaultGroupChatDetails from '../GroupChatDetails'
import DefaultGroupChatEdit from '../GroupChatEdit'
import DefaultProfileSummary from '../ProfileSummary'
import DefaultSingleChatCreate from '../SingleChatCreate'
import { LEFT_PANEL_CONTENT } from './constants'
import { ChatRoomContainer, ChatRoomsContainer, ChatRoomsListContainer } from './styled'
import { ChatRoomsComponentProps, LeftPanelContentValues } from './types'
import { ChatRoomsComponentProps } from './types'

const ChatRoomsComponent: FC<ChatRoomsComponentProps> = ({
chatRoomsQueryData,
Expand All @@ -31,15 +32,14 @@ const ChatRoomsComponent: FC<ChatRoomsComponentProps> = ({
GroupChatEditComponentProps = {},
SingleChatCreateComponent = DefaultSingleChatCreate,
SingleChatCreateComponentProps = {},
ProfileSummaryComponent = DefaultProfileSummary,
}) => {
const isUpToMd = useResponsive('up', 'md')
const [leftPanelContent, setLeftPanelContent] = useState<LeftPanelContentValues>(
LEFT_PANEL_CONTENT.chatRoomList,
)

const [groupDetailsQueryRef, loadGroupDetailsQuery] =
useQueryLoader<GroupDetailsQueryType>(GroupDetailsQuery)
const { id: selectedRoom } = useChatRoom()

const { id: selectedRoom, leftPanelContent, setLeftPanelContent } = useChatRoom()

const displayGroupDetails = () => {
if (selectedRoom) {
Expand Down Expand Up @@ -99,6 +99,12 @@ const ChatRoomsComponent: FC<ChatRoomsComponentProps> = ({
{...SingleChatCreateComponentProps}
/>
)
case LEFT_PANEL_CONTENT.profileSummary:
return (
<ProfileSummaryComponent
onBackButtonClicked={() => setLeftPanelContent(LEFT_PANEL_CONTENT.chatRoomList)}
/>
)
default:
return (
<AllChatRoomsListComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AllChatRoomsListProps } from '../AllChatRoomsList/types'
import { GroupChatCreateProps } from '../GroupChatCreate/types'
import { GroupChatDetailsProps } from '../GroupChatDetails/types'
import { GroupChatEditProps } from '../GroupChatEdit/types'
import { ProfileSummaryProps } from '../ProfileSummary/types'
import { SingleChatCreateProps } from '../SingleChatCreate/types'
import { LEFT_PANEL_CONTENT } from './constants'

Expand All @@ -32,4 +33,6 @@ export interface ChatRoomsComponentProps {
GroupChatEditComponentProps?: Partial<GroupChatEditProps>
SingleChatCreateComponent?: FC<SingleChatCreateProps>
SingleChatCreateComponentProps?: Partial<SingleChatCreateProps>
ProfileSummaryComponent?: FC<ProfileSummaryProps>
ProfileSummaryComponentProps?: Partial<ProfileSummaryProps>
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const mockChatRoomStore = create<UseChatRoom>((set) => ({
id: 'room-123',
setChatRoom: (newState) => set(newState),
resetChatRoom: () => set({ id: '' }),
setLeftPanelContent: (_content) => {},
setSingleChatProfileDetails: (_details) => {},
}))

const meta: Meta<typeof MessageListWithQuery> = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { FC } from 'react'

import { CircledAvatar } from '@baseapp-frontend/design-system/components/web/avatars'
import { IconButton } from '@baseapp-frontend/design-system/components/web/buttons'
import {
NewGroupIcon,
ProfileNoCircleIcon,
} from '@baseapp-frontend/design-system/components/web/icons'
import { TypographyWithEllipsis } from '@baseapp-frontend/design-system/components/web/typographies'

import { Box, Divider, Typography } from '@mui/material'

import {
ButtonContainer,
HeaderContainer,
Subheader,
SubheaderContainer,
TitleContainer,
} from './styled'
import { BodyProps } from './types'

const Body: FC<BodyProps> = ({ avatar, avatarSize = 144, biography, username, name, pk }) => {
const formattedUsername = username ? username.replace(/^\/+/, '') : ''
const profilePath = username ?? `/profile/${pk}`
return (
<Box sx={{ display: 'grid', gridTemplateRows: 'auto 1fr' }}>
<HeaderContainer>
<CircledAvatar src={avatar} width={avatarSize} height={avatarSize} hasError={false} />
<TitleContainer>
<TypographyWithEllipsis variant="subtitle1" color="text.primary">
{name}
</TypographyWithEllipsis>
<TypographyWithEllipsis variant="body2" color="text.secondary">
{`@${formattedUsername}`}
</TypographyWithEllipsis>
</TitleContainer>
</HeaderContainer>
<SubheaderContainer>
<ButtonContainer>
<IconButton
size="small"
aria-label="go to profile"
onClick={() => window.open(profilePath, '_blank')}
sx={{ maxWidth: 'fit-content', gap: '8px' }}
>
<ProfileNoCircleIcon sx={{ fontSize: '18px' }} />
<Typography variant="subtitle2" color="text.primary">
Go to profile
</Typography>
</IconButton>

<IconButton
size="small"
aria-label="edit group chat"
sx={{ maxWidth: 'fit-content', gap: '8px' }}
>
<NewGroupIcon sx={{ fontSize: '18px', color: 'text.primary' }} />
<Typography variant="subtitle2" color="text.primary">
Add contact to a group
</Typography>
</IconButton>
</ButtonContainer>
<Subheader>
<Typography variant="subtitle2" color="text.primary">
About
</Typography>
</Subheader>
<Divider />
<Subheader>
<Typography variant="caption" color="text.secondary">
{biography?.split('\n').map((line, index) => (
<span key={index}>
{line}
{index < biography.split('\n').length - 1 && <br />}
</span>
))}
</Typography>
</Subheader>
</SubheaderContainer>
</Box>
)
}

export default Body
Loading
Loading