@sendbird/uikit-react-native 3.5.3 → 3.6.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 (234) hide show
  1. package/lib/commonjs/components/ChannelInput/SendInput.js +23 -6
  2. package/lib/commonjs/components/ChannelInput/SendInput.js.map +1 -1
  3. package/lib/commonjs/components/ChannelInput/index.js.map +1 -1
  4. package/lib/commonjs/components/ChannelMessageList/index.js +22 -4
  5. package/lib/commonjs/components/ChannelMessageList/index.js.map +1 -1
  6. package/lib/commonjs/components/ChannelThreadMessageList/index.js +349 -0
  7. package/lib/commonjs/components/ChannelThreadMessageList/index.js.map +1 -0
  8. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js +2 -2
  9. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js.map +1 -1
  10. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.js +100 -0
  11. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.js.map +1 -0
  12. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js +24 -6
  13. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js.map +1 -1
  14. package/lib/commonjs/components/ReactionAddons/MessageReactionAddon.js +23 -6
  15. package/lib/commonjs/components/ReactionAddons/MessageReactionAddon.js.map +1 -1
  16. package/lib/commonjs/components/ThreadChatFlatList/index.js +76 -0
  17. package/lib/commonjs/components/ThreadChatFlatList/index.js.map +1 -0
  18. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.js +41 -0
  19. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.js.map +1 -0
  20. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.js +74 -0
  21. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.js.map +1 -0
  22. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.js +42 -0
  23. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.js.map +1 -0
  24. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.js +94 -0
  25. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.js.map +1 -0
  26. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.user.js +61 -0
  27. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.user.js.map +1 -0
  28. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.js +127 -0
  29. package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.js.map +1 -0
  30. package/lib/commonjs/components/ThreadParentMessageRenderer/index.js +206 -0
  31. package/lib/commonjs/components/ThreadParentMessageRenderer/index.js.map +1 -0
  32. package/lib/commonjs/containers/SendbirdUIKitContainer.js +7 -1
  33. package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -1
  34. package/lib/commonjs/contexts/SendbirdChatCtx.js +7 -0
  35. package/lib/commonjs/contexts/SendbirdChatCtx.js.map +1 -1
  36. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +28 -5
  37. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  38. package/lib/commonjs/domain/groupChannel/module/moduleContext.js +14 -4
  39. package/lib/commonjs/domain/groupChannel/module/moduleContext.js.map +1 -1
  40. package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
  41. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadHeader.js +82 -0
  42. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadHeader.js.map +1 -0
  43. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadInput.js +44 -0
  44. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadInput.js.map +1 -0
  45. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadMessageList.js +127 -0
  46. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadMessageList.js.map +1 -0
  47. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js +315 -0
  48. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js.map +1 -0
  49. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.js +27 -0
  50. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.js.map +1 -0
  51. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.js +27 -0
  52. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.js.map +1 -0
  53. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.js +195 -0
  54. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.js.map +1 -0
  55. package/lib/commonjs/domain/groupChannelThread/index.js +69 -0
  56. package/lib/commonjs/domain/groupChannelThread/index.js.map +1 -0
  57. package/lib/commonjs/domain/groupChannelThread/module/createGroupChannelThreadModule.js +42 -0
  58. package/lib/commonjs/domain/groupChannelThread/module/createGroupChannelThreadModule.js.map +1 -0
  59. package/lib/commonjs/domain/groupChannelThread/module/moduleContext.js +148 -0
  60. package/lib/commonjs/domain/groupChannelThread/module/moduleContext.js.map +1 -0
  61. package/lib/commonjs/domain/groupChannelThread/types.js +6 -0
  62. package/lib/commonjs/domain/groupChannelThread/types.js.map +1 -0
  63. package/lib/commonjs/fragments/createGroupChannelFragment.js +30 -5
  64. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  65. package/lib/commonjs/fragments/createGroupChannelThreadFragment.js +267 -0
  66. package/lib/commonjs/fragments/createGroupChannelThreadFragment.js.map +1 -0
  67. package/lib/commonjs/hooks/useMentionSuggestion.js +5 -2
  68. package/lib/commonjs/hooks/useMentionSuggestion.js.map +1 -1
  69. package/lib/commonjs/index.js +72 -40
  70. package/lib/commonjs/index.js.map +1 -1
  71. package/lib/commonjs/libs/VoiceMessageStatusManager.js +66 -0
  72. package/lib/commonjs/libs/VoiceMessageStatusManager.js.map +1 -0
  73. package/lib/commonjs/localization/StringSet.type.js.map +1 -1
  74. package/lib/commonjs/localization/createBaseStringSet.js +25 -3
  75. package/lib/commonjs/localization/createBaseStringSet.js.map +1 -1
  76. package/lib/commonjs/version.js +1 -1
  77. package/lib/commonjs/version.js.map +1 -1
  78. package/lib/module/components/ChannelInput/SendInput.js +23 -6
  79. package/lib/module/components/ChannelInput/SendInput.js.map +1 -1
  80. package/lib/module/components/ChannelInput/index.js.map +1 -1
  81. package/lib/module/components/ChannelMessageList/index.js +22 -4
  82. package/lib/module/components/ChannelMessageList/index.js.map +1 -1
  83. package/lib/module/components/ChannelThreadMessageList/index.js +341 -0
  84. package/lib/module/components/ChannelThreadMessageList/index.js.map +1 -0
  85. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js +2 -2
  86. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js.map +1 -1
  87. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.js +92 -0
  88. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.js.map +1 -0
  89. package/lib/module/components/GroupChannelMessageRenderer/index.js +24 -6
  90. package/lib/module/components/GroupChannelMessageRenderer/index.js.map +1 -1
  91. package/lib/module/components/ReactionAddons/MessageReactionAddon.js +23 -6
  92. package/lib/module/components/ReactionAddons/MessageReactionAddon.js.map +1 -1
  93. package/lib/module/components/ThreadChatFlatList/index.js +66 -0
  94. package/lib/module/components/ThreadChatFlatList/index.js.map +1 -0
  95. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.js +34 -0
  96. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.js.map +1 -0
  97. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.js +67 -0
  98. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.js.map +1 -0
  99. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.js +34 -0
  100. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.js.map +1 -0
  101. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.js +87 -0
  102. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.js.map +1 -0
  103. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.user.js +54 -0
  104. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.user.js.map +1 -0
  105. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.js +119 -0
  106. package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.js.map +1 -0
  107. package/lib/module/components/ThreadParentMessageRenderer/index.js +196 -0
  108. package/lib/module/components/ThreadParentMessageRenderer/index.js.map +1 -0
  109. package/lib/module/containers/SendbirdUIKitContainer.js +7 -1
  110. package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -1
  111. package/lib/module/contexts/SendbirdChatCtx.js +6 -0
  112. package/lib/module/contexts/SendbirdChatCtx.js.map +1 -1
  113. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +30 -6
  114. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  115. package/lib/module/domain/groupChannel/module/moduleContext.js +14 -4
  116. package/lib/module/domain/groupChannel/module/moduleContext.js.map +1 -1
  117. package/lib/module/domain/groupChannel/types.js.map +1 -1
  118. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadHeader.js +73 -0
  119. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadHeader.js.map +1 -0
  120. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadInput.js +34 -0
  121. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadInput.js.map +1 -0
  122. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadMessageList.js +117 -0
  123. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadMessageList.js.map +1 -0
  124. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js +305 -0
  125. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js.map +1 -0
  126. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.js +19 -0
  127. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.js.map +1 -0
  128. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.js +19 -0
  129. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.js.map +1 -0
  130. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.js +185 -0
  131. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.js.map +1 -0
  132. package/lib/module/domain/groupChannelThread/index.js +9 -0
  133. package/lib/module/domain/groupChannelThread/index.js.map +1 -0
  134. package/lib/module/domain/groupChannelThread/module/createGroupChannelThreadModule.js +34 -0
  135. package/lib/module/domain/groupChannelThread/module/createGroupChannelThreadModule.js.map +1 -0
  136. package/lib/module/domain/groupChannelThread/module/moduleContext.js +137 -0
  137. package/lib/module/domain/groupChannelThread/module/moduleContext.js.map +1 -0
  138. package/lib/module/domain/groupChannelThread/types.js +2 -0
  139. package/lib/module/domain/groupChannelThread/types.js.map +1 -0
  140. package/lib/module/fragments/createGroupChannelFragment.js +33 -7
  141. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  142. package/lib/module/fragments/createGroupChannelThreadFragment.js +257 -0
  143. package/lib/module/fragments/createGroupChannelThreadFragment.js.map +1 -0
  144. package/lib/module/hooks/useMentionSuggestion.js +5 -2
  145. package/lib/module/hooks/useMentionSuggestion.js.map +1 -1
  146. package/lib/module/index.js +3 -0
  147. package/lib/module/index.js.map +1 -1
  148. package/lib/module/libs/VoiceMessageStatusManager.js +59 -0
  149. package/lib/module/libs/VoiceMessageStatusManager.js.map +1 -0
  150. package/lib/module/localization/StringSet.type.js.map +1 -1
  151. package/lib/module/localization/createBaseStringSet.js +27 -4
  152. package/lib/module/localization/createBaseStringSet.js.map +1 -1
  153. package/lib/module/version.js +1 -1
  154. package/lib/module/version.js.map +1 -1
  155. package/lib/typescript/src/components/ChannelInput/index.d.ts +1 -0
  156. package/lib/typescript/src/components/ChannelMessageList/index.d.ts +5 -2
  157. package/lib/typescript/src/components/ChannelThreadMessageList/index.d.ts +55 -0
  158. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.d.ts +1 -1
  159. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.d.ts +9 -0
  160. package/lib/typescript/src/components/GroupChannelMessageRenderer/index.d.ts +3 -1
  161. package/lib/typescript/src/components/OpenChannelMessageRenderer/index.d.ts +3 -1
  162. package/lib/typescript/src/components/ReactionAddons/MessageReactionAddon.d.ts +3 -1
  163. package/lib/typescript/src/components/ReactionAddons/index.d.ts +2 -1
  164. package/lib/typescript/src/components/ThreadChatFlatList/index.d.ts +9 -0
  165. package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.d.ts +4 -0
  166. package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.d.ts +4 -0
  167. package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.d.ts +9 -0
  168. package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.d.ts +13 -0
  169. package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.user.d.ts +10 -0
  170. package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.d.ts +10 -0
  171. package/lib/typescript/src/components/ThreadParentMessageRenderer/index.d.ts +20 -0
  172. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +6 -4
  173. package/lib/typescript/src/contexts/SendbirdChatCtx.d.ts +15 -1
  174. package/lib/typescript/src/domain/groupChannel/types.d.ts +4 -1
  175. package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadHeader.d.ts +4 -0
  176. package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadInput.d.ts +3 -0
  177. package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadMessageList.d.ts +7 -0
  178. package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.d.ts +8 -0
  179. package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.d.ts +3 -0
  180. package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.d.ts +3 -0
  181. package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.d.ts +4 -0
  182. package/lib/typescript/src/domain/groupChannelThread/index.d.ts +8 -0
  183. package/lib/typescript/src/domain/groupChannelThread/module/createGroupChannelThreadModule.d.ts +3 -0
  184. package/lib/typescript/src/domain/groupChannelThread/module/moduleContext.d.ts +3 -0
  185. package/lib/typescript/src/domain/groupChannelThread/types.d.ts +136 -0
  186. package/lib/typescript/src/domain/openChannel/component/OpenChannelHeader.d.ts +1 -1
  187. package/lib/typescript/src/fragments/createGroupChannelThreadFragment.d.ts +5 -0
  188. package/lib/typescript/src/hooks/useChannelInputItems.d.ts +1 -1
  189. package/lib/typescript/src/index.d.ts +3 -0
  190. package/lib/typescript/src/libs/VoiceMessageStatusManager.d.ts +11 -0
  191. package/lib/typescript/src/localization/StringSet.type.d.ts +23 -0
  192. package/lib/typescript/src/localization/createBaseStringSet.d.ts +1 -1
  193. package/lib/typescript/src/version.d.ts +1 -1
  194. package/package.json +6 -6
  195. package/src/components/ChannelInput/SendInput.tsx +24 -5
  196. package/src/components/ChannelInput/index.tsx +1 -0
  197. package/src/components/ChannelMessageList/index.tsx +27 -5
  198. package/src/components/ChannelThreadMessageList/index.tsx +406 -0
  199. package/src/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.tsx +3 -3
  200. package/src/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.tsx +96 -0
  201. package/src/components/GroupChannelMessageRenderer/index.tsx +21 -5
  202. package/src/components/ReactionAddons/MessageReactionAddon.tsx +38 -5
  203. package/src/components/ThreadChatFlatList/index.tsx +63 -0
  204. package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.tsx +36 -0
  205. package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.tsx +61 -0
  206. package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.tsx +45 -0
  207. package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.tsx +107 -0
  208. package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.tsx +133 -0
  209. package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.user.tsx +65 -0
  210. package/src/components/ThreadParentMessageRenderer/index.tsx +194 -0
  211. package/src/containers/SendbirdUIKitContainer.tsx +9 -4
  212. package/src/contexts/SendbirdChatCtx.tsx +20 -0
  213. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +37 -8
  214. package/src/domain/groupChannel/module/moduleContext.tsx +12 -2
  215. package/src/domain/groupChannel/types.ts +5 -0
  216. package/src/domain/groupChannelThread/component/GroupChannelThreadHeader.tsx +63 -0
  217. package/src/domain/groupChannelThread/component/GroupChannelThreadInput.tsx +38 -0
  218. package/src/domain/groupChannelThread/component/GroupChannelThreadMessageList.tsx +105 -0
  219. package/src/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.tsx +326 -0
  220. package/src/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.tsx +18 -0
  221. package/src/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.tsx +18 -0
  222. package/src/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.tsx +174 -0
  223. package/src/domain/groupChannelThread/index.ts +8 -0
  224. package/src/domain/groupChannelThread/module/createGroupChannelThreadModule.tsx +35 -0
  225. package/src/domain/groupChannelThread/module/moduleContext.tsx +165 -0
  226. package/src/domain/groupChannelThread/types.ts +184 -0
  227. package/src/fragments/createGroupChannelFragment.tsx +38 -8
  228. package/src/fragments/createGroupChannelThreadFragment.tsx +280 -0
  229. package/src/hooks/useMentionSuggestion.ts +13 -9
  230. package/src/index.ts +4 -0
  231. package/src/libs/VoiceMessageStatusManager.ts +56 -0
  232. package/src/localization/StringSet.type.ts +27 -0
  233. package/src/localization/createBaseStringSet.ts +33 -4
  234. package/src/version.ts +1 -1
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+
3
+ import { type RegexTextPattern, Text, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
4
+ import { RegexText, createStyleSheet } from '@sendbird/uikit-react-native-foundation';
5
+ import { SendbirdUserMessage, urlRegexStrict } from '@sendbird/uikit-utils';
6
+
7
+ import { ThreadParentMessageRendererProps } from './index';
8
+
9
+ type Props = ThreadParentMessageRendererProps<{
10
+ regexTextPatterns?: RegexTextPattern[];
11
+ renderRegexTextChildren?: (message: SendbirdUserMessage) => string;
12
+ }>;
13
+
14
+ const ThreadParentMessageUser = (props: Props) => {
15
+ const userMessage: SendbirdUserMessage = props.parentMessage as SendbirdUserMessage;
16
+ if (!userMessage) return null;
17
+
18
+ const { colors } = useUIKitTheme();
19
+
20
+ return (
21
+ <Text body3 color={colors.onBackground01} suppressHighlighting>
22
+ <RegexText
23
+ body3
24
+ color={colors.onBackground01}
25
+ patterns={[
26
+ ...(props.regexTextPatterns ?? []),
27
+ {
28
+ regex: urlRegexStrict,
29
+ replacer({ match, parentProps, keyPrefix, index }) {
30
+ return (
31
+ <Text
32
+ {...parentProps}
33
+ key={`${keyPrefix}-${index}`}
34
+ onPress={() => props.onPressURL?.(match)}
35
+ style={[parentProps?.style, styles.urlText]}
36
+ >
37
+ {match}
38
+ </Text>
39
+ );
40
+ },
41
+ },
42
+ ]}
43
+ >
44
+ {props.renderRegexTextChildren?.(userMessage)}
45
+ </RegexText>
46
+ {Boolean(userMessage.updatedAt) && (
47
+ <Text body3 color={colors.onBackground02}>
48
+ {' (edited)'}
49
+ </Text>
50
+ )}
51
+ </Text>
52
+ );
53
+ };
54
+
55
+ const styles = createStyleSheet({
56
+ bubble: {
57
+ paddingHorizontal: 12,
58
+ paddingVertical: 6,
59
+ },
60
+ urlText: {
61
+ textDecorationLine: 'underline',
62
+ },
63
+ });
64
+
65
+ export default ThreadParentMessageUser;
@@ -0,0 +1,194 @@
1
+ import React, { useRef } from 'react';
2
+
3
+ import { RegexTextPattern, Text, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
4
+ import {
5
+ SendbirdFileMessage,
6
+ type SendbirdUser,
7
+ SendbirdUserMessage,
8
+ getMessageType,
9
+ isMyMessage,
10
+ isVoiceMessage,
11
+ } from '@sendbird/uikit-utils';
12
+
13
+ import { VOICE_MESSAGE_META_ARRAY_DURATION_KEY } from '../../constants';
14
+ import SBUUtils from '../../libs/SBUUtils';
15
+ import { usePlatformService, useSendbirdChat } from './../../hooks/useContext';
16
+ import ThreadParentMessageFile from './ThreadParentMessage.file';
17
+ import ThreadParentMessageFileImage from './ThreadParentMessage.file.image';
18
+ import ThreadParentMessageFileVideo from './ThreadParentMessage.file.video';
19
+ import ThreadParentMessageFileVoice, { VoiceFileMessageState } from './ThreadParentMessage.file.voice';
20
+ import ThreadParentMessageUser from './ThreadParentMessage.user';
21
+ import ThreadParentMessageUserOg from './ThreadParentMessage.user.og';
22
+
23
+ export type ThreadParentMessageRendererProps<AdditionalProps = unknown> = {
24
+ parentMessage: SendbirdUserMessage | SendbirdFileMessage;
25
+ onPress?: () => void;
26
+ onLongPress?: () => void;
27
+ onPressURL?: (url: string) => void;
28
+ onPressMentionedUser?: (mentionedUser?: SendbirdUser) => void;
29
+ onToggleVoiceMessage?: (
30
+ state: VoiceFileMessageState,
31
+ setState: React.Dispatch<React.SetStateAction<VoiceFileMessageState>>,
32
+ ) => Promise<void>;
33
+ } & AdditionalProps;
34
+
35
+ const ThreadParentMessageRenderer = (props: ThreadParentMessageRendererProps) => {
36
+ const playerUnsubscribes = useRef<(() => void)[]>([]);
37
+ const { sbOptions, currentUser, mentionManager } = useSendbirdChat();
38
+ const { palette } = useUIKitTheme();
39
+ const { mediaService, playerService } = usePlatformService();
40
+ const parentMessage = props.parentMessage;
41
+
42
+ const resetPlayer = async () => {
43
+ playerUnsubscribes.current.forEach((unsubscribe) => {
44
+ try {
45
+ unsubscribe();
46
+ } catch {}
47
+ });
48
+ playerUnsubscribes.current.length = 0;
49
+ await playerService.reset();
50
+ };
51
+
52
+ const messageProps: ThreadParentMessageRendererProps = {
53
+ onPressURL: (url) => SBUUtils.openURL(url),
54
+ onToggleVoiceMessage: async (state, setState) => {
55
+ if (isVoiceMessage(parentMessage) && parentMessage.sendingStatus === 'succeeded') {
56
+ if (playerService.uri === parentMessage.url) {
57
+ if (playerService.state === 'playing') {
58
+ await playerService.pause();
59
+ } else {
60
+ await playerService.play(parentMessage.url);
61
+ }
62
+ } else {
63
+ if (playerService.state !== 'idle') {
64
+ await resetPlayer();
65
+ }
66
+
67
+ const shouldSeekToTime = state.duration > state.currentTime && state.currentTime > 0;
68
+ let seekFinished = !shouldSeekToTime;
69
+
70
+ const forPlayback = playerService.addPlaybackListener(({ stopped, currentTime, duration }) => {
71
+ if (seekFinished) {
72
+ setState((prevState) => ({ ...prevState, currentTime: stopped ? 0 : currentTime, duration }));
73
+ }
74
+ });
75
+ const forState = playerService.addStateListener((state) => {
76
+ switch (state) {
77
+ case 'preparing':
78
+ setState((prevState) => ({ ...prevState, status: 'preparing' }));
79
+ break;
80
+ case 'playing':
81
+ setState((prevState) => ({ ...prevState, status: 'playing' }));
82
+ break;
83
+ case 'idle':
84
+ case 'paused': {
85
+ setState((prevState) => ({ ...prevState, status: 'paused' }));
86
+ break;
87
+ }
88
+ case 'stopped':
89
+ setState((prevState) => ({ ...prevState, status: 'paused' }));
90
+ break;
91
+ }
92
+ });
93
+ playerUnsubscribes.current.push(forPlayback, forState);
94
+
95
+ await playerService.play(parentMessage.url);
96
+ if (shouldSeekToTime) {
97
+ await playerService.seek(state.currentTime);
98
+ seekFinished = true;
99
+ }
100
+ }
101
+ }
102
+ },
103
+ ...props,
104
+ };
105
+
106
+ const userMessageProps: {
107
+ renderRegexTextChildren: (message: SendbirdUserMessage) => string;
108
+ regexTextPatterns: RegexTextPattern[];
109
+ } = {
110
+ renderRegexTextChildren: (message) => {
111
+ if (
112
+ mentionManager.shouldUseMentionedMessageTemplate(message, sbOptions.uikit.groupChannel.channel.enableMention)
113
+ ) {
114
+ return message.mentionedMessageTemplate;
115
+ } else {
116
+ return message.message;
117
+ }
118
+ },
119
+ regexTextPatterns: [
120
+ {
121
+ regex: mentionManager.templateRegex,
122
+ replacer({ match, groups, parentProps, index, keyPrefix }) {
123
+ const user = parentMessage.mentionedUsers?.find((it) => it.userId === groups[2]);
124
+ if (user) {
125
+ const mentionColor =
126
+ !isMyMessage(parentMessage, currentUser?.userId) && user.userId === currentUser?.userId
127
+ ? palette.onBackgroundLight01
128
+ : parentProps?.color;
129
+
130
+ return (
131
+ <Text
132
+ {...parentProps}
133
+ key={`${keyPrefix}-${index}`}
134
+ color={mentionColor}
135
+ onPress={() => messageProps.onPressMentionedUser?.(user)}
136
+ onLongPress={messageProps.onLongPress}
137
+ style={[
138
+ parentProps?.style,
139
+ { fontWeight: '700' },
140
+ user.userId === currentUser?.userId && { backgroundColor: palette.highlight },
141
+ ]}
142
+ >
143
+ {`${mentionManager.asMentionedMessageText(user)}`}
144
+ </Text>
145
+ );
146
+ }
147
+ return match;
148
+ },
149
+ },
150
+ ],
151
+ };
152
+
153
+ switch (getMessageType(props.parentMessage)) {
154
+ case 'user': {
155
+ return <ThreadParentMessageUser {...userMessageProps} {...messageProps} />;
156
+ }
157
+ case 'user.opengraph': {
158
+ return <ThreadParentMessageUserOg {...userMessageProps} {...messageProps} />;
159
+ }
160
+ case 'file':
161
+ case 'file.audio': {
162
+ return <ThreadParentMessageFile {...messageProps} />;
163
+ }
164
+ case 'file.video': {
165
+ return (
166
+ <ThreadParentMessageFileVideo
167
+ fetchThumbnailFromVideoSource={(uri) => mediaService.getVideoThumbnail({ url: uri, timeMills: 1000 })}
168
+ {...messageProps}
169
+ />
170
+ );
171
+ }
172
+ case 'file.image': {
173
+ return <ThreadParentMessageFileImage {...messageProps} />;
174
+ }
175
+ case 'file.voice': {
176
+ return (
177
+ <ThreadParentMessageFileVoice
178
+ durationMetaArrayKey={VOICE_MESSAGE_META_ARRAY_DURATION_KEY}
179
+ onUnmount={() => {
180
+ if (isVoiceMessage(parentMessage) && playerService.uri === parentMessage.url) {
181
+ resetPlayer();
182
+ }
183
+ }}
184
+ {...messageProps}
185
+ />
186
+ );
187
+ }
188
+ default: {
189
+ return null;
190
+ }
191
+ }
192
+ };
193
+
194
+ export default React.memo(ThreadParentMessageRenderer);
@@ -38,6 +38,7 @@ import InternalLocalCacheStorage from '../libs/InternalLocalCacheStorage';
38
38
  import MentionConfig, { MentionConfigInterface } from '../libs/MentionConfig';
39
39
  import MentionManager from '../libs/MentionManager';
40
40
  import VoiceMessageConfig, { VoiceMessageConfigInterface } from '../libs/VoiceMessageConfig';
41
+ import VoiceMessageStatusManager from '../libs/VoiceMessageStatusManager';
41
42
  import StringSetEn from '../localization/StringSet.en';
42
43
  import type { StringSet } from '../localization/StringSet.type';
43
44
  import SBUDynamicModule from '../platform/dynamicModule';
@@ -64,7 +65,6 @@ export const SendbirdUIKit = Object.freeze({
64
65
  },
65
66
  });
66
67
 
67
- type UnimplementedFeatures = 'threadReplySelectType' | 'replyType';
68
68
  export type ChatOmittedInitParams = Omit<
69
69
  SendbirdChatParams<[GroupChannelModule, OpenChannelModule]>,
70
70
  (typeof chatOmitKeys)[number]
@@ -102,8 +102,11 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
102
102
  Partial<ChatRelatedFeaturesInUIKit>;
103
103
  uikitOptions?: PartialDeep<{
104
104
  common: SBUConfig['common'];
105
- groupChannel: Omit<SBUConfig['groupChannel']['channel'], UnimplementedFeatures> & {
106
- replyType: Extract<SBUConfig['groupChannel']['channel']['replyType'], 'none' | 'quote_reply'>;
105
+ groupChannel: Omit<SBUConfig['groupChannel']['channel'], 'enableReactionsSupergroup'> & {
106
+ /**
107
+ * @deprecated Currently, this feature is turned off by default. If you wish to use this feature, contact us: {@link https://dashboard.sendbird.com/settings/contact_us?category=feedback_and_feature_requests&product=UIKit}
108
+ */
109
+ enableReactionsSupergroup: never;
107
110
  };
108
111
  groupChannelList: SBUConfig['groupChannel']['channelList'];
109
112
  groupChannelSettings: SBUConfig['groupChannel']['setting'];
@@ -176,6 +179,7 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
176
179
  const { imageCompressionConfig, voiceMessageConfig, mentionConfig } = useConfigInstance(props);
177
180
  const emojiManager = useMemo(() => new EmojiManager(internalStorage), [internalStorage]);
178
181
  const mentionManager = useMemo(() => new MentionManager(mentionConfig), [mentionConfig]);
182
+ const voiceMessageStatusManager = useMemo(() => new VoiceMessageStatusManager(), []);
179
183
 
180
184
  useLayoutEffect(() => {
181
185
  if (!isFirstMount) {
@@ -208,7 +212,7 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
208
212
  localConfigs={{
209
213
  common: uikitOptions?.common,
210
214
  groupChannel: {
211
- channel: uikitOptions?.groupChannel,
215
+ channel: { ...uikitOptions?.groupChannel, enableReactionsSupergroup: undefined },
212
216
  channelList: uikitOptions?.groupChannelList,
213
217
  setting: uikitOptions?.groupChannelSettings,
214
218
  },
@@ -223,6 +227,7 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
223
227
  mentionManager={mentionManager}
224
228
  imageCompressionConfig={imageCompressionConfig}
225
229
  voiceMessageConfig={voiceMessageConfig}
230
+ voiceMessageStatusManager={voiceMessageStatusManager}
226
231
  enableAutoPushTokenRegistration={
227
232
  chatOptions.enableAutoPushTokenRegistration ?? SendbirdUIKit.DEFAULT.AUTO_PUSH_TOKEN_REGISTRATION
228
233
  }
@@ -14,7 +14,9 @@ import type EmojiManager from '../libs/EmojiManager';
14
14
  import type ImageCompressionConfig from '../libs/ImageCompressionConfig';
15
15
  import type MentionManager from '../libs/MentionManager';
16
16
  import type VoiceMessageConfig from '../libs/VoiceMessageConfig';
17
+ import VoiceMessageStatusManager from '../libs/VoiceMessageStatusManager';
17
18
  import type { FileType } from '../platform/types';
19
+ import pubsub, { type PubSub } from '../utils/pubsub';
18
20
 
19
21
  export interface ChatRelatedFeaturesInUIKit {
20
22
  enableAutoPushTokenRegistration: boolean;
@@ -27,10 +29,18 @@ interface Props extends ChatRelatedFeaturesInUIKit, React.PropsWithChildren {
27
29
 
28
30
  emojiManager: EmojiManager;
29
31
  mentionManager: MentionManager;
32
+ voiceMessageStatusManager: VoiceMessageStatusManager;
30
33
  imageCompressionConfig: ImageCompressionConfig;
31
34
  voiceMessageConfig: VoiceMessageConfig;
32
35
  }
33
36
 
37
+ export type GroupChannelFragmentOptionsPubSubContextPayload = {
38
+ type: 'OVERRIDE_SEARCH_ITEM_STARTING_POINT';
39
+ data: {
40
+ startingPoint: number;
41
+ };
42
+ };
43
+
34
44
  export type SendbirdChatContextType = {
35
45
  sdk: SendbirdChatSDK;
36
46
  currentUser?: SendbirdUser;
@@ -39,6 +49,7 @@ export type SendbirdChatContextType = {
39
49
  // feature related instances
40
50
  emojiManager: EmojiManager;
41
51
  mentionManager: MentionManager;
52
+ voiceMessageStatusManager: VoiceMessageStatusManager;
42
53
  imageCompressionConfig: ImageCompressionConfig;
43
54
  voiceMessageConfig: VoiceMessageConfig;
44
55
 
@@ -46,6 +57,9 @@ export type SendbirdChatContextType = {
46
57
  updateCurrentUserInfo: (nickname?: string, profile?: string | FileType) => Promise<SendbirdUser>;
47
58
  markAsDeliveredWithChannel: (channel: SendbirdGroupChannel) => void;
48
59
 
60
+ groupChannelFragmentOptions: {
61
+ pubsub: PubSub<GroupChannelFragmentOptionsPubSubContextPayload>;
62
+ };
49
63
  sbOptions: {
50
64
  // UIKit options
51
65
  uikit: SBUConfig;
@@ -80,6 +94,7 @@ export type SendbirdChatContextType = {
80
94
  broadcastChannelEnabled: boolean;
81
95
  superGroupChannelEnabled: boolean;
82
96
  reactionEnabled: boolean;
97
+ uploadSizeLimit: number | undefined;
83
98
  };
84
99
  };
85
100
  };
@@ -90,6 +105,7 @@ export const SendbirdChatProvider = ({
90
105
  sdkInstance,
91
106
  emojiManager,
92
107
  mentionManager,
108
+ voiceMessageStatusManager,
93
109
  imageCompressionConfig,
94
110
  voiceMessageConfig,
95
111
  enableAutoPushTokenRegistration,
@@ -164,11 +180,15 @@ export const SendbirdChatProvider = ({
164
180
  mentionManager,
165
181
  imageCompressionConfig,
166
182
  voiceMessageConfig,
183
+ voiceMessageStatusManager,
167
184
  currentUser,
168
185
  setCurrentUser,
169
186
 
170
187
  updateCurrentUserInfo,
171
188
  markAsDeliveredWithChannel,
189
+ groupChannelFragmentOptions: {
190
+ pubsub: pubsub<GroupChannelFragmentOptionsPubSubContextPayload>(),
191
+ },
172
192
 
173
193
  // TODO: Options should be moved to the common area at the higher level to be passed to the context of each product.
174
194
  // For example, common -> chat context, common -> calls context
@@ -2,11 +2,12 @@ import React, { useContext, useEffect } from 'react';
2
2
 
3
3
  import { useChannelHandler } from '@sendbird/uikit-chat-hooks';
4
4
  import { useToast } from '@sendbird/uikit-react-native-foundation';
5
- import type { SendbirdMessage } from '@sendbird/uikit-utils';
6
- import { isDifferentChannel, useFreshCallback, useIsFirstMount, useUniqHandlerId } from '@sendbird/uikit-utils';
5
+ import { SendbirdMessage, SendbirdSendableMessage, useIsFirstMount } from '@sendbird/uikit-utils';
6
+ import { isDifferentChannel, useFreshCallback, useUniqHandlerId } from '@sendbird/uikit-utils';
7
7
 
8
8
  import ChannelMessageList from '../../../components/ChannelMessageList';
9
9
  import { MESSAGE_FOCUS_ANIMATION_DELAY, MESSAGE_SEARCH_SAFE_SCROLL_DELAY } from '../../../constants';
10
+ import { GroupChannelFragmentOptionsPubSubContextPayload } from '../../../contexts/SendbirdChatCtx';
10
11
  import { useLocalization, useSendbirdChat } from '../../../hooks/useContext';
11
12
  import { GroupChannelContexts } from '../module/moduleContext';
12
13
  import type { GroupChannelProps } from '../types';
@@ -14,10 +15,12 @@ import type { GroupChannelProps } from '../types';
14
15
  const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
15
16
  const toast = useToast();
16
17
  const { STRINGS } = useLocalization();
17
- const { sdk } = useSendbirdChat();
18
+ const { sdk, sbOptions, groupChannelFragmentOptions } = useSendbirdChat();
18
19
  const { setMessageToEdit, setMessageToReply } = useContext(GroupChannelContexts.Fragment);
19
20
  const { subscribe } = useContext(GroupChannelContexts.PubSub);
20
- const { flatListRef, lazyScrollToBottom, lazyScrollToIndex } = useContext(GroupChannelContexts.MessageList);
21
+ const { flatListRef, lazyScrollToBottom, lazyScrollToIndex, onPressReplyMessageInThread } = useContext(
22
+ GroupChannelContexts.MessageList,
23
+ );
21
24
 
22
25
  const id = useUniqHandlerId('GroupChannelMessageList');
23
26
  const isFirstMount = useIsFirstMount();
@@ -90,6 +93,17 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
90
93
  });
91
94
  }, [props.scrolledAwayFromBottom]);
92
95
 
96
+ useEffect(() => {
97
+ return groupChannelFragmentOptions.pubsub.subscribe((payload: GroupChannelFragmentOptionsPubSubContextPayload) => {
98
+ switch (payload.type) {
99
+ case 'OVERRIDE_SEARCH_ITEM_STARTING_POINT': {
100
+ scrollToMessageWithCreatedAt(payload.data.startingPoint, false, MESSAGE_SEARCH_SAFE_SCROLL_DELAY);
101
+ break;
102
+ }
103
+ }
104
+ });
105
+ }, []);
106
+
93
107
  useEffect(() => {
94
108
  // Only trigger once when message list mount with initial props.searchItem
95
109
  // - Search screen + searchItem > mount message list
@@ -99,16 +113,31 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
99
113
  }
100
114
  }, [isFirstMount]);
101
115
 
102
- const onPressParentMessage = useFreshCallback((message: SendbirdMessage) => {
103
- const canScrollToParent = scrollToMessageWithCreatedAt(message.createdAt, true, 0);
104
- if (!canScrollToParent) toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');
105
- });
116
+ const onPressParentMessage = useFreshCallback(
117
+ (parentMessage: SendbirdMessage, childMessage: SendbirdSendableMessage) => {
118
+ if (
119
+ onPressReplyMessageInThread &&
120
+ sbOptions.uikit.groupChannel.channel.replyType === 'thread' &&
121
+ sbOptions.uikit.groupChannel.channel.threadReplySelectType === 'thread'
122
+ ) {
123
+ if (parentMessage.createdAt >= props.channel.messageOffsetTimestamp) {
124
+ onPressReplyMessageInThread(parentMessage as SendbirdSendableMessage, childMessage.createdAt);
125
+ } else {
126
+ toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');
127
+ }
128
+ } else {
129
+ const canScrollToParent = scrollToMessageWithCreatedAt(parentMessage.createdAt, true, 0);
130
+ if (!canScrollToParent) toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');
131
+ }
132
+ },
133
+ );
106
134
 
107
135
  return (
108
136
  <ChannelMessageList
109
137
  {...props}
110
138
  ref={flatListRef}
111
139
  onReplyMessage={setMessageToReply}
140
+ onReplyInThreadMessage={setMessageToReply}
112
141
  onEditMessage={setMessageToEdit}
113
142
  onPressParentMessage={onPressParentMessage}
114
143
  onPressNewMessagesButton={scrollToBottom}
@@ -58,12 +58,13 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
58
58
  groupChannelPubSub,
59
59
  messages,
60
60
  onUpdateSearchItem,
61
+ onPressReplyMessageInThread,
61
62
  }) => {
62
63
  if (!channel) throw new Error('GroupChannel is not provided to GroupChannelModule');
63
64
 
64
65
  const handlerId = useUniqHandlerId('GroupChannelContextsProvider');
65
66
  const { STRINGS } = useLocalization();
66
- const { currentUser, sdk } = useSendbirdChat();
67
+ const { currentUser, sdk, sbOptions } = useSendbirdChat();
67
68
 
68
69
  const [typingUsers, setTypingUsers] = useState<SendbirdUser[]>([]);
69
70
  const [messageToEdit, setMessageToEdit] = useState<SendbirdUserMessage | SendbirdFileMessage>();
@@ -90,6 +91,14 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
90
91
  }
91
92
  };
92
93
 
94
+ const onPressMessageToReply = (parentMessage?: SendbirdUserMessage | SendbirdFileMessage) => {
95
+ if (sbOptions.uikit.groupChannel.channel.replyType === 'thread' && parentMessage) {
96
+ onPressReplyMessageInThread?.(parentMessage, Number.MAX_SAFE_INTEGER);
97
+ } else if (sbOptions.uikit.groupChannel.channel.replyType === 'quote_reply') {
98
+ updateInputMode('reply', parentMessage);
99
+ }
100
+ };
101
+
93
102
  useChannelHandler(sdk, handlerId, {
94
103
  onMessageDeleted(_, messageId) {
95
104
  if (messageToReply?.messageId === messageId) {
@@ -125,7 +134,7 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
125
134
  messageToEdit,
126
135
  setMessageToEdit: useCallback((message) => updateInputMode('edit', message), []),
127
136
  messageToReply,
128
- setMessageToReply: useCallback((message) => updateInputMode('reply', message), []),
137
+ setMessageToReply: useCallback((message) => onPressMessageToReply(message), []),
129
138
  }}
130
139
  >
131
140
  <GroupChannelContexts.PubSub.Provider value={groupChannelPubSub}>
@@ -136,6 +145,7 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
136
145
  scrollToMessage,
137
146
  lazyScrollToIndex,
138
147
  lazyScrollToBottom,
148
+ onPressReplyMessageInThread,
139
149
  }}
140
150
  >
141
151
  {children}
@@ -11,6 +11,7 @@ import type {
11
11
  SendbirdFileMessageUpdateParams,
12
12
  SendbirdGroupChannel,
13
13
  SendbirdMessage,
14
+ SendbirdSendableMessage,
14
15
  SendbirdUser,
15
16
  SendbirdUserMessage,
16
17
  SendbirdUserMessageCreateParams,
@@ -30,6 +31,7 @@ export interface GroupChannelProps {
30
31
  onPressHeaderLeft: GroupChannelProps['Header']['onPressHeaderLeft'];
31
32
  onPressHeaderRight: GroupChannelProps['Header']['onPressHeaderRight'];
32
33
  onPressMediaMessage?: GroupChannelProps['MessageList']['onPressMediaMessage'];
34
+ onPressReplyMessageInThread?: GroupChannelProps['Provider']['onPressReplyMessageInThread'];
33
35
 
34
36
  onBeforeSendUserMessage?: OnBeforeHandler<SendbirdUserMessageCreateParams>;
35
37
  onBeforeSendFileMessage?: OnBeforeHandler<SendbirdFileMessageCreateParams>;
@@ -114,6 +116,7 @@ export interface GroupChannelProps {
114
116
  messages: SendbirdMessage[];
115
117
  // Changing the search item will trigger the focus animation on messages.
116
118
  onUpdateSearchItem: (searchItem?: GroupChannelProps['MessageList']['searchItem']) => void;
119
+ onPressReplyMessageInThread: (parentMessage: SendbirdSendableMessage, startingPoint?: number) => void;
117
120
  };
118
121
  }
119
122
 
@@ -171,6 +174,8 @@ export interface GroupChannelContextsType {
171
174
  timeout?: number;
172
175
  viewPosition?: number;
173
176
  }) => void;
177
+
178
+ onPressReplyMessageInThread?: (parentMessage: SendbirdSendableMessage, startingPoint?: number) => void;
174
179
  }>;
175
180
  }
176
181
  export interface GroupChannelModule {
@@ -0,0 +1,63 @@
1
+ import React, { useContext } from 'react';
2
+ import { View } from 'react-native';
3
+
4
+ import { Icon, Text, createStyleSheet, useHeaderStyle, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
5
+
6
+ import { useLocalization, useSendbirdChat } from '../../../hooks/useContext';
7
+ import { GroupChannelThreadContexts } from '../module/moduleContext';
8
+ import type { GroupChannelThreadProps } from '../types';
9
+
10
+ const GroupChannelThreadHeader = ({ onPressLeft, onPressSubtitle }: GroupChannelThreadProps['Header']) => {
11
+ const { headerTitle, channel } = useContext(GroupChannelThreadContexts.Fragment);
12
+ const { HeaderComponent } = useHeaderStyle();
13
+ const { STRINGS } = useLocalization();
14
+ const { select, colors, palette } = useUIKitTheme();
15
+ const { currentUser } = useSendbirdChat();
16
+
17
+ const renderSubtitle = () => {
18
+ if (!currentUser) return null;
19
+
20
+ return (
21
+ <Text
22
+ onPress={onPressSubtitle}
23
+ caption2
24
+ style={styles.subtitle}
25
+ color={select({ light: palette.primary300, dark: palette.primary200 })}
26
+ numberOfLines={1}
27
+ >
28
+ {STRINGS.GROUP_CHANNEL_THREAD.HEADER_SUBTITLE(currentUser.userId, channel)}
29
+ </Text>
30
+ );
31
+ };
32
+
33
+ return (
34
+ <HeaderComponent
35
+ clearTitleMargin
36
+ title={
37
+ <View style={styles.titleContainer}>
38
+ <View style={{ flexShrink: 1 }}>
39
+ <Text h2 color={colors.onBackground01} numberOfLines={1}>
40
+ {headerTitle}
41
+ </Text>
42
+ {renderSubtitle()}
43
+ </View>
44
+ </View>
45
+ }
46
+ left={<Icon icon={'arrow-left'} size={24} />}
47
+ onPressLeft={onPressLeft}
48
+ />
49
+ );
50
+ };
51
+
52
+ const styles = createStyleSheet({
53
+ titleContainer: {
54
+ maxWidth: '100%',
55
+ flexDirection: 'row',
56
+ width: '100%',
57
+ },
58
+ subtitle: {
59
+ marginTop: 2,
60
+ },
61
+ });
62
+
63
+ export default GroupChannelThreadHeader;
@@ -0,0 +1,38 @@
1
+ import React, { useContext } from 'react';
2
+
3
+ import { getGroupChannelChatAvailableState } from '@sendbird/uikit-utils';
4
+
5
+ import ChannelInput from '../../../components/ChannelInput';
6
+ import { GroupChannelThreadContexts } from '../module/moduleContext';
7
+ import type { GroupChannelThreadProps } from '../types';
8
+
9
+ const GroupChannelThreadInput = ({ inputDisabled, ...props }: GroupChannelThreadProps['Input']) => {
10
+ const {
11
+ channel,
12
+ keyboardAvoidOffset = 0,
13
+ messageToEdit,
14
+ setMessageToEdit,
15
+ parentMessage,
16
+ } = useContext(GroupChannelThreadContexts.Fragment);
17
+
18
+ const chatAvailableState = getGroupChannelChatAvailableState(channel);
19
+
20
+ return (
21
+ <ChannelInput
22
+ channel={channel}
23
+ messageToEdit={messageToEdit}
24
+ setMessageToEdit={setMessageToEdit}
25
+ messageForThread={parentMessage}
26
+ keyboardAvoidOffset={keyboardAvoidOffset}
27
+ inputMuted={chatAvailableState.muted}
28
+ inputFrozen={chatAvailableState.frozen}
29
+ inputDisabled={inputDisabled ?? chatAvailableState.disabled}
30
+ MessageToReplyPreview={() => {
31
+ return null;
32
+ }}
33
+ {...props}
34
+ />
35
+ );
36
+ };
37
+
38
+ export default React.memo(GroupChannelThreadInput);