Skip to content

Commit a5ff69d

Browse files
authored
fix: display date separators before visible messages (#1733)
1 parent 2d44d17 commit a5ff69d

File tree

9 files changed

+106
-21
lines changed

9 files changed

+106
-21
lines changed

examples/TypeScriptMessaging/App.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ const ChannelScreen: React.FC<ChannelScreenProps> = ({ navigation }) => {
120120
setTopInset(headerHeight);
121121
}, [headerHeight]);
122122

123+
if (channel === undefined) {
124+
return null;
125+
}
126+
123127
return (
124128
<SafeAreaView>
125129
<Chat client={chatClient} i18nInstance={streami18n}>

examples/TypeScriptMessaging/ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ EXTERNAL SOURCES:
626626
SPEC CHECKSUMS:
627627
boost: a7c83b31436843459a1961bfd74b96033dc77234
628628
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
629-
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
629+
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
630630
FBLazyVector: 1d83d91816fa605d16227a83f1b2e71c8df09d22
631631
FBReactNativeSpec: 626e35e73f83c637ff166f906d584f4c6750c251
632632
Flipper: bdadd9d6edfc8dfc5c4b9bb59b2ffa60e4a167e7
@@ -639,12 +639,12 @@ SPEC CHECKSUMS:
639639
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
640640
FlipperKit: 17618d288848b0178ff8be2c9682e6800800f07d
641641
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
642-
glog: 85ecdd10ee8d8ec362ef519a6a45ff9aa27b2e85
642+
glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a
643643
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
644644
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
645645
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
646646
PromisesSwift: 99fddfe4a0ec88a56486644c0da106694c92a604
647-
RCT-Folly: 803a9cfd78114b2ec0f140cfa6fa2a6bafb2d685
647+
RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a
648648
RCTRequired: 66822c147facf02f7774af99825e0a31e39df42e
649649
RCTTypeSafety: 309306c4e711b14a83c55c2816a6cc490ec19827
650650
React: a779632422a918b26db4f1b57225a41c14d20525

examples/TypeScriptMessaging/yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7097,10 +7097,10 @@ statuses@~1.5.0:
70977097
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
70987098
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
70997099

7100-
stream-chat-react-native-core@5.1.0:
7101-
version "5.1.0"
7102-
resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-5.1.0.tgz#65a867ad684add2fc6ec702a65d57010434f550b"
7103-
integrity sha512-jWIB5tjCPqFsnPOkB+yKD2bW18NYlt6AFMjrHIurKkdR08+8E4/wtCutZztTCTqyiJ3RXA2NL8d8vDWfBzV4zg==
7100+
stream-chat-react-native-core@5.3.0:
7101+
version "5.3.0"
7102+
resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-5.3.0.tgz#5ff9771f4933d2291f5a2b7bd1316fcdd9b1767e"
7103+
integrity sha512-VRooo1bMGWy16jwpT0QCY8y2AGhzQ5giFnYSJRk/Vo+BSW9COFnk/y5Ja9GXiz8WjadXwv2YEmO/MKpkgxJeNQ==
71047104
dependencies:
71057105
"@babel/runtime" "^7.12.5"
71067106
"@gorhom/bottom-sheet" "^4.1.6"

package/native-package/yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,10 +1618,10 @@ source-map@^0.5.0:
16181618
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
16191619
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
16201620

1621-
stream-chat-react-native-core@5.1.0:
1622-
version "5.1.0"
1623-
resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-5.1.0.tgz#65a867ad684add2fc6ec702a65d57010434f550b"
1624-
integrity sha512-jWIB5tjCPqFsnPOkB+yKD2bW18NYlt6AFMjrHIurKkdR08+8E4/wtCutZztTCTqyiJ3RXA2NL8d8vDWfBzV4zg==
1621+
stream-chat-react-native-core@5.3.0:
1622+
version "5.3.0"
1623+
resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-5.3.0.tgz#5ff9771f4933d2291f5a2b7bd1316fcdd9b1767e"
1624+
integrity sha512-VRooo1bMGWy16jwpT0QCY8y2AGhzQ5giFnYSJRk/Vo+BSW9COFnk/y5Ja9GXiz8WjadXwv2YEmO/MKpkgxJeNQ==
16251625
dependencies:
16261626
"@babel/runtime" "^7.12.5"
16271627
"@gorhom/bottom-sheet" "^4.1.6"

package/src/components/MessageList/MessageList.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ type MessageListPropsWithContext<
133133
Pick<OverlayContextValue, 'overlay'> &
134134
Pick<
135135
MessagesContextValue<StreamChatGenerics>,
136-
| 'deletedMessagesVisibilityType'
137136
| 'DateHeader'
138137
| 'disableTypingIndicator'
139138
| 'FlatList'
@@ -236,7 +235,6 @@ const MessageListWithContext = <
236235
client,
237236
closePicker,
238237
DateHeader,
239-
deletedMessagesVisibilityType,
240238
disabled,
241239
disableTypingIndicator,
242240
EmptyStateIndicator,
@@ -296,7 +294,6 @@ const MessageListWithContext = <
296294
);
297295

298296
const messageList = useMessageList<StreamChatGenerics>({
299-
deletedMessagesVisibilityType,
300297
inverted,
301298
noGroupByUser,
302299
threadList,
@@ -1062,7 +1059,6 @@ export const MessageList = <
10621059
const { setMessages } = useImageGalleryContext<StreamChatGenerics>();
10631060
const {
10641061
DateHeader,
1065-
deletedMessagesVisibilityType,
10661062
disableTypingIndicator,
10671063
FlatList,
10681064
initialScrollToFirstUnreadMessage,
@@ -1089,7 +1085,6 @@ export const MessageList = <
10891085
client,
10901086
closePicker,
10911087
DateHeader,
1092-
deletedMessagesVisibilityType,
10931088
disabled,
10941089
disableTypingIndicator,
10951090
EmptyStateIndicator,

package/src/components/MessageList/hooks/useMessageList.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import {
55
useChannelContext,
66
} from '../../../contexts/channelContext/ChannelContext';
77
import { useChatContext } from '../../../contexts/chatContext/ChatContext';
8+
import {
9+
DeletedMessagesVisibilityType,
10+
useMessagesContext,
11+
} from '../../../contexts/messagesContext/MessagesContext';
812
import { usePaginatedMessageListContext } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext';
913
import { useThreadContext } from '../../../contexts/threadContext/ThreadContext';
1014
import type { DefaultStreamChatGenerics } from '../../../types/types';
@@ -13,7 +17,7 @@ import { getGroupStyles } from '../utils/getGroupStyles';
1317
import { getReadStates } from '../utils/getReadStates';
1418

1519
export type UseMessageListParams = {
16-
deletedMessagesVisibilityType?: 'always' | 'never' | 'receiver' | 'sender';
20+
deletedMessagesVisibilityType?: DeletedMessagesVisibilityType;
1721
inverted?: boolean;
1822
noGroupByUser?: boolean;
1923
threadList?: boolean;
@@ -48,10 +52,11 @@ export const useMessageList = <
4852
>(
4953
params: UseMessageListParams,
5054
) => {
51-
const { deletedMessagesVisibilityType, inverted, noGroupByUser, threadList } = params;
55+
const { inverted, noGroupByUser, threadList } = params;
5256
const { client } = useChatContext<StreamChatGenerics>();
5357
const { hideDateSeparators, maxTimeBetweenGroupedMessages, read } =
5458
useChannelContext<StreamChatGenerics>();
59+
const { deletedMessagesVisibilityType } = useMessagesContext<StreamChatGenerics>();
5560
const { messages } = usePaginatedMessageListContext<StreamChatGenerics>();
5661
const { threadMessages } = useThreadContext<StreamChatGenerics>();
5762

@@ -61,6 +66,7 @@ export const useMessageList = <
6166
: read;
6267

6368
const dateSeparators = getDateSeparators<StreamChatGenerics>({
69+
deletedMessagesVisibilityType,
6470
hideDateSeparators,
6571
messages: messageList,
6672
userId: client.userID,
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import type { PaginatedMessageListContextValue } from '../../../../contexts/paginatedMessageListContext/PaginatedMessageListContext';
2+
import { getDateSeparators } from '../getDateSeparators';
3+
4+
describe('getDateSeparators', () => {
5+
it('should return an empty object if no messages are passed', () => {
6+
expect(getDateSeparators({ messages: [] })).toEqual({});
7+
});
8+
9+
it('should return a date separator for each message in a new day', () => {
10+
const firstDate = new Date('2020-01-01T00:00:00.000Z');
11+
const secondDate = new Date('2020-01-02T00:00:00.000Z');
12+
const messages = [
13+
{
14+
created_at: firstDate,
15+
id: '1',
16+
text: 'foo',
17+
},
18+
{
19+
created_at: secondDate,
20+
id: '2',
21+
text: 'bar',
22+
},
23+
{
24+
created_at: secondDate,
25+
id: '3',
26+
text: 'baz',
27+
},
28+
] as PaginatedMessageListContextValue['messages'];
29+
30+
expect(getDateSeparators({ messages })).toEqual({
31+
1: firstDate,
32+
2: secondDate,
33+
});
34+
});
35+
36+
it('should return a date separator for the visible message in a day if deleted messages are not visible to the user', () => {
37+
const firstDate = new Date('2020-01-01T00:00:00.000Z');
38+
const secondDate = new Date('2020-01-02T00:00:00.000Z');
39+
40+
const messages = [
41+
{
42+
created_at: firstDate,
43+
id: '1',
44+
text: 'foo',
45+
type: 'regular',
46+
},
47+
{
48+
created_at: secondDate,
49+
id: '2',
50+
text: 'bar',
51+
type: 'deleted',
52+
},
53+
{
54+
created_at: secondDate,
55+
id: '3',
56+
text: 'baz',
57+
type: 'regular',
58+
},
59+
] as PaginatedMessageListContextValue['messages'];
60+
61+
expect(getDateSeparators({ deletedMessagesVisibilityType: 'never', messages })).toEqual({
62+
1: firstDate,
63+
3: secondDate,
64+
});
65+
66+
expect(getDateSeparators({ deletedMessagesVisibilityType: 'receiver', messages })).toEqual({
67+
1: firstDate,
68+
3: secondDate,
69+
});
70+
});
71+
});

package/src/components/MessageList/utils/getDateSeparators.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { DeletedMessagesVisibilityType } from '../../../contexts/messagesContext/MessagesContext';
12
import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext';
23
import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext';
34
import type { DefaultStreamChatGenerics } from '../../../types/types';
@@ -8,6 +9,7 @@ export type GetDateSeparatorsParams<
89
messages:
910
| PaginatedMessageListContextValue<StreamChatGenerics>['messages']
1011
| ThreadContextValue<StreamChatGenerics>['threadMessages'];
12+
deletedMessagesVisibilityType?: DeletedMessagesVisibilityType;
1113
hideDateSeparators?: boolean;
1214
userId?: string;
1315
};
@@ -21,7 +23,7 @@ export const getDateSeparators = <
2123
>(
2224
params: GetDateSeparatorsParams<StreamChatGenerics>,
2325
) => {
24-
const { hideDateSeparators, messages, userId } = params;
26+
const { deletedMessagesVisibilityType, hideDateSeparators, messages, userId } = params;
2527
const dateSeparators: DateSeparators = {};
2628

2729
if (hideDateSeparators) {
@@ -30,7 +32,13 @@ export const getDateSeparators = <
3032

3133
const messagesWithoutDeleted = messages.filter((message) => {
3234
const isMessageTypeDeleted = message.type === 'deleted';
33-
return !isMessageTypeDeleted || userId === message.user?.id;
35+
36+
const isDeletedMessageVisibleToSender =
37+
deletedMessagesVisibilityType === 'sender' || deletedMessagesVisibilityType === 'always';
38+
39+
return (
40+
!isMessageTypeDeleted || (userId === message.user?.id && isDeletedMessageVisibleToSender)
41+
);
3442
});
3543

3644
for (let i = 0; i < messagesWithoutDeleted.length; i++) {

package/src/contexts/messagesContext/MessagesContext.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ import { getDisplayName } from '../utils/getDisplayName';
5959
import { isTestEnvironment } from '../utils/isTestEnvironment';
6060

6161
export type MessageContentType = 'attachments' | 'files' | 'gallery' | 'quoted_reply' | 'text';
62+
export type DeletedMessagesVisibilityType = 'always' | 'never' | 'receiver' | 'sender';
6263

6364
export type MessagesContextValue<
6465
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -281,7 +282,7 @@ export type MessagesContextValue<
281282
*/
282283

283284
/** Control if the deleted message is visible to both the send and reciever, either of them or none */
284-
deletedMessagesVisibilityType?: 'always' | 'never' | 'receiver' | 'sender';
285+
deletedMessagesVisibilityType?: DeletedMessagesVisibilityType;
285286

286287
disableTypingIndicator?: boolean;
287288

0 commit comments

Comments
 (0)