From a4a815716338b19d718793a3b3e87d1a7367a236 Mon Sep 17 00:00:00 2001 From: bang9 Date: Thu, 8 Feb 2024 11:41:56 +0900 Subject: [PATCH] fix: should pass render props properly in channel module --- .../Channel/components/ChannelUI/index.tsx | 44 ++++-------- .../Channel/components/MessageList/index.tsx | 18 ++--- .../GroupChannelUI/GroupChannelUIView.tsx | 72 +++++++++++-------- .../components/GroupChannelUI/index.tsx | 47 +++++------- 4 files changed, 79 insertions(+), 102 deletions(-) diff --git a/src/modules/Channel/components/ChannelUI/index.tsx b/src/modules/Channel/components/ChannelUI/index.tsx index 9a1e68d5a..4a35636d0 100644 --- a/src/modules/Channel/components/ChannelUI/index.tsx +++ b/src/modules/Channel/components/ChannelUI/index.tsx @@ -1,53 +1,37 @@ import React from 'react'; -import type { MessageContentProps } from '../../../../ui/MessageContent'; -import type { GroupChannelHeaderProps } from '../../../GroupChannel/components/GroupChannelHeader'; -import type { RenderCustomSeparatorProps } from '../../../../types'; -import { RenderMessageParamsType } from '../../../../types'; import { useChannelContext } from '../../context/ChannelProvider'; -import { GroupChannelUIView } from '../../../GroupChannel/components/GroupChannelUI/GroupChannelUIView'; +import { GroupChannelUIBasicProps, GroupChannelUIView } from '../../../GroupChannel/components/GroupChannelUI/GroupChannelUIView'; + import ChannelHeader from '../ChannelHeader'; import MessageList from '../MessageList'; import MessageInputWrapper from '../MessageInputWrapper'; -export interface ChannelUIProps { +export interface ChannelUIProps extends GroupChannelUIBasicProps { isLoading?: boolean; - renderPlaceholderLoader?: () => React.ReactElement; - renderPlaceholderInvalid?: () => React.ReactElement; - renderPlaceholderEmpty?: () => React.ReactElement; - renderChannelHeader?: (props: GroupChannelHeaderProps) => React.ReactElement; - renderMessage?: (props: RenderMessageParamsType) => React.ReactElement; - renderMessageContent?: (props: MessageContentProps) => React.ReactElement; - renderMessageInput?: () => React.ReactElement; - renderFileUploadIcon?: () => React.ReactElement; - renderVoiceMessageIcon?: () => React.ReactElement; - renderSendMessageIcon?: () => React.ReactElement; - renderTypingIndicator?: () => React.ReactElement; - renderCustomSeparator?: (props: RenderCustomSeparatorProps) => React.ReactElement; - renderFrozenNotification?: () => React.ReactElement; } const ChannelUI = (props: ChannelUIProps) => { const context = useChannelContext(); + const { channelUrl, isInvalid, loading } = context; + + // Inject components to presentation layer const { - channelUrl, - isInvalid, - loading, - } = context; + renderChannelHeader = (p) => , + renderMessageList = (p) => , + renderMessageInput = () => , + } = props; return ( ()} - renderMessageList={(props) => ()} - renderMessageInput={() => ( - props.renderMessageInput?.() - ?? - )} + channelUrl={channelUrl} + renderChannelHeader={renderChannelHeader} + renderMessageList={renderMessageList} + renderMessageInput={renderMessageInput} /> ); }; diff --git a/src/modules/Channel/components/MessageList/index.tsx b/src/modules/Channel/components/MessageList/index.tsx index f10cf5095..f27cd6fc1 100644 --- a/src/modules/Channel/components/MessageList/index.tsx +++ b/src/modules/Channel/components/MessageList/index.tsx @@ -4,14 +4,12 @@ import '../../../GroupChannel/components/MessageList/index.scss'; import React, { useState } from 'react'; import type { UserMessage } from '@sendbird/chat/message'; -import type { MessageContentProps } from '../../../../ui/MessageContent'; import { useChannelContext } from '../../context/ChannelProvider'; import PlaceHolder, { PlaceHolderTypes } from '../../../../ui/PlaceHolder'; import Icon, { IconColors, IconTypes } from '../../../../ui/Icon'; import Message from '../Message'; -import { EveryMessage, RenderCustomSeparatorProps, RenderMessageParamsType, TypingIndicatorType } from '../../../../types'; +import { EveryMessage, TypingIndicatorType } from '../../../../types'; import { isAboutSame } from '../../context/utils'; -import { getMessagePartsInfo } from '../../../GroupChannel/components/MessageList/getMessagePartsInfo'; import UnreadCount from '../UnreadCount'; import FrozenNotification from '../FrozenNotification'; import { SCROLL_BUFFER } from '../../../../utils/consts'; @@ -23,18 +21,12 @@ import { useScrollBehavior } from './hooks/useScrollBehavior'; import TypingIndicatorBubble from '../../../../ui/TypingIndicatorBubble'; import { useOnScrollPositionChangeDetector } from '../../../../hooks/useOnScrollReachedEndDetector'; -const SCROLL_BOTTOM_PADDING = 50; +import { getMessagePartsInfo } from '../../../GroupChannel/components/MessageList/getMessagePartsInfo'; +import { GroupChannelMessageListProps } from '../../../GroupChannel/components/MessageList'; -export interface MessageListProps { - className?: string; - renderMessage?: (props: RenderMessageParamsType) => React.ReactElement; - renderMessageContent?: (props: MessageContentProps) => React.ReactElement; - renderPlaceholderEmpty?: () => React.ReactElement; - renderCustomSeparator?: (props: RenderCustomSeparatorProps) => React.ReactElement; - renderPlaceholderLoader?: () => React.ReactElement; - renderFrozenNotification?: () => React.ReactElement; -} +const SCROLL_BOTTOM_PADDING = 50; +export type MessageListProps = GroupChannelMessageListProps; export const MessageList = ({ className = '', renderMessage, diff --git a/src/modules/GroupChannel/components/GroupChannelUI/GroupChannelUIView.tsx b/src/modules/GroupChannel/components/GroupChannelUI/GroupChannelUIView.tsx index fa7c82011..55f06b12e 100644 --- a/src/modules/GroupChannel/components/GroupChannelUI/GroupChannelUIView.tsx +++ b/src/modules/GroupChannel/components/GroupChannelUI/GroupChannelUIView.tsx @@ -1,42 +1,63 @@ import './index.scss'; import React from 'react'; -import type { GroupChannelUIProps } from '.'; import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext'; -import GroupChannelHeader, { type GroupChannelHeaderProps } from '../GroupChannelHeader'; -import MessageList from '../MessageList'; import TypingIndicator from '../TypingIndicator'; import { TypingIndicatorType } from '../../../../types'; import ConnectionStatus from '../../../../ui/ConnectionStatus'; import PlaceHolder, { PlaceHolderTypes } from '../../../../ui/PlaceHolder'; -import MessageInputWrapper from '../MessageInputWrapper'; -export interface GroupChannelUIViewProps extends GroupChannelUIProps, GroupChannelHeaderProps { - requestedChannelUrl: string; +import type { RenderCustomSeparatorProps, RenderMessageParamsType } from '../../../../types'; +import type { GroupChannelHeaderProps } from '../GroupChannelHeader'; +import type { GroupChannelMessageListProps } from '../MessageList'; +import type { MessageContentProps } from '../../../../ui/MessageContent'; + +export interface GroupChannelUIBasicProps { + // Components + renderPlaceholderLoader?: () => React.ReactElement; + renderPlaceholderInvalid?: () => React.ReactElement; + renderPlaceholderEmpty?: () => React.ReactElement; + renderChannelHeader?: (props: GroupChannelHeaderProps) => React.ReactElement; + renderMessageList?: (props: GroupChannelMessageListProps) => React.ReactElement; + renderMessageInput?: () => React.ReactElement; + + // Sub components + // MessageList + renderMessage?: (props: RenderMessageParamsType) => React.ReactElement; + renderMessageContent?: (props: MessageContentProps) => React.ReactElement; + renderCustomSeparator?: (props: RenderCustomSeparatorProps) => React.ReactElement; + renderFrozenNotification?: () => React.ReactElement; + + // MessageInput + renderFileUploadIcon?: () => React.ReactElement; + renderVoiceMessageIcon?: () => React.ReactElement; + renderSendMessageIcon?: () => React.ReactElement; + renderTypingIndicator?: () => React.ReactElement; +} + +export interface GroupChannelUIViewProps extends GroupChannelUIBasicProps { loading: boolean; isInvalid: boolean; + channelUrl: string; + renderChannelHeader: GroupChannelUIBasicProps['renderChannelHeader']; + renderMessageList: GroupChannelUIBasicProps['renderMessageList']; + renderMessageInput: GroupChannelUIBasicProps['renderMessageInput']; } export const GroupChannelUIView = (props: GroupChannelUIViewProps) => { const { - requestedChannelUrl, loading, isInvalid, - renderChannelHeader = (props) => ( - - ), - renderMessageList = (props) => ( - - ), - renderMessageInput = () => , + channelUrl, + renderChannelHeader, + renderMessageList, + renderMessageInput, renderTypingIndicator, renderPlaceholderLoader, renderPlaceholderInvalid, } = props; + const { stores, config } = useSendbirdStateContext(); const sdkError = stores?.sdkStore?.error; const { logger, isOnline } = config; @@ -45,9 +66,9 @@ export const GroupChannelUIView = (props: GroupChannelUIViewProps) => { return
{renderPlaceholderLoader?.() || }
; } - if (!requestedChannelUrl) { + if (!channelUrl) { return ( -
{renderPlaceholderInvalid?.() || }
+
{renderPlaceholderInvalid?.() || }
); } @@ -72,21 +93,16 @@ export const GroupChannelUIView = (props: GroupChannelUIViewProps) => { } return ( -
+
{renderChannelHeader?.({ className: 'sendbird-conversation__channel-header' })} {renderMessageList?.(props)}
{renderMessageInput?.()}
{renderTypingIndicator?.() - || ( - config?.groupChannel?.enableTypingIndicator - && config?.groupChannel?.typingIndicatorTypes?.has(TypingIndicatorType.Text) - && ( - - ) - ) - } + || (config?.groupChannel?.enableTypingIndicator && config?.groupChannel?.typingIndicatorTypes?.has(TypingIndicatorType.Text) && ( + + ))} {!isOnline && }
diff --git a/src/modules/GroupChannel/components/GroupChannelUI/index.tsx b/src/modules/GroupChannel/components/GroupChannelUI/index.tsx index 0e7734aea..2b02473e2 100644 --- a/src/modules/GroupChannel/components/GroupChannelUI/index.tsx +++ b/src/modules/GroupChannel/components/GroupChannelUI/index.tsx @@ -1,50 +1,35 @@ import React from 'react'; -import type { GroupChannelHeaderProps } from '../GroupChannelHeader'; -import type { MessageListProps } from '../../../Channel/components/MessageList'; -import type { GroupChannelMessageListProps } from '../MessageList'; -import { RenderCustomSeparatorProps, RenderMessageParamsType } from '../../../../types'; import { useGroupChannelContext } from '../../context/GroupChannelProvider'; -import { GroupChannelUIView } from './GroupChannelUIView'; -import type { MessageContentProps } from '../../../../ui/MessageContent'; +import { GroupChannelUIBasicProps, GroupChannelUIView } from './GroupChannelUIView'; + +import GroupChannelHeader from '../GroupChannelHeader'; +import MessageList from '../MessageList'; import MessageInputWrapper from '../MessageInputWrapper'; -export interface GroupChannelUIProps { - renderPlaceholderLoader?: () => React.ReactElement; - renderPlaceholderInvalid?: () => React.ReactElement; - renderPlaceholderEmpty?: () => React.ReactElement; - renderChannelHeader?: (props: GroupChannelHeaderProps) => React.ReactElement; - renderMessage?: (props: RenderMessageParamsType) => React.ReactElement; - renderMessageContent?: (props: MessageContentProps) => React.ReactElement; - renderMessageList?: (props: MessageListProps | GroupChannelMessageListProps) => React.ReactElement; - renderMessageInput?: () => React.ReactElement; - renderFileUploadIcon?: () => React.ReactElement; - renderVoiceMessageIcon?: () => React.ReactElement; - renderSendMessageIcon?: () => React.ReactElement; - renderTypingIndicator?: () => React.ReactElement; - renderCustomSeparator?: (props: RenderCustomSeparatorProps) => React.ReactElement; - renderFrozenNotification?: () => React.ReactElement; -} +export interface GroupChannelUIProps extends GroupChannelUIBasicProps {} export const GroupChannelUI = (props: GroupChannelUIProps) => { const context = useGroupChannelContext(); + const { currentChannel, channelUrl, loading } = context; + + // Inject components to presentation layer const { - currentChannel, - channelUrl, - loading, - } = context; + renderChannelHeader = (props) => , + renderMessageList = (props) => , + renderMessageInput = () => , + } = props; return ( ( - props.renderMessageInput?.() - ?? - )} + channelUrl={channelUrl} + renderChannelHeader={renderChannelHeader} + renderMessageList={renderMessageList} + renderMessageInput={renderMessageInput} /> ); };