Skip to content

Commit d5a608b

Browse files
Merge pull request #351 from GetStream/vishal/context-cleanup
Removing MessagesContext and ThreadContext
2 parents ad3ef0f + 96a7c68 commit d5a608b

File tree

17 files changed

+88
-351
lines changed

17 files changed

+88
-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
/**
@@ -458,48 +452,42 @@ const Channel = (props) => {
458452
};
459453

460454
const channelContext = {
455+
Attachment: props.Attachment,
461456
channel,
457+
clearEditingState,
458+
closeThread,
462459
disabled: channel?.data?.frozen && disableIfFrozenChannel,
460+
editing,
461+
editMessage,
462+
emojiData,
463463
EmptyStateIndicator,
464464
error,
465465
eventHistory,
466+
hasMore,
466467
lastRead,
467468
loading,
468-
markRead: markReadThrottled,
469-
members,
470-
read,
471-
setLastRead,
472-
typing,
473-
watcherCount,
474-
watchers,
475-
};
476-
477-
const messagesContext = {
478-
Attachment: props.Attachment,
479-
clearEditingState,
480-
editing,
481-
editMessage,
482-
emojiData,
483-
hasMore,
484469
loadingMore,
485470
loadMore: loadMoreThrottled,
471+
loadMoreThread,
472+
markRead: markReadThrottled,
473+
members,
486474
Message: props.Message,
487475
messages,
476+
openThread,
477+
read,
488478
removeMessage,
489479
retrySendMessage,
490480
sendMessage,
491481
setEditingState,
492-
updateMessage,
493-
};
494-
495-
const threadContext = {
496-
closeThread,
497-
loadMoreThread,
498-
openThread,
482+
setLastRead,
499483
thread,
500484
threadHasMore,
501485
threadLoadingMore,
502486
threadMessages,
487+
typing,
488+
updateMessage,
489+
watcherCount,
490+
watchers,
503491
};
504492

505493
if (!channel || error) {
@@ -521,11 +509,7 @@ const Channel = (props) => {
521509
return (
522510
<KeyboardCompatibleView enabled={!disableKeyboardCompatibleView}>
523511
<ChannelContext.Provider value={channelContext}>
524-
<MessagesContext.Provider value={messagesContext}>
525-
<ThreadContext.Provider value={threadContext}>
526-
<SuggestionsProvider>{children}</SuggestionsProvider>
527-
</ThreadContext.Provider>
528-
</MessagesContext.Provider>
512+
<SuggestionsProvider>{children}</SuggestionsProvider>
529513
</ChannelContext.Provider>
530514
</KeyboardCompatibleView>
531515
);

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)