Skip to content

Commit 349f26b

Browse files
Merge branch 'master' of github.com:GetStream/stream-chat-react-native into vishal/keyboard
# Conflicts: # src/components/Message/Message.js
2 parents 42f45f6 + d5a608b commit 349f26b

File tree

17 files changed

+96
-351
lines changed

17 files changed

+96
-351
lines changed

CHANGELOG.md

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,57 +23,6 @@
2323

2424
- On upgrading to this release, ensure events and any custom handling functions (ex: `onAddedToChannel` or `onMessageNew`) are properly processed and update the list UI as expected.
2525

26-
*ChannelContext*
27-
28-
- We have split the `ChannelContext` into three separate contexts to further modularize the code and reduce renders as items in context change. The following contexts now contain the following values, previously all held within the `ChannelContext`:
29-
30-
- `ChannelContext`:
31-
32-
- `channel`
33-
- `disabled`
34-
- `EmptyStateIndicator`
35-
- `error`
36-
- `eventHistory`
37-
- `lastRead`
38-
- `loading`
39-
- `markRead`
40-
- `members`
41-
- `read`
42-
- `setLastRead`
43-
- `typing`
44-
- `watcherCount`
45-
- `watchers`
46-
47-
- `MessagesContext`
48-
49-
- `Attachment`
50-
- `clearEditingState`
51-
- `editing`
52-
- `editMessage`
53-
- `emojiData`
54-
- `hasMore`
55-
- `loadingMore`
56-
- `loadMore`
57-
- `Message`
58-
- `messages`
59-
- `removeMessage`
60-
- `retrySendMessage`
61-
- `sendMessage`
62-
- `setEditingState`
63-
- `updateMessage`
64-
65-
- `ThreadContext`
66-
67-
- `closeThread`
68-
- `loadMoreThread`
69-
- `openThread`
70-
- `thread`
71-
- `threadHasMore`
72-
- `threadLoadingMore`
73-
- `threadMessages`
74-
75-
- All contexts are exported and any values can be accessed through a higher order component (ex: `withMessagesContext`) or the `useContext` hook (ex: `const { messages } = useContext(MessagesContext);`)
76-
7726
*FileUploadPreview*
7827

7928
- We fixed a bug for being unable to remove a file from the `MessageInput` and made it consistent to `ImageUploadPreview`

src/components/Channel/Channel.js

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,7 @@ import LoadingIndicatorDefault from '../Indicators/LoadingIndicator';
1313
import KeyboardCompatibleViewDefault from '../KeyboardCompatibleView/KeyboardCompatibleView';
1414
import SuggestionsProvider from '../SuggestionsProvider/SuggestionsProvider';
1515

16-
import {
17-
ChannelContext,
18-
ChatContext,
19-
MessagesContext,
20-
ThreadContext,
21-
TranslationContext,
22-
} from '../../context';
16+
import { ChannelContext, ChatContext, TranslationContext } from '../../context';
2317
import { emojiData as emojiDataDefault } from '../../utils/utils';
2418

2519
/**
@@ -459,48 +453,42 @@ const Channel = (props) => {
459453
};
460454

461455
const channelContext = {
456+
Attachment: props.Attachment,
462457
channel,
458+
clearEditingState,
459+
closeThread,
463460
disabled: channel?.data?.frozen && disableIfFrozenChannel,
461+
editing,
462+
editMessage,
463+
emojiData,
464464
EmptyStateIndicator,
465465
error,
466466
eventHistory,
467+
hasMore,
467468
lastRead,
468469
loading,
469-
markRead: markReadThrottled,
470-
members,
471-
read,
472-
setLastRead,
473-
typing,
474-
watcherCount,
475-
watchers,
476-
};
477-
478-
const messagesContext = {
479-
Attachment: props.Attachment,
480-
clearEditingState,
481-
editing,
482-
editMessage,
483-
emojiData,
484-
hasMore,
485470
loadingMore,
486471
loadMore: loadMoreThrottled,
472+
loadMoreThread,
473+
markRead: markReadThrottled,
474+
members,
487475
Message: props.Message,
488476
messages,
477+
openThread,
478+
read,
489479
removeMessage,
490480
retrySendMessage,
491481
sendMessage,
492482
setEditingState,
493-
updateMessage,
494-
};
495-
496-
const threadContext = {
497-
closeThread,
498-
loadMoreThread,
499-
openThread,
483+
setLastRead,
500484
thread,
501485
threadHasMore,
502486
threadLoadingMore,
503487
threadMessages,
488+
typing,
489+
updateMessage,
490+
watcherCount,
491+
watchers,
504492
};
505493

506494
if (!channel || error) {
@@ -531,11 +519,7 @@ const Channel = (props) => {
531519
keyboardVerticalOffset={keyboardVerticalOffset}
532520
>
533521
<ChannelContext.Provider value={channelContext}>
534-
<MessagesContext.Provider value={messagesContext}>
535-
<ThreadContext.Provider value={threadContext}>
536-
<SuggestionsProvider>{children}</SuggestionsProvider>
537-
</ThreadContext.Provider>
538-
</MessagesContext.Provider>
522+
<SuggestionsProvider>{children}</SuggestionsProvider>
539523
</ChannelContext.Provider>
540524
</KeyboardCompatibleView>
541525
);

src/components/Channel/__tests__/Channel.test.js

Lines changed: 24 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,9 @@ import { getTestClientWithUser } from 'mock-builders/mock';
1313

1414
import Channel from '../Channel';
1515

16-
import Attachment from '../../Attachment/Attachment';
1716
import Chat from '../../Chat/Chat';
1817

19-
import {
20-
ChannelContext,
21-
MessagesContext,
22-
ThreadContext,
23-
} from '../../../context';
18+
import { ChannelContext } from '../../../context';
2419

2520
// This component is used for performing effects in a component that consumes ChannelContext,
2621
// i.e. making use of the callbacks & values provided by the Channel component.
@@ -173,17 +168,13 @@ describe('Channel', () => {
173168
const hasThread = jest.fn();
174169
// this renders Channel, calls openThread from a child context consumer with a message,
175170
// and then calls hasThread with the thread id if it was set.
176-
renderComponent(
177-
{ channel },
178-
({ openThread, thread }) => {
179-
if (!thread) {
180-
openThread(threadMessage);
181-
} else {
182-
hasThread(thread.id);
183-
}
184-
},
185-
ThreadContext,
186-
);
171+
renderComponent({ channel }, ({ openThread, thread }) => {
172+
if (!thread) {
173+
openThread(threadMessage);
174+
} else {
175+
hasThread(thread.id);
176+
}
177+
});
187178
await waitFor(() =>
188179
expect(hasThread).toHaveBeenCalledWith(threadMessage.id),
189180
);
@@ -220,7 +211,6 @@ describe('Channel', () => {
220211
channelHasMore = hasMore;
221212
}
222213
},
223-
MessagesContext,
224214
);
225215
await waitFor(() => expect(channelHasMore).toBe(false));
226216
});
@@ -230,14 +220,10 @@ describe('Channel', () => {
230220

231221
const newMessages = [generateMessage()];
232222

233-
renderComponent(
234-
{ channel },
235-
({ loadMore }) => {
236-
useMockedApis(chatClient, [queryChannelWithNewMessages(newMessages)]);
237-
loadMore(limit);
238-
},
239-
MessagesContext,
240-
);
223+
renderComponent({ channel }, ({ loadMore }) => {
224+
useMockedApis(chatClient, [queryChannelWithNewMessages(newMessages)]);
225+
loadMore(limit);
226+
});
241227

242228
await waitFor(() => expect(channelQuerySpy).toHaveBeenCalled());
243229
});
@@ -246,16 +232,12 @@ describe('Channel', () => {
246232
const queryPromise = new Promise(() => {});
247233
let isLoadingMore = false;
248234

249-
renderComponent(
250-
{ channel },
251-
({ loadingMore, loadMore }) => {
252-
// return a promise that hasn't resolved yet, so loadMore will be stuck in the 'await' part of the function
253-
jest.spyOn(channel, 'query').mockImplementationOnce(() => queryPromise);
254-
loadMore();
255-
isLoadingMore = loadingMore;
256-
},
257-
MessagesContext,
258-
);
235+
renderComponent({ channel }, ({ loadingMore, loadMore }) => {
236+
// return a promise that hasn't resolved yet, so loadMore will be stuck in the 'await' part of the function
237+
jest.spyOn(channel, 'query').mockImplementationOnce(() => queryPromise);
238+
loadMore();
239+
isLoadingMore = loadingMore;
240+
});
259241

260242
await waitFor(() => expect(isLoadingMore).toBe(true));
261243
});
@@ -265,13 +247,9 @@ describe('Channel', () => {
265247
const updatedMessage = { ...messages[0], text: newText };
266248
const clientUpdateMessageSpy = jest.spyOn(chatClient, 'updateMessage');
267249

268-
renderComponent(
269-
{ channel },
270-
({ editMessage }) => {
271-
editMessage(updatedMessage);
272-
},
273-
MessagesContext,
274-
);
250+
renderComponent({ channel }, ({ editMessage }) => {
251+
editMessage(updatedMessage);
252+
});
275253

276254
await waitFor(() =>
277255
expect(clientUpdateMessageSpy).toHaveBeenCalledWith(updatedMessage),
@@ -280,13 +258,9 @@ describe('Channel', () => {
280258

281259
it('should use doUpdateMessageRequest for the editMessage callback if provided', async () => {
282260
const doUpdateMessageRequest = jest.fn((channelId, message) => message);
283-
renderComponent(
284-
{ channel, doUpdateMessageRequest },
285-
({ editMessage }) => {
286-
editMessage(messages[0]);
287-
},
288-
MessagesContext,
289-
);
261+
renderComponent({ channel, doUpdateMessageRequest }, ({ editMessage }) => {
262+
editMessage(messages[0]);
263+
});
290264

291265
await waitFor(() =>
292266
expect(doUpdateMessageRequest).toHaveBeenCalledWith(
@@ -311,7 +285,6 @@ describe('Channel', () => {
311285
allMessagesRemoved = true;
312286
}
313287
},
314-
MessagesContext,
315288
);
316289

317290
await waitFor(() => {
@@ -361,88 +334,4 @@ describe('Channel', () => {
361334
});
362335
});
363336
});
364-
365-
describe('MessagesContext', () => {
366-
it('renders children without crashing', async () => {
367-
const { getByTestId } = render(
368-
<MessagesContext.Provider>
369-
<View testID='children' />
370-
</MessagesContext.Provider>,
371-
);
372-
373-
await waitFor(() => expect(getByTestId('children')).toBeTruthy());
374-
});
375-
376-
it('exposes the messages context', async () => {
377-
let context;
378-
379-
const mockContext = {
380-
Attachment,
381-
editing: false,
382-
messages,
383-
sendMessage: () => {},
384-
};
385-
386-
render(
387-
<MessagesContext.Provider value={mockContext}>
388-
<ContextConsumer
389-
context={MessagesContext}
390-
fn={(ctx) => {
391-
context = ctx;
392-
}}
393-
></ContextConsumer>
394-
</MessagesContext.Provider>,
395-
);
396-
397-
await waitFor(() => {
398-
expect(context).toBeInstanceOf(Object);
399-
expect(context.Attachment).toBeInstanceOf(Function);
400-
expect(context.editing).toBe(false);
401-
expect(context.messages).toBeInstanceOf(Array);
402-
expect(context.sendMessage).toBeInstanceOf(Function);
403-
});
404-
});
405-
});
406-
407-
describe('ThreadContext', () => {
408-
it('renders children without crashing', async () => {
409-
const { getByTestId } = render(
410-
<ThreadContext.Provider>
411-
<View testID='children' />
412-
</ThreadContext.Provider>,
413-
);
414-
415-
await waitFor(() => expect(getByTestId('children')).toBeTruthy());
416-
});
417-
418-
it('exposes the thread context', async () => {
419-
let context;
420-
421-
const mockContext = {
422-
openThread: () => {},
423-
thread: {},
424-
threadHasMore: true,
425-
threadLoadingMore: false,
426-
};
427-
428-
render(
429-
<ThreadContext.Provider value={mockContext}>
430-
<ContextConsumer
431-
context={ThreadContext}
432-
fn={(ctx) => {
433-
context = ctx;
434-
}}
435-
></ContextConsumer>
436-
</ThreadContext.Provider>,
437-
);
438-
439-
await waitFor(() => {
440-
expect(context).toBeInstanceOf(Object);
441-
expect(context.openThread).toBeInstanceOf(Function);
442-
expect(context.thread).toBeInstanceOf(Object);
443-
expect(context.threadHasMore).toBe(true);
444-
expect(context.threadLoadingMore).toBe(false);
445-
});
446-
});
447-
});
448337
});

0 commit comments

Comments
 (0)