Skip to content

Commit 5c473d3

Browse files
authored
feat: reaction list top redesign (#3428)
This pull request refactors the message reaction list UI components to simplify the codebase, improve maintainability, and enhance layout flexibility. The main changes include removing redundant code for reaction items, introducing a new clustered reaction list layout, and updating prop handling and styling for better alignment and customization. **Reaction List Refactor and UI Improvements:** - Replaced the segmented reaction list type with a new 'clustered' layout as the default for `reactionListType`, and updated all relevant components to support this change (`Channel.tsx`, `MessageBubble.tsx`). [[1]](diffhunk://#diff-f7139f4cdb523365cfc277d72b827a3432325b9c6460cf14628f9df67d0e4d85L712-R712) [[2]](diffhunk://#diff-78869e39c4e5a321d52b07aae9183d0bc2aff8c2f2a2d7405cb2547740865793L54-R102) - Refactored `ReactionListBottom` to delegate clustered reaction rendering to the new `ReactionListClustered` component, removing the old segmented logic and redundant icon/count code. Reaction items now consistently use `ReactionListItem` (`ReactionListBottom.tsx`). [[1]](diffhunk://#diff-926ded9f8a41b99e3b915a72424b44c11631585a26cfc0fa236d68979dafddb6L2-R5) [[2]](diffhunk://#diff-926ded9f8a41b99e3b915a72424b44c11631585a26cfc0fa236d68979dafddb6L16-R20) [[3]](diffhunk://#diff-926ded9f8a41b99e3b915a72424b44c11631585a26cfc0fa236d68979dafddb6L270-R141) - Updated prop types and usage for reaction list components, ensuring consistent passing of `reactionListType`, alignment, and removing unused or redundant props such as `hasReactions` (`MessageBubble.tsx`, `MessageSimple.tsx`). [[1]](diffhunk://#diff-78869e39c4e5a321d52b07aae9183d0bc2aff8c2f2a2d7405cb2547740865793L25-R47) [[2]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83L52) [[3]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83L101) [[4]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83L226-R225) [[5]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83R237-R245) [[6]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83R255) [[7]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83L296) [[8]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83L307) [[9]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83L316-L320) [[10]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83L430) [[11]](diffhunk://#diff-6c4943fcf0d32148b663091935ac039195d602cef7654b16bb93514ca2b3ba83L475) **Styling and Layout Enhancements:** - Improved alignment and container structure for message bubbles and reaction lists, including new style properties for wrappers and containers to better support left/right alignment and error states (`MessageBubble.tsx`). [[1]](diffhunk://#diff-78869e39c4e5a321d52b07aae9183d0bc2aff8c2f2a2d7405cb2547740865793L54-R102) [[2]](diffhunk://#diff-78869e39c4e5a321d52b07aae9183d0bc2aff8c2f2a2d7405cb2547740865793L226-R253) [[3]](diffhunk://#diff-78869e39c4e5a321d52b07aae9183d0bc2aff8c2f2a2d7405cb2547740865793R264-R265) - Cleaned up and simplified style hooks in `ReactionListBottom`, removing unused style properties and semantic color references for a leaner implementation (`ReactionListBottom.tsx`). [[1]](diffhunk://#diff-926ded9f8a41b99e3b915a72424b44c11631585a26cfc0fa236d68979dafddb6L321-R153) [[2]](diffhunk://#diff-926ded9f8a41b99e3b915a72424b44c11631585a26cfc0fa236d68979dafddb6L343-R173) These changes collectively modernize the reaction list UI, reduce code duplication, and provide more flexibility for future customization.
1 parent 1f8b90d commit 5c473d3

11 files changed

Lines changed: 1080 additions & 774 deletions

File tree

package/src/components/Channel/Channel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
709709
PollContent,
710710
ReactionListBottom = ReactionListBottomDefault,
711711
reactionListPosition = 'top',
712-
reactionListType = 'segmented',
712+
reactionListType = 'clustered',
713713
ReactionListTop = ReactionListTopDefault,
714714
Reply = ReplyDefault,
715715
ScrollToBottomButton = ScrollToBottomButtonDefault,

package/src/components/Message/MessageSimple/MessageBubble.tsx

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import Animated, {
1212

1313
import { MessageContentProps } from './MessageContent';
1414
import { MessageSimplePropsWithContext } from './MessageSimple';
15-
import { ReactionListTopProps } from './ReactionList/ReactionListTop';
1615

1716
import { MessagesContextValue, useTheme } from '../../../contexts';
1817

@@ -22,23 +21,30 @@ import { MessageStatusTypes } from '../../../utils/utils';
2221

2322
export type MessageBubbleProps = Pick<
2423
MessagesContextValue,
25-
'reactionListPosition' | 'MessageContent' | 'ReactionListTop' | 'MessageError'
24+
| 'reactionListPosition'
25+
| 'MessageContent'
26+
| 'ReactionListTop'
27+
| 'MessageError'
28+
| 'reactionListType'
2629
> &
2730
Pick<
2831
MessageContentProps,
2932
| 'isVeryLastMessage'
3033
| 'backgroundColor'
3134
| 'messageGroupedSingleOrBottom'
3235
| 'noBorder'
33-
| 'setMessageContentWidth'
3436
| 'message'
37+
| 'setMessageContentWidth'
3538
> &
36-
Pick<ReactionListTopProps, 'messageContentWidth'>;
39+
Pick<MessageSimplePropsWithContext, 'alignment'> & {
40+
messageContentWidth: number;
41+
};
3742

3843
export const MessageBubble = React.memo(
3944
({
45+
alignment,
4046
reactionListPosition,
41-
messageContentWidth,
47+
reactionListType,
4248
setMessageContentWidth,
4349
MessageContent,
4450
ReactionListTop,
@@ -51,29 +57,48 @@ export const MessageBubble = React.memo(
5157
}: MessageBubbleProps) => {
5258
const {
5359
theme: {
54-
messageSimple: { contentContainer },
60+
messageSimple: {
61+
bubble: { contentContainer, errorContainer, reactionListTopContainer, wrapper },
62+
},
5563
},
5664
} = useTheme();
5765
const isMessageErrorType =
5866
message?.type === 'error' || message?.status === MessageStatusTypes.FAILED;
5967

6068
return (
61-
<View style={[styles.contentContainer, contentContainer]}>
62-
<MessageContent
63-
backgroundColor={backgroundColor}
64-
isVeryLastMessage={isVeryLastMessage}
65-
messageGroupedSingleOrBottom={messageGroupedSingleOrBottom}
66-
noBorder={noBorder}
67-
setMessageContentWidth={setMessageContentWidth}
68-
/>
69+
<View style={[styles.wrapper, wrapper]}>
6970
{reactionListPosition === 'top' && ReactionListTop ? (
70-
<ReactionListTop messageContentWidth={messageContentWidth} />
71-
) : null}
72-
{isMessageErrorType ? (
73-
<View style={styles.errorContainer}>
74-
<MessageError />
71+
<View
72+
style={[
73+
styles.reactionListTopContainer,
74+
reactionListTopContainer,
75+
{ alignSelf: alignment === 'left' ? 'flex-end' : 'flex-start' },
76+
]}
77+
>
78+
<ReactionListTop type={reactionListType} />
7579
</View>
7680
) : null}
81+
<View
82+
style={[
83+
styles.contentContainer,
84+
{ alignSelf: alignment === 'left' ? 'flex-start' : 'flex-end' },
85+
contentContainer,
86+
]}
87+
>
88+
<MessageContent
89+
backgroundColor={backgroundColor}
90+
isVeryLastMessage={isVeryLastMessage}
91+
messageGroupedSingleOrBottom={messageGroupedSingleOrBottom}
92+
noBorder={noBorder}
93+
setMessageContentWidth={setMessageContentWidth}
94+
/>
95+
96+
{isMessageErrorType ? (
97+
<View style={[styles.errorContainer, errorContainer]}>
98+
<MessageError />
99+
</View>
100+
) : null}
101+
</View>
77102
</View>
78103
);
79104
},
@@ -223,7 +248,9 @@ const styles = StyleSheet.create({
223248
flexDirection: 'row',
224249
zIndex: 1, // To hide the stick inside the message content
225250
},
226-
contentContainer: {},
251+
contentContainer: {
252+
alignSelf: 'flex-start',
253+
},
227254
swipeContentContainer: {
228255
flexShrink: 0,
229256
overflow: 'hidden',
@@ -234,4 +261,6 @@ const styles = StyleSheet.create({
234261
top: 8,
235262
right: -12,
236263
},
264+
reactionListTopContainer: {},
265+
wrapper: {},
237266
});

package/src/components/Message/MessageSimple/MessageSimple.tsx

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ export type MessageSimplePropsWithContext = Pick<
4949
| 'alignment'
5050
| 'channel'
5151
| 'groupStyles'
52-
| 'hasReactions'
5352
| 'isMyMessage'
5453
| 'message'
5554
| 'onlyEmojis'
@@ -98,7 +97,6 @@ const MessageSimpleWithContext = forwardRef<View, MessageSimplePropsWithContext>
9897
enableMessageGroupingByUser,
9998
enableSwipeToReply,
10099
groupStyles,
101-
hasReactions,
102100
isMyMessage,
103101
message,
104102
MessageAvatar,
@@ -128,11 +126,9 @@ const MessageSimpleWithContext = forwardRef<View, MessageSimplePropsWithContext>
128126
container,
129127
repliesContainer,
130128
content: { container: contentContainer, errorContainer },
131-
headerWrapper,
132129
lastMessageContainer,
133130
messageGroupedSingleOrBottomContainer,
134131
messageGroupedTopContainer,
135-
reactionListTop: { position: reactionPosition },
136132
},
137133
},
138134
} = useTheme();
@@ -218,23 +214,10 @@ const MessageSimpleWithContext = forwardRef<View, MessageSimplePropsWithContext>
218214
]}
219215
testID='message-components'
220216
>
221-
{/* TODO: Find a better way to avoid Remounting here. */}
222-
{reactionListPosition === 'top' && hasReactions ? (
223-
<View
224-
style={[
225-
{
226-
paddingBottom: reactionPosition,
227-
},
228-
headerWrapper,
229-
]}
230-
>
231-
<MessageHeader />
232-
</View>
233-
) : (
234-
<MessageHeader />
235-
)}
217+
<MessageHeader />
236218
{enableSwipeToReply ? (
237219
<SwipableMessageBubble
220+
alignment={alignment}
238221
backgroundColor={backgroundColor}
239222
isVeryLastMessage={isVeryLastMessage}
240223
MessageContent={MessageContent}
@@ -246,13 +229,15 @@ const MessageSimpleWithContext = forwardRef<View, MessageSimplePropsWithContext>
246229
noBorder={noBorder}
247230
onSwipe={onSwipeActionHandler}
248231
reactionListPosition={reactionListPosition}
232+
reactionListType={reactionListType}
249233
ReactionListTop={ReactionListTop}
250234
setMessageContentWidth={setMessageContentWidth}
251235
shouldRenderSwipeableWrapper={shouldRenderSwipeableWrapper}
252236
message={message}
253237
/>
254238
) : (
255239
<MessageBubble
240+
alignment={alignment}
256241
backgroundColor={backgroundColor}
257242
isVeryLastMessage={isVeryLastMessage}
258243
MessageContent={MessageContent}
@@ -262,6 +247,7 @@ const MessageSimpleWithContext = forwardRef<View, MessageSimplePropsWithContext>
262247
noBorder={noBorder}
263248
reactionListPosition={reactionListPosition}
264249
ReactionListTop={ReactionListTop}
250+
reactionListType={reactionListType}
265251
setMessageContentWidth={setMessageContentWidth}
266252
message={message}
267253
/>
@@ -289,7 +275,6 @@ const areEqual = (
289275
const {
290276
channel: prevChannel,
291277
groupStyles: prevGroupStyles,
292-
hasReactions: prevHasReactions,
293278
message: prevMessage,
294279
myMessageTheme: prevMyMessageTheme,
295280
onlyEmojis: prevOnlyEmojis,
@@ -300,7 +285,6 @@ const areEqual = (
300285
const {
301286
channel: nextChannel,
302287
groupStyles: nextGroupStyles,
303-
hasReactions: nextHasReactions,
304288
message: nextMessage,
305289
myMessageTheme: nextMyMessageTheme,
306290
onlyEmojis: nextOnlyEmojis,
@@ -309,11 +293,6 @@ const areEqual = (
309293
members: nextMembers,
310294
} = nextProps;
311295

312-
const hasReactionsEqual = prevHasReactions === nextHasReactions;
313-
if (!hasReactionsEqual) {
314-
return false;
315-
}
316-
317296
const groupStylesEqual = JSON.stringify(prevGroupStyles) === JSON.stringify(nextGroupStyles);
318297
if (!groupStylesEqual) {
319298
return false;
@@ -423,7 +402,6 @@ export const MessageSimple = forwardRef<View, MessageSimpleProps>((props, ref) =
423402
alignment,
424403
channel,
425404
groupStyles,
426-
hasReactions,
427405
isMyMessage,
428406
message,
429407
onlyEmojis,
@@ -468,7 +446,6 @@ export const MessageSimple = forwardRef<View, MessageSimpleProps>((props, ref) =
468446
enableMessageGroupingByUser,
469447
enableSwipeToReply,
470448
groupStyles,
471-
hasReactions,
472449
isMyMessage,
473450
message,
474451
MessageAvatar,

0 commit comments

Comments
 (0)