Skip to content

Commit 825868a

Browse files
chohongmbang9
andauthored
fix: Support optional customize functions returning null case (#1047)
Fixes: [CLNP-2851](https://sendbird.atlassian.net/browse/CLNP-2851) ### Changelogs - Fixed a bug where injecting an optional property with null value not rendering the expected default component [CLNP-2851]: https://sendbird.atlassian.net/browse/CLNP-2851?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: bang9 <[email protected]>
1 parent b2cea9f commit 825868a

File tree

11 files changed

+138
-92
lines changed

11 files changed

+138
-92
lines changed

src/modules/Channel/components/ChannelUI/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { GroupChannelUIBasicProps, GroupChannelUIView } from '../../../GroupChan
66
import ChannelHeader from '../ChannelHeader';
77
import MessageList from '../MessageList';
88
import MessageInputWrapper from '../MessageInputWrapper';
9+
import { deleteNullish } from '../../../../utils/utils';
910

1011
export interface ChannelUIProps extends GroupChannelUIBasicProps {
1112
isLoading?: boolean;
@@ -24,7 +25,7 @@ const ChannelUI = (props: ChannelUIProps) => {
2425
renderChannelHeader = (p) => <ChannelHeader {...p} />,
2526
renderMessageList = (p) => <MessageList {...p} className="sendbird-conversation__message-list" />,
2627
renderMessageInput = () => <MessageInputWrapper {...props} />,
27-
} = props;
28+
} = deleteNullish(props);
2829

2930
return (
3031
<GroupChannelUIView

src/modules/Channel/components/MessageList/index.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { useOnScrollPositionChangeDetector } from '../../../../hooks/useOnScroll
2424
import { getMessagePartsInfo } from '../../../GroupChannel/components/MessageList/getMessagePartsInfo';
2525
import { GroupChannelMessageListProps } from '../../../GroupChannel/components/MessageList';
2626
import { GroupChannelUIBasicProps } from '../../../GroupChannel/components/GroupChannelUI/GroupChannelUIView';
27+
import { deleteNullish } from '../../../../utils/utils';
2728

2829
const SCROLL_BOTTOM_PADDING = 50;
2930

@@ -33,16 +34,18 @@ export interface MessageListProps extends GroupChannelMessageListProps {
3334
* */
3435
renderMessage?: GroupChannelUIBasicProps['renderMessage'];
3536
}
36-
export const MessageList = ({
37-
className = '',
38-
renderMessage,
39-
renderMessageContent,
40-
renderSuggestedReplies,
41-
renderCustomSeparator,
42-
renderPlaceholderLoader = () => <PlaceHolder type={PlaceHolderTypes.LOADING} />,
43-
renderPlaceholderEmpty = () => <PlaceHolder className="sendbird-conversation__no-messages" type={PlaceHolderTypes.NO_MESSAGES} />,
44-
renderFrozenNotification = () => <FrozenNotification className="sendbird-conversation__messages__notification" />,
45-
}: MessageListProps) => {
37+
export const MessageList = (props: MessageListProps) => {
38+
const { className = '' } = props;
39+
const {
40+
renderMessage,
41+
renderMessageContent,
42+
renderSuggestedReplies,
43+
renderCustomSeparator,
44+
renderPlaceholderLoader = () => <PlaceHolder type={PlaceHolderTypes.LOADING} />,
45+
renderPlaceholderEmpty = () => <PlaceHolder className="sendbird-conversation__no-messages" type={PlaceHolderTypes.NO_MESSAGES} />,
46+
renderFrozenNotification = () => <FrozenNotification className="sendbird-conversation__messages__notification" />,
47+
} = deleteNullish(props);
48+
4649
const {
4750
allMessages,
4851
localMessages,

src/modules/ChannelSettings/components/ChannelSettingsUI/index.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import React, { useContext, useState } from 'react';
55
import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext';
66
import { useChannelSettingsContext } from '../../context/ChannelSettingsProvider';
77

8-
import { ChannelSettingsHeader, type ChannelSettingsHeaderProps } from './ChannelSettingsHeader';
8+
import { ChannelSettingsHeader, ChannelSettingsHeaderProps } from './ChannelSettingsHeader';
99

1010
import PlaceHolder, { PlaceHolderTypes } from '../../../../ui/PlaceHolder';
1111
import Label, { LabelTypography, LabelColors } from '../../../../ui/Label';
@@ -15,6 +15,7 @@ import ChannelProfile from '../ChannelProfile';
1515
import ModerationPanel from '../ModerationPanel';
1616
import LeaveChannelModal from '../LeaveChannel';
1717
import UserPanel from '../UserPanel';
18+
import { deleteNullish } from '../../../../utils/utils';
1819

1920
export interface ChannelSettingsUIProps {
2021
renderHeader?: (props: ChannelSettingsHeaderProps) => React.ReactElement;
@@ -25,14 +26,16 @@ export interface ChannelSettingsUIProps {
2526
renderPlaceholderLoading?: () => React.ReactElement;
2627
}
2728

28-
const ChannelSettingsUI: React.FC<ChannelSettingsUIProps> = ({
29-
renderHeader = (props) => <ChannelSettingsHeader {...props}/>,
30-
renderLeaveChannel,
31-
renderChannelProfile,
32-
renderModerationPanel,
33-
renderPlaceholderError,
34-
renderPlaceholderLoading,
35-
}: ChannelSettingsUIProps) => {
29+
const ChannelSettingsUI = (props: ChannelSettingsUIProps) => {
30+
const {
31+
renderHeader = (p) => <ChannelSettingsHeader {...p} />,
32+
renderLeaveChannel,
33+
renderChannelProfile,
34+
renderModerationPanel,
35+
renderPlaceholderError,
36+
renderPlaceholderLoading,
37+
} = deleteNullish(props);
38+
3639
const state = useSendbirdStateContext();
3740
const isOnline = state?.config?.isOnline;
3841
const { stringSet } = useContext(LocalizationContext);

src/modules/GroupChannel/components/GroupChannelUI/GroupChannelUIView.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type { GroupChannelHeaderProps } from '../GroupChannelHeader';
1313
import type { GroupChannelMessageListProps } from '../MessageList';
1414
import type { MessageContentProps } from '../../../../ui/MessageContent';
1515
import { SuggestedRepliesProps } from '../SuggestedReplies';
16+
import { deleteNullish } from '../../../../utils/utils';
1617

1718
export interface GroupChannelUIBasicProps {
1819
// Components
@@ -93,17 +94,15 @@ export interface GroupChannelUIViewProps extends GroupChannelUIBasicProps {
9394
}
9495

9596
export const GroupChannelUIView = (props: GroupChannelUIViewProps) => {
97+
const { isLoading, isInvalid, channelUrl } = props;
9698
const {
97-
isLoading,
98-
isInvalid,
99-
channelUrl,
10099
renderChannelHeader,
101100
renderMessageList,
102101
renderMessageInput,
103102
renderTypingIndicator,
104103
renderPlaceholderLoader,
105104
renderPlaceholderInvalid,
106-
} = props;
105+
} = deleteNullish(props);
107106

108107
const { stores, config } = useSendbirdStateContext();
109108
const sdkError = stores?.sdkStore?.error;

src/modules/GroupChannel/components/GroupChannelUI/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { GroupChannelUIBasicProps, GroupChannelUIView } from './GroupChannelUIVi
66
import GroupChannelHeader from '../GroupChannelHeader';
77
import MessageList from '../MessageList';
88
import MessageInputWrapper from '../MessageInputWrapper';
9+
import { deleteNullish } from '../../../../utils/utils';
910

1011
export interface GroupChannelUIProps extends GroupChannelUIBasicProps {}
1112

@@ -18,7 +19,7 @@ export const GroupChannelUI = (props: GroupChannelUIProps) => {
1819
renderChannelHeader = (props) => <GroupChannelHeader {...props} />,
1920
renderMessageList = (props) => <MessageList {...props} className="sendbird-conversation__message-list" />,
2021
renderMessageInput = () => <MessageInputWrapper {...props} />,
21-
} = props;
22+
} = deleteNullish(props);
2223

2324
return (
2425
<GroupChannelUIView

src/modules/GroupChannel/components/Message/MessageView.tsx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import MessageContent, { MessageContentProps } from '../../../../ui/MessageConte
2121
import SuggestedReplies, { SuggestedRepliesProps } from '../SuggestedReplies';
2222
import SuggestedMentionListView from '../SuggestedMentionList/SuggestedMentionListView';
2323
import type { OnBeforeDownloadFileMessageType } from '../../context/GroupChannelProvider';
24+
import { deleteNullish } from '../../../../utils/utils';
2425

2526
export interface MessageProps {
2627
message: EveryMessage;
@@ -83,7 +84,7 @@ export interface MessageViewProps extends MessageProps {
8384
/**
8485
* You can't use this prop in the Channel component (legacy).
8586
* Accepting this prop only for the GroupChannel.
86-
*/
87+
*/
8788
onBeforeDownloadFileMessage?: OnBeforeDownloadFileMessageType;
8889

8990
animatedMessageId: number;
@@ -103,14 +104,7 @@ const MessageView = (props: MessageViewProps) => {
103104
const {
104105
// MessageProps
105106
message,
106-
renderMessage,
107107
children,
108-
renderMessageContent = (props) => <MessageContent {...props} />,
109-
renderSuggestedReplies = (props) => (
110-
<SuggestedReplies {...props} />
111-
),
112-
renderCustomSeparator,
113-
renderEditInput,
114108
hasSeparator,
115109
chainTop,
116110
chainBottom,
@@ -126,7 +120,6 @@ const MessageView = (props: MessageViewProps) => {
126120
threadReplySelectType,
127121
nicknamesMap,
128122

129-
renderUserMentionItem,
130123
scrollToMessage,
131124
toggleReaction,
132125
setQuoteMessage,
@@ -139,15 +132,23 @@ const MessageView = (props: MessageViewProps) => {
139132
resendMessage,
140133
deleteMessage,
141134

142-
renderFileViewer,
143-
renderRemoveMessageModal,
144-
145135
setAnimatedMessageId,
146136
animatedMessageId,
147137
onMessageAnimated,
148138
usedInLegacy = true,
149139
} = props;
150140

141+
const {
142+
renderUserMentionItem,
143+
renderMessage,
144+
renderMessageContent = (props) => <MessageContent {...props} />,
145+
renderSuggestedReplies = (props) => <SuggestedReplies {...props} />,
146+
renderCustomSeparator,
147+
renderEditInput,
148+
renderFileViewer,
149+
renderRemoveMessageModal,
150+
} = deleteNullish(props);
151+
151152
const { dateLocale, stringSet } = useLocalization();
152153
const globalStore = useSendbirdStateContext();
153154

src/modules/GroupChannel/components/MessageList/index.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import TypingIndicatorBubble from '../../../../ui/TypingIndicatorBubble';
1919
import { useGroupChannelContext } from '../../context/GroupChannelProvider';
2020
import { getComponentKeyFromMessage } from '../../context/utils';
2121
import { GroupChannelUIBasicProps } from '../GroupChannelUI/GroupChannelUIView';
22+
import { deleteNullish } from '../../../../utils/utils';
2223

2324
export interface GroupChannelMessageListProps {
2425
className?: string;
@@ -52,16 +53,18 @@ export interface GroupChannelMessageListProps {
5253
renderSuggestedReplies?: GroupChannelUIBasicProps['renderSuggestedReplies'];
5354
}
5455

55-
export const MessageList = ({
56-
className = '',
57-
renderMessage = (props) => <Message {...props} />,
58-
renderMessageContent,
59-
renderSuggestedReplies,
60-
renderCustomSeparator,
61-
renderPlaceholderLoader = () => <PlaceHolder type={PlaceHolderTypes.LOADING} />,
62-
renderPlaceholderEmpty = () => <PlaceHolder className="sendbird-conversation__no-messages" type={PlaceHolderTypes.NO_MESSAGES} />,
63-
renderFrozenNotification = () => <FrozenNotification className="sendbird-conversation__messages__notification" />,
64-
}: GroupChannelMessageListProps) => {
56+
export const MessageList = (props: GroupChannelMessageListProps) => {
57+
const { className = '' } = props;
58+
const {
59+
renderMessage = (props) => <Message {...props} />,
60+
renderMessageContent,
61+
renderSuggestedReplies,
62+
renderCustomSeparator,
63+
renderPlaceholderLoader = () => <PlaceHolder type={PlaceHolderTypes.LOADING} />,
64+
renderPlaceholderEmpty = () => <PlaceHolder className="sendbird-conversation__no-messages" type={PlaceHolderTypes.NO_MESSAGES} />,
65+
renderFrozenNotification = () => <FrozenNotification className="sendbird-conversation__messages__notification" />,
66+
} = deleteNullish(props);
67+
6568
const {
6669
channelUrl,
6770
hasNext,

src/ui/MessageContent/index.tsx

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { useMediaQueryContext } from '../../lib/MediaQueryContext';
3434
import ThreadReplies from '../ThreadReplies';
3535
import { ThreadReplySelectType } from '../../modules/Channel/context/const';
3636
import { Nullable, ReplyType } from '../../types';
37-
import { noop } from '../../utils/utils';
37+
import { deleteNullish, noop } from '../../utils/utils';
3838
import MessageProfile, { MessageProfileProps } from './MessageProfile';
3939
import MessageBody, { MessageBodyProps } from './MessageBody';
4040
import MessageHeader, { MessageHeaderProps } from './MessageHeader';
@@ -113,31 +113,19 @@ export default function MessageContent(props: MessageContentProps): ReactElement
113113
onQuoteMessageClick,
114114
onMessageHeightChange,
115115
onBeforeDownloadFileMessage,
116-
117-
// Public props for customization
118-
renderSenderProfile = (props: MessageProfileProps) => (
119-
<MessageProfile {...props}/>
120-
),
121-
renderMessageBody = (props: MessageBodyProps) => (
122-
<MessageBody {...props}/>
123-
),
124-
renderMessageHeader = (props: MessageHeaderProps) => (
125-
<MessageHeader {...props}/>
126-
),
127-
renderMessageMenu = (props: MessageMenuProps) => (
128-
<MessageMenu {...props} />
129-
),
130-
renderEmojiMenu = (props: MessageEmojiMenuProps) => (
131-
<MessageEmojiMenu {...props} />
132-
),
133-
renderEmojiReactions = (props: EmojiReactionsProps) => (
134-
<EmojiReactions {...props} />
135-
),
136-
renderMobileMenuOnLongPress = (props: MobileBottomSheetProps) => (
137-
<MobileMenu {...props} />
138-
),
139116
} = props;
140117

118+
// Public props for customization
119+
const {
120+
renderSenderProfile = (props: MessageProfileProps) => <MessageProfile {...props} />,
121+
renderMessageBody = (props: MessageBodyProps) => <MessageBody {...props} />,
122+
renderMessageHeader = (props: MessageHeaderProps) => <MessageHeader {...props} />,
123+
renderMessageMenu = (props: MessageMenuProps) => <MessageMenu {...props} />,
124+
renderEmojiMenu = (props: MessageEmojiMenuProps) => <MessageEmojiMenu {...props} />,
125+
renderEmojiReactions = (props: EmojiReactionsProps) => <EmojiReactions {...props} />,
126+
renderMobileMenuOnLongPress = (props: MobileBottomSheetProps) => <MobileMenu {...props} />,
127+
} = deleteNullish(props);
128+
141129
const { dateLocale } = useLocalization();
142130
const { config, eventHandlers } = useSendbirdStateContext?.() || {};
143131
const { logger } = config;

src/ui/MessageItemMenu/index.tsx

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
import { LocalizationContext } from '../../lib/LocalizationContext';
2020
import { Role } from '../../lib/types';
2121
import { ReplyType } from '../../types';
22+
import { deleteNullish } from '../../utils/utils';
2223

2324
export interface MessageMenuRenderMenuItemProps {
2425
className?: string;
@@ -46,26 +47,27 @@ export interface MessageMenuProps {
4647
renderMenuItem?: (props: MessageMenuRenderMenuItemProps) => ReactElement;
4748
}
4849

49-
export function MessageMenu({
50-
className,
51-
message,
52-
channel,
53-
isByMe = false,
54-
disabled = false,
55-
replyType,
56-
disableDeleteMessage = null,
57-
showEdit,
58-
showRemove,
59-
deleteMessage,
60-
resendMessage,
61-
setQuoteMessage,
62-
setSupposedHover,
63-
onReplyInThread,
64-
onMoveToParentMessage = null,
65-
renderMenuItem = (props: MessageMenuRenderMenuItemProps) => (
66-
<MenuItem {...props}>{props.text}</MenuItem>
67-
),
68-
}: MessageMenuProps): ReactElement {
50+
export function MessageMenu(props: MessageMenuProps): ReactElement {
51+
const {
52+
className,
53+
message,
54+
channel,
55+
isByMe = false,
56+
disabled = false,
57+
replyType,
58+
disableDeleteMessage = null,
59+
showEdit,
60+
showRemove,
61+
deleteMessage,
62+
resendMessage,
63+
setQuoteMessage,
64+
setSupposedHover,
65+
onReplyInThread,
66+
onMoveToParentMessage = null,
67+
} = props;
68+
69+
const { renderMenuItem = (props: MessageMenuRenderMenuItemProps) => <MenuItem {...props}>{props.text}</MenuItem> } = deleteNullish(props);
70+
6971
const { stringSet } = useContext(LocalizationContext);
7072
const triggerRef = useRef(null);
7173
const containerRef = useRef(null);

0 commit comments

Comments
 (0)