Skip to content

Commit

Permalink
feat: handle message.new events in ChannelList with custom handler on…
Browse files Browse the repository at this point in the history
…MessageNewHandler
  • Loading branch information
MartinCupela committed Dec 19, 2023
1 parent 16dcc5d commit bd4a9a0
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 15 deletions.
12 changes: 10 additions & 2 deletions docusaurus/docs/React/components/core-components/channel-list.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ re-setting the list state, you can customize behavior and UI.
| `channel.truncated` | Updates the channel | [onChannelTruncated](#onchanneltruncated) |
| `channel.updated` | Updates the channel | [onChannelUpdated](#onchannelupdated) |
| `channel.visible` | Adds channel to list | [onChannelVisible](#onchannelvisible) |
| `connection.recovered` | Forces a component render | N/A |
| `message.new` | Moves channel to top of list | N/A |
| `connection.recovered` | Forces a component render | N/A |
| `message.new` | Moves channel to top of list | [onMessageNewHandler](#onmessagenewhandler) |
| `notification.added_to_channel` | Moves channel to top of list and starts watching | [onAddedToChannel](#onaddedtochannel) |
| `notification.message_new` | Moves channel to top of list and starts watching | [onMessageNew](#onmessagenew) |
| `notification.removed_from_channel` | Removes channel from list | [onRemovedFromChannel](#onremovedfromchannel) |
Expand Down Expand Up @@ -324,6 +324,14 @@ Function to override the default behavior when a message is received on a channe
| -------- |
| function |

### onMessageNewHandler

Function to override the default behavior when a message is received on a channel being watched. Handles `message.new` event.

| Type |
|-------------------------------------------------------------------------------------------------------------------------------------|
| `(setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>, event: Event<StreamChatGenerics>) => void` |

### onRemovedFromChannel

Function to override the default behavior when a user gets removed from a channel.
Expand Down
13 changes: 12 additions & 1 deletion src/components/ChannelList/ChannelList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ export type ChannelListProps<
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
event: Event<StreamChatGenerics>,
) => void;
/** 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 */
onMessageNewHandler?: (
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
event: Event<StreamChatGenerics>,
) => void;
/** 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 */
onRemovedFromChannel?: (
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
Expand Down Expand Up @@ -171,6 +176,7 @@ const UnMemoizedChannelList = <
onChannelUpdated,
onChannelVisible,
onMessageNew,
onMessageNewHandler,
onRemovedFromChannel,
options,
Paginator = LoadMorePaginator,
Expand Down Expand Up @@ -272,7 +278,12 @@ const UnMemoizedChannelList = <

useMobileNavigation(channelListRef, navOpen, closeMobileNav);

useMessageNewListener(setChannels, lockChannelOrder, allowNewMessagesFromUnfilteredChannels);
useMessageNewListener(
setChannels,
onMessageNewHandler,
lockChannelOrder,
allowNewMessagesFromUnfilteredChannels,
);
useNotificationMessageNewListener(
setChannels,
onMessageNew,
Expand Down
24 changes: 24 additions & 0 deletions src/components/ChannelList/__tests__/ChannelList.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,30 @@ describe('ChannelList', () => {
const results = await axe(container);
expect(results).toHaveNoViolations();
});

it('should execute custom event handler', async () => {
const onMessageNewEvent = jest.fn();
await act(() => {
render(
<Chat client={chatClient}>
<ChannelList {...props} onMessageNewHandler={onMessageNewEvent} />
</Chat>,
);
});
const message = sendNewMessageOnChannel3();
await waitFor(() => {
expect(onMessageNewEvent.mock.calls[0][0]).toStrictEqual(expect.any(Function));
expect(onMessageNewEvent.mock.calls[0][1]).toStrictEqual(
expect.objectContaining({
channel: testChannel3.channel,
cid: testChannel3.channel.cid,
message,
type: 'message.new',
user: message.user,
}),
);
});
});
});

describe('notification.message_new', () => {
Expand Down
32 changes: 20 additions & 12 deletions src/components/ChannelList/hooks/useMessageNewListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,33 @@ export const useMessageNewListener = <
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
>(
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
customHandler?: (
setChannels: React.Dispatch<React.SetStateAction<Array<Channel<StreamChatGenerics>>>>,
event: Event<StreamChatGenerics>,
) => void,
lockChannelOrder = false,
allowNewMessagesFromUnfilteredChannels = true,
) => {
const { client } = useChatContext<StreamChatGenerics>('useMessageNewListener');

useEffect(() => {
const handleEvent = (event: Event<StreamChatGenerics>) => {
setChannels((channels) => {
const channelInList = channels.filter((channel) => channel.cid === event.cid).length > 0;

if (!channelInList && allowNewMessagesFromUnfilteredChannels && event.channel_type) {
const channel = client.channel(event.channel_type, event.channel_id);
return uniqBy([channel, ...channels], 'cid');
}

if (!lockChannelOrder) return moveChannelUp({ channels, cid: event.cid || '' });

return channels;
});
if (customHandler && typeof customHandler === 'function') {
customHandler(setChannels, event);
} else {
setChannels((channels) => {
const channelInList = channels.filter((channel) => channel.cid === event.cid).length > 0;

if (!channelInList && allowNewMessagesFromUnfilteredChannels && event.channel_type) {
const channel = client.channel(event.channel_type, event.channel_id);
return uniqBy([channel, ...channels], 'cid');
}

if (!lockChannelOrder) return moveChannelUp({ channels, cid: event.cid || '' });

return channels;
});
}
};

client.on('message.new', handleEvent);
Expand Down

0 comments on commit bd4a9a0

Please sign in to comment.