stream-chat-react-native-core 8.5.2 → 8.6.0-beta.2

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 (63) hide show
  1. package/lib/commonjs/components/MessageList/MessageFlashList.js +877 -0
  2. package/lib/commonjs/components/MessageList/MessageFlashList.js.map +1 -0
  3. package/lib/commonjs/components/MessageList/MessageList.js +6 -8
  4. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  5. package/lib/commonjs/components/MessageList/hooks/useMessageList.js +8 -3
  6. package/lib/commonjs/components/MessageList/hooks/useMessageList.js.map +1 -1
  7. package/lib/commonjs/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.js +1 -1
  8. package/lib/commonjs/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.js.map +1 -1
  9. package/lib/commonjs/components/MessageList/utils/getLastReceivedMessageFlashList.js +15 -0
  10. package/lib/commonjs/components/MessageList/utils/getLastReceivedMessageFlashList.js.map +1 -0
  11. package/lib/commonjs/components/MessageMenu/MessageUserReactions.js +4 -4
  12. package/lib/commonjs/components/MessageMenu/MessageUserReactions.js.map +1 -1
  13. package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js +28 -24
  14. package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  15. package/lib/commonjs/components/Thread/Thread.js +12 -1
  16. package/lib/commonjs/components/Thread/Thread.js.map +1 -1
  17. package/lib/commonjs/components/index.js +11 -0
  18. package/lib/commonjs/components/index.js.map +1 -1
  19. package/lib/commonjs/version.json +1 -1
  20. package/lib/module/components/MessageList/MessageFlashList.js +877 -0
  21. package/lib/module/components/MessageList/MessageFlashList.js.map +1 -0
  22. package/lib/module/components/MessageList/MessageList.js +6 -8
  23. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  24. package/lib/module/components/MessageList/hooks/useMessageList.js +8 -3
  25. package/lib/module/components/MessageList/hooks/useMessageList.js.map +1 -1
  26. package/lib/module/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.js +1 -1
  27. package/lib/module/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.js.map +1 -1
  28. package/lib/module/components/MessageList/utils/getLastReceivedMessageFlashList.js +15 -0
  29. package/lib/module/components/MessageList/utils/getLastReceivedMessageFlashList.js.map +1 -0
  30. package/lib/module/components/MessageMenu/MessageUserReactions.js +4 -4
  31. package/lib/module/components/MessageMenu/MessageUserReactions.js.map +1 -1
  32. package/lib/module/components/MessageMenu/hooks/useFetchReactions.js +28 -24
  33. package/lib/module/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  34. package/lib/module/components/Thread/Thread.js +12 -1
  35. package/lib/module/components/Thread/Thread.js.map +1 -1
  36. package/lib/module/components/index.js +11 -0
  37. package/lib/module/components/index.js.map +1 -1
  38. package/lib/module/version.json +1 -1
  39. package/lib/typescript/components/MessageList/MessageFlashList.d.ts +81 -0
  40. package/lib/typescript/components/MessageList/MessageFlashList.d.ts.map +1 -0
  41. package/lib/typescript/components/MessageList/MessageList.d.ts +2 -1
  42. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  43. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts +1 -0
  44. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts.map +1 -1
  45. package/lib/typescript/components/MessageList/utils/getLastReceivedMessageFlashList.d.ts +3 -0
  46. package/lib/typescript/components/MessageList/utils/getLastReceivedMessageFlashList.d.ts.map +1 -0
  47. package/lib/typescript/components/MessageMenu/MessageUserReactions.d.ts.map +1 -1
  48. package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts.map +1 -1
  49. package/lib/typescript/components/Thread/Thread.d.ts +9 -1
  50. package/lib/typescript/components/Thread/Thread.d.ts.map +1 -1
  51. package/lib/typescript/components/index.d.ts +1 -0
  52. package/lib/typescript/components/index.d.ts.map +1 -1
  53. package/package.json +7 -1
  54. package/src/components/MessageList/MessageFlashList.tsx +1319 -0
  55. package/src/components/MessageList/MessageList.tsx +9 -6
  56. package/src/components/MessageList/hooks/useMessageList.ts +8 -3
  57. package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts +1 -1
  58. package/src/components/MessageList/utils/getLastReceivedMessageFlashList.ts +20 -0
  59. package/src/components/MessageMenu/MessageUserReactions.tsx +13 -9
  60. package/src/components/MessageMenu/hooks/useFetchReactions.ts +27 -24
  61. package/src/components/Thread/Thread.tsx +31 -6
  62. package/src/components/index.ts +1 -0
  63. package/src/version.json +1 -1
@@ -37,6 +37,10 @@ import {
37
37
  MessagesContextValue,
38
38
  useMessagesContext,
39
39
  } from '../../contexts/messagesContext/MessagesContext';
40
+ import {
41
+ OwnCapabilitiesContextValue,
42
+ useOwnCapabilitiesContext,
43
+ } from '../../contexts/ownCapabilitiesContext/OwnCapabilitiesContext';
40
44
  import {
41
45
  PaginatedMessageListContextValue,
42
46
  usePaginatedMessageListContext,
@@ -67,11 +71,6 @@ const styles = StyleSheet.create({
67
71
  paddingBottom: 4,
68
72
  },
69
73
  flex: { flex: 1 },
70
- invertAndroid: {
71
- // Invert the Y AND X axis to prevent a react native issue that can lead to ANRs on android 13
72
- // details: https://github.com/Expensify/App/pull/12820
73
- transform: [{ scaleX: -1 }, { scaleY: -1 }],
74
- },
75
74
  listContainer: {
76
75
  flex: 1,
77
76
  width: '100%',
@@ -120,6 +119,7 @@ type MessageListPropsWithContext = Pick<
120
119
  AttachmentPickerContextValue,
121
120
  'closePicker' | 'selectedPicker' | 'setSelectedPicker'
122
121
  > &
122
+ Pick<OwnCapabilitiesContextValue, 'readEvents'> &
123
123
  Pick<
124
124
  ChannelContextValue,
125
125
  | 'channel'
@@ -282,6 +282,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
282
282
  noGroupByUser,
283
283
  onListScroll,
284
284
  onThreadSelect,
285
+ readEvents,
285
286
  reloadChannel,
286
287
  ScrollToBottomButton,
287
288
  selectedPicker,
@@ -446,7 +447,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
446
447
  }
447
448
  messagesLength.current = processedMessageList.length;
448
449
 
449
- if (!viewableItems.length) {
450
+ if (!viewableItems.length || !readEvents) {
450
451
  setIsUnreadNotificationOpen(false);
451
452
  return;
452
453
  }
@@ -1299,6 +1300,7 @@ export const MessageList = (props: MessageListProps) => {
1299
1300
  } = useChannelContext();
1300
1301
  const { client } = useChatContext();
1301
1302
  const { setMessages } = useImageGalleryContext();
1303
+ const { readEvents } = useOwnCapabilitiesContext();
1302
1304
  const {
1303
1305
  DateHeader,
1304
1306
  disableTypingIndicator,
@@ -1350,6 +1352,7 @@ export const MessageList = (props: MessageListProps) => {
1350
1352
  MessageSystem,
1351
1353
  myMessageTheme,
1352
1354
  NetworkDownIndicator,
1355
+ readEvents,
1353
1356
  reloadChannel,
1354
1357
  ScrollToBottomButton,
1355
1358
  scrollToFirstUnreadThreshold,
@@ -20,6 +20,7 @@ export type UseMessageListParams = {
20
20
  noGroupByUser?: boolean;
21
21
  threadList?: boolean;
22
22
  isLiveStreaming?: boolean;
23
+ isFlashList?: boolean;
23
24
  };
24
25
 
25
26
  export type GroupType = string;
@@ -50,7 +51,7 @@ export const shouldIncludeMessageInList = (
50
51
  };
51
52
 
52
53
  export const useMessageList = (params: UseMessageListParams) => {
53
- const { noGroupByUser, threadList, isLiveStreaming } = params;
54
+ const { noGroupByUser, threadList, isLiveStreaming, isFlashList } = params;
54
55
  const { client } = useChatContext();
55
56
  const { hideDateSeparators, maxTimeBetweenGroupedMessages } = useChannelContext();
56
57
  const { deletedMessagesVisibilityType, getMessagesGroupStyles = getGroupStyles } =
@@ -106,11 +107,15 @@ export const useMessageList = (params: UseMessageListParams) => {
106
107
  userId: client.userID,
107
108
  })
108
109
  ) {
109
- newMessageList.unshift(message);
110
+ if (isFlashList) {
111
+ newMessageList.push(message);
112
+ } else {
113
+ newMessageList.unshift(message);
114
+ }
110
115
  }
111
116
  }
112
117
  return newMessageList;
113
- }, [client.userID, deletedMessagesVisibilityType, messageList]);
118
+ }, [client.userID, deletedMessagesVisibilityType, isFlashList, messageList]);
114
119
 
115
120
  const data = useRAFCoalescedValue(processedMessageList, isLiveStreaming);
116
121
 
@@ -31,7 +31,7 @@ export function useShouldScrollToRecentOnNewOwnMessage(
31
31
  if (rawMessageList && rawMessageList.length) {
32
32
  if (!initialFocusRegistered.current) {
33
33
  initialFocusRegistered.current = true;
34
- const lastMessage = rawMessageList[0];
34
+ const lastMessage = rawMessageList[rawMessageList.length - 1];
35
35
  if (lastMessage && lastMessage.user?.id === currentUserId) {
36
36
  lastFocusedOwnMessageId.current = lastMessage.id;
37
37
  }
@@ -0,0 +1,20 @@
1
+ import { LocalMessage } from 'stream-chat';
2
+
3
+ import { MessageStatusTypes } from '../../../utils/utils';
4
+
5
+ export const getLastReceivedMessageFlashList = (messages: LocalMessage[]) => {
6
+ /**
7
+ * There are no status on dates so they will be skipped
8
+ */
9
+ for (let i = messages.length - 1; i >= 0; i--) {
10
+ const message = messages[i];
11
+ if (
12
+ message?.status === MessageStatusTypes.RECEIVED ||
13
+ message?.status === MessageStatusTypes.SENDING
14
+ ) {
15
+ return message;
16
+ }
17
+ }
18
+
19
+ return;
20
+ };
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo } from 'react';
1
+ import React, { useCallback, useEffect, useMemo } from 'react';
2
2
  import { StyleSheet, Text, View } from 'react-native';
3
3
  import { FlatList } from 'react-native-gesture-handler';
4
4
 
@@ -138,16 +138,20 @@ export const MessageUserReactions = (props: MessageUserReactionsProps) => {
138
138
  [propReactions, fetchedReactions],
139
139
  );
140
140
 
141
- const renderItem = ({ item }: { item: Reaction }) => (
142
- <MessageUserReactionsItem
143
- MessageUserReactionsAvatar={MessageUserReactionsAvatar}
144
- reaction={item}
145
- supportedReactions={supportedReactions ?? []}
146
- />
141
+ const renderItem = useCallback(
142
+ ({ item }: { item: Reaction }) => (
143
+ <MessageUserReactionsItem
144
+ MessageUserReactionsAvatar={MessageUserReactionsAvatar}
145
+ reaction={item}
146
+ supportedReactions={supportedReactions ?? []}
147
+ />
148
+ ),
149
+ [MessageUserReactionsAvatar, MessageUserReactionsItem, supportedReactions],
147
150
  );
148
151
 
149
- const renderHeader = () => (
150
- <Text style={[styles.reactionsText, reactionsText]}>{t('Message Reactions')}</Text>
152
+ const renderHeader = useCallback(
153
+ () => <Text style={[styles.reactionsText, reactionsText]}>{t('Message Reactions')}</Text>,
154
+ [t, reactionsText],
151
155
  );
152
156
 
153
157
  const selectorReactions: ReactionSelectorItemType[] = messageReactions.map((reaction) => ({
@@ -22,44 +22,47 @@ export const useFetchReactions = ({
22
22
  const [next, setNext] = useState<string | undefined>(undefined);
23
23
  const messageId = message?.id;
24
24
 
25
- const { client, enableOfflineSupport } = useChatContext();
25
+ const { client } = useChatContext();
26
26
 
27
27
  const sortString = useMemo(() => JSON.stringify(sort), [sort]);
28
28
 
29
- const fetchReactions = useCallback(async () => {
30
- if (!messageId) {
31
- return;
32
- }
33
- try {
34
- const response = await client.queryReactions(
35
- messageId,
36
- reactionType ? { type: reactionType } : {},
37
- sort,
38
- { limit, next },
39
- );
40
- if (response) {
41
- setReactions((prevReactions) =>
42
- next ? [...prevReactions, ...response.reactions] : response.reactions,
29
+ const fetchReactions = useCallback(
30
+ async (next: string | undefined) => {
31
+ if (!messageId) {
32
+ return;
33
+ }
34
+ try {
35
+ const response = await client.queryReactions(
36
+ messageId,
37
+ reactionType ? { type: reactionType } : {},
38
+ sort,
39
+ { limit, next },
43
40
  );
44
- setNext(response.next);
45
- setLoading(false);
41
+ if (response) {
42
+ setNext(response.next);
43
+
44
+ setReactions((prevReactions) =>
45
+ next ? [...prevReactions, ...response.reactions] : response.reactions,
46
+ );
47
+ setLoading(false);
48
+ }
49
+ } catch (error) {
50
+ console.log('Error fetching reactions: ', error);
46
51
  }
47
- } catch (error) {
48
- console.log('Error fetching reactions: ', error);
49
- }
50
- // eslint-disable-next-line react-hooks/exhaustive-deps
51
- }, [client, messageId, reactionType, sortString, next, limit, enableOfflineSupport]);
52
+ },
53
+ [messageId, client, reactionType, sort, limit],
54
+ );
52
55
 
53
56
  const loadNextPage = useCallback(async () => {
54
57
  if (next) {
55
- await fetchReactions();
58
+ await fetchReactions(next);
56
59
  }
57
60
  }, [fetchReactions, next]);
58
61
 
59
62
  useEffect(() => {
60
63
  setReactions([]);
61
64
  setNext(undefined);
62
- fetchReactions();
65
+ fetchReactions(undefined);
63
66
  }, [fetchReactions, messageId, reactionType, sortString]);
64
67
 
65
68
  useEffect(() => {
@@ -14,7 +14,16 @@ import {
14
14
  MessageInput as DefaultMessageInput,
15
15
  MessageInputProps,
16
16
  } from '../MessageInput/MessageInput';
17
- import type { MessageListProps } from '../MessageList/MessageList';
17
+ import { MessageFlashList, MessageFlashListProps } from '../MessageList/MessageFlashList';
18
+ import { MessageListProps } from '../MessageList/MessageList';
19
+
20
+ let FlashList;
21
+
22
+ try {
23
+ FlashList = require('@shopify/flash-list').FlashList;
24
+ } catch {
25
+ FlashList = undefined;
26
+ }
18
27
 
19
28
  type ThreadPropsWithContext = Pick<ChatContextValue, 'client'> &
20
29
  Pick<MessagesContextValue, 'MessageList'> &
@@ -37,6 +46,13 @@ type ThreadPropsWithContext = Pick<ChatContextValue, 'client'> &
37
46
  * Available props - https://getstream.io/chat/docs/sdk/reactnative/ui-components/message-list/#props
38
47
  * */
39
48
  additionalMessageListProps?: Partial<MessageListProps>;
49
+ /**
50
+ * @experimental This prop is experimental and is subject to change.
51
+ *
52
+ * Additional props for underlying MessageListFlashList component.
53
+ * Available props - https://shopify.github.io/flash-list/docs/usage
54
+ */
55
+ additionalMessageFlashListProps?: Partial<MessageFlashListProps>;
40
56
  /** Make input focus on mounting thread */
41
57
  autoFocus?: boolean;
42
58
  /** Closes thread on dismount, defaults to true */
@@ -58,6 +74,7 @@ const ThreadWithContext = (props: ThreadPropsWithContext) => {
58
74
  const {
59
75
  additionalMessageInputProps,
60
76
  additionalMessageListProps,
77
+ additionalMessageFlashListProps,
61
78
  autoFocus = true,
62
79
  closeThread,
63
80
  closeThreadOnDismount = true,
@@ -108,11 +125,19 @@ const ThreadWithContext = (props: ThreadPropsWithContext) => {
108
125
 
109
126
  return (
110
127
  <React.Fragment key={`thread-${thread.id}`}>
111
- <MessageList
112
- FooterComponent={MemoizedThreadFooterComponent}
113
- threadList
114
- {...additionalMessageListProps}
115
- />
128
+ {FlashList ? (
129
+ <MessageFlashList
130
+ HeaderComponent={MemoizedThreadFooterComponent}
131
+ threadList
132
+ {...additionalMessageFlashListProps}
133
+ />
134
+ ) : (
135
+ <MessageList
136
+ FooterComponent={MemoizedThreadFooterComponent}
137
+ threadList
138
+ {...additionalMessageListProps}
139
+ />
140
+ )}
116
141
  <MessageInput
117
142
  additionalTextInputProps={{
118
143
  autoFocus,
@@ -145,6 +145,7 @@ export * from './MessageList/InlineLoadingMoreIndicator';
145
145
  export * from './MessageList/InlineLoadingMoreRecentIndicator';
146
146
  export * from './MessageList/InlineUnreadIndicator';
147
147
  export * from './MessageList/MessageList';
148
+ export * from './MessageList/MessageFlashList';
148
149
  export * from './MessageList/MessageSystem';
149
150
  export * from './MessageList/NetworkDownIndicator';
150
151
  export * from './MessageList/ScrollToBottomButton';
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "8.5.2"
2
+ "version": "8.6.0-beta.2"
3
3
  }