Skip to content

Commit c0b6dce

Browse files
Merge pull request #623 from GetStream/onchannelvisible-prop-channellist
CRNS-279: Handle channel.visible event
2 parents 032e4c2 + 2e6328b commit c0b6dce

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

src/components/ChannelList/ChannelList.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ import { useChannelDeleted } from './hooks/listeners/useChannelDeleted';
1313
import { useChannelHidden } from './hooks/listeners/useChannelHidden';
1414
import { useChannelTruncated } from './hooks/listeners/useChannelTruncated';
1515
import { useChannelUpdated } from './hooks/listeners/useChannelUpdated';
16+
import { useChannelVisible } from './hooks/listeners/useChannelVisible';
1617
import { useConnectionRecovered } from './hooks/listeners/useConnectionRecovered';
1718
import { useNewMessage } from './hooks/listeners/useNewMessage';
1819
import { useNewMessageNotification } from './hooks/listeners/useNewMessageNotification';
19-
import { useCreateChannelsContext } from './hooks/useCreateChannelsContext';
20-
import { usePaginatedChannels } from './hooks/usePaginatedChannels';
2120
import { useRemovedFromChannelNotification } from './hooks/listeners/useRemovedFromChannelNotification';
2221
import { useUserPresence } from './hooks/listeners/useUserPresence';
22+
import { useCreateChannelsContext } from './hooks/useCreateChannelsContext';
23+
import { usePaginatedChannels } from './hooks/usePaginatedChannels';
2324
import { Skeleton as SkeletonDefault } from './Skeleton';
2425

2526
import { ChannelPreviewMessenger } from '../ChannelPreview/ChannelPreviewMessenger';
@@ -174,6 +175,20 @@ export type ChannelListProps<
174175
>,
175176
event: Event<At, Ch, Co, Ev, Me, Re, Us>,
176177
) => void;
178+
/**
179+
* Function that overrides default behavior when a channel gets visible. In absence of this prop, the channel will be added to the list.
180+
*
181+
* @param setChannels Setter for internal state property - `channels`. It's created from useState() hook.
182+
* @param event An [Event object](https://getstream.io/chat/docs/event_object) corresponding to `channel.visible` event
183+
*
184+
* @overrideType Function
185+
* */
186+
onChannelVisible?: (
187+
setChannels: React.Dispatch<
188+
React.SetStateAction<Channel<At, Ch, Co, Ev, Me, Re, Us>[]>
189+
>,
190+
event: Event<At, Ch, Co, Ev, Me, Re, Us>,
191+
) => void;
177192
/**
178193
* Override the default listener/handler for event `notification.message_new`
179194
* This event is received on channel, which is not being watched.
@@ -256,6 +271,7 @@ export const ChannelList = <
256271
onAddedToChannel,
257272
onChannelDeleted,
258273
onChannelHidden,
274+
onChannelVisible,
259275
onChannelTruncated,
260276
onChannelUpdated,
261277
onMessageNew,
@@ -320,6 +336,11 @@ export const ChannelList = <
320336
setChannels,
321337
});
322338

339+
useChannelVisible({
340+
onChannelVisible,
341+
setChannels,
342+
});
343+
323344
useConnectionRecovered<At, Ch, Co, Ev, Me, Re, Us>({
324345
refreshList,
325346
setForceUpdate,
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { useEffect } from 'react';
2+
import uniqBy from 'lodash/uniqBy';
3+
4+
import { useChatContext } from '../../../../contexts/chatContext/ChatContext';
5+
import { getChannel } from '../../utils';
6+
7+
import type { Channel, Event } from 'stream-chat';
8+
9+
import type {
10+
DefaultAttachmentType,
11+
DefaultChannelType,
12+
DefaultCommandType,
13+
DefaultEventType,
14+
DefaultMessageType,
15+
DefaultReactionType,
16+
DefaultUserType,
17+
UnknownType,
18+
} from '../../../../types/types';
19+
20+
type Parameters<
21+
At extends UnknownType = DefaultAttachmentType,
22+
Ch extends UnknownType = DefaultChannelType,
23+
Co extends string = DefaultCommandType,
24+
Ev extends UnknownType = DefaultEventType,
25+
Me extends UnknownType = DefaultMessageType,
26+
Re extends UnknownType = DefaultReactionType,
27+
Us extends UnknownType = DefaultUserType
28+
> = {
29+
setChannels: React.Dispatch<
30+
React.SetStateAction<Channel<At, Ch, Co, Ev, Me, Re, Us>[]>
31+
>;
32+
onChannelVisible?: (
33+
setChannels: React.Dispatch<
34+
React.SetStateAction<Channel<At, Ch, Co, Ev, Me, Re, Us>[]>
35+
>,
36+
event: Event<At, Ch, Co, Ev, Me, Re, Us>,
37+
) => void;
38+
};
39+
40+
export const useChannelVisible = <
41+
At extends UnknownType = DefaultAttachmentType,
42+
Ch extends UnknownType = DefaultChannelType,
43+
Co extends string = DefaultCommandType,
44+
Ev extends UnknownType = DefaultEventType,
45+
Me extends UnknownType = DefaultMessageType,
46+
Re extends UnknownType = DefaultReactionType,
47+
Us extends UnknownType = DefaultUserType
48+
>({
49+
onChannelVisible,
50+
setChannels,
51+
}: Parameters<At, Ch, Co, Ev, Me, Re, Us>) => {
52+
const { client } = useChatContext<At, Ch, Co, Ev, Me, Re, Us>();
53+
54+
useEffect(() => {
55+
const handleEvent = async (event: Event<At, Ch, Co, Ev, Me, Re, Us>) => {
56+
if (typeof onChannelVisible === 'function') {
57+
onChannelVisible(setChannels, event);
58+
} else {
59+
if (event.channel_id && event.channel_type) {
60+
const channel = await getChannel<At, Ch, Co, Ev, Me, Re, Us>({
61+
client,
62+
id: event.channel_id,
63+
type: event.channel_type,
64+
});
65+
setChannels((channels) => uniqBy([channel, ...channels], 'cid'));
66+
}
67+
}
68+
};
69+
70+
client.on('channel.visible', handleEvent);
71+
return () => client.off('channel.visible', handleEvent);
72+
}, []);
73+
};

0 commit comments

Comments
 (0)