Skip to content

Commit 008cf01

Browse files
authored
Merge pull request #2796 from GetStream/fix/backporting-variety-fixes
fix: backporting variety fixes
2 parents e6908e9 + 5a58a65 commit 008cf01

File tree

5 files changed

+89
-34
lines changed

5 files changed

+89
-34
lines changed

package/expo-package/src/optionalDependencies/pickImage.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ export const pickImage = ImagePicker
5353
return { cancelled: true };
5454
}
5555
}
56+
return { cancelled: true };
5657
} catch (error) {
5758
console.log('Error while picking image', error);
59+
return { cancelled: true };
5860
}
5961
}
6062
: null;

package/native-package/src/optionalDependencies/pickImage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const pickImage = ImagePicker
3535
}
3636
} catch (error) {
3737
console.log('Error picking image: ', error);
38+
return { cancelled: true };
3839
}
3940
}
4041
: null;

package/src/components/ChannelPreview/ChannelPreview.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import React from 'react';
33
import type { Channel } from 'stream-chat';
44

55
import { useChannelPreviewData } from './hooks/useChannelPreviewData';
6-
import { useLatestMessagePreview } from './hooks/useLatestMessagePreview';
76

87
import {
98
ChannelsContextValue,
@@ -31,15 +30,16 @@ export const ChannelPreview = <
3130
const { channel, client: propClient, forceUpdate: propForceUpdate, Preview: propPreview } = props;
3231

3332
const { client: contextClient } = useChatContext<StreamChatGenerics>();
34-
const { forceUpdate: contextForceUpdate, Preview: contextPreview } =
35-
useChannelsContext<StreamChatGenerics>();
33+
const { Preview: contextPreview } = useChannelsContext<StreamChatGenerics>();
3634

3735
const client = propClient || contextClient;
38-
const forceUpdate = propForceUpdate || contextForceUpdate;
3936
const Preview = propPreview || contextPreview;
4037

41-
const { lastMessage, muted, unread } = useChannelPreviewData(channel, client, forceUpdate);
42-
const latestMessagePreview = useLatestMessagePreview(channel, forceUpdate, lastMessage);
38+
const { latestMessagePreview, muted, unread } = useChannelPreviewData(
39+
channel,
40+
client,
41+
propForceUpdate,
42+
);
4343

4444
return (
4545
<Preview

package/src/components/ChannelPreview/__tests__/ChannelPreview.test.tsx

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ describe('ChannelPreview', () => {
6969
);
7070
};
7171

72+
const generateChannelWrapper = (overrides: Record<string, unknown>) =>
73+
generateChannel({
74+
countUnread: jest.fn().mockReturnValue(0),
75+
initialized: true,
76+
lastMessage: jest.fn().mockReturnValue(generateMessage()),
77+
muteStatus: jest.fn().mockReturnValue({ muted: false }),
78+
...overrides,
79+
});
80+
7281
const useInitializeChannel = async (c: GetOrCreateChannelApiParams) => {
7382
useMockedApis(chatClient, [getOrCreateChannelApi(c)]);
7483

@@ -89,9 +98,8 @@ describe('ChannelPreview', () => {
8998
it("should not update the unread count if the event's cid does not match the channel's cid", async () => {
9099
const channelOnMock = jest.fn().mockReturnValue({ unsubscribe: jest.fn() });
91100

92-
const c = generateChannel({
101+
const c = generateChannelWrapper({
93102
countUnread: jest.fn().mockReturnValue(10),
94-
muteStatus: jest.fn().mockReturnValue({ muted: false }),
95103
on: channelOnMock,
96104
});
97105

@@ -117,9 +125,8 @@ describe('ChannelPreview', () => {
117125
it('should update the unread count to 0', async () => {
118126
const channelOnMock = jest.fn().mockReturnValue({ unsubscribe: jest.fn() });
119127

120-
const c = generateChannel({
128+
const c = generateChannelWrapper({
121129
countUnread: jest.fn().mockReturnValue(10),
122-
muteStatus: jest.fn().mockReturnValue({ muted: false }),
123130
on: channelOnMock,
124131
});
125132

@@ -147,9 +154,7 @@ describe('ChannelPreview', () => {
147154
it("should not update the unread count if the event's cid is undefined", async () => {
148155
const channelOnMock = jest.fn().mockReturnValue({ unsubscribe: jest.fn() });
149156

150-
const c = generateChannel({
151-
countUnread: jest.fn().mockReturnValue(0),
152-
muteStatus: jest.fn().mockReturnValue({ muted: false }),
157+
const c = generateChannelWrapper({
153158
on: channelOnMock,
154159
});
155160

@@ -182,9 +187,7 @@ describe('ChannelPreview', () => {
182187
it("should not update the unread count if the event's cid does not match the channel's cid", async () => {
183188
const channelOnMock = jest.fn().mockReturnValue({ unsubscribe: jest.fn() });
184189

185-
const c = generateChannel({
186-
countUnread: jest.fn().mockReturnValue(0),
187-
muteStatus: jest.fn().mockReturnValue({ muted: false }),
190+
const c = generateChannelWrapper({
188191
on: channelOnMock,
189192
});
190193

@@ -217,9 +220,7 @@ describe('ChannelPreview', () => {
217220
it("should not update the unread count if the event's user id does not match the client's user id", async () => {
218221
const channelOnMock = jest.fn().mockReturnValue({ unsubscribe: jest.fn() });
219222

220-
const c = generateChannel({
221-
countUnread: jest.fn().mockReturnValue(0),
222-
muteStatus: jest.fn().mockReturnValue({ muted: false }),
223+
const c = generateChannelWrapper({
223224
on: channelOnMock,
224225
});
225226

@@ -255,12 +256,10 @@ describe('ChannelPreview', () => {
255256
await useInitializeChannel(c);
256257
const channelOnMock = jest.fn().mockReturnValue({ unsubscribe: jest.fn() });
257258

258-
const testChannel = {
259+
const testChannel = generateChannelWrapper({
259260
...channel,
260-
countUnread: jest.fn().mockReturnValue(0),
261-
muteStatus: jest.fn().mockReturnValue({ muted: false }),
262261
on: channelOnMock,
263-
};
262+
});
264263

265264
const { getByTestId } = render(<TestComponent />);
266265

@@ -291,9 +290,9 @@ describe('ChannelPreview', () => {
291290
it('should update the unread count to 0 if the channel is muted', async () => {
292291
const channelOnMock = jest.fn().mockReturnValue({ unsubscribe: jest.fn() });
293292

294-
const c = generateChannel({
293+
const c = generateChannelWrapper({
295294
countUnread: jest.fn().mockReturnValue(10),
296-
muteStatus: jest.fn().mockReturnValue({ muted: false }),
295+
muteStatus: jest.fn().mockReturnValue({ muted: true }),
297296
on: channelOnMock,
298297
});
299298

@@ -304,7 +303,7 @@ describe('ChannelPreview', () => {
304303
await waitFor(() => getByTestId('channel-id'));
305304

306305
await waitFor(() => {
307-
expect(getByTestId('unread-count')).toHaveTextContent('10');
306+
expect(getByTestId('unread-count')).toHaveTextContent('0');
308307
});
309308

310309
act(() => {

package/src/components/ChannelPreview/hooks/useChannelPreviewData.ts

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,65 @@ import type { Channel, ChannelState, Event, MessageResponse, StreamChat } from '
55

66
import { useIsChannelMuted } from './useIsChannelMuted';
77

8+
import { useLatestMessagePreview } from './useLatestMessagePreview';
9+
10+
import { useChannelsContext } from '../../../contexts';
811
import type { DefaultStreamChatGenerics } from '../../../types/types';
912

1013
export const useChannelPreviewData = <
1114
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
1215
>(
1316
channel: Channel<StreamChatGenerics>,
1417
client: StreamChat<StreamChatGenerics>,
15-
forceUpdate?: number,
18+
forceUpdateOverride?: number,
1619
) => {
20+
const [forceUpdate, setForceUpdate] = useState(0);
1721
const [lastMessage, setLastMessage] = useState<
1822
| ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>
1923
| MessageResponse<StreamChatGenerics>
2024
>(channel.state.messages[channel.state.messages.length - 1]);
2125
const [unread, setUnread] = useState(channel.countUnread());
2226
const { muted } = useIsChannelMuted(channel);
27+
const { forceUpdate: contextForceUpdate } = useChannelsContext<StreamChatGenerics>();
28+
const channelListForceUpdate = forceUpdateOverride ?? contextForceUpdate;
29+
30+
const channelLastMessage = channel.lastMessage();
31+
const channelLastMessageString = `${channelLastMessage?.id}${channelLastMessage?.updated_at}`;
32+
33+
useEffect(() => {
34+
const { unsubscribe } = client.on('notification.mark_read', () => {
35+
setUnread(channel.countUnread());
36+
});
37+
return unsubscribe;
38+
}, [channel, client]);
39+
40+
useEffect(() => {
41+
if (
42+
channelLastMessage &&
43+
(channelLastMessage.id !== lastMessage?.id ||
44+
channelLastMessage.updated_at !== lastMessage?.updated_at)
45+
) {
46+
setLastMessage(channelLastMessage);
47+
}
48+
const newUnreadCount = channel.countUnread();
49+
setUnread(newUnreadCount);
50+
// eslint-disable-next-line react-hooks/exhaustive-deps
51+
}, [channel, channelLastMessageString, channelListForceUpdate]);
2352

2453
/**
2554
* This effect listens for the `notification.mark_read` event and sets the unread count to 0
2655
*/
2756
useEffect(() => {
2857
const handleReadEvent = (event: Event) => {
2958
if (!event.cid) return;
30-
if (channel.cid === event.cid) setUnread(0);
59+
if (channel.cid !== event.cid) return;
60+
if (event?.user?.id === client.userID) {
61+
setUnread(0);
62+
} else if (event?.user?.id) {
63+
setForceUpdate((prev) => prev + 1);
64+
}
3165
};
32-
const { unsubscribe } = client.on('notification.mark_read', handleReadEvent);
66+
const { unsubscribe } = client.on('message.read', handleReadEvent);
3367
return unsubscribe;
3468
}, [client, channel]);
3569

@@ -70,16 +104,35 @@ export const useChannelPreviewData = <
70104
refreshUnreadCount();
71105
};
72106

107+
const handleNewMessageEvent = (event: Event<StreamChatGenerics>) => {
108+
const message = event.message;
109+
if (message && (!message.parent_id || message.show_in_channel)) {
110+
setLastMessage(message);
111+
setUnread(channel.countUnread());
112+
}
113+
};
114+
115+
const handleUpdatedOrDeletedMessage = (event: Event<StreamChatGenerics>) => {
116+
setLastMessage((prevLastMessage) => {
117+
if (prevLastMessage?.id === event.message?.id) {
118+
return event.message;
119+
}
120+
return prevLastMessage;
121+
});
122+
};
123+
73124
const listeners = [
74-
channel.on('message.new', handleEvent),
75-
channel.on('message.updated', handleEvent),
76-
channel.on('message.deleted', handleEvent),
125+
channel.on('message.new', handleNewMessageEvent),
126+
channel.on('message.updated', handleUpdatedOrDeletedMessage),
127+
channel.on('message.deleted', handleUpdatedOrDeletedMessage),
77128
channel.on('message.undeleted', handleEvent),
78129
channel.on('channel.truncated', handleEvent),
79130
];
80131

81132
return () => listeners.forEach((l) => l.unsubscribe());
82-
}, [channel, refreshUnreadCount, forceUpdate]);
133+
}, [channel, refreshUnreadCount, forceUpdate, channelListForceUpdate]);
134+
135+
const latestMessagePreview = useLatestMessagePreview(channel, forceUpdate, lastMessage);
83136

84-
return { lastMessage, muted, unread };
137+
return { latestMessagePreview, muted, unread };
85138
};

0 commit comments

Comments
 (0)