stream-chat-react-native-core 8.11.0 → 8.12.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/components/Channel/Channel.js +26 -17
  3. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  4. package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js +3 -2
  5. package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
  6. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  7. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  8. package/lib/commonjs/components/Message/Message.js +6 -8
  9. package/lib/commonjs/components/Message/Message.js.map +1 -1
  10. package/lib/commonjs/components/Message/MessageSimple/MessageBlocked.js +70 -0
  11. package/lib/commonjs/components/Message/MessageSimple/MessageBlocked.js.map +1 -0
  12. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js +0 -2
  13. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js.map +1 -1
  14. package/lib/commonjs/components/Message/MessageSimple/MessageWrapper.js +126 -0
  15. package/lib/commonjs/components/Message/MessageSimple/MessageWrapper.js.map +1 -0
  16. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +1 -3
  17. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  18. package/lib/commonjs/components/MessageList/MessageFlashList.js +74 -105
  19. package/lib/commonjs/components/MessageList/MessageFlashList.js.map +1 -1
  20. package/lib/commonjs/components/MessageList/MessageList.js +77 -119
  21. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  22. package/lib/commonjs/components/MessageList/UnreadMessagesNotification.js +2 -2
  23. package/lib/commonjs/components/MessageList/UnreadMessagesNotification.js.map +1 -1
  24. package/lib/commonjs/components/MessageList/hooks/useMessageDateSeparator.js +45 -0
  25. package/lib/commonjs/components/MessageList/hooks/useMessageDateSeparator.js.map +1 -0
  26. package/lib/commonjs/components/MessageList/hooks/useMessageGroupStyles.js +46 -0
  27. package/lib/commonjs/components/MessageList/hooks/useMessageGroupStyles.js.map +1 -0
  28. package/lib/commonjs/components/MessageList/hooks/useMessageList.js +49 -29
  29. package/lib/commonjs/components/MessageList/hooks/useMessageList.js.map +1 -1
  30. package/lib/commonjs/components/MessageList/utils/getDateSeparators.js +5 -14
  31. package/lib/commonjs/components/MessageList/utils/getDateSeparators.js.map +1 -1
  32. package/lib/commonjs/components/MessageList/utils/getGroupStyles.js +22 -17
  33. package/lib/commonjs/components/MessageList/utils/getGroupStyles.js.map +1 -1
  34. package/lib/commonjs/components/MessageList/utils/getLastReceivedMessage.js +1 -1
  35. package/lib/commonjs/components/MessageList/utils/getLastReceivedMessage.js.map +1 -1
  36. package/lib/commonjs/components/index.js +33 -0
  37. package/lib/commonjs/components/index.js.map +1 -1
  38. package/lib/commonjs/contexts/channelContext/ChannelContext.js.map +1 -1
  39. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  40. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +3 -0
  41. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  42. package/lib/commonjs/contexts/messageListItemContext/MessageListItemContext.js +29 -0
  43. package/lib/commonjs/contexts/messageListItemContext/MessageListItemContext.js.map +1 -0
  44. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  45. package/lib/commonjs/contexts/themeContext/utils/theme.js +6 -0
  46. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  47. package/lib/commonjs/state-store/channel-unread-state.js +31 -0
  48. package/lib/commonjs/state-store/channel-unread-state.js.map +1 -0
  49. package/lib/commonjs/state-store/message-list-prev-next-state.js +46 -0
  50. package/lib/commonjs/state-store/message-list-prev-next-state.js.map +1 -0
  51. package/lib/commonjs/store/apis/getChannelMessages.js +7 -10
  52. package/lib/commonjs/store/apis/getChannelMessages.js.map +1 -1
  53. package/lib/commonjs/utils/utils.js +4 -4
  54. package/lib/commonjs/utils/utils.js.map +1 -1
  55. package/lib/commonjs/version.json +1 -1
  56. package/lib/module/components/Channel/Channel.js +26 -17
  57. package/lib/module/components/Channel/Channel.js.map +1 -1
  58. package/lib/module/components/Channel/hooks/useCreateChannelContext.js +3 -2
  59. package/lib/module/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
  60. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  61. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  62. package/lib/module/components/Message/Message.js +6 -8
  63. package/lib/module/components/Message/Message.js.map +1 -1
  64. package/lib/module/components/Message/MessageSimple/MessageBlocked.js +70 -0
  65. package/lib/module/components/Message/MessageSimple/MessageBlocked.js.map +1 -0
  66. package/lib/module/components/Message/MessageSimple/MessageContent.js +0 -2
  67. package/lib/module/components/Message/MessageSimple/MessageContent.js.map +1 -1
  68. package/lib/module/components/Message/MessageSimple/MessageWrapper.js +126 -0
  69. package/lib/module/components/Message/MessageSimple/MessageWrapper.js.map +1 -0
  70. package/lib/module/components/Message/hooks/useCreateMessageContext.js +1 -3
  71. package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  72. package/lib/module/components/MessageList/MessageFlashList.js +74 -105
  73. package/lib/module/components/MessageList/MessageFlashList.js.map +1 -1
  74. package/lib/module/components/MessageList/MessageList.js +77 -119
  75. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  76. package/lib/module/components/MessageList/UnreadMessagesNotification.js +2 -2
  77. package/lib/module/components/MessageList/UnreadMessagesNotification.js.map +1 -1
  78. package/lib/module/components/MessageList/hooks/useMessageDateSeparator.js +45 -0
  79. package/lib/module/components/MessageList/hooks/useMessageDateSeparator.js.map +1 -0
  80. package/lib/module/components/MessageList/hooks/useMessageGroupStyles.js +46 -0
  81. package/lib/module/components/MessageList/hooks/useMessageGroupStyles.js.map +1 -0
  82. package/lib/module/components/MessageList/hooks/useMessageList.js +49 -29
  83. package/lib/module/components/MessageList/hooks/useMessageList.js.map +1 -1
  84. package/lib/module/components/MessageList/utils/getDateSeparators.js +5 -14
  85. package/lib/module/components/MessageList/utils/getDateSeparators.js.map +1 -1
  86. package/lib/module/components/MessageList/utils/getGroupStyles.js +22 -17
  87. package/lib/module/components/MessageList/utils/getGroupStyles.js.map +1 -1
  88. package/lib/module/components/MessageList/utils/getLastReceivedMessage.js +1 -1
  89. package/lib/module/components/MessageList/utils/getLastReceivedMessage.js.map +1 -1
  90. package/lib/module/components/index.js +33 -0
  91. package/lib/module/components/index.js.map +1 -1
  92. package/lib/module/contexts/channelContext/ChannelContext.js.map +1 -1
  93. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  94. package/lib/module/contexts/messageInputContext/MessageInputContext.js +3 -0
  95. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  96. package/lib/module/contexts/messageListItemContext/MessageListItemContext.js +29 -0
  97. package/lib/module/contexts/messageListItemContext/MessageListItemContext.js.map +1 -0
  98. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  99. package/lib/module/contexts/themeContext/utils/theme.js +6 -0
  100. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  101. package/lib/module/state-store/channel-unread-state.js +31 -0
  102. package/lib/module/state-store/channel-unread-state.js.map +1 -0
  103. package/lib/module/state-store/message-list-prev-next-state.js +46 -0
  104. package/lib/module/state-store/message-list-prev-next-state.js.map +1 -0
  105. package/lib/module/store/apis/getChannelMessages.js +7 -10
  106. package/lib/module/store/apis/getChannelMessages.js.map +1 -1
  107. package/lib/module/utils/utils.js +4 -4
  108. package/lib/module/utils/utils.js.map +1 -1
  109. package/lib/module/version.json +1 -1
  110. package/lib/typescript/components/Channel/Channel.d.ts +3 -3
  111. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  112. package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts +1 -1
  113. package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts.map +1 -1
  114. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +1 -1
  115. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts.map +1 -1
  116. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts +2 -2
  117. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -1
  118. package/lib/typescript/components/Message/Message.d.ts +1 -1
  119. package/lib/typescript/components/Message/Message.d.ts.map +1 -1
  120. package/lib/typescript/components/Message/MessageSimple/MessageBlocked.d.ts +19 -0
  121. package/lib/typescript/components/Message/MessageSimple/MessageBlocked.d.ts.map +1 -0
  122. package/lib/typescript/components/Message/MessageSimple/MessageContent.d.ts.map +1 -1
  123. package/lib/typescript/components/Message/MessageSimple/MessageWrapper.d.ts +7 -0
  124. package/lib/typescript/components/Message/MessageSimple/MessageWrapper.d.ts.map +1 -0
  125. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
  126. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
  127. package/lib/typescript/components/MessageList/MessageFlashList.d.ts +1 -1
  128. package/lib/typescript/components/MessageList/MessageFlashList.d.ts.map +1 -1
  129. package/lib/typescript/components/MessageList/MessageList.d.ts +1 -1
  130. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  131. package/lib/typescript/components/MessageList/hooks/useMessageDateSeparator.d.ts +16 -0
  132. package/lib/typescript/components/MessageList/hooks/useMessageDateSeparator.d.ts.map +1 -0
  133. package/lib/typescript/components/MessageList/hooks/useMessageGroupStyles.d.ts +15 -0
  134. package/lib/typescript/components/MessageList/hooks/useMessageGroupStyles.d.ts.map +1 -0
  135. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts +8 -0
  136. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts.map +1 -1
  137. package/lib/typescript/components/MessageList/utils/getDateSeparators.d.ts +12 -0
  138. package/lib/typescript/components/MessageList/utils/getDateSeparators.d.ts.map +1 -1
  139. package/lib/typescript/components/MessageList/utils/getGroupStyles.d.ts +25 -0
  140. package/lib/typescript/components/MessageList/utils/getGroupStyles.d.ts.map +1 -1
  141. package/lib/typescript/components/MessageList/utils/getLastReceivedMessage.d.ts.map +1 -1
  142. package/lib/typescript/components/index.d.ts +3 -0
  143. package/lib/typescript/components/index.d.ts.map +1 -1
  144. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts +10 -4
  145. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts.map +1 -1
  146. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +4 -1
  147. package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
  148. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
  149. package/lib/typescript/contexts/messageListItemContext/MessageListItemContext.d.ts +37 -0
  150. package/lib/typescript/contexts/messageListItemContext/MessageListItemContext.d.ts.map +1 -0
  151. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +11 -1
  152. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
  153. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +6 -0
  154. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  155. package/lib/typescript/hooks/useTranslatedMessage.d.ts.map +1 -1
  156. package/lib/typescript/state-store/channel-unread-state.d.ts +12 -0
  157. package/lib/typescript/state-store/channel-unread-state.d.ts.map +1 -0
  158. package/lib/typescript/state-store/message-list-prev-next-state.d.ts +16 -0
  159. package/lib/typescript/state-store/message-list-prev-next-state.d.ts.map +1 -0
  160. package/lib/typescript/store/apis/getChannelMessages.d.ts.map +1 -1
  161. package/lib/typescript/utils/utils.d.ts +1 -2
  162. package/lib/typescript/utils/utils.d.ts.map +1 -1
  163. package/package.json +2 -2
  164. package/src/components/Channel/Channel.tsx +31 -16
  165. package/src/components/Channel/hooks/useCreateChannelContext.ts +2 -2
  166. package/src/components/Channel/hooks/useCreateMessagesContext.ts +4 -0
  167. package/src/components/Message/Message.tsx +6 -15
  168. package/src/components/Message/MessageSimple/MessageBlocked.tsx +67 -0
  169. package/src/components/Message/MessageSimple/MessageContent.tsx +0 -2
  170. package/src/components/Message/MessageSimple/MessageWrapper.tsx +147 -0
  171. package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js +1 -5
  172. package/src/components/Message/hooks/useCreateMessageContext.ts +0 -3
  173. package/src/components/MessageList/MessageFlashList.tsx +81 -143
  174. package/src/components/MessageList/MessageList.tsx +83 -165
  175. package/src/components/MessageList/UnreadMessagesNotification.tsx +2 -2
  176. package/src/components/MessageList/__tests__/MessageList.test.js +10 -8
  177. package/src/components/MessageList/__tests__/useMessageDateSeparator.test.ts +83 -0
  178. package/src/components/MessageList/hooks/useMessageDateSeparator.ts +66 -0
  179. package/src/components/MessageList/hooks/useMessageGroupStyles.ts +75 -0
  180. package/src/components/MessageList/hooks/useMessageList.ts +68 -36
  181. package/src/components/MessageList/utils/getDateSeparators.ts +16 -20
  182. package/src/components/MessageList/utils/getGroupStyles.ts +44 -33
  183. package/src/components/MessageList/utils/getLastReceivedMessage.ts +1 -4
  184. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +6 -6
  185. package/src/components/index.ts +3 -0
  186. package/src/contexts/channelContext/ChannelContext.tsx +13 -4
  187. package/src/contexts/messageContext/MessageContext.tsx +4 -1
  188. package/src/contexts/messageInputContext/MessageInputContext.tsx +5 -0
  189. package/src/contexts/messageListItemContext/MessageListItemContext.tsx +63 -0
  190. package/src/contexts/messagesContext/MessagesContext.tsx +16 -1
  191. package/src/contexts/themeContext/utils/theme.ts +12 -0
  192. package/src/state-store/channel-unread-state.ts +28 -0
  193. package/src/state-store/message-list-prev-next-state.ts +58 -0
  194. package/src/store/apis/getChannelMessages.ts +9 -12
  195. package/src/utils/utils.ts +9 -8
  196. package/src/version.json +1 -1
  197. package/src/components/MessageList/utils/__tests__/getDateSeparators.test.ts +0 -71
@@ -0,0 +1,75 @@
1
+ import { useCallback, useMemo } from 'react';
2
+
3
+ import { LocalMessage } from 'stream-chat';
4
+
5
+ import { useMessageDateSeparator } from './useMessageDateSeparator';
6
+
7
+ import { MessagesContextValue } from '../../../contexts/messagesContext/MessagesContext';
8
+ import { useStateStore } from '../../../hooks/useStateStore';
9
+ import {
10
+ MessagePreviousAndNextMessageStore,
11
+ MessagePreviousAndNextMessageStoreType,
12
+ } from '../../../state-store/message-list-prev-next-state';
13
+ import { getGroupStyle } from '../utils/getGroupStyles';
14
+
15
+ /**
16
+ * Hook to get the group styles for a message
17
+ */
18
+ export const useMessageGroupStyles = ({
19
+ noGroupByUser,
20
+ dateSeparatorDate,
21
+ maxTimeBetweenGroupedMessages,
22
+ message,
23
+ messageListPreviousAndNextMessageStore,
24
+ getMessageGroupStyle = getGroupStyle,
25
+ }: {
26
+ noGroupByUser?: boolean;
27
+ getMessageGroupStyle: MessagesContextValue['getMessageGroupStyle'];
28
+ dateSeparatorDate?: Date;
29
+ maxTimeBetweenGroupedMessages?: number;
30
+ message: LocalMessage;
31
+ messageListPreviousAndNextMessageStore: MessagePreviousAndNextMessageStore;
32
+ }) => {
33
+ const selector = useCallback(
34
+ (state: MessagePreviousAndNextMessageStoreType) => ({
35
+ nextMessage: state.messageList[message.id]?.nextMessage,
36
+ previousMessage: state.messageList[message.id]?.previousMessage,
37
+ }),
38
+ [message.id],
39
+ );
40
+ const { previousMessage, nextMessage } = useStateStore(
41
+ messageListPreviousAndNextMessageStore.state,
42
+ selector,
43
+ );
44
+
45
+ // This is needed to calculate the group styles for the next message
46
+ const nextMessageDateSeparatorDate = useMessageDateSeparator({
47
+ message: nextMessage,
48
+ messageListPreviousAndNextMessageStore,
49
+ });
50
+
51
+ const groupStyles = useMemo(() => {
52
+ if (noGroupByUser) {
53
+ return [];
54
+ }
55
+ return getMessageGroupStyle({
56
+ dateSeparatorDate,
57
+ maxTimeBetweenGroupedMessages,
58
+ message,
59
+ nextMessage,
60
+ nextMessageDateSeparatorDate,
61
+ previousMessage,
62
+ });
63
+ }, [
64
+ noGroupByUser,
65
+ getMessageGroupStyle,
66
+ dateSeparatorDate,
67
+ maxTimeBetweenGroupedMessages,
68
+ message,
69
+ nextMessage,
70
+ nextMessageDateSeparatorDate,
71
+ previousMessage,
72
+ ]);
73
+
74
+ return groupStyles;
75
+ };
@@ -1,4 +1,4 @@
1
- import { useMemo, useRef } from 'react';
1
+ import { useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import type { LocalMessage } from 'stream-chat';
4
4
 
@@ -12,17 +12,24 @@ import { usePaginatedMessageListContext } from '../../../contexts/paginatedMessa
12
12
  import { useThreadContext } from '../../../contexts/threadContext/ThreadContext';
13
13
 
14
14
  import { useRAFCoalescedValue } from '../../../hooks';
15
+ import { MessagePreviousAndNextMessageStore } from '../../../state-store/message-list-prev-next-state';
15
16
  import { DateSeparators, getDateSeparators } from '../utils/getDateSeparators';
16
17
  import { getGroupStyles } from '../utils/getGroupStyles';
17
18
 
18
19
  export type UseMessageListParams = {
19
20
  deletedMessagesVisibilityType?: DeletedMessagesVisibilityType;
21
+ /**
22
+ * @deprecated
23
+ */
20
24
  noGroupByUser?: boolean;
21
25
  threadList?: boolean;
22
26
  isLiveStreaming?: boolean;
23
27
  isFlashList?: boolean;
24
28
  };
25
29
 
30
+ /**
31
+ * FIXME: To change it to a more specific type.
32
+ */
26
33
  export type GroupType = string;
27
34
 
28
35
  export type MessageGroupStyles = {
@@ -35,23 +42,27 @@ export const shouldIncludeMessageInList = (
35
42
  ) => {
36
43
  const { deletedMessagesVisibilityType, userId } = options;
37
44
  const isMessageTypeDeleted = message.type === 'deleted';
45
+ const isSender = message.user?.id === userId;
46
+
47
+ if (!isMessageTypeDeleted) {
48
+ return true;
49
+ }
50
+
38
51
  switch (deletedMessagesVisibilityType) {
52
+ case 'always':
53
+ return true;
39
54
  case 'sender':
40
- return !isMessageTypeDeleted || message.user?.id === userId;
41
-
55
+ return isSender;
42
56
  case 'receiver':
43
- return !isMessageTypeDeleted || message.user?.id !== userId;
44
-
57
+ return !isSender;
45
58
  case 'never':
46
- return !isMessageTypeDeleted;
47
-
48
59
  default:
49
- return !!message;
60
+ return false;
50
61
  }
51
62
  };
52
63
 
53
64
  export const useMessageList = (params: UseMessageListParams) => {
54
- const { noGroupByUser, threadList, isLiveStreaming, isFlashList } = params;
65
+ const { noGroupByUser, threadList, isLiveStreaming, isFlashList = false } = params;
55
66
  const { client } = useChatContext();
56
67
  const { hideDateSeparators, maxTimeBetweenGroupedMessages } = useChannelContext();
57
68
  const { deletedMessagesVisibilityType, getMessagesGroupStyles = getGroupStyles } =
@@ -59,64 +70,84 @@ export const useMessageList = (params: UseMessageListParams) => {
59
70
  const { messages, viewabilityChangedCallback } = usePaginatedMessageListContext();
60
71
  const { threadMessages } = useThreadContext();
61
72
  const messageList = threadList ? threadMessages : messages;
73
+ const [messageListPreviousAndNextMessageStore] = useState(
74
+ () => new MessagePreviousAndNextMessageStore(),
75
+ );
62
76
 
77
+ const processedMessageList = useMemo<LocalMessage[]>(() => {
78
+ const newMessageList = [];
79
+ for (const message of messageList) {
80
+ if (
81
+ !shouldIncludeMessageInList(message, {
82
+ deletedMessagesVisibilityType,
83
+ userId: client.userID,
84
+ })
85
+ ) {
86
+ continue;
87
+ }
88
+ if (isFlashList) {
89
+ newMessageList.push(message);
90
+ } else {
91
+ newMessageList.unshift(message);
92
+ }
93
+ }
94
+ return newMessageList;
95
+ }, [messageList, deletedMessagesVisibilityType, client.userID, isFlashList]);
96
+
97
+ useEffect(() => {
98
+ messageListPreviousAndNextMessageStore.setMessageListPreviousAndNextMessage({
99
+ isFlashList,
100
+ messages: processedMessageList,
101
+ });
102
+ }, [processedMessageList, messageListPreviousAndNextMessageStore, isFlashList]);
103
+
104
+ /**
105
+ * @deprecated use `useDateSeparator` hook instead directly in the Message.
106
+ */
63
107
  const dateSeparators = useMemo(
64
108
  () =>
65
109
  getDateSeparators({
66
- deletedMessagesVisibilityType,
67
110
  hideDateSeparators,
68
- messages: messageList,
69
- userId: client.userID,
111
+ messages: processedMessageList,
70
112
  }),
71
- [deletedMessagesVisibilityType, hideDateSeparators, messageList, client.userID],
113
+ [hideDateSeparators, processedMessageList],
72
114
  );
73
115
 
116
+ /**
117
+ * @deprecated use `useDateSeparator` hook instead directly in the Message.
118
+ */
74
119
  const dateSeparatorsRef = useRef<DateSeparators>(dateSeparators);
75
120
  dateSeparatorsRef.current = dateSeparators;
76
121
 
122
+ /**
123
+ * @deprecated use `useMessageGroupStyles` hook instead directly in the Message.
124
+ */
77
125
  const messageGroupStyles = useMemo(
78
126
  () =>
79
127
  getMessagesGroupStyles({
80
128
  dateSeparators: dateSeparatorsRef.current,
81
129
  hideDateSeparators,
82
130
  maxTimeBetweenGroupedMessages,
83
- messages: messageList,
131
+ messages: processedMessageList,
84
132
  noGroupByUser,
85
133
  userId: client.userID,
86
134
  }),
87
135
  [
88
- dateSeparatorsRef,
89
136
  getMessagesGroupStyles,
90
137
  hideDateSeparators,
91
138
  maxTimeBetweenGroupedMessages,
92
- messageList,
139
+ processedMessageList,
93
140
  noGroupByUser,
94
141
  client.userID,
95
142
  ],
96
143
  );
97
144
 
145
+ /**
146
+ * @deprecated use `useMessageGroupStyles` hook instead directly in the Message.
147
+ */
98
148
  const messageGroupStylesRef = useRef<MessageGroupStyles>(messageGroupStyles);
99
149
  messageGroupStylesRef.current = messageGroupStyles;
100
150
 
101
- const processedMessageList = useMemo<LocalMessage[]>(() => {
102
- const newMessageList = [];
103
- for (const message of messageList) {
104
- if (
105
- shouldIncludeMessageInList(message, {
106
- deletedMessagesVisibilityType,
107
- userId: client.userID,
108
- })
109
- ) {
110
- if (isFlashList) {
111
- newMessageList.push(message);
112
- } else {
113
- newMessageList.unshift(message);
114
- }
115
- }
116
- }
117
- return newMessageList;
118
- }, [client.userID, deletedMessagesVisibilityType, isFlashList, messageList]);
119
-
120
151
  const data = useRAFCoalescedValue(processedMessageList, isLiveStreaming);
121
152
 
122
153
  return useMemo(
@@ -125,12 +156,13 @@ export const useMessageList = (params: UseMessageListParams) => {
125
156
  dateSeparatorsRef,
126
157
  /** Message group styles */
127
158
  messageGroupStylesRef,
159
+ messageListPreviousAndNextMessageStore,
128
160
  /** Messages enriched with dates/readby/groups and also reversed in order */
129
161
  processedMessageList: data,
130
162
  /** Raw messages from the channel state */
131
163
  rawMessageList: messageList,
132
164
  viewabilityChangedCallback,
133
165
  }),
134
- [data, messageList, viewabilityChangedCallback],
166
+ [data, messageList, messageListPreviousAndNextMessageStore, viewabilityChangedCallback],
135
167
  );
136
168
  };
@@ -2,10 +2,19 @@ import type { DeletedMessagesVisibilityType } from '../../../contexts/messagesCo
2
2
  import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext';
3
3
  import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext';
4
4
 
5
+ /**
6
+ * @deprecated in favor of `useDateSeparator` hook instead directly in the Message.
7
+ */
5
8
  export type GetDateSeparatorsParams = {
6
9
  messages: PaginatedMessageListContextValue['messages'] | ThreadContextValue['threadMessages'];
10
+ /**
11
+ * @deprecated The computations are done ahead of time in the useMessageList hook so this parameter is no longer needed.
12
+ */
7
13
  deletedMessagesVisibilityType?: DeletedMessagesVisibilityType;
8
14
  hideDateSeparators?: boolean;
15
+ /**
16
+ * @deprecated The computations are done ahead of time in the useMessageList hook so this parameter is no longer needed.
17
+ */
9
18
  userId?: string;
10
19
  };
11
20
 
@@ -13,33 +22,20 @@ export type DateSeparators = {
13
22
  [key: string]: Date;
14
23
  };
15
24
 
25
+ /**
26
+ * @deprecated in favor of `useDateSeparator` hook instead directly in the Message.
27
+ */
16
28
  export const getDateSeparators = (params: GetDateSeparatorsParams) => {
17
- const { deletedMessagesVisibilityType, hideDateSeparators, messages, userId } = params;
29
+ const { hideDateSeparators, messages } = params;
18
30
  const dateSeparators: DateSeparators = {};
19
31
 
20
32
  if (hideDateSeparators) {
21
33
  return dateSeparators;
22
34
  }
23
35
 
24
- const messagesWithoutDeleted = messages.filter((message) => {
25
- const isMessageTypeDeleted = message.type === 'deleted';
26
-
27
- const isDeletedMessageVisibleToSender =
28
- deletedMessagesVisibilityType === 'sender' || deletedMessagesVisibilityType === 'always';
29
-
30
- const isDeletedMessageVisibleToReceiver =
31
- deletedMessagesVisibilityType === 'receiver' || deletedMessagesVisibilityType === 'always';
32
-
33
- return (
34
- !isMessageTypeDeleted ||
35
- (userId === message.user?.id && isDeletedMessageVisibleToSender) ||
36
- (userId !== message.user?.id && isDeletedMessageVisibleToReceiver)
37
- );
38
- });
39
-
40
- for (let i = 0; i < messagesWithoutDeleted.length; i++) {
41
- const previousMessage = messagesWithoutDeleted[i - 1];
42
- const message = messagesWithoutDeleted[i];
36
+ for (let i = 0; i < messages.length; i++) {
37
+ const previousMessage = messages[i - 1];
38
+ const message = messages[i];
43
39
 
44
40
  const messageDate = message.created_at.toDateString();
45
41
 
@@ -8,25 +8,46 @@ import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadC
8
8
  import { isEditedMessage } from '../../../utils/utils';
9
9
  import type { GroupType } from '../hooks/useMessageList';
10
10
 
11
+ export type MessageGroupStylesParams = {
12
+ message: LocalMessage;
13
+ previousMessage: LocalMessage;
14
+ nextMessage: LocalMessage;
15
+ maxTimeBetweenGroupedMessages?: number;
16
+ dateSeparatorDate?: Date;
17
+ nextMessageDateSeparatorDate?: Date;
18
+ };
19
+
20
+ /**
21
+ * @deprecated in favor of `useMessageGroupStyles` hook instead directly in the Message.
22
+ */
11
23
  export type GetGroupStylesParams = {
12
24
  dateSeparators: DateSeparators;
13
25
  messages: PaginatedMessageListContextValue['messages'] | ThreadContextValue['threadMessages'];
26
+ /**
27
+ * @deprecated in favor of `useDateSeparator` hook instead directly in the Message.
28
+ */
14
29
  hideDateSeparators?: boolean;
15
30
  maxTimeBetweenGroupedMessages?: number;
16
31
  noGroupByUser?: boolean;
32
+ /**
33
+ * @deprecated
34
+ */
17
35
  userId?: string;
18
36
  };
19
37
 
20
38
  export type GroupStyle = '' | 'middle' | 'top' | 'bottom' | 'single';
21
39
 
22
- const getGroupStyle = (
23
- dateSeparators: DateSeparators,
24
- message: LocalMessage,
25
- previousMessage: LocalMessage,
26
- nextMessage: LocalMessage,
27
- hideDateSeparators?: boolean,
28
- maxTimeBetweenGroupedMessages?: number,
29
- ): GroupStyle[] => {
40
+ /**
41
+ * Get the group styles for a message
42
+ */
43
+ export const getGroupStyle = ({
44
+ message,
45
+ previousMessage,
46
+ nextMessage,
47
+ maxTimeBetweenGroupedMessages,
48
+ nextMessageDateSeparatorDate,
49
+ dateSeparatorDate,
50
+ }: MessageGroupStylesParams): GroupStyle[] => {
30
51
  const groupStyles: GroupStyle[] = [];
31
52
 
32
53
  const isPrevMessageTypeDeleted = previousMessage?.type === 'deleted';
@@ -41,7 +62,7 @@ const getGroupStyle = (
41
62
  userId !== previousMessage?.user?.id ||
42
63
  !!isPrevMessageTypeDeleted ||
43
64
  // NOTE: This is needed for the group styles to work after the message separated by date.
44
- (!hideDateSeparators && dateSeparators[message.id]) ||
65
+ dateSeparatorDate ||
45
66
  isEditedMessage(previousMessage);
46
67
 
47
68
  const isBottomMessage =
@@ -50,7 +71,7 @@ const getGroupStyle = (
50
71
  nextMessage.type === 'error' ||
51
72
  userId !== nextMessage?.user?.id ||
52
73
  !!isNextMessageTypeDeleted ||
53
- (!hideDateSeparators && dateSeparators[nextMessage.id]) ||
74
+ nextMessageDateSeparatorDate ||
54
75
  (maxTimeBetweenGroupedMessages !== undefined &&
55
76
  (nextMessage.created_at as Date).getTime() - (message.created_at as Date).getTime() >
56
77
  maxTimeBetweenGroupedMessages) ||
@@ -98,15 +119,11 @@ const getGroupStyle = (
98
119
  return groupStyles;
99
120
  };
100
121
 
122
+ /**
123
+ * @deprecated in favor of `useMessageGroupStyles` hook instead directly in the Message.
124
+ */
101
125
  export const getGroupStyles = (params: GetGroupStylesParams) => {
102
- const {
103
- dateSeparators,
104
- hideDateSeparators,
105
- maxTimeBetweenGroupedMessages,
106
- messages,
107
- noGroupByUser,
108
- userId,
109
- } = params;
126
+ const { dateSeparators, maxTimeBetweenGroupedMessages, messages, noGroupByUser } = params;
110
127
 
111
128
  if (noGroupByUser) {
112
129
  return {};
@@ -114,25 +131,19 @@ export const getGroupStyles = (params: GetGroupStylesParams) => {
114
131
 
115
132
  const messageGroupStyles: { [key: string]: GroupType[] } = {};
116
133
 
117
- const messagesFilteredForNonUser = messages.filter((message) => {
118
- const isMessageTypeDeleted = message.type === 'deleted';
119
- return !isMessageTypeDeleted || userId === message.user?.id;
120
- });
121
-
122
- for (let i = 0; i < messagesFilteredForNonUser.length; i++) {
123
- const previousMessage = messagesFilteredForNonUser[i - 1];
124
- const message = messagesFilteredForNonUser[i];
125
- const nextMessage = messagesFilteredForNonUser[i + 1];
134
+ for (let i = 0; i < messages.length; i++) {
135
+ const previousMessage = messages[i - 1];
136
+ const message = messages[i];
137
+ const nextMessage = messages[i + 1];
126
138
 
127
139
  if (message.id) {
128
- messageGroupStyles[message.id] = getGroupStyle(
129
- dateSeparators,
140
+ messageGroupStyles[message.id] = getGroupStyle({
141
+ dateSeparatorDate: dateSeparators[message.id],
142
+ maxTimeBetweenGroupedMessages,
130
143
  message,
131
- previousMessage,
132
144
  nextMessage,
133
- hideDateSeparators,
134
- maxTimeBetweenGroupedMessages,
135
- );
145
+ previousMessage,
146
+ });
136
147
  }
137
148
  }
138
149
 
@@ -7,10 +7,7 @@ export const getLastReceivedMessage = (messages: LocalMessage[]) => {
7
7
  * There are no status on dates so they will be skipped
8
8
  */
9
9
  for (const message of messages) {
10
- if (
11
- message?.status === MessageStatusTypes.RECEIVED ||
12
- message?.status === MessageStatusTypes.SENDING
13
- ) {
10
+ if (message?.status !== MessageStatusTypes.FAILED) {
14
11
  return message;
15
12
  }
16
13
  }
@@ -232,10 +232,10 @@ exports[`Thread should match thread snapshot 1`] = `
232
232
  }
233
233
  >
234
234
  <View
235
- testID="message-list-item-0"
235
+ testID="message-list-item-38ef6f7c-3090-5759-a37f-ab0053aadb96"
236
236
  >
237
237
  <View
238
- testID="message-list-item-0"
238
+ testID="message-list-item-38ef6f7c-3090-5759-a37f-ab0053aadb96"
239
239
  >
240
240
  <View
241
241
  style={
@@ -602,10 +602,10 @@ exports[`Thread should match thread snapshot 1`] = `
602
602
  }
603
603
  >
604
604
  <View
605
- testID="message-list-item-1"
605
+ testID="message-list-item-516efa25-5d29-5c9a-ad2d-4cc183e785bd"
606
606
  >
607
607
  <View
608
- testID="message-list-item-1"
608
+ testID="message-list-item-516efa25-5d29-5c9a-ad2d-4cc183e785bd"
609
609
  >
610
610
  <View
611
611
  style={
@@ -972,10 +972,10 @@ exports[`Thread should match thread snapshot 1`] = `
972
972
  }
973
973
  >
974
974
  <View
975
- testID="message-list-item-2"
975
+ testID="message-list-item-82a83b16-b611-527c-b3ac-765ef6220490"
976
976
  >
977
977
  <View
978
- testID="message-list-item-2"
978
+ testID="message-list-item-82a83b16-b611-527c-b3ac-765ef6220490"
979
979
  >
980
980
  <View
981
981
  style={
@@ -99,6 +99,7 @@ export * from './Message/hooks/useMessageReadData';
99
99
  export * from './Message/Message';
100
100
  export * from './Message/MessageSimple/MessageAvatar';
101
101
  export * from './Message/MessageSimple/MessageBounce';
102
+ export * from './Message/MessageSimple/MessageBlocked';
102
103
  export * from './Message/MessageSimple/MessageContent';
103
104
  export * from './Message/MessageSimple/MessageDeleted';
104
105
  export * from './Message/MessageSimple/MessageEditedTimestamp';
@@ -162,6 +163,8 @@ export * from './MessageList/utils/getGroupStyles';
162
163
  export * from './MessageList/utils/getLastReceivedMessage';
163
164
  export * from './Message/hooks/useMessageDeliveryData';
164
165
  export * from './Message/hooks/useMessageReadData';
166
+ export * from './MessageList/hooks/useMessageDateSeparator';
167
+ export * from './MessageList/hooks/useMessageGroupStyles';
165
168
 
166
169
  export * from './MessageMenu/MessageActionList';
167
170
  export * from './MessageMenu/MessageActionListItem';
@@ -6,7 +6,11 @@ import { MarkReadFunctionOptions } from '../../components/Channel/Channel';
6
6
  import type { EmptyStateProps } from '../../components/Indicators/EmptyStateIndicator';
7
7
  import type { LoadingProps } from '../../components/Indicators/LoadingIndicator';
8
8
  import { StickyHeaderProps } from '../../components/MessageList/StickyHeader';
9
- import type { ChannelUnreadState } from '../../types/types';
9
+ import {
10
+ ChannelUnreadStateStore,
11
+ ChannelUnreadStateStoreType,
12
+ } from '../../state-store/channel-unread-state';
13
+ import { ChannelUnreadState } from '../../types/types';
10
14
  import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';
11
15
 
12
16
  import { isTestEnvironment } from '../utils/isTestEnvironment';
@@ -81,9 +85,9 @@ export type ChannelContextValue = {
81
85
  limit,
82
86
  setTargetedMessage,
83
87
  }: {
84
- channelUnreadState?: ChannelUnreadState;
88
+ channelUnreadState?: ChannelUnreadStateStoreType['channelUnreadState'];
85
89
  limit?: number;
86
- setChannelUnreadState?: React.Dispatch<React.SetStateAction<ChannelUnreadState | undefined>>;
90
+ setChannelUnreadState?: (data: ChannelUnreadStateStoreType['channelUnreadState']) => void;
87
91
  setTargetedMessage?: (messageId: string) => void;
88
92
  }) => Promise<void>;
89
93
 
@@ -123,7 +127,7 @@ export type ChannelContextValue = {
123
127
  read: ChannelState['read'];
124
128
  reloadChannel: () => Promise<void>;
125
129
  scrollToFirstUnreadThreshold: number;
126
- setChannelUnreadState: React.Dispatch<React.SetStateAction<ChannelUnreadState | undefined>>;
130
+ setChannelUnreadState: (data: ChannelUnreadStateStoreType['channelUnreadState']) => void;
127
131
  setLastRead: React.Dispatch<React.SetStateAction<Date | undefined>>;
128
132
  setTargetedMessage: (messageId?: string) => void;
129
133
  /**
@@ -131,7 +135,12 @@ export type ChannelContextValue = {
131
135
  * Its a map of filename and AbortController
132
136
  */
133
137
  uploadAbortControllerRef: React.MutableRefObject<Map<string, AbortController>>;
138
+ /**
139
+ * Channel unread data
140
+ * @deprecated Use channelUnreadStateStore instead
141
+ */
134
142
  channelUnreadState?: ChannelUnreadState;
143
+ channelUnreadStateStore: ChannelUnreadStateStore;
135
144
  disabled?: boolean;
136
145
  enableMessageGroupingByUser?: boolean;
137
146
  /**
@@ -112,7 +112,10 @@ export type MessageContextValue = {
112
112
  * @returns
113
113
  */
114
114
  handleReaction?: (reactionType: string) => Promise<void>;
115
- /** Latest message id on current channel */
115
+ /**
116
+ * Latest message id on current channel
117
+ * @deprecated and will be removed in the future. This is pretty much accessible through the message-list itself.
118
+ */
116
119
  lastReceivedId?: string;
117
120
  /**
118
121
  * Theme provided only to messages that are the current users
@@ -603,6 +603,7 @@ export const MessageInputProvider = ({
603
603
  return;
604
604
  }
605
605
 
606
+ // MODERATION: This is for the case where the message is of type 'error' and if you try to edit it, it will throw an error.
606
607
  if (editedMessage && editedMessage.type !== 'error') {
607
608
  try {
608
609
  clearEditingState();
@@ -624,6 +625,10 @@ export const MessageInputProvider = ({
624
625
  } else {
625
626
  messageComposer.clear();
626
627
  }
628
+ // Even though we edit, but we eventually send the message as a regular message, so we need to clear the editing state.
629
+ if (editedMessage) {
630
+ clearEditingState();
631
+ }
627
632
  await value.sendMessage({
628
633
  localMessage,
629
634
  message,
@@ -0,0 +1,63 @@
1
+ import React, { createContext, PropsWithChildren, useContext } from 'react';
2
+
3
+ import { MessageListProps } from '../../components/MessageList/MessageList';
4
+ import { MessagePreviousAndNextMessageStore } from '../../state-store/message-list-prev-next-state';
5
+
6
+ import { Theme } from '../themeContext/utils/theme';
7
+ import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';
8
+ import { isTestEnvironment } from '../utils/isTestEnvironment';
9
+
10
+ export type MessageListItemContextValue = {
11
+ /**
12
+ * Handler to go to a particular message when its quoted.
13
+ *
14
+ * @param messageId The id of the message to go to.
15
+ * @returns void
16
+ */
17
+ goToMessage: (messageId: string) => void;
18
+ /**
19
+ * Store to get the previous and next message in the message list
20
+ */
21
+ messageListPreviousAndNextMessageStore: MessagePreviousAndNextMessageStore;
22
+ /**
23
+ * Theme to use for the message list item
24
+ */
25
+ modifiedTheme: Theme;
26
+ /**
27
+ * Whether to group messages by user
28
+ */
29
+ noGroupByUser?: boolean;
30
+ /**
31
+ * Handler to open the thread on message. This is callback for touch event for replies button.
32
+ *
33
+ * @param message A message object to open the thread upon.
34
+ */
35
+ onThreadSelect: MessageListProps['onThreadSelect'];
36
+ };
37
+
38
+ export const MessageListItemContext = createContext(
39
+ DEFAULT_BASE_CONTEXT_VALUE as MessageListItemContextValue,
40
+ );
41
+
42
+ export const MessageListItemProvider = ({
43
+ children,
44
+ value,
45
+ }: PropsWithChildren<{
46
+ value?: MessageListItemContextValue;
47
+ }>) => (
48
+ <MessageListItemContext.Provider value={value as unknown as MessageListItemContextValue}>
49
+ {children}
50
+ </MessageListItemContext.Provider>
51
+ );
52
+
53
+ export const useMessageListItemContext = () => {
54
+ const contextValue = useContext(MessageListItemContext) as unknown as MessageListItemContextValue;
55
+
56
+ if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) {
57
+ throw new Error(
58
+ 'The useMessageListItemContext hook was called outside of the MessageListItemContext provider. Make sure you have configured MessageListItem component correctly - https://getstream.io/chat/docs/sdk/reactnative/basics/hello_stream_chat/#message-list',
59
+ );
60
+ }
61
+
62
+ return contextValue;
63
+ };