Skip to content

Commit 443952d

Browse files
committed
Merge branch 'master' into feature/pinned-messages
2 parents c556c70 + 93ab582 commit 443952d

File tree

10 files changed

+79
-12
lines changed

10 files changed

+79
-12
lines changed

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
# Changelog
22

3+
## [3.5.3](https://github.com/GetStream/stream-chat-react/releases/tag/v3.5.3) 2021-01-26
4+
5+
### Feature
6+
7+
- `ChannelList` accepts an optional prop to filter/sort channels prior to render [#678](https://github.com/GetStream/stream-chat-react/pull/678)
8+
9+
## [3.5.2](https://github.com/GetStream/stream-chat-react/releases/tag/v3.5.2) 2021-01-21
10+
11+
### Fix
12+
13+
- Handle emoji picker event listener race condition [#675](https://github.com/GetStream/stream-chat-react/pull/675)
14+
- Adjust style for only emoji messages [#676](https://github.com/GetStream/stream-chat-react/pull/676)
15+
316
## [3.5.1](https://github.com/GetStream/stream-chat-react/releases/tag/v3.5.1) 2021-01-19
417

518
### Fix
619

7-
- Upload PSD attachments as file [#67](https://github.com/GetStream/stream-chat-react/pull/673)
20+
- Upload PSD attachments as file [#673](https://github.com/GetStream/stream-chat-react/pull/673)
821

922
### Chore
1023

docs/build/bundle.c0da581c.js renamed to docs/build/bundle.33cc8b6e.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
</head>
1010
<body>
1111
<div id="rsg-root"></div>
12-
<script src="build/bundle.c0da581c.js"></script>
12+
<script src="build/bundle.33cc8b6e.js"></script>
1313
</body>
1414
</html>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "stream-chat-react",
3-
"version": "3.5.1",
3+
"version": "3.5.3",
44
"description": "React components to create chat conversations or livestream style chat",
55
"author": "GetStream",
66
"homepage": "https://getstream.io/chat/",

src/components/ChannelList/ChannelList.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ const ChannelList = (props) => {
118118
activeChannelHandler,
119119
);
120120

121+
const loadedChannels = props.channelRenderFilterFn
122+
? props.channelRenderFilterFn(channels)
123+
: channels;
124+
121125
useMobileNavigation(channelListRef, navOpen, closeMobileNav);
122126

123127
// All the event listeners
@@ -216,13 +220,13 @@ const ChannelList = (props) => {
216220
LoadingIndicator={LoadingIndicator}
217221
LoadingErrorIndicator={LoadingErrorIndicator}
218222
>
219-
{!channels || channels.length === 0
223+
{!loadedChannels || loadedChannels.length === 0
220224
? renderEmptyStateIndicator()
221225
: smartRender(Paginator, {
222226
loadNextPage,
223227
hasNextPage,
224228
refreshing: status.refreshing,
225-
children: channels.map((item) => renderChannel(item)),
229+
children: loadedChannels.map(renderChannel),
226230
})}
227231
</List>
228232
);
@@ -352,6 +356,13 @@ ChannelList.propTypes = {
352356
* @param {Event} event [Event object](https://getstream.io/chat/docs/event_object/?language=js) corresponding to `channel.deleted` event
353357
* */
354358
onChannelDeleted: PropTypes.func,
359+
/**
360+
* Optional function to filter channels prior to loading in the DOM. Do not use any complex or async logic here that would significantly delay the loading of the ChannelList.
361+
* We recommend using a pure function with array methods like filter/sort/reduce.
362+
* @param {Array} channels
363+
* @returns {Array} channels
364+
* */
365+
channelRenderFilterFn: /** @type {PropTypes.Validator<(channels: import('stream-chat').Channel[]) => import('stream-chat').Channel[]>} */ (PropTypes.func),
355366
/**
356367
* Object containing query filters
357368
* @see See [Channel query documentation](https://getstream.io/chat/docs/query_channels/?language=js) for a list of available fields for filter.

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,37 @@ describe('ChannelList', () => {
176176
});
177177
});
178178

179+
it('should only show filtered channels when a filter function prop is provided', async () => {
180+
const filteredChannel = generateChannel({ channel: { type: 'filtered' } });
181+
182+
const customFilterFunction = (channels) => {
183+
return channels.filter((channel) => channel.type === 'filtered');
184+
};
185+
186+
const props = {
187+
filters: {},
188+
Preview: ChannelPreviewComponent,
189+
List: ChannelListComponent,
190+
channelRenderFilterFn: customFilterFunction,
191+
};
192+
193+
useMockedApis(chatClientUthred, [
194+
queryChannelsApi([filteredChannel, testChannel1]),
195+
]);
196+
197+
const { getByRole, queryAllByRole } = render(
198+
<Chat client={chatClientUthred}>
199+
<ChannelList {...props} />
200+
</Chat>,
201+
);
202+
203+
// Wait for list of channels to load in DOM.
204+
await waitFor(() => {
205+
expect(getByRole('list')).toBeInTheDocument();
206+
expect(queryAllByRole('listitem')).toHaveLength(1);
207+
});
208+
});
209+
179210
it('should render `LoadingErrorIndicator` when queryChannels api throws error', async () => {
180211
useMockedApis(chatClientUthred, [erroredGetApi()]);
181212
jest.spyOn(console, 'warn').mockImplementationOnce(() => null);

src/components/MessageInput/hooks/messageInput.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,19 +343,27 @@ export default function useMessageInput(props) {
343343
type: 'setEmojiPickerIsOpen',
344344
value: false,
345345
});
346-
document.removeEventListener('click', closeEmojiPicker, false);
347346
}
348347
},
349348
[emojiPickerRef],
350349
);
351350

352-
const openEmojiPicker = useCallback(() => {
351+
const openEmojiPicker = useCallback((event) => {
353352
dispatch({
354353
type: 'setEmojiPickerIsOpen',
355354
value: true,
356355
});
357-
document.addEventListener('click', closeEmojiPicker, false);
358-
}, [closeEmojiPicker]);
356+
357+
// Prevent event from bubbling to document, so the close handler is never called for this event
358+
event.stopPropagation();
359+
}, []);
360+
361+
useEffect(() => {
362+
if (state.emojiPickerIsOpen) {
363+
document.addEventListener('click', closeEmojiPicker, false);
364+
}
365+
return () => document.removeEventListener('click', closeEmojiPicker, false);
366+
}, [closeEmojiPicker, state.emojiPickerIsOpen]);
359367

360368
const onSelectEmoji = useCallback((emoji) => insertText(emoji.native), [
361369
insertText,

src/styles/Message.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,6 @@
625625
max-width: 460px;
626626

627627
&.str-chat__message-simple-text-inner--is-emoji {
628-
margin: 5px 0;
629628
background: transparent;
630629
p {
631630
line-height: 48px;

types/index.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,11 @@ export interface ChannelListProps {
322322
e: Client.Event,
323323
): void;
324324
setActiveChannelOnMount?: boolean;
325+
/**
326+
* Optional function to filter channels prior to loading in the DOM. Do not use any complex or async logic here that would significantly delay the loading of the ChannelList.
327+
* We recommend using a pure function with array methods like filter/sort/reduce.
328+
*/
329+
channelRenderFilterFn?: (channels: Client.Channel[]) => Client.Channel[];
325330
/** Object containing query filters */
326331
filters?: Client.ChannelFilters;
327332
/** Object containing query options */

0 commit comments

Comments
 (0)