Skip to content

Commit 7ffeeaf

Browse files
authored
feat: handle message.new events in ChannelList with custom handler onMessageNewHandler (#2221)
1 parent df8988e commit 7ffeeaf

File tree

4 files changed

+66
-15
lines changed

4 files changed

+66
-15
lines changed

docusaurus/docs/React/components/core-components/channel-list.mdx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ re-setting the list state, you can customize behavior and UI.
111111
| `channel.truncated` | Updates the channel | [onChannelTruncated](#onchanneltruncated) |
112112
| `channel.updated` | Updates the channel | [onChannelUpdated](#onchannelupdated) |
113113
| `channel.visible` | Adds channel to list | [onChannelVisible](#onchannelvisible) |
114-
| `connection.recovered` | Forces a component render | N/A |
115-
| `message.new` | Moves channel to top of list | N/A |
114+
| `connection.recovered` | Forces a component render | N/A |
115+
| `message.new` | Moves channel to top of list | [onMessageNewHandler](#onmessagenewhandler) |
116116
| `notification.added_to_channel` | Moves channel to top of list and starts watching | [onAddedToChannel](#onaddedtochannel) |
117117
| `notification.message_new` | Moves channel to top of list and starts watching | [onMessageNew](#onmessagenew) |
118118
| `notification.removed_from_channel` | Removes channel from list | [onRemovedFromChannel](#onremovedfromchannel) |
@@ -324,6 +324,14 @@ Function to override the default behavior when a message is received on a channe
324324
| -------- |
325325
| function |
326326

327+
### onMessageNewHandler
328+
329+
Function to override the default behavior when a message is received on a channel being watched. Handles `message.new` event.
330+
331+
| Type |
332+
|-------------------------------------------------------------------------------------------------------------------------------------|
333+
| `(setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>, event: Event<StreamChatGenerics>) => void` |
334+
327335
### onRemovedFromChannel
328336

329337
Function to override the default behavior when a user gets removed from a channel.

src/components/ChannelList/ChannelList.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ export type ChannelListProps<
111111
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
112112
event: Event<StreamChatGenerics>,
113113
) => void;
114+
/** Function to override the default behavior when a message is received on a channel being watched, handles [message.new](https://getstream.io/chat/docs/javascript/event_object/?language=javascript) event */
115+
onMessageNewHandler?: (
116+
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
117+
event: Event<StreamChatGenerics>,
118+
) => void;
114119
/** Function to override the default behavior when a user gets removed from a channel, corresponds to [notification.removed\_from\_channel](https://getstream.io/chat/docs/javascript/event_object/?language=javascript) event */
115120
onRemovedFromChannel?: (
116121
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
@@ -171,6 +176,7 @@ const UnMemoizedChannelList = <
171176
onChannelUpdated,
172177
onChannelVisible,
173178
onMessageNew,
179+
onMessageNewHandler,
174180
onRemovedFromChannel,
175181
options,
176182
Paginator = LoadMorePaginator,
@@ -272,7 +278,12 @@ const UnMemoizedChannelList = <
272278

273279
useMobileNavigation(channelListRef, navOpen, closeMobileNav);
274280

275-
useMessageNewListener(setChannels, lockChannelOrder, allowNewMessagesFromUnfilteredChannels);
281+
useMessageNewListener(
282+
setChannels,
283+
onMessageNewHandler,
284+
lockChannelOrder,
285+
allowNewMessagesFromUnfilteredChannels,
286+
);
276287
useNotificationMessageNewListener(
277288
setChannels,
278289
onMessageNew,

src/components/ChannelList/__tests__/ChannelList.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,30 @@ describe('ChannelList', () => {
875875
const results = await axe(container);
876876
expect(results).toHaveNoViolations();
877877
});
878+
879+
it('should execute custom event handler', async () => {
880+
const onMessageNewEvent = jest.fn();
881+
await act(() => {
882+
render(
883+
<Chat client={chatClient}>
884+
<ChannelList {...props} onMessageNewHandler={onMessageNewEvent} />
885+
</Chat>,
886+
);
887+
});
888+
const message = sendNewMessageOnChannel3();
889+
await waitFor(() => {
890+
expect(onMessageNewEvent.mock.calls[0][0]).toStrictEqual(expect.any(Function));
891+
expect(onMessageNewEvent.mock.calls[0][1]).toStrictEqual(
892+
expect.objectContaining({
893+
channel: testChannel3.channel,
894+
cid: testChannel3.channel.cid,
895+
message,
896+
type: 'message.new',
897+
user: message.user,
898+
}),
899+
);
900+
});
901+
});
878902
});
879903

880904
describe('notification.message_new', () => {

src/components/ChannelList/hooks/useMessageNewListener.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,33 @@ export const useMessageNewListener = <
1313
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
1414
>(
1515
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
16+
customHandler?: (
17+
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
18+
event: Event<StreamChatGenerics>,
19+
) => void,
1620
lockChannelOrder = false,
1721
allowNewMessagesFromUnfilteredChannels = true,
1822
) => {
1923
const { client } = useChatContext<StreamChatGenerics>('useMessageNewListener');
2024

2125
useEffect(() => {
2226
const handleEvent = (event: Event<StreamChatGenerics>) => {
23-
setChannels((channels) => {
24-
const channelInList = channels.filter((channel) => channel.cid === event.cid).length > 0;
25-
26-
if (!channelInList && allowNewMessagesFromUnfilteredChannels && event.channel_type) {
27-
const channel = client.channel(event.channel_type, event.channel_id);
28-
return uniqBy([channel, ...channels], 'cid');
29-
}
30-
31-
if (!lockChannelOrder) return moveChannelUp({ channels, cid: event.cid || '' });
32-
33-
return channels;
34-
});
27+
if (customHandler && typeof customHandler === 'function') {
28+
customHandler(setChannels, event);
29+
} else {
30+
setChannels((channels) => {
31+
const channelInList = channels.filter((channel) => channel.cid === event.cid).length > 0;
32+
33+
if (!channelInList && allowNewMessagesFromUnfilteredChannels && event.channel_type) {
34+
const channel = client.channel(event.channel_type, event.channel_id);
35+
return uniqBy([channel, ...channels], 'cid');
36+
}
37+
38+
if (!lockChannelOrder) return moveChannelUp({ channels, cid: event.cid || '' });
39+
40+
return channels;
41+
});
42+
}
3543
};
3644

3745
client.on('message.new', handleEvent);

0 commit comments

Comments
 (0)