@sendbird/uikit-react-native 3.9.6 → 3.10.0

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 (59) hide show
  1. package/lib/commonjs/components/ChannelMessageList/index.js +57 -9
  2. package/lib/commonjs/components/ChannelMessageList/index.js.map +1 -1
  3. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageNewLine.js +53 -0
  4. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageNewLine.js.map +1 -0
  5. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js +5 -0
  6. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js.map +1 -1
  7. package/lib/commonjs/components/UnreadMessagesFloating.js +77 -0
  8. package/lib/commonjs/components/UnreadMessagesFloating.js.map +1 -0
  9. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +156 -7
  10. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  11. package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
  12. package/lib/commonjs/fragments/createGroupChannelFragment.js +57 -3
  13. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  14. package/lib/commonjs/localization/StringSet.type.js.map +1 -1
  15. package/lib/commonjs/localization/createBaseStringSet.js +16 -2
  16. package/lib/commonjs/localization/createBaseStringSet.js.map +1 -1
  17. package/lib/commonjs/version.js +1 -1
  18. package/lib/commonjs/version.js.map +1 -1
  19. package/lib/module/components/ChannelMessageList/index.js +57 -9
  20. package/lib/module/components/ChannelMessageList/index.js.map +1 -1
  21. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageNewLine.js +46 -0
  22. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageNewLine.js.map +1 -0
  23. package/lib/module/components/GroupChannelMessageRenderer/index.js +5 -0
  24. package/lib/module/components/GroupChannelMessageRenderer/index.js.map +1 -1
  25. package/lib/module/components/UnreadMessagesFloating.js +70 -0
  26. package/lib/module/components/UnreadMessagesFloating.js.map +1 -0
  27. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +158 -9
  28. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  29. package/lib/module/domain/groupChannel/types.js.map +1 -1
  30. package/lib/module/fragments/createGroupChannelFragment.js +59 -5
  31. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  32. package/lib/module/localization/StringSet.type.js.map +1 -1
  33. package/lib/module/localization/createBaseStringSet.js +16 -2
  34. package/lib/module/localization/createBaseStringSet.js.map +1 -1
  35. package/lib/module/version.js +1 -1
  36. package/lib/module/version.js.map +1 -1
  37. package/lib/typescript/src/components/ChannelMessageList/index.d.ts +8 -1
  38. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageNewLine.d.ts +6 -0
  39. package/lib/typescript/src/components/GroupChannelMessageRenderer/index.d.ts +1 -0
  40. package/lib/typescript/src/components/OpenChannelMessageRenderer/index.d.ts +1 -0
  41. package/lib/typescript/src/components/UnreadMessagesFloating.d.ts +8 -0
  42. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +1 -1
  43. package/lib/typescript/src/domain/groupChannel/component/GroupChannelMessageList.d.ts +6 -1
  44. package/lib/typescript/src/domain/groupChannel/types.d.ts +13 -1
  45. package/lib/typescript/src/domain/openChannel/component/OpenChannelHeader.d.ts +1 -1
  46. package/lib/typescript/src/hooks/useChannelInputItems.d.ts +1 -1
  47. package/lib/typescript/src/localization/StringSet.type.d.ts +3 -0
  48. package/lib/typescript/src/version.d.ts +1 -1
  49. package/package.json +8 -7
  50. package/src/components/ChannelMessageList/index.tsx +71 -5
  51. package/src/components/GroupChannelMessageRenderer/GroupChannelMessageNewLine.tsx +45 -0
  52. package/src/components/GroupChannelMessageRenderer/index.tsx +5 -0
  53. package/src/components/UnreadMessagesFloating.tsx +60 -0
  54. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +204 -5
  55. package/src/domain/groupChannel/types.ts +15 -0
  56. package/src/fragments/createGroupChannelFragment.tsx +67 -4
  57. package/src/localization/StringSet.type.ts +3 -0
  58. package/src/localization/createBaseStringSet.ts +16 -4
  59. package/src/version.ts +1 -1
@@ -1,8 +1,8 @@
1
1
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
- import React, { useContext, useEffect } from 'react';
2
+ import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
3
3
  import { useToast } from '@sendbird/uikit-react-native-foundation';
4
4
  import { useGroupChannelHandler } from '@sendbird/uikit-tools';
5
- import { isDifferentChannel, useFreshCallback, useIsFirstMount } from '@sendbird/uikit-utils';
5
+ import { confirmAndMarkAsRead, isDifferentChannel, useFreshCallback, useIsFirstMount } from '@sendbird/uikit-utils';
6
6
  import ChannelMessageList from '../../../components/ChannelMessageList';
7
7
  import { MESSAGE_FOCUS_ANIMATION_DELAY, MESSAGE_SEARCH_SAFE_SCROLL_DELAY } from '../../../constants';
8
8
  import { useLocalization, useSendbirdChat } from '../../../hooks/useContext';
@@ -21,9 +21,7 @@ const GroupChannelMessageList = props => {
21
21
  setMessageToEdit,
22
22
  setMessageToReply
23
23
  } = useContext(GroupChannelContexts.Fragment);
24
- const {
25
- subscribe
26
- } = useContext(GroupChannelContexts.PubSub);
24
+ const groupChannelPubSub = useContext(GroupChannelContexts.PubSub);
27
25
  const {
28
26
  flatListRef,
29
27
  lazyScrollToBottom,
@@ -31,6 +29,28 @@ const GroupChannelMessageList = props => {
31
29
  onPressReplyMessageInThread
32
30
  } = useContext(GroupChannelContexts.MessageList);
33
31
  const isFirstMount = useIsFirstMount();
32
+ const hasSeenNewLineRef = useRef(false);
33
+ const isNewLineInViewportRef = useRef(false);
34
+ const isNewLineExistInChannelRef = useRef(false);
35
+ const scrolledAwayFromBottomRef = useRef(false);
36
+ const [isVisibleUnreadMessageFloating, setIsVisibleUnreadMessageFloating] = useState(false);
37
+ const viewableMessages = useRef();
38
+ const hasUserMarkedAsUnreadRef = useRef(false);
39
+ const [unreadFirstMessage, setUnreadFirstMessage] = useState(undefined);
40
+ const updateHasSeenNewLine = useCallback(hasSeenNewLine => {
41
+ if (hasSeenNewLineRef.current !== hasSeenNewLine) {
42
+ var _props$onNewLineSeenC;
43
+ hasSeenNewLineRef.current = hasSeenNewLine;
44
+ (_props$onNewLineSeenC = props.onNewLineSeenChange) === null || _props$onNewLineSeenC === void 0 || _props$onNewLineSeenC.call(props, hasSeenNewLine);
45
+ }
46
+ }, [props.onNewLineSeenChange]);
47
+ const updateHasUserMarkedAsUnread = useCallback(hasUserMarkedAsUnread => {
48
+ if (hasUserMarkedAsUnreadRef.current !== hasUserMarkedAsUnread) {
49
+ var _props$onUserMarkedAs;
50
+ hasUserMarkedAsUnreadRef.current = hasUserMarkedAsUnread;
51
+ (_props$onUserMarkedAs = props.onUserMarkedAsUnreadChange) === null || _props$onUserMarkedAs === void 0 || _props$onUserMarkedAs.call(props, hasUserMarkedAsUnread);
52
+ }
53
+ }, [props.onUserMarkedAsUnreadChange]);
34
54
  const scrollToMessageWithCreatedAt = useFreshCallback((createdAt, focusAnimated, timeout) => {
35
55
  const foundMessageIndex = props.messages.findIndex(it => it.createdAt === createdAt);
36
56
  const isIncludedInList = foundMessageIndex > -1;
@@ -59,12 +79,16 @@ const GroupChannelMessageList = props => {
59
79
  }
60
80
  return true;
61
81
  });
82
+ const onScrolledAwayFromBottom = useFreshCallback(value => {
83
+ scrolledAwayFromBottomRef.current = value;
84
+ props.onScrolledAwayFromBottom(value);
85
+ });
62
86
  const scrollToBottom = useFreshCallback(async (animated = false) => {
63
87
  if (props.hasNext()) {
64
88
  props.onUpdateSearchItem(undefined);
65
- props.onScrolledAwayFromBottom(false);
89
+ onScrolledAwayFromBottom(false);
66
90
  await props.onResetMessageList().catch(_ => {});
67
- props.onScrolledAwayFromBottom(false);
91
+ onScrolledAwayFromBottom(false);
68
92
  lazyScrollToBottom({
69
93
  animated
70
94
  });
@@ -74,6 +98,107 @@ const GroupChannelMessageList = props => {
74
98
  });
75
99
  }
76
100
  });
101
+ const onPressUnreadMessagesFloatingCloseButton = useCallback(() => {
102
+ var _props$resetNewMessag;
103
+ updateHasSeenNewLine(true);
104
+ updateHasUserMarkedAsUnread(false);
105
+ (_props$resetNewMessag = props.resetNewMessages) === null || _props$resetNewMessag === void 0 || _props$resetNewMessag.call(props);
106
+ confirmAndMarkAsRead([props.channel]);
107
+ }, [updateHasSeenNewLine, updateHasUserMarkedAsUnread, props.channel.url, props.resetNewMessages]);
108
+ const getPrevNonSilentMessage = useCallback((messages, prevMessageIndex) => {
109
+ if (messages.length <= prevMessageIndex) {
110
+ return null;
111
+ }
112
+ const prevMessage = messages[prevMessageIndex];
113
+ if (prevMessage) {
114
+ if (prevMessage.silent) {
115
+ return getPrevNonSilentMessage(messages, prevMessageIndex + 1);
116
+ } else {
117
+ return prevMessage;
118
+ }
119
+ }
120
+ return null;
121
+ }, []);
122
+ const findFirstUnreadMessage = useFreshCallback(isNewLineExistInChannel => {
123
+ if (!sbOptions.uikit.groupChannel.channel.enableMarkAsUnread || !isNewLineExistInChannel) {
124
+ return;
125
+ }
126
+ return props.messages.find((msg, index) => {
127
+ var _props$hasPrevious;
128
+ if (msg.silent) {
129
+ return false;
130
+ }
131
+ const isMarkedAsUnreadMessage = props.channel.myLastRead === msg.createdAt - 1;
132
+ if (isMarkedAsUnreadMessage) {
133
+ return true;
134
+ }
135
+ const prevNonSilentMessage = getPrevNonSilentMessage(props.messages, index + 1);
136
+ const hasNoPreviousAndNoPrevMessage = !((_props$hasPrevious = props.hasPrevious) !== null && _props$hasPrevious !== void 0 && _props$hasPrevious.call(props)) && prevNonSilentMessage == null;
137
+ const prevMessageIsRead = prevNonSilentMessage != null && prevNonSilentMessage.createdAt <= props.channel.myLastRead;
138
+ const isMessageUnread = props.channel.myLastRead < msg.createdAt;
139
+ return (hasNoPreviousAndNoPrevMessage || prevMessageIsRead) && isMessageUnread;
140
+ });
141
+ });
142
+ useEffect(() => {
143
+ if (!unreadFirstMessage) {
144
+ const foundUnreadFirstMessage = findFirstUnreadMessage(props.isNewLineExistInChannel ?? false);
145
+ if (foundUnreadFirstMessage) {
146
+ processNewLineVisibility(foundUnreadFirstMessage);
147
+ setUnreadFirstMessage(foundUnreadFirstMessage);
148
+ }
149
+ }
150
+ }, [props.messages, props.channel.myLastRead, sbOptions.uikit.groupChannel.channel.enableMarkAsUnread]);
151
+ const processNewLineVisibility = useFreshCallback(unreadFirstMsg => {
152
+ var _viewableMessages$cur;
153
+ const isNewLineInViewport = !!((_viewableMessages$cur = viewableMessages.current) !== null && _viewableMessages$cur !== void 0 && _viewableMessages$cur.some(message => message.messageId === (unreadFirstMsg === null || unreadFirstMsg === void 0 ? void 0 : unreadFirstMsg.messageId)));
154
+ if (isNewLineInViewportRef.current !== isNewLineInViewport) {
155
+ isNewLineInViewportRef.current = isNewLineInViewport;
156
+ updateUnreadMessagesFloatingProps();
157
+ if (!isNewLineInViewport || hasSeenNewLineRef.current) {
158
+ return;
159
+ }
160
+ updateHasSeenNewLine(true);
161
+ if (hasUserMarkedAsUnreadRef.current) {
162
+ return;
163
+ }
164
+ if (0 < props.newMessages.length) {
165
+ props.channel.markAsUnread(props.newMessages[0]);
166
+ } else {
167
+ props.channel.markAsRead();
168
+ }
169
+ }
170
+ });
171
+ const onViewableItemsChanged = useFreshCallback(async info => {
172
+ if (!sbOptions.uikit.groupChannel.channel.enableMarkAsUnread) {
173
+ return;
174
+ }
175
+ viewableMessages.current = info.viewableItems.filter(token => token.item).map(token => token.item);
176
+ processNewLineVisibility(unreadFirstMessage);
177
+ });
178
+ const onPressMarkAsUnreadMessage = useCallback(async message => {
179
+ if (sbOptions.uikit.groupChannel.channel.enableMarkAsUnread && message) {
180
+ await props.channel.markAsUnread(message);
181
+ updateHasUserMarkedAsUnread(true);
182
+ }
183
+ }, [sbOptions.uikit.groupChannel.channel.enableMarkAsUnread, updateHasUserMarkedAsUnread]);
184
+ useEffect(() => {
185
+ isNewLineExistInChannelRef.current = !!props.isNewLineExistInChannel && !!viewableMessages.current;
186
+ }, [props.isNewLineExistInChannel, viewableMessages.current]);
187
+ const unreadMessagesFloatingPropsRef = useRef();
188
+ const updateUnreadMessagesFloatingProps = useFreshCallback(() => {
189
+ const canAutoMarkAsRead = !scrolledAwayFromBottomRef.current && !hasUserMarkedAsUnreadRef.current && (hasSeenNewLineRef.current || !isNewLineExistInChannelRef.current);
190
+ unreadMessagesFloatingPropsRef.current = {
191
+ visible: sbOptions.uikit.groupChannel.channel.enableMarkAsUnread && !canAutoMarkAsRead && isNewLineExistInChannelRef.current && 0 < props.channel.unreadMessageCount && !isNewLineInViewportRef.current,
192
+ onPressClose: onPressUnreadMessagesFloatingCloseButton,
193
+ unreadMessageCount: props.channel.unreadMessageCount
194
+ };
195
+ if (isVisibleUnreadMessageFloating !== unreadMessagesFloatingPropsRef.current.visible) {
196
+ setIsVisibleUnreadMessageFloating(unreadMessagesFloatingPropsRef.current.visible);
197
+ }
198
+ });
199
+ useEffect(() => {
200
+ updateUnreadMessagesFloatingProps();
201
+ }, [isNewLineExistInChannelRef.current, props.channel.unreadMessageCount, sbOptions.uikit.groupChannel.channel.enableMarkAsUnread]);
77
202
  useGroupChannelHandler(sdk, {
78
203
  onReactionUpdated(channel, event) {
79
204
  if (isDifferentChannel(channel, props.channel)) return;
@@ -86,10 +211,13 @@ const GroupChannelMessageList = props => {
86
211
  timeout: 250
87
212
  });
88
213
  }
214
+ },
215
+ onChannelChanged(channel) {
216
+ if (isDifferentChannel(channel, props.channel)) return;
89
217
  }
90
218
  });
91
219
  useEffect(() => {
92
- return subscribe(({
220
+ return groupChannelPubSub.subscribe(({
93
221
  type,
94
222
  data
95
223
  }) => {
@@ -121,6 +249,22 @@ const GroupChannelMessageList = props => {
121
249
  scrollToBottom(false);
122
250
  break;
123
251
  }
252
+ case 'ON_MARKED_AS_READ_BY_CURRENT_USER':
253
+ {
254
+ updateUnreadMessagesFloatingProps();
255
+ break;
256
+ }
257
+ case 'ON_MARKED_AS_UNREAD_BY_CURRENT_USER':
258
+ {
259
+ isNewLineExistInChannelRef.current = true;
260
+ const foundFirstUnreadMessage = findFirstUnreadMessage(true);
261
+ processNewLineVisibility(foundFirstUnreadMessage);
262
+ setUnreadFirstMessage(foundFirstUnreadMessage);
263
+ if (!props.scrolledAwayFromBottom) {
264
+ scrollToBottom(true);
265
+ }
266
+ break;
267
+ }
124
268
  }
125
269
  });
126
270
  }, [props.scrolledAwayFromBottom]);
@@ -157,12 +301,17 @@ const GroupChannelMessageList = props => {
157
301
  });
158
302
  return /*#__PURE__*/React.createElement(ChannelMessageList, _extends({}, props, {
159
303
  ref: flatListRef,
304
+ onScrolledAwayFromBottom: onScrolledAwayFromBottom,
160
305
  onReplyMessage: setMessageToReply,
161
306
  onReplyInThreadMessage: setMessageToReply,
162
307
  onEditMessage: setMessageToEdit,
308
+ onViewableItemsChanged: onViewableItemsChanged,
163
309
  onPressParentMessage: onPressParentMessage,
164
310
  onPressNewMessagesButton: scrollToBottom,
165
- onPressScrollToBottomButton: scrollToBottom
311
+ onPressScrollToBottomButton: scrollToBottom,
312
+ onPressMarkAsUnreadMessage: onPressMarkAsUnreadMessage,
313
+ unreadFirstMessage: unreadFirstMessage,
314
+ unreadMessagesFloatingProps: unreadMessagesFloatingPropsRef.current
166
315
  }));
167
316
  };
168
317
  export default /*#__PURE__*/React.memo(GroupChannelMessageList);
@@ -1 +1 @@
1
- {"version":3,"names":["React","useContext","useEffect","useToast","useGroupChannelHandler","isDifferentChannel","useFreshCallback","useIsFirstMount","ChannelMessageList","MESSAGE_FOCUS_ANIMATION_DELAY","MESSAGE_SEARCH_SAFE_SCROLL_DELAY","useLocalization","useSendbirdChat","GroupChannelContexts","GroupChannelMessageList","props","toast","STRINGS","sdk","sbOptions","groupChannelFragmentOptions","setMessageToEdit","setMessageToReply","Fragment","subscribe","PubSub","flatListRef","lazyScrollToBottom","lazyScrollToIndex","onPressReplyMessageInThread","MessageList","isFirstMount","scrollToMessageWithCreatedAt","createdAt","focusAnimated","timeout","foundMessageIndex","messages","findIndex","it","isIncludedInList","setTimeout","onUpdateSearchItem","startingPoint","index","animated","channel","messageOffsetTimestamp","onResetMessageListWithStartingPoint","catch","_","scrollToBottom","hasNext","undefined","onScrolledAwayFromBottom","onResetMessageList","onReactionUpdated","event","recentMessage","isRecentMessage","messageId","scrollReachedBottomAndCanScroll","scrolledAwayFromBottom","type","data","lastMessage","updatedMessage","lastMessageUpdated","isMaybeStreaming","hasAiBot","pubsub","payload","searchItem","onPressParentMessage","parentMessage","childMessage","uikit","groupChannel","replyType","threadReplySelectType","show","TOAST","FIND_PARENT_MSG_ERROR","canScrollToParent","createElement","_extends","ref","onReplyMessage","onReplyInThreadMessage","onEditMessage","onPressNewMessagesButton","onPressScrollToBottomButton","memo"],"sources":["GroupChannelMessageList.tsx"],"sourcesContent":["import React, { useContext, useEffect } from 'react';\n\nimport { useToast } from '@sendbird/uikit-react-native-foundation';\nimport { useGroupChannelHandler } from '@sendbird/uikit-tools';\nimport {\n SendbirdMessage,\n SendbirdSendableMessage,\n isDifferentChannel,\n useFreshCallback,\n useIsFirstMount,\n} from '@sendbird/uikit-utils';\n\nimport ChannelMessageList from '../../../components/ChannelMessageList';\nimport { MESSAGE_FOCUS_ANIMATION_DELAY, MESSAGE_SEARCH_SAFE_SCROLL_DELAY } from '../../../constants';\nimport { GroupChannelFragmentOptionsPubSubContextPayload } from '../../../contexts/SendbirdChatCtx';\nimport { useLocalization, useSendbirdChat } from '../../../hooks/useContext';\nimport { GroupChannelContexts } from '../module/moduleContext';\nimport type { GroupChannelProps } from '../types';\n\nconst GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {\n const toast = useToast();\n const { STRINGS } = useLocalization();\n const { sdk, sbOptions, groupChannelFragmentOptions } = useSendbirdChat();\n const { setMessageToEdit, setMessageToReply } = useContext(GroupChannelContexts.Fragment);\n const { subscribe } = useContext(GroupChannelContexts.PubSub);\n const { flatListRef, lazyScrollToBottom, lazyScrollToIndex, onPressReplyMessageInThread } = useContext(\n GroupChannelContexts.MessageList,\n );\n\n const isFirstMount = useIsFirstMount();\n\n const scrollToMessageWithCreatedAt = useFreshCallback(\n (createdAt: number, focusAnimated: boolean, timeout: number): boolean => {\n const foundMessageIndex = props.messages.findIndex((it) => it.createdAt === createdAt);\n const isIncludedInList = foundMessageIndex > -1;\n\n if (isIncludedInList) {\n if (focusAnimated) {\n setTimeout(() => props.onUpdateSearchItem({ startingPoint: createdAt }), MESSAGE_FOCUS_ANIMATION_DELAY);\n }\n lazyScrollToIndex({ index: foundMessageIndex, animated: true, timeout });\n } else {\n if (props.channel.messageOffsetTimestamp <= createdAt) {\n if (focusAnimated) {\n props.onUpdateSearchItem({ startingPoint: createdAt });\n }\n props.onResetMessageListWithStartingPoint(createdAt).catch((_) => {});\n } else {\n return false;\n }\n }\n return true;\n },\n );\n\n const scrollToBottom = useFreshCallback(async (animated = false) => {\n if (props.hasNext()) {\n props.onUpdateSearchItem(undefined);\n props.onScrolledAwayFromBottom(false);\n\n await props.onResetMessageList().catch((_) => {});\n props.onScrolledAwayFromBottom(false);\n lazyScrollToBottom({ animated });\n } else {\n lazyScrollToBottom({ animated });\n }\n });\n\n useGroupChannelHandler(sdk, {\n onReactionUpdated(channel, event) {\n if (isDifferentChannel(channel, props.channel)) return;\n const recentMessage = props.messages[0];\n const isRecentMessage = recentMessage && recentMessage.messageId === event.messageId;\n const scrollReachedBottomAndCanScroll = !props.scrolledAwayFromBottom && !props.hasNext();\n if (isRecentMessage && scrollReachedBottomAndCanScroll) {\n lazyScrollToBottom({ animated: true, timeout: 250 });\n }\n },\n });\n\n useEffect(() => {\n return subscribe(({ type, data }) => {\n switch (type) {\n case 'TYPING_BUBBLE_RENDERED':\n case 'MESSAGES_RECEIVED': {\n if (!props.scrolledAwayFromBottom) {\n scrollToBottom(true);\n }\n break;\n }\n case 'MESSAGES_UPDATED': {\n const lastMessage = props.channel.lastMessage;\n const [updatedMessage] = data.messages;\n\n const lastMessageUpdated =\n updatedMessage && lastMessage && lastMessage.messageId === updatedMessage.messageId;\n\n const isMaybeStreaming = props.channel.hasAiBot && lastMessageUpdated;\n\n if (isMaybeStreaming) {\n scrollToBottom(false);\n } else if (!props.scrolledAwayFromBottom && lastMessageUpdated) {\n scrollToBottom(true);\n }\n break;\n }\n case 'MESSAGE_SENT_SUCCESS':\n case 'MESSAGE_SENT_PENDING': {\n scrollToBottom(false);\n break;\n }\n }\n });\n }, [props.scrolledAwayFromBottom]);\n\n useEffect(() => {\n return groupChannelFragmentOptions.pubsub.subscribe((payload: GroupChannelFragmentOptionsPubSubContextPayload) => {\n switch (payload.type) {\n case 'OVERRIDE_SEARCH_ITEM_STARTING_POINT': {\n scrollToMessageWithCreatedAt(payload.data.startingPoint, false, MESSAGE_SEARCH_SAFE_SCROLL_DELAY);\n break;\n }\n }\n });\n }, []);\n\n useEffect(() => {\n // Only trigger once when message list mount with initial props.searchItem\n // - Search screen + searchItem > mount message list\n // - Reset message list + searchItem > re-mount message list\n if (isFirstMount && props.searchItem) {\n scrollToMessageWithCreatedAt(props.searchItem.startingPoint, false, MESSAGE_SEARCH_SAFE_SCROLL_DELAY);\n }\n }, [isFirstMount]);\n\n const onPressParentMessage = useFreshCallback(\n (parentMessage: SendbirdMessage, childMessage: SendbirdSendableMessage) => {\n if (\n onPressReplyMessageInThread &&\n sbOptions.uikit.groupChannel.channel.replyType === 'thread' &&\n sbOptions.uikit.groupChannel.channel.threadReplySelectType === 'thread'\n ) {\n if (parentMessage.createdAt >= props.channel.messageOffsetTimestamp) {\n onPressReplyMessageInThread(parentMessage as SendbirdSendableMessage, childMessage.createdAt);\n } else {\n toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');\n }\n } else {\n const canScrollToParent = scrollToMessageWithCreatedAt(parentMessage.createdAt, true, 0);\n if (!canScrollToParent) toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');\n }\n },\n );\n\n return (\n <ChannelMessageList\n {...props}\n ref={flatListRef}\n onReplyMessage={setMessageToReply}\n onReplyInThreadMessage={setMessageToReply}\n onEditMessage={setMessageToEdit}\n onPressParentMessage={onPressParentMessage}\n onPressNewMessagesButton={scrollToBottom}\n onPressScrollToBottomButton={scrollToBottom}\n />\n );\n};\n\nexport default React.memo(GroupChannelMessageList);\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","useCallback","useContext","useEffect","useRef","useState","useToast","useGroupChannelHandler","confirmAndMarkAsRead","isDifferentChannel","useFreshCallback","useIsFirstMount","ChannelMessageList","MESSAGE_FOCUS_ANIMATION_DELAY","MESSAGE_SEARCH_SAFE_SCROLL_DELAY","useLocalization","useSendbirdChat","GroupChannelContexts","GroupChannelMessageList","props","toast","STRINGS","sdk","sbOptions","groupChannelFragmentOptions","setMessageToEdit","setMessageToReply","Fragment","groupChannelPubSub","PubSub","flatListRef","lazyScrollToBottom","lazyScrollToIndex","onPressReplyMessageInThread","MessageList","isFirstMount","hasSeenNewLineRef","isNewLineInViewportRef","isNewLineExistInChannelRef","scrolledAwayFromBottomRef","isVisibleUnreadMessageFloating","setIsVisibleUnreadMessageFloating","viewableMessages","hasUserMarkedAsUnreadRef","unreadFirstMessage","setUnreadFirstMessage","undefined","updateHasSeenNewLine","hasSeenNewLine","current","_props$onNewLineSeenC","onNewLineSeenChange","call","updateHasUserMarkedAsUnread","hasUserMarkedAsUnread","_props$onUserMarkedAs","onUserMarkedAsUnreadChange","scrollToMessageWithCreatedAt","createdAt","focusAnimated","timeout","foundMessageIndex","messages","findIndex","it","isIncludedInList","setTimeout","onUpdateSearchItem","startingPoint","index","animated","channel","messageOffsetTimestamp","onResetMessageListWithStartingPoint","catch","_","onScrolledAwayFromBottom","value","scrollToBottom","hasNext","onResetMessageList","onPressUnreadMessagesFloatingCloseButton","_props$resetNewMessag","resetNewMessages","url","getPrevNonSilentMessage","prevMessageIndex","length","prevMessage","silent","findFirstUnreadMessage","isNewLineExistInChannel","uikit","groupChannel","enableMarkAsUnread","find","msg","_props$hasPrevious","isMarkedAsUnreadMessage","myLastRead","prevNonSilentMessage","hasNoPreviousAndNoPrevMessage","hasPrevious","prevMessageIsRead","isMessageUnread","foundUnreadFirstMessage","processNewLineVisibility","unreadFirstMsg","_viewableMessages$cur","isNewLineInViewport","some","message","messageId","updateUnreadMessagesFloatingProps","newMessages","markAsUnread","markAsRead","onViewableItemsChanged","info","viewableItems","filter","token","item","map","onPressMarkAsUnreadMessage","unreadMessagesFloatingPropsRef","canAutoMarkAsRead","visible","unreadMessageCount","onPressClose","onReactionUpdated","event","recentMessage","isRecentMessage","scrollReachedBottomAndCanScroll","scrolledAwayFromBottom","onChannelChanged","subscribe","type","data","lastMessage","updatedMessage","lastMessageUpdated","isMaybeStreaming","hasAiBot","foundFirstUnreadMessage","pubsub","payload","searchItem","onPressParentMessage","parentMessage","childMessage","replyType","threadReplySelectType","show","TOAST","FIND_PARENT_MSG_ERROR","canScrollToParent","createElement","_extends","ref","onReplyMessage","onReplyInThreadMessage","onEditMessage","onPressNewMessagesButton","onPressScrollToBottomButton","unreadMessagesFloatingProps","memo"],"sources":["GroupChannelMessageList.tsx"],"sourcesContent":["import type { ViewToken } from '@react-native/virtualized-lists';\nimport React, { useCallback, useContext, useEffect, useRef, useState } from 'react';\n\nimport { useToast } from '@sendbird/uikit-react-native-foundation';\nimport { useGroupChannelHandler } from '@sendbird/uikit-tools';\nimport {\n SendbirdMessage,\n SendbirdSendableMessage,\n confirmAndMarkAsRead,\n isDifferentChannel,\n useFreshCallback,\n useIsFirstMount,\n} from '@sendbird/uikit-utils';\n\nimport ChannelMessageList from '../../../components/ChannelMessageList';\nimport { UnreadMessagesFloatingProps } from '../../../components/UnreadMessagesFloating';\nimport { MESSAGE_FOCUS_ANIMATION_DELAY, MESSAGE_SEARCH_SAFE_SCROLL_DELAY } from '../../../constants';\nimport { GroupChannelFragmentOptionsPubSubContextPayload } from '../../../contexts/SendbirdChatCtx';\nimport { useLocalization, useSendbirdChat } from '../../../hooks/useContext';\nimport { GroupChannelContexts } from '../module/moduleContext';\nimport type { GroupChannelProps } from '../types';\n\nconst GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {\n const toast = useToast();\n const { STRINGS } = useLocalization();\n const { sdk, sbOptions, groupChannelFragmentOptions } = useSendbirdChat();\n const { setMessageToEdit, setMessageToReply } = useContext(GroupChannelContexts.Fragment);\n const groupChannelPubSub = useContext(GroupChannelContexts.PubSub);\n const { flatListRef, lazyScrollToBottom, lazyScrollToIndex, onPressReplyMessageInThread } = useContext(\n GroupChannelContexts.MessageList,\n );\n\n const isFirstMount = useIsFirstMount();\n\n const hasSeenNewLineRef = useRef(false);\n const isNewLineInViewportRef = useRef(false);\n const isNewLineExistInChannelRef = useRef(false);\n const scrolledAwayFromBottomRef = useRef(false);\n const [isVisibleUnreadMessageFloating, setIsVisibleUnreadMessageFloating] = useState(false);\n const viewableMessages = useRef<SendbirdMessage[]>();\n const hasUserMarkedAsUnreadRef = useRef(false);\n const [unreadFirstMessage, setUnreadFirstMessage] = useState<SendbirdMessage | undefined>(undefined);\n\n const updateHasSeenNewLine = useCallback(\n (hasSeenNewLine: boolean) => {\n if (hasSeenNewLineRef.current !== hasSeenNewLine) {\n hasSeenNewLineRef.current = hasSeenNewLine;\n props.onNewLineSeenChange?.(hasSeenNewLine);\n }\n },\n [props.onNewLineSeenChange],\n );\n\n const updateHasUserMarkedAsUnread = useCallback(\n (hasUserMarkedAsUnread: boolean) => {\n if (hasUserMarkedAsUnreadRef.current !== hasUserMarkedAsUnread) {\n hasUserMarkedAsUnreadRef.current = hasUserMarkedAsUnread;\n props.onUserMarkedAsUnreadChange?.(hasUserMarkedAsUnread);\n }\n },\n [props.onUserMarkedAsUnreadChange],\n );\n\n const scrollToMessageWithCreatedAt = useFreshCallback(\n (createdAt: number, focusAnimated: boolean, timeout: number): boolean => {\n const foundMessageIndex = props.messages.findIndex((it) => it.createdAt === createdAt);\n const isIncludedInList = foundMessageIndex > -1;\n\n if (isIncludedInList) {\n if (focusAnimated) {\n setTimeout(() => props.onUpdateSearchItem({ startingPoint: createdAt }), MESSAGE_FOCUS_ANIMATION_DELAY);\n }\n lazyScrollToIndex({ index: foundMessageIndex, animated: true, timeout });\n } else {\n if (props.channel.messageOffsetTimestamp <= createdAt) {\n if (focusAnimated) {\n props.onUpdateSearchItem({ startingPoint: createdAt });\n }\n props.onResetMessageListWithStartingPoint(createdAt).catch((_) => {});\n } else {\n return false;\n }\n }\n return true;\n },\n );\n\n const onScrolledAwayFromBottom = useFreshCallback((value: boolean) => {\n scrolledAwayFromBottomRef.current = value;\n props.onScrolledAwayFromBottom(value);\n });\n\n const scrollToBottom = useFreshCallback(async (animated = false) => {\n if (props.hasNext()) {\n props.onUpdateSearchItem(undefined);\n onScrolledAwayFromBottom(false);\n\n await props.onResetMessageList().catch((_) => {});\n onScrolledAwayFromBottom(false);\n lazyScrollToBottom({ animated });\n } else {\n lazyScrollToBottom({ animated });\n }\n });\n\n const onPressUnreadMessagesFloatingCloseButton = useCallback(() => {\n updateHasSeenNewLine(true);\n updateHasUserMarkedAsUnread(false);\n props.resetNewMessages?.();\n confirmAndMarkAsRead([props.channel]);\n }, [updateHasSeenNewLine, updateHasUserMarkedAsUnread, props.channel.url, props.resetNewMessages]);\n\n const getPrevNonSilentMessage = useCallback(\n (messages: SendbirdMessage[], prevMessageIndex: number): SendbirdMessage | null => {\n if (messages.length <= prevMessageIndex) {\n return null;\n }\n\n const prevMessage = messages[prevMessageIndex];\n if (prevMessage) {\n if (prevMessage.silent) {\n return getPrevNonSilentMessage(messages, prevMessageIndex + 1);\n } else {\n return prevMessage;\n }\n }\n return null;\n },\n [],\n );\n\n const findFirstUnreadMessage = useFreshCallback((isNewLineExistInChannel: boolean) => {\n if (!sbOptions.uikit.groupChannel.channel.enableMarkAsUnread || !isNewLineExistInChannel) {\n return;\n }\n\n return props.messages.find((msg, index) => {\n if (msg.silent) {\n return false;\n }\n\n const isMarkedAsUnreadMessage = props.channel.myLastRead === msg.createdAt - 1;\n if (isMarkedAsUnreadMessage) {\n return true;\n }\n\n const prevNonSilentMessage = getPrevNonSilentMessage(props.messages, index + 1);\n const hasNoPreviousAndNoPrevMessage = !props.hasPrevious?.() && prevNonSilentMessage == null;\n const prevMessageIsRead =\n prevNonSilentMessage != null && prevNonSilentMessage.createdAt <= props.channel.myLastRead;\n const isMessageUnread = props.channel.myLastRead < msg.createdAt;\n return (hasNoPreviousAndNoPrevMessage || prevMessageIsRead) && isMessageUnread;\n });\n });\n\n useEffect(() => {\n if (!unreadFirstMessage) {\n const foundUnreadFirstMessage = findFirstUnreadMessage(props.isNewLineExistInChannel ?? false);\n if (foundUnreadFirstMessage) {\n processNewLineVisibility(foundUnreadFirstMessage);\n setUnreadFirstMessage(foundUnreadFirstMessage);\n }\n }\n }, [props.messages, props.channel.myLastRead, sbOptions.uikit.groupChannel.channel.enableMarkAsUnread]);\n\n const processNewLineVisibility = useFreshCallback((unreadFirstMsg: SendbirdMessage | undefined) => {\n const isNewLineInViewport = !!viewableMessages.current?.some(\n (message) => message.messageId === unreadFirstMsg?.messageId,\n );\n\n if (isNewLineInViewportRef.current !== isNewLineInViewport) {\n isNewLineInViewportRef.current = isNewLineInViewport;\n updateUnreadMessagesFloatingProps();\n if (!isNewLineInViewport || hasSeenNewLineRef.current) {\n return;\n }\n\n updateHasSeenNewLine(true);\n if (hasUserMarkedAsUnreadRef.current) {\n return;\n }\n\n if (0 < props.newMessages.length) {\n props.channel.markAsUnread(props.newMessages[0]);\n } else {\n props.channel.markAsRead();\n }\n }\n });\n\n const onViewableItemsChanged = useFreshCallback(\n async (info: { viewableItems: Array<ViewToken<SendbirdMessage>>; changed: Array<ViewToken<SendbirdMessage>> }) => {\n if (!sbOptions.uikit.groupChannel.channel.enableMarkAsUnread) {\n return;\n }\n\n viewableMessages.current = info.viewableItems.filter((token) => token.item).map((token) => token.item);\n processNewLineVisibility(unreadFirstMessage);\n },\n );\n\n const onPressMarkAsUnreadMessage = useCallback(\n async (message: SendbirdMessage) => {\n if (sbOptions.uikit.groupChannel.channel.enableMarkAsUnread && message) {\n await props.channel.markAsUnread(message);\n updateHasUserMarkedAsUnread(true);\n }\n },\n [sbOptions.uikit.groupChannel.channel.enableMarkAsUnread, updateHasUserMarkedAsUnread],\n );\n\n useEffect(() => {\n isNewLineExistInChannelRef.current = !!props.isNewLineExistInChannel && !!viewableMessages.current;\n }, [props.isNewLineExistInChannel, viewableMessages.current]);\n\n const unreadMessagesFloatingPropsRef = useRef<UnreadMessagesFloatingProps>();\n const updateUnreadMessagesFloatingProps = useFreshCallback(() => {\n const canAutoMarkAsRead =\n !scrolledAwayFromBottomRef.current &&\n !hasUserMarkedAsUnreadRef.current &&\n (hasSeenNewLineRef.current || !isNewLineExistInChannelRef.current);\n\n unreadMessagesFloatingPropsRef.current = {\n visible:\n sbOptions.uikit.groupChannel.channel.enableMarkAsUnread &&\n !canAutoMarkAsRead &&\n isNewLineExistInChannelRef.current &&\n 0 < props.channel.unreadMessageCount &&\n !isNewLineInViewportRef.current,\n onPressClose: onPressUnreadMessagesFloatingCloseButton,\n unreadMessageCount: props.channel.unreadMessageCount,\n };\n if (isVisibleUnreadMessageFloating !== unreadMessagesFloatingPropsRef.current.visible) {\n setIsVisibleUnreadMessageFloating(unreadMessagesFloatingPropsRef.current.visible);\n }\n });\n\n useEffect(() => {\n updateUnreadMessagesFloatingProps();\n }, [\n isNewLineExistInChannelRef.current,\n props.channel.unreadMessageCount,\n sbOptions.uikit.groupChannel.channel.enableMarkAsUnread,\n ]);\n\n useGroupChannelHandler(sdk, {\n onReactionUpdated(channel, event) {\n if (isDifferentChannel(channel, props.channel)) return;\n const recentMessage = props.messages[0];\n const isRecentMessage = recentMessage && recentMessage.messageId === event.messageId;\n const scrollReachedBottomAndCanScroll = !props.scrolledAwayFromBottom && !props.hasNext();\n if (isRecentMessage && scrollReachedBottomAndCanScroll) {\n lazyScrollToBottom({ animated: true, timeout: 250 });\n }\n },\n onChannelChanged(channel) {\n if (isDifferentChannel(channel, props.channel)) return;\n },\n });\n\n useEffect(() => {\n return groupChannelPubSub.subscribe(({ type, data }) => {\n switch (type) {\n case 'TYPING_BUBBLE_RENDERED':\n case 'MESSAGES_RECEIVED': {\n if (!props.scrolledAwayFromBottom) {\n scrollToBottom(true);\n }\n break;\n }\n case 'MESSAGES_UPDATED': {\n const lastMessage = props.channel.lastMessage;\n const [updatedMessage] = data.messages;\n\n const lastMessageUpdated =\n updatedMessage && lastMessage && lastMessage.messageId === updatedMessage.messageId;\n\n const isMaybeStreaming = props.channel.hasAiBot && lastMessageUpdated;\n\n if (isMaybeStreaming) {\n scrollToBottom(false);\n } else if (!props.scrolledAwayFromBottom && lastMessageUpdated) {\n scrollToBottom(true);\n }\n break;\n }\n case 'MESSAGE_SENT_SUCCESS':\n case 'MESSAGE_SENT_PENDING': {\n scrollToBottom(false);\n break;\n }\n case 'ON_MARKED_AS_READ_BY_CURRENT_USER': {\n updateUnreadMessagesFloatingProps();\n break;\n }\n case 'ON_MARKED_AS_UNREAD_BY_CURRENT_USER': {\n isNewLineExistInChannelRef.current = true;\n const foundFirstUnreadMessage = findFirstUnreadMessage(true);\n processNewLineVisibility(foundFirstUnreadMessage);\n setUnreadFirstMessage(foundFirstUnreadMessage);\n if (!props.scrolledAwayFromBottom) {\n scrollToBottom(true);\n }\n break;\n }\n }\n });\n }, [props.scrolledAwayFromBottom]);\n\n useEffect(() => {\n return groupChannelFragmentOptions.pubsub.subscribe((payload: GroupChannelFragmentOptionsPubSubContextPayload) => {\n switch (payload.type) {\n case 'OVERRIDE_SEARCH_ITEM_STARTING_POINT': {\n scrollToMessageWithCreatedAt(payload.data.startingPoint, false, MESSAGE_SEARCH_SAFE_SCROLL_DELAY);\n break;\n }\n }\n });\n }, []);\n\n useEffect(() => {\n // Only trigger once when message list mount with initial props.searchItem\n // - Search screen + searchItem > mount message list\n // - Reset message list + searchItem > re-mount message list\n if (isFirstMount && props.searchItem) {\n scrollToMessageWithCreatedAt(props.searchItem.startingPoint, false, MESSAGE_SEARCH_SAFE_SCROLL_DELAY);\n }\n }, [isFirstMount]);\n\n const onPressParentMessage = useFreshCallback(\n (parentMessage: SendbirdMessage, childMessage: SendbirdSendableMessage) => {\n if (\n onPressReplyMessageInThread &&\n sbOptions.uikit.groupChannel.channel.replyType === 'thread' &&\n sbOptions.uikit.groupChannel.channel.threadReplySelectType === 'thread'\n ) {\n if (parentMessage.createdAt >= props.channel.messageOffsetTimestamp) {\n onPressReplyMessageInThread(parentMessage as SendbirdSendableMessage, childMessage.createdAt);\n } else {\n toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');\n }\n } else {\n const canScrollToParent = scrollToMessageWithCreatedAt(parentMessage.createdAt, true, 0);\n if (!canScrollToParent) toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');\n }\n },\n );\n\n return (\n <ChannelMessageList\n {...props}\n ref={flatListRef}\n onScrolledAwayFromBottom={onScrolledAwayFromBottom}\n onReplyMessage={setMessageToReply}\n onReplyInThreadMessage={setMessageToReply}\n onEditMessage={setMessageToEdit}\n onViewableItemsChanged={onViewableItemsChanged}\n onPressParentMessage={onPressParentMessage}\n onPressNewMessagesButton={scrollToBottom}\n onPressScrollToBottomButton={scrollToBottom}\n onPressMarkAsUnreadMessage={onPressMarkAsUnreadMessage}\n unreadFirstMessage={unreadFirstMessage}\n unreadMessagesFloatingProps={unreadMessagesFloatingPropsRef.current}\n />\n );\n};\n\nexport default React.memo(GroupChannelMessageList);\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type React from 'react';\nimport type { FlatList } from 'react-native';\n\nimport type { MessageCollectionParams, MessageFilterParams } from '@sendbird/chat/groupChannel';\nimport type { UseGroupChannelMessagesOptions } from '@sendbird/uikit-chat-hooks';\nimport type {\n OnBeforeHandler,\n PickPartial,\n SendbirdFileMessage,\n SendbirdFileMessageCreateParams,\n SendbirdFileMessageUpdateParams,\n SendbirdGroupChannel,\n SendbirdMessage,\n SendbirdSendableMessage,\n SendbirdUser,\n SendbirdUserMessage,\n SendbirdUserMessageCreateParams,\n SendbirdUserMessageUpdateParams,\n} from '@sendbird/uikit-utils';\n\nimport type { ChannelInputProps, SuggestedMentionListProps } from '../../components/ChannelInput';\nimport type { ChannelMessageListProps } from '../../components/ChannelMessageList';\nimport type { CommonComponent } from '../../types';\nimport type { PubSub } from '../../utils/pubsub';\n\nexport type MessageListQueryParamsType = Omit<MessageCollectionParams, 'filter'> & MessageFilterParams;\nexport interface GroupChannelProps {\n Fragment: {\n channel: SendbirdGroupChannel;\n onChannelDeleted: () => void;\n onPressHeaderLeft: GroupChannelProps['Header']['onPressHeaderLeft'];\n onPressHeaderRight: GroupChannelProps['Header']['onPressHeaderRight'];\n onPressMediaMessage?: GroupChannelProps['MessageList']['onPressMediaMessage'];\n onPressReplyMessageInThread?: GroupChannelProps['Provider']['onPressReplyMessageInThread'];\n\n onBeforeSendUserMessage?: OnBeforeHandler<SendbirdUserMessageCreateParams>;\n onBeforeSendFileMessage?: OnBeforeHandler<SendbirdFileMessageCreateParams>;\n onBeforeUpdateUserMessage?: OnBeforeHandler<SendbirdUserMessageUpdateParams>;\n onBeforeUpdateFileMessage?: OnBeforeHandler<SendbirdFileMessageUpdateParams>;\n\n renderMessage?: GroupChannelProps['MessageList']['renderMessage'];\n renderNewMessagesButton?: GroupChannelProps['MessageList']['renderNewMessagesButton'];\n renderScrollToBottomButton?: GroupChannelProps['MessageList']['renderScrollToBottomButton'];\n\n enableTypingIndicator?: GroupChannelProps['Provider']['enableTypingIndicator'];\n enableMessageGrouping?: GroupChannelProps['MessageList']['enableMessageGrouping'];\n\n keyboardAvoidOffset?: GroupChannelProps['Provider']['keyboardAvoidOffset'];\n flatListComponent?: GroupChannelProps['MessageList']['flatListComponent'];\n flatListProps?: GroupChannelProps['MessageList']['flatListProps'];\n sortComparator?: UseGroupChannelMessagesOptions['sortComparator'];\n\n searchItem?: GroupChannelProps['MessageList']['searchItem'];\n\n /**\n * @description You can specify the query parameters for the message list.\n * @example\n * ```\n * <GroupChannelFragment messageListQueryParams={{ prevResultLimit: 20, customTypesFilter: ['filter'] }} />\n * ```\n * */\n messageListQueryParams?: MessageListQueryParamsType;\n /** @deprecated Please use `messageListQueryParams` instead */\n collectionCreator?: UseGroupChannelMessagesOptions['collectionCreator'];\n };\n Header: {\n shouldHideRight: () => boolean;\n onPressHeaderLeft: () => void;\n onPressHeaderRight: () => void;\n };\n MessageList: Pick<\n ChannelMessageListProps<SendbirdGroupChannel>,\n | 'enableMessageGrouping'\n | 'currentUserId'\n | 'channel'\n | 'messages'\n | 'newMessages'\n | 'scrolledAwayFromBottom'\n | 'onScrolledAwayFromBottom'\n | 'onTopReached'\n | 'onBottomReached'\n | 'onResendFailedMessage'\n | 'onDeleteMessage'\n | 'onPressMediaMessage'\n | 'renderMessage'\n | 'renderNewMessagesButton'\n | 'renderScrollToBottomButton'\n | 'flatListComponent'\n | 'flatListProps'\n | 'hasNext'\n | 'searchItem'\n > & {\n onResetMessageList: () => Promise<void>;\n onResetMessageListWithStartingPoint: (startingPoint: number) => Promise<void>;\n\n // Changing the search item will trigger the focus animation on messages.\n onUpdateSearchItem: (searchItem?: GroupChannelProps['MessageList']['searchItem']) => void;\n };\n Input: PickPartial<\n ChannelInputProps,\n | 'shouldRenderInput'\n | 'onPressSendUserMessage'\n | 'onPressSendFileMessage'\n | 'onPressUpdateUserMessage'\n | 'onPressUpdateFileMessage'\n | 'SuggestedMentionList'\n | 'AttachmentsButton',\n 'inputDisabled'\n >;\n\n SuggestedMentionList: SuggestedMentionListProps;\n Provider: {\n channel: SendbirdGroupChannel;\n enableTypingIndicator: boolean;\n keyboardAvoidOffset?: number;\n groupChannelPubSub: PubSub<GroupChannelPubSubContextPayload>;\n\n messages: SendbirdMessage[];\n // Changing the search item will trigger the focus animation on messages.\n onUpdateSearchItem: (searchItem?: GroupChannelProps['MessageList']['searchItem']) => void;\n onPressReplyMessageInThread: (parentMessage: SendbirdSendableMessage, startingPoint?: number) => void;\n };\n}\n\n/**\n * Internal context for GroupChannel\n * For example, the developer can create a custom header\n * with getting data from the domain context\n * */\nexport interface GroupChannelContextsType {\n Fragment: React.Context<{\n headerTitle: string;\n keyboardAvoidOffset?: number;\n channel: SendbirdGroupChannel;\n messageToEdit?: SendbirdUserMessage | SendbirdFileMessage;\n setMessageToEdit: (msg?: SendbirdUserMessage | SendbirdFileMessage) => void;\n messageToReply?: SendbirdUserMessage | SendbirdFileMessage;\n setMessageToReply: (msg?: SendbirdUserMessage | SendbirdFileMessage) => void;\n }>;\n TypingIndicator: React.Context<{\n typingUsers: SendbirdUser[];\n }>;\n PubSub: React.Context<PubSub<GroupChannelPubSubContextPayload>>;\n MessageList: React.Context<{\n /**\n * ref object for FlatList of MessageList\n * */\n flatListRef: React.MutableRefObject<FlatList | null>;\n /**\n * Function that scrolls to a message within a group channel.\n * @param messageId {number} - The id of the message to scroll.\n * @param options {object} - Scroll options (optional).\n * @param options.focusAnimated {boolean} - Enable a shake animation on the message component upon completion of scrolling.\n * @param options.viewPosition {number} - Position information to adjust the visible area during scrolling. bottom(0) ~ top(1.0)\n *\n * @example\n * ```\n * const { scrollToMessage } = useContext(GroupChannelContexts.MessageList);\n * const messageIncludedInMessageList = scrollToMessage(lastMessage.messageId, { focusAnimated: true, viewPosition: 1 });\n * if (!messageIncludedInMessageList) console.warn('Message not found in the message list.');\n * ```\n * */\n scrollToMessage: (messageId: number, options?: { focusAnimated?: boolean; viewPosition?: number }) => boolean;\n /**\n * Call the FlatList function asynchronously to scroll to bottom lazily\n * to avoid scrolling before data rendering has been committed.\n * */\n lazyScrollToBottom: (params?: { animated?: boolean; timeout?: number }) => void;\n /**\n * Call the FlatList function asynchronously to scroll to index lazily.\n * to avoid scrolling before data rendering has been committed.\n * */\n lazyScrollToIndex: (params?: {\n index?: number;\n animated?: boolean;\n timeout?: number;\n viewPosition?: number;\n }) => void;\n\n onPressReplyMessageInThread?: (parentMessage: SendbirdSendableMessage, startingPoint?: number) => void;\n }>;\n}\nexport interface GroupChannelModule {\n Provider: CommonComponent<GroupChannelProps['Provider']>;\n Header: CommonComponent<GroupChannelProps['Header']>;\n MessageList: CommonComponent<GroupChannelProps['MessageList']>;\n Input: CommonComponent<GroupChannelProps['Input']>;\n SuggestedMentionList: CommonComponent<GroupChannelProps['SuggestedMentionList']>;\n StatusEmpty: CommonComponent;\n StatusLoading: CommonComponent;\n}\n\nexport type GroupChannelFragment = React.FC<GroupChannelProps['Fragment']>;\n\nexport type GroupChannelPubSubContextPayload =\n | {\n type: 'MESSAGE_SENT_PENDING' | 'MESSAGE_SENT_SUCCESS';\n data: {\n message: SendbirdUserMessage | SendbirdFileMessage;\n };\n }\n | {\n type: 'MESSAGES_RECEIVED' | 'MESSAGES_UPDATED';\n data: {\n messages: SendbirdMessage[];\n };\n }\n | {\n type: 'TYPING_BUBBLE_RENDERED';\n data?: undefined;\n };\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type React from 'react';\nimport type { FlatList } from 'react-native';\n\nimport type { MessageCollectionParams, MessageFilterParams } from '@sendbird/chat/groupChannel';\nimport type { UseGroupChannelMessagesOptions } from '@sendbird/uikit-chat-hooks';\nimport type {\n OnBeforeHandler,\n PickPartial,\n SendbirdFileMessage,\n SendbirdFileMessageCreateParams,\n SendbirdFileMessageUpdateParams,\n SendbirdGroupChannel,\n SendbirdMessage,\n SendbirdSendableMessage,\n SendbirdUser,\n SendbirdUserMessage,\n SendbirdUserMessageCreateParams,\n SendbirdUserMessageUpdateParams,\n} from '@sendbird/uikit-utils';\n\nimport type { ChannelInputProps, SuggestedMentionListProps } from '../../components/ChannelInput';\nimport type { ChannelMessageListProps } from '../../components/ChannelMessageList';\nimport type { CommonComponent } from '../../types';\nimport type { PubSub } from '../../utils/pubsub';\n\nexport type MessageListQueryParamsType = Omit<MessageCollectionParams, 'filter'> & MessageFilterParams;\nexport interface GroupChannelProps {\n Fragment: {\n channel: SendbirdGroupChannel;\n onChannelDeleted: () => void;\n onPressHeaderLeft: GroupChannelProps['Header']['onPressHeaderLeft'];\n onPressHeaderRight: GroupChannelProps['Header']['onPressHeaderRight'];\n onPressMediaMessage?: GroupChannelProps['MessageList']['onPressMediaMessage'];\n onPressReplyMessageInThread?: GroupChannelProps['Provider']['onPressReplyMessageInThread'];\n\n onBeforeSendUserMessage?: OnBeforeHandler<SendbirdUserMessageCreateParams>;\n onBeforeSendFileMessage?: OnBeforeHandler<SendbirdFileMessageCreateParams>;\n onBeforeUpdateUserMessage?: OnBeforeHandler<SendbirdUserMessageUpdateParams>;\n onBeforeUpdateFileMessage?: OnBeforeHandler<SendbirdFileMessageUpdateParams>;\n\n renderMessage?: GroupChannelProps['MessageList']['renderMessage'];\n renderNewMessagesButton?: GroupChannelProps['MessageList']['renderNewMessagesButton'];\n renderScrollToBottomButton?: GroupChannelProps['MessageList']['renderScrollToBottomButton'];\n renderUnreadMessagesFloating?: GroupChannelProps['MessageList']['renderUnreadMessagesFloating'];\n\n enableTypingIndicator?: GroupChannelProps['Provider']['enableTypingIndicator'];\n enableMessageGrouping?: GroupChannelProps['MessageList']['enableMessageGrouping'];\n\n keyboardAvoidOffset?: GroupChannelProps['Provider']['keyboardAvoidOffset'];\n flatListComponent?: GroupChannelProps['MessageList']['flatListComponent'];\n flatListProps?: GroupChannelProps['MessageList']['flatListProps'];\n sortComparator?: UseGroupChannelMessagesOptions['sortComparator'];\n\n searchItem?: GroupChannelProps['MessageList']['searchItem'];\n\n /**\n * @description You can specify the query parameters for the message list.\n * @example\n * ```\n * <GroupChannelFragment messageListQueryParams={{ prevResultLimit: 20, customTypesFilter: ['filter'] }} />\n * ```\n * */\n messageListQueryParams?: MessageListQueryParamsType;\n /** @deprecated Please use `messageListQueryParams` instead */\n collectionCreator?: UseGroupChannelMessagesOptions['collectionCreator'];\n };\n Header: {\n shouldHideRight: () => boolean;\n onPressHeaderLeft: () => void;\n onPressHeaderRight: () => void;\n };\n MessageList: Pick<\n ChannelMessageListProps<SendbirdGroupChannel>,\n | 'enableMessageGrouping'\n | 'currentUserId'\n | 'channel'\n | 'messages'\n | 'newMessages'\n | 'scrolledAwayFromBottom'\n | 'onScrolledAwayFromBottom'\n | 'onTopReached'\n | 'onBottomReached'\n | 'onResendFailedMessage'\n | 'onDeleteMessage'\n | 'onPressMediaMessage'\n | 'renderMessage'\n | 'renderNewMessagesButton'\n | 'renderScrollToBottomButton'\n | 'renderUnreadMessagesFloating'\n | 'flatListComponent'\n | 'flatListProps'\n | 'hasNext'\n | 'searchItem'\n > & {\n onResetMessageList: () => Promise<void>;\n onResetMessageListWithStartingPoint: (startingPoint: number) => Promise<void>;\n\n // Changing the search item will trigger the focus animation on messages.\n onUpdateSearchItem: (searchItem?: GroupChannelProps['MessageList']['searchItem']) => void;\n hasPrevious?: () => boolean;\n resetNewMessages?: () => void;\n isNewLineExistInChannel?: boolean;\n onNewLineSeenChange?: (hasSeenNewLine: boolean) => void;\n onUserMarkedAsUnreadChange?: (hasUserMarkedAsUnread: boolean) => void;\n };\n Input: PickPartial<\n ChannelInputProps,\n | 'shouldRenderInput'\n | 'onPressSendUserMessage'\n | 'onPressSendFileMessage'\n | 'onPressUpdateUserMessage'\n | 'onPressUpdateFileMessage'\n | 'SuggestedMentionList'\n | 'AttachmentsButton',\n 'inputDisabled'\n >;\n\n SuggestedMentionList: SuggestedMentionListProps;\n Provider: {\n channel: SendbirdGroupChannel;\n enableTypingIndicator: boolean;\n keyboardAvoidOffset?: number;\n groupChannelPubSub: PubSub<GroupChannelPubSubContextPayload>;\n\n messages: SendbirdMessage[];\n // Changing the search item will trigger the focus animation on messages.\n onUpdateSearchItem: (searchItem?: GroupChannelProps['MessageList']['searchItem']) => void;\n onPressReplyMessageInThread: (parentMessage: SendbirdSendableMessage, startingPoint?: number) => void;\n };\n}\n\n/**\n * Internal context for GroupChannel\n * For example, the developer can create a custom header\n * with getting data from the domain context\n * */\nexport interface GroupChannelContextsType {\n Fragment: React.Context<{\n headerTitle: string;\n keyboardAvoidOffset?: number;\n channel: SendbirdGroupChannel;\n messageToEdit?: SendbirdUserMessage | SendbirdFileMessage;\n setMessageToEdit: (msg?: SendbirdUserMessage | SendbirdFileMessage) => void;\n messageToReply?: SendbirdUserMessage | SendbirdFileMessage;\n setMessageToReply: (msg?: SendbirdUserMessage | SendbirdFileMessage) => void;\n }>;\n TypingIndicator: React.Context<{\n typingUsers: SendbirdUser[];\n }>;\n PubSub: React.Context<PubSub<GroupChannelPubSubContextPayload>>;\n MessageList: React.Context<{\n /**\n * ref object for FlatList of MessageList\n * */\n flatListRef: React.MutableRefObject<FlatList | null>;\n /**\n * Function that scrolls to a message within a group channel.\n * @param messageId {number} - The id of the message to scroll.\n * @param options {object} - Scroll options (optional).\n * @param options.focusAnimated {boolean} - Enable a shake animation on the message component upon completion of scrolling.\n * @param options.viewPosition {number} - Position information to adjust the visible area during scrolling. bottom(0) ~ top(1.0)\n *\n * @example\n * ```\n * const { scrollToMessage } = useContext(GroupChannelContexts.MessageList);\n * const messageIncludedInMessageList = scrollToMessage(lastMessage.messageId, { focusAnimated: true, viewPosition: 1 });\n * if (!messageIncludedInMessageList) console.warn('Message not found in the message list.');\n * ```\n * */\n scrollToMessage: (messageId: number, options?: { focusAnimated?: boolean; viewPosition?: number }) => boolean;\n /**\n * Call the FlatList function asynchronously to scroll to bottom lazily\n * to avoid scrolling before data rendering has been committed.\n * */\n lazyScrollToBottom: (params?: { animated?: boolean; timeout?: number }) => void;\n /**\n * Call the FlatList function asynchronously to scroll to index lazily.\n * to avoid scrolling before data rendering has been committed.\n * */\n lazyScrollToIndex: (params?: {\n index?: number;\n animated?: boolean;\n timeout?: number;\n viewPosition?: number;\n }) => void;\n\n onPressReplyMessageInThread?: (parentMessage: SendbirdSendableMessage, startingPoint?: number) => void;\n }>;\n}\nexport interface GroupChannelModule {\n Provider: CommonComponent<GroupChannelProps['Provider']>;\n Header: CommonComponent<GroupChannelProps['Header']>;\n MessageList: CommonComponent<GroupChannelProps['MessageList']>;\n Input: CommonComponent<GroupChannelProps['Input']>;\n SuggestedMentionList: CommonComponent<GroupChannelProps['SuggestedMentionList']>;\n StatusEmpty: CommonComponent;\n StatusLoading: CommonComponent;\n}\n\nexport type GroupChannelFragment = React.FC<GroupChannelProps['Fragment']>;\n\nexport type GroupChannelPubSubContextPayload =\n | {\n type: 'MESSAGE_SENT_PENDING' | 'MESSAGE_SENT_SUCCESS';\n data: {\n message: SendbirdUserMessage | SendbirdFileMessage;\n };\n }\n | {\n type: 'MESSAGES_RECEIVED' | 'MESSAGES_UPDATED';\n data: {\n messages: SendbirdMessage[];\n };\n }\n | {\n type: 'TYPING_BUBBLE_RENDERED';\n data?: undefined;\n }\n | {\n type: 'ON_MARKED_AS_READ_BY_CURRENT_USER';\n data?: undefined;\n }\n | {\n type: 'ON_MARKED_AS_UNREAD_BY_CURRENT_USER';\n data?: undefined;\n };\n"],"mappings":"","ignoreList":[]}
@@ -1,5 +1,5 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
- import { MessageFilter } from '@sendbird/chat/groupChannel';
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { GroupChannelEventSource, MessageFilter } from '@sendbird/chat/groupChannel';
3
3
  import { ReplyType } from '@sendbird/chat/message';
4
4
  import { Box, useToast } from '@sendbird/uikit-react-native-foundation';
5
5
  import { useGroupChannelMessages } from '@sendbird/uikit-tools';
@@ -9,6 +9,7 @@ import GroupChannelMessageRenderer, { GroupChannelTypingIndicatorBubble } from '
9
9
  import NewMessagesButton from '../components/NewMessagesButton';
10
10
  import ScrollToBottomButton from '../components/ScrollToBottomButton';
11
11
  import StatusComposition from '../components/StatusComposition';
12
+ import UnreadMessagesFloating from '../components/UnreadMessagesFloating';
12
13
  import createGroupChannelModule from '../domain/groupChannel/module/createGroupChannelModule';
13
14
  import { useLocalization, usePlatformService, useSendbirdChat } from '../hooks/useContext';
14
15
  import pubsub from '../utils/pubsub';
@@ -16,6 +17,7 @@ const createGroupChannelFragment = initModule => {
16
17
  const GroupChannelModule = createGroupChannelModule(initModule);
17
18
  return ({
18
19
  searchItem,
20
+ renderUnreadMessagesFloating = props => /*#__PURE__*/React.createElement(UnreadMessagesFloating, props),
19
21
  renderNewMessagesButton = props => /*#__PURE__*/React.createElement(NewMessagesButton, props),
20
22
  renderScrollToBottomButton = props => /*#__PURE__*/React.createElement(ScrollToBottomButton, props),
21
23
  renderMessage,
@@ -64,6 +66,28 @@ const createGroupChannelFragment = initModule => {
64
66
  return ReplyType.ONLY_REPLY_TO_CHANNEL;
65
67
  }
66
68
  });
69
+ const [isNewLineExistInChannel, setIsNewLineExistInChannel] = useState(false);
70
+ const hasSeenNewLineRef = useRef(false);
71
+ const hasUserMarkedAsUnreadRef = useRef(false);
72
+ useEffect(() => {
73
+ var _channel$lastMessage;
74
+ setIsNewLineExistInChannel(channel.myLastRead < (((_channel$lastMessage = channel.lastMessage) === null || _channel$lastMessage === void 0 ? void 0 : _channel$lastMessage.createdAt) ?? Number.MIN_SAFE_INTEGER));
75
+ }, [channel.url]);
76
+ const onNewLineSeenChange = useFreshCallback(hasSeenNewLine => {
77
+ hasSeenNewLineRef.current = hasSeenNewLine;
78
+ });
79
+ const onUserMarkedAsUnreadChange = useFreshCallback(hasUserMarkedAsUnread => {
80
+ hasUserMarkedAsUnreadRef.current = hasUserMarkedAsUnread;
81
+ });
82
+ const markAsRead = useFreshCallback(channels => {
83
+ if (sbOptions.uikit.groupChannel.channel.enableMarkAsUnread) {
84
+ if (!scrolledAwayFromBottom && !hasUserMarkedAsUnreadRef.current && (hasSeenNewLineRef.current || !isNewLineExistInChannel)) {
85
+ confirmAndMarkAsRead(channels, true);
86
+ }
87
+ } else {
88
+ confirmAndMarkAsRead(channels);
89
+ }
90
+ });
67
91
  const {
68
92
  loading,
69
93
  messages,
@@ -72,6 +96,7 @@ const createGroupChannelFragment = initModule => {
72
96
  loadNext,
73
97
  loadPrevious,
74
98
  hasNext,
99
+ hasPrevious,
75
100
  sendFileMessage,
76
101
  sendUserMessage,
77
102
  updateFileMessage,
@@ -97,11 +122,27 @@ const createGroupChannelFragment = initModule => {
97
122
  }
98
123
  });
99
124
  },
125
+ onChannelUpdated(_, ctx) {
126
+ if ((ctx === null || ctx === void 0 ? void 0 : ctx.source) === GroupChannelEventSource.EVENT_CHANNEL_READ) {
127
+ if (ctx.userIds.includes((currentUser === null || currentUser === void 0 ? void 0 : currentUser.userId) ?? '')) {
128
+ groupChannelPubSub.publish({
129
+ type: 'ON_MARKED_AS_READ_BY_CURRENT_USER'
130
+ });
131
+ }
132
+ } else if ((ctx === null || ctx === void 0 ? void 0 : ctx.source) === GroupChannelEventSource.EVENT_CHANNEL_UNREAD) {
133
+ if (ctx.userIds.includes((currentUser === null || currentUser === void 0 ? void 0 : currentUser.userId) ?? '')) {
134
+ setIsNewLineExistInChannel(true);
135
+ groupChannelPubSub.publish({
136
+ type: 'ON_MARKED_AS_UNREAD_BY_CURRENT_USER'
137
+ });
138
+ }
139
+ }
140
+ },
100
141
  onChannelDeleted,
101
142
  onCurrentUserBanned: onChannelDeleted,
102
143
  collectionCreator: getCollectionCreator(channel, messageListQueryParams, collectionCreator),
103
144
  sortComparator,
104
- markAsRead: confirmAndMarkAsRead,
145
+ markAsRead: markAsRead,
105
146
  replyType,
106
147
  startingPoint: internalSearchItem === null || internalSearchItem === void 0 ? void 0 : internalSearchItem.startingPoint
107
148
  });
@@ -199,7 +240,14 @@ const createGroupChannelFragment = initModule => {
199
240
  await updateFileMessage(message.messageId, processedParams);
200
241
  });
201
242
  const onScrolledAwayFromBottom = useFreshCallback(value => {
202
- if (!value) resetNewMessages();
243
+ if (!value) {
244
+ resetNewMessages();
245
+ if (sbOptions.uikit.groupChannel.channel.enableMarkAsUnread) {
246
+ if (!hasUserMarkedAsUnreadRef.current && (hasSeenNewLineRef.current || !isNewLineExistInChannel)) {
247
+ confirmAndMarkAsRead([channel]);
248
+ }
249
+ }
250
+ }
203
251
  setScrolledAwayFromBottom(value);
204
252
  });
205
253
  return /*#__PURE__*/React.createElement(GroupChannelModule.Provider, {
@@ -231,15 +279,21 @@ const createGroupChannelFragment = initModule => {
231
279
  onTopReached: loadPrevious,
232
280
  onBottomReached: loadNext,
233
281
  hasNext: hasNext,
282
+ hasPrevious: hasPrevious,
283
+ resetNewMessages: resetNewMessages,
234
284
  scrolledAwayFromBottom: scrolledAwayFromBottom,
235
285
  onScrolledAwayFromBottom: onScrolledAwayFromBottom,
236
286
  renderNewMessagesButton: renderNewMessagesButton,
237
287
  renderScrollToBottomButton: renderScrollToBottomButton,
288
+ renderUnreadMessagesFloating: renderUnreadMessagesFloating,
238
289
  onResendFailedMessage: resendMessage,
239
290
  onDeleteMessage: deleteMessage,
240
291
  onPressMediaMessage: _onPressMediaMessage,
241
292
  flatListComponent: flatListComponent,
242
- flatListProps: memoizedFlatListProps
293
+ flatListProps: memoizedFlatListProps,
294
+ isNewLineExistInChannel: isNewLineExistInChannel,
295
+ onNewLineSeenChange: onNewLineSeenChange,
296
+ onUserMarkedAsUnreadChange: onUserMarkedAsUnreadChange
243
297
  }), /*#__PURE__*/React.createElement(GroupChannelModule.Input, {
244
298
  SuggestedMentionList: GroupChannelModule.SuggestedMentionList,
245
299
  shouldRenderInput: shouldRenderInput(channel),