@sendbird/uikit-react-native 2.1.0 → 2.3.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 (431) hide show
  1. package/README.md +42 -17
  2. package/lib/commonjs/components/ChatFlatList.js +2 -1
  3. package/lib/commonjs/components/ChatFlatList.js.map +1 -1
  4. package/lib/commonjs/components/FileViewer.js +2 -5
  5. package/lib/commonjs/components/FileViewer.js.map +1 -1
  6. package/lib/commonjs/components/MessageRenderer/FileMessage/BaseFileMessage.js +11 -6
  7. package/lib/commonjs/components/MessageRenderer/FileMessage/BaseFileMessage.js.map +1 -1
  8. package/lib/commonjs/components/MessageRenderer/FileMessage/ImageFileMessage.js +12 -2
  9. package/lib/commonjs/components/MessageRenderer/FileMessage/ImageFileMessage.js.map +1 -1
  10. package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js +26 -11
  11. package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -1
  12. package/lib/commonjs/components/MessageRenderer/FileMessage/index.js +1 -6
  13. package/lib/commonjs/components/MessageRenderer/FileMessage/index.js.map +1 -1
  14. package/lib/commonjs/components/MessageRenderer/UserMessage/BaseUserMessage.js +86 -10
  15. package/lib/commonjs/components/MessageRenderer/UserMessage/BaseUserMessage.js.map +1 -1
  16. package/lib/commonjs/components/MessageRenderer/UserMessage/OpenGraphUserMessage.js +102 -15
  17. package/lib/commonjs/components/MessageRenderer/UserMessage/OpenGraphUserMessage.js.map +1 -1
  18. package/lib/commonjs/components/MessageRenderer/UserMessage/index.js.map +1 -1
  19. package/lib/commonjs/components/MessageRenderer/index.js +22 -3
  20. package/lib/commonjs/components/MessageRenderer/index.js.map +1 -1
  21. package/lib/commonjs/components/ReactionAddons/BottomSheetReactionAddon.js +150 -0
  22. package/lib/commonjs/components/ReactionAddons/BottomSheetReactionAddon.js.map +1 -0
  23. package/lib/commonjs/components/ReactionAddons/MessageReactionAddon.js +135 -0
  24. package/lib/commonjs/components/ReactionAddons/MessageReactionAddon.js.map +1 -0
  25. package/lib/commonjs/components/ReactionAddons/ReactionRoundedButton.js +87 -0
  26. package/lib/commonjs/components/ReactionAddons/ReactionRoundedButton.js.map +1 -0
  27. package/lib/commonjs/components/ReactionAddons/index.js +19 -0
  28. package/lib/commonjs/components/ReactionAddons/index.js.map +1 -0
  29. package/lib/commonjs/components/ReactionBottomSheets/ReactionListBottomSheet.js +150 -0
  30. package/lib/commonjs/components/ReactionBottomSheets/ReactionListBottomSheet.js.map +1 -0
  31. package/lib/commonjs/components/ReactionBottomSheets/ReactionUserListBottomSheet.js +276 -0
  32. package/lib/commonjs/components/ReactionBottomSheets/ReactionUserListBottomSheet.js.map +1 -0
  33. package/lib/commonjs/components/ReactionBottomSheets/index.js +19 -0
  34. package/lib/commonjs/components/ReactionBottomSheets/index.js.map +1 -0
  35. package/lib/commonjs/constants.js +3 -1
  36. package/lib/commonjs/constants.js.map +1 -1
  37. package/lib/commonjs/containers/GroupChannelPreviewContainer.js +4 -1
  38. package/lib/commonjs/containers/GroupChannelPreviewContainer.js.map +1 -1
  39. package/lib/commonjs/containers/SendbirdUIKitContainer.js +130 -79
  40. package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -1
  41. package/lib/commonjs/contexts/PlatformServiceCtx.js.map +1 -1
  42. package/lib/commonjs/contexts/ReactionCtx.js +107 -0
  43. package/lib/commonjs/contexts/ReactionCtx.js.map +1 -0
  44. package/lib/commonjs/contexts/SendbirdChatCtx.js +26 -18
  45. package/lib/commonjs/contexts/SendbirdChatCtx.js.map +1 -1
  46. package/lib/commonjs/contexts/UserProfileCtx.js +9 -0
  47. package/lib/commonjs/contexts/UserProfileCtx.js.map +1 -1
  48. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/EditInput.js +33 -37
  49. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/EditInput.js.map +1 -1
  50. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js +95 -23
  51. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
  52. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/index.js +121 -31
  53. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/index.js.map +1 -1
  54. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +34 -13
  55. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  56. package/lib/commonjs/domain/groupChannel/component/GroupChannelSuggestedMentionList.js +210 -0
  57. package/lib/commonjs/domain/groupChannel/component/GroupChannelSuggestedMentionList.js.map +1 -0
  58. package/lib/commonjs/domain/groupChannel/index.js +8 -0
  59. package/lib/commonjs/domain/groupChannel/index.js.map +1 -1
  60. package/lib/commonjs/domain/groupChannel/module/createGroupChannelModule.js +4 -0
  61. package/lib/commonjs/domain/groupChannel/module/createGroupChannelModule.js.map +1 -1
  62. package/lib/commonjs/domain/groupChannel/module/moduleContext.js +4 -4
  63. package/lib/commonjs/domain/groupChannel/module/moduleContext.js.map +1 -1
  64. package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
  65. package/lib/commonjs/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.js +3 -2
  66. package/lib/commonjs/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.js.map +1 -1
  67. package/lib/commonjs/domain/groupChannelList/component/GroupChannelListList.js +2 -1
  68. package/lib/commonjs/domain/groupChannelList/component/GroupChannelListList.js.map +1 -1
  69. package/lib/commonjs/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.js +2 -1
  70. package/lib/commonjs/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.js.map +1 -1
  71. package/lib/commonjs/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.js +39 -0
  72. package/lib/commonjs/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.js.map +1 -0
  73. package/lib/commonjs/domain/groupChannelNotifications/component/GroupChannelNotificationsView.js +140 -0
  74. package/lib/commonjs/domain/groupChannelNotifications/component/GroupChannelNotificationsView.js.map +1 -0
  75. package/lib/commonjs/domain/groupChannelNotifications/index.js +46 -0
  76. package/lib/commonjs/domain/groupChannelNotifications/index.js.map +1 -0
  77. package/lib/commonjs/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.js +33 -0
  78. package/lib/commonjs/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.js.map +1 -0
  79. package/lib/commonjs/domain/groupChannelNotifications/module/moduleContext.js +45 -0
  80. package/lib/commonjs/domain/groupChannelNotifications/module/moduleContext.js.map +1 -0
  81. package/lib/commonjs/domain/groupChannelNotifications/types.js +6 -0
  82. package/lib/commonjs/domain/groupChannelNotifications/types.js.map +1 -0
  83. package/lib/commonjs/domain/groupChannelOperators/component/GroupChannelOperatorsList.js +2 -1
  84. package/lib/commonjs/domain/groupChannelOperators/component/GroupChannelOperatorsList.js.map +1 -1
  85. package/lib/commonjs/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js +49 -6
  86. package/lib/commonjs/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js.map +1 -1
  87. package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js +11 -16
  88. package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
  89. package/lib/commonjs/domain/groupChannelSettings/types.js.map +1 -1
  90. package/lib/commonjs/domain/groupChannelUserList/types.js.map +1 -1
  91. package/lib/commonjs/domain/userList/component/UserListList.js +4 -1
  92. package/lib/commonjs/domain/userList/component/UserListList.js.map +1 -1
  93. package/lib/commonjs/domain/userList/module/createUserListModule.js.map +1 -1
  94. package/lib/commonjs/fragments/createGroupChannelCreateFragment.js.map +1 -1
  95. package/lib/commonjs/fragments/createGroupChannelFragment.js +11 -4
  96. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  97. package/lib/commonjs/fragments/createGroupChannelInviteFragment.js.map +1 -1
  98. package/lib/commonjs/fragments/createGroupChannelListFragment.js +4 -14
  99. package/lib/commonjs/fragments/createGroupChannelListFragment.js.map +1 -1
  100. package/lib/commonjs/fragments/createGroupChannelNotificationsFragment.js +34 -0
  101. package/lib/commonjs/fragments/createGroupChannelNotificationsFragment.js.map +1 -0
  102. package/lib/commonjs/fragments/createGroupChannelSettingsFragment.js +3 -1
  103. package/lib/commonjs/fragments/createGroupChannelSettingsFragment.js.map +1 -1
  104. package/lib/commonjs/hooks/useConnection.js +3 -0
  105. package/lib/commonjs/hooks/useConnection.js.map +1 -1
  106. package/lib/commonjs/hooks/useContext.js +11 -1
  107. package/lib/commonjs/hooks/useContext.js.map +1 -1
  108. package/lib/commonjs/hooks/useKeyboardStatus.js +97 -0
  109. package/lib/commonjs/hooks/useKeyboardStatus.js.map +1 -0
  110. package/lib/commonjs/hooks/useMentionSuggestion.js +110 -0
  111. package/lib/commonjs/hooks/useMentionSuggestion.js.map +1 -0
  112. package/lib/commonjs/hooks/useMentionTextInput.js +139 -0
  113. package/lib/commonjs/hooks/useMentionTextInput.js.map +1 -0
  114. package/lib/commonjs/index.js +95 -40
  115. package/lib/commonjs/index.js.map +1 -1
  116. package/lib/commonjs/libs/EmojiManager.js +100 -0
  117. package/lib/commonjs/libs/EmojiManager.js.map +1 -0
  118. package/lib/commonjs/libs/ImageCompressionConfig.js +38 -0
  119. package/lib/commonjs/libs/ImageCompressionConfig.js.map +1 -0
  120. package/lib/commonjs/libs/MentionConfig.js +47 -0
  121. package/lib/commonjs/libs/MentionConfig.js.map +1 -0
  122. package/lib/commonjs/libs/MentionManager.js +235 -0
  123. package/lib/commonjs/libs/MentionManager.js.map +1 -0
  124. package/lib/commonjs/libs/SBUUtils.js +27 -0
  125. package/lib/commonjs/libs/SBUUtils.js.map +1 -1
  126. package/lib/commonjs/localization/StringSet.type.js +20 -5
  127. package/lib/commonjs/localization/StringSet.type.js.map +1 -1
  128. package/lib/commonjs/platform/createMediaService.expo.js +35 -1
  129. package/lib/commonjs/platform/createMediaService.expo.js.map +1 -1
  130. package/lib/commonjs/platform/createMediaService.native.js +41 -6
  131. package/lib/commonjs/platform/createMediaService.native.js.map +1 -1
  132. package/lib/commonjs/platform/dynamicModule.js +9 -57
  133. package/lib/commonjs/platform/dynamicModule.js.map +1 -1
  134. package/lib/commonjs/platform/types.js.map +1 -1
  135. package/lib/commonjs/types.js.map +1 -1
  136. package/lib/commonjs/version.js +1 -1
  137. package/lib/commonjs/version.js.map +1 -1
  138. package/lib/module/components/ChatFlatList.js +3 -2
  139. package/lib/module/components/ChatFlatList.js.map +1 -1
  140. package/lib/module/components/FileViewer.js +2 -5
  141. package/lib/module/components/FileViewer.js.map +1 -1
  142. package/lib/module/components/MessageRenderer/FileMessage/BaseFileMessage.js +11 -6
  143. package/lib/module/components/MessageRenderer/FileMessage/BaseFileMessage.js.map +1 -1
  144. package/lib/module/components/MessageRenderer/FileMessage/ImageFileMessage.js +12 -2
  145. package/lib/module/components/MessageRenderer/FileMessage/ImageFileMessage.js.map +1 -1
  146. package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js +26 -11
  147. package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -1
  148. package/lib/module/components/MessageRenderer/FileMessage/index.js +1 -5
  149. package/lib/module/components/MessageRenderer/FileMessage/index.js.map +1 -1
  150. package/lib/module/components/MessageRenderer/UserMessage/BaseUserMessage.js +86 -12
  151. package/lib/module/components/MessageRenderer/UserMessage/BaseUserMessage.js.map +1 -1
  152. package/lib/module/components/MessageRenderer/UserMessage/OpenGraphUserMessage.js +103 -19
  153. package/lib/module/components/MessageRenderer/UserMessage/OpenGraphUserMessage.js.map +1 -1
  154. package/lib/module/components/MessageRenderer/UserMessage/index.js.map +1 -1
  155. package/lib/module/components/MessageRenderer/index.js +21 -4
  156. package/lib/module/components/MessageRenderer/index.js.map +1 -1
  157. package/lib/module/components/ReactionAddons/BottomSheetReactionAddon.js +132 -0
  158. package/lib/module/components/ReactionAddons/BottomSheetReactionAddon.js.map +1 -0
  159. package/lib/module/components/ReactionAddons/MessageReactionAddon.js +118 -0
  160. package/lib/module/components/ReactionAddons/MessageReactionAddon.js.map +1 -0
  161. package/lib/module/components/ReactionAddons/ReactionRoundedButton.js +74 -0
  162. package/lib/module/components/ReactionAddons/ReactionRoundedButton.js.map +1 -0
  163. package/lib/module/components/ReactionAddons/index.js +7 -0
  164. package/lib/module/components/ReactionAddons/index.js.map +1 -0
  165. package/lib/module/components/ReactionBottomSheets/ReactionListBottomSheet.js +135 -0
  166. package/lib/module/components/ReactionBottomSheets/ReactionListBottomSheet.js.map +1 -0
  167. package/lib/module/components/ReactionBottomSheets/ReactionUserListBottomSheet.js +259 -0
  168. package/lib/module/components/ReactionBottomSheets/ReactionUserListBottomSheet.js.map +1 -0
  169. package/lib/module/components/ReactionBottomSheets/index.js +7 -0
  170. package/lib/module/components/ReactionBottomSheets/index.js.map +1 -0
  171. package/lib/module/constants.js +1 -0
  172. package/lib/module/constants.js.map +1 -1
  173. package/lib/module/containers/GroupChannelPreviewContainer.js +4 -1
  174. package/lib/module/containers/GroupChannelPreviewContainer.js.map +1 -1
  175. package/lib/module/containers/SendbirdUIKitContainer.js +127 -81
  176. package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -1
  177. package/lib/module/contexts/PlatformServiceCtx.js.map +1 -1
  178. package/lib/module/contexts/ReactionCtx.js +85 -0
  179. package/lib/module/contexts/ReactionCtx.js.map +1 -0
  180. package/lib/module/contexts/SendbirdChatCtx.js +28 -18
  181. package/lib/module/contexts/SendbirdChatCtx.js.map +1 -1
  182. package/lib/module/contexts/UserProfileCtx.js +7 -0
  183. package/lib/module/contexts/UserProfileCtx.js.map +1 -1
  184. package/lib/module/domain/groupChannel/component/GroupChannelInput/EditInput.js +34 -39
  185. package/lib/module/domain/groupChannel/component/GroupChannelInput/EditInput.js.map +1 -1
  186. package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js +92 -26
  187. package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
  188. package/lib/module/domain/groupChannel/component/GroupChannelInput/index.js +118 -33
  189. package/lib/module/domain/groupChannel/component/GroupChannelInput/index.js.map +1 -1
  190. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +35 -16
  191. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  192. package/lib/module/domain/groupChannel/component/GroupChannelSuggestedMentionList.js +188 -0
  193. package/lib/module/domain/groupChannel/component/GroupChannelSuggestedMentionList.js.map +1 -0
  194. package/lib/module/domain/groupChannel/index.js +1 -0
  195. package/lib/module/domain/groupChannel/index.js.map +1 -1
  196. package/lib/module/domain/groupChannel/module/createGroupChannelModule.js +3 -0
  197. package/lib/module/domain/groupChannel/module/createGroupChannelModule.js.map +1 -1
  198. package/lib/module/domain/groupChannel/module/moduleContext.js +4 -4
  199. package/lib/module/domain/groupChannel/module/moduleContext.js.map +1 -1
  200. package/lib/module/domain/groupChannel/types.js.map +1 -1
  201. package/lib/module/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.js +4 -3
  202. package/lib/module/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.js.map +1 -1
  203. package/lib/module/domain/groupChannelList/component/GroupChannelListList.js +3 -2
  204. package/lib/module/domain/groupChannelList/component/GroupChannelListList.js.map +1 -1
  205. package/lib/module/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.js +3 -2
  206. package/lib/module/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.js.map +1 -1
  207. package/lib/module/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.js +25 -0
  208. package/lib/module/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.js.map +1 -0
  209. package/lib/module/domain/groupChannelNotifications/component/GroupChannelNotificationsView.js +122 -0
  210. package/lib/module/domain/groupChannelNotifications/component/GroupChannelNotificationsView.js.map +1 -0
  211. package/lib/module/domain/groupChannelNotifications/index.js +5 -0
  212. package/lib/module/domain/groupChannelNotifications/index.js.map +1 -0
  213. package/lib/module/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.js +21 -0
  214. package/lib/module/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.js.map +1 -0
  215. package/lib/module/domain/groupChannelNotifications/module/moduleContext.js +25 -0
  216. package/lib/module/domain/groupChannelNotifications/module/moduleContext.js.map +1 -0
  217. package/lib/module/domain/groupChannelNotifications/types.js +2 -0
  218. package/lib/module/domain/groupChannelNotifications/types.js.map +1 -0
  219. package/lib/module/domain/groupChannelOperators/component/GroupChannelOperatorsList.js +3 -2
  220. package/lib/module/domain/groupChannelOperators/component/GroupChannelOperatorsList.js.map +1 -1
  221. package/lib/module/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js +46 -6
  222. package/lib/module/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js.map +1 -1
  223. package/lib/module/domain/groupChannelSettings/module/moduleContext.js +12 -17
  224. package/lib/module/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
  225. package/lib/module/domain/groupChannelSettings/types.js.map +1 -1
  226. package/lib/module/domain/groupChannelUserList/types.js.map +1 -1
  227. package/lib/module/domain/userList/component/UserListList.js +3 -1
  228. package/lib/module/domain/userList/component/UserListList.js.map +1 -1
  229. package/lib/module/domain/userList/module/createUserListModule.js.map +1 -1
  230. package/lib/module/fragments/createGroupChannelCreateFragment.js.map +1 -1
  231. package/lib/module/fragments/createGroupChannelFragment.js +11 -4
  232. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  233. package/lib/module/fragments/createGroupChannelInviteFragment.js.map +1 -1
  234. package/lib/module/fragments/createGroupChannelListFragment.js +5 -9
  235. package/lib/module/fragments/createGroupChannelListFragment.js.map +1 -1
  236. package/lib/module/fragments/createGroupChannelNotificationsFragment.js +22 -0
  237. package/lib/module/fragments/createGroupChannelNotificationsFragment.js.map +1 -0
  238. package/lib/module/fragments/createGroupChannelSettingsFragment.js +3 -1
  239. package/lib/module/fragments/createGroupChannelSettingsFragment.js.map +1 -1
  240. package/lib/module/hooks/useConnection.js +3 -0
  241. package/lib/module/hooks/useConnection.js.map +1 -1
  242. package/lib/module/hooks/useContext.js +6 -0
  243. package/lib/module/hooks/useContext.js.map +1 -1
  244. package/lib/module/hooks/useKeyboardStatus.js +78 -0
  245. package/lib/module/hooks/useKeyboardStatus.js.map +1 -0
  246. package/lib/module/hooks/useMentionSuggestion.js +100 -0
  247. package/lib/module/hooks/useMentionSuggestion.js.map +1 -0
  248. package/lib/module/hooks/useMentionTextInput.js +128 -0
  249. package/lib/module/hooks/useMentionTextInput.js.map +1 -0
  250. package/lib/module/index.js +8 -3
  251. package/lib/module/index.js.map +1 -1
  252. package/lib/module/libs/EmojiManager.js +90 -0
  253. package/lib/module/libs/EmojiManager.js.map +1 -0
  254. package/lib/module/libs/ImageCompressionConfig.js +30 -0
  255. package/lib/module/libs/ImageCompressionConfig.js.map +1 -0
  256. package/lib/module/libs/MentionConfig.js +39 -0
  257. package/lib/module/libs/MentionConfig.js.map +1 -0
  258. package/lib/module/libs/MentionManager.js +223 -0
  259. package/lib/module/libs/MentionManager.js.map +1 -0
  260. package/lib/module/libs/SBUUtils.js +26 -1
  261. package/lib/module/libs/SBUUtils.js.map +1 -1
  262. package/lib/module/localization/StringSet.type.js +21 -6
  263. package/lib/module/localization/StringSet.type.js.map +1 -1
  264. package/lib/module/platform/createMediaService.expo.js +33 -1
  265. package/lib/module/platform/createMediaService.expo.js.map +1 -1
  266. package/lib/module/platform/createMediaService.native.js +38 -5
  267. package/lib/module/platform/createMediaService.native.js.map +1 -1
  268. package/lib/module/platform/dynamicModule.js +10 -56
  269. package/lib/module/platform/dynamicModule.js.map +1 -1
  270. package/lib/module/platform/types.js.map +1 -1
  271. package/lib/module/types.js.map +1 -1
  272. package/lib/module/version.js +1 -1
  273. package/lib/module/version.js.map +1 -1
  274. package/lib/typescript/__template__/types.d.ts +3 -3
  275. package/lib/typescript/src/components/ChannelCover.d.ts +1 -1
  276. package/lib/typescript/src/components/ChatFlatList.d.ts +1 -1
  277. package/lib/typescript/src/components/FileViewer.d.ts +1 -1
  278. package/lib/typescript/src/components/MessageRenderer/AdminMessage/index.d.ts +1 -1
  279. package/lib/typescript/src/components/MessageRenderer/FileMessage/BaseFileMessage.d.ts +2 -2
  280. package/lib/typescript/src/components/MessageRenderer/FileMessage/ImageFileMessage.d.ts +1 -1
  281. package/lib/typescript/src/components/MessageRenderer/FileMessage/VideoFileMessage.d.ts +1 -1
  282. package/lib/typescript/src/components/MessageRenderer/FileMessage/index.d.ts +11 -2
  283. package/lib/typescript/src/components/MessageRenderer/MessageDateSeparator.d.ts +1 -1
  284. package/lib/typescript/src/components/MessageRenderer/MessageIncomingAvatar.d.ts +1 -1
  285. package/lib/typescript/src/components/MessageRenderer/MessageIncomingSenderName.d.ts +1 -1
  286. package/lib/typescript/src/components/MessageRenderer/MessageOutgoingStatus.d.ts +1 -1
  287. package/lib/typescript/src/components/MessageRenderer/MessageTime.d.ts +1 -1
  288. package/lib/typescript/src/components/MessageRenderer/UnknownMessage/index.d.ts +1 -1
  289. package/lib/typescript/src/components/MessageRenderer/UserMessage/BaseUserMessage.d.ts +1 -1
  290. package/lib/typescript/src/components/MessageRenderer/UserMessage/OpenGraphUserMessage.d.ts +2 -2
  291. package/lib/typescript/src/components/MessageRenderer/UserMessage/index.d.ts +4 -1
  292. package/lib/typescript/src/components/MessageRenderer/index.d.ts +4 -3
  293. package/lib/typescript/src/components/NewMessagesButton.d.ts +1 -1
  294. package/lib/typescript/src/components/ReactionAddons/BottomSheetReactionAddon.d.ts +8 -0
  295. package/lib/typescript/src/components/ReactionAddons/MessageReactionAddon.d.ts +6 -0
  296. package/lib/typescript/src/components/ReactionAddons/ReactionRoundedButton.d.ts +14 -0
  297. package/lib/typescript/src/components/ReactionAddons/index.d.ts +11 -0
  298. package/lib/typescript/src/components/ReactionBottomSheets/ReactionListBottomSheet.d.ts +3 -0
  299. package/lib/typescript/src/components/ReactionBottomSheets/ReactionUserListBottomSheet.d.ts +3 -0
  300. package/lib/typescript/src/components/ReactionBottomSheets/index.d.ts +20 -0
  301. package/lib/typescript/src/components/ScrollToBottomButton.d.ts +1 -1
  302. package/lib/typescript/src/components/StatusComposition.d.ts +1 -1
  303. package/lib/typescript/src/components/TypedPlaceholder.d.ts +1 -1
  304. package/lib/typescript/src/components/UserActionBar.d.ts +1 -1
  305. package/lib/typescript/src/components/UserSelectableBar.d.ts +1 -1
  306. package/lib/typescript/src/constants.d.ts +1 -0
  307. package/lib/typescript/src/containers/GroupChannelPreviewContainer.d.ts +1 -1
  308. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +20 -8
  309. package/lib/typescript/src/contexts/LocalizationCtx.d.ts +2 -2
  310. package/lib/typescript/src/contexts/PlatformServiceCtx.d.ts +9 -3
  311. package/lib/typescript/src/contexts/ReactionCtx.d.ts +18 -0
  312. package/lib/typescript/src/contexts/SendbirdChatCtx.d.ts +16 -3
  313. package/lib/typescript/src/contexts/UserProfileCtx.d.ts +4 -4
  314. package/lib/typescript/src/domain/groupChannel/component/GroupChannelInput/EditInput.d.ts +35 -7
  315. package/lib/typescript/src/domain/groupChannel/component/GroupChannelInput/SendInput.d.ts +32 -5
  316. package/lib/typescript/src/domain/groupChannel/component/GroupChannelInput/index.d.ts +19 -2
  317. package/lib/typescript/src/domain/groupChannel/component/GroupChannelSuggestedMentionList.d.ts +3 -0
  318. package/lib/typescript/src/domain/groupChannel/index.d.ts +1 -0
  319. package/lib/typescript/src/domain/groupChannel/module/createGroupChannelModule.d.ts +1 -1
  320. package/lib/typescript/src/domain/groupChannel/types.d.ts +24 -7
  321. package/lib/typescript/src/domain/groupChannelBannedUsers/types.d.ts +3 -3
  322. package/lib/typescript/src/domain/groupChannelList/types.d.ts +2 -2
  323. package/lib/typescript/src/domain/groupChannelModeration/types.d.ts +3 -3
  324. package/lib/typescript/src/domain/groupChannelMutedMembers/types.d.ts +3 -3
  325. package/lib/typescript/src/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.d.ts +3 -0
  326. package/lib/typescript/src/domain/groupChannelNotifications/component/GroupChannelNotificationsView.d.ts +2 -0
  327. package/lib/typescript/src/domain/groupChannelNotifications/index.d.ts +4 -0
  328. package/lib/typescript/src/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.d.ts +3 -0
  329. package/lib/typescript/src/domain/groupChannelNotifications/module/moduleContext.d.ts +3 -0
  330. package/lib/typescript/src/domain/groupChannelNotifications/types.d.ts +33 -0
  331. package/lib/typescript/src/domain/groupChannelOperators/types.d.ts +3 -3
  332. package/lib/typescript/src/domain/groupChannelSettings/component/GroupChannelSettingsMenu.d.ts +1 -1
  333. package/lib/typescript/src/domain/groupChannelSettings/types.d.ts +3 -1
  334. package/lib/typescript/src/domain/groupChannelUserList/types.d.ts +6 -6
  335. package/lib/typescript/src/domain/userList/component/UserListList.d.ts +2 -1
  336. package/lib/typescript/src/domain/userList/module/createUserListModule.d.ts +2 -1
  337. package/lib/typescript/src/fragments/createGroupChannelCreateFragment.d.ts +1 -1
  338. package/lib/typescript/src/fragments/createGroupChannelInviteFragment.d.ts +1 -1
  339. package/lib/typescript/src/fragments/createGroupChannelNotificationsFragment.d.ts +3 -0
  340. package/lib/typescript/src/hooks/useConnection.d.ts +1 -1
  341. package/lib/typescript/src/hooks/useContext.d.ts +3 -26
  342. package/lib/typescript/src/hooks/useKeyboardStatus.d.ts +6 -0
  343. package/lib/typescript/src/hooks/useMentionSuggestion.d.ts +17 -0
  344. package/lib/typescript/src/hooks/useMentionTextInput.d.ts +18 -0
  345. package/lib/typescript/src/index.d.ts +8 -3
  346. package/lib/typescript/src/libs/EmojiManager.d.ts +16 -0
  347. package/lib/typescript/src/libs/ImageCompressionConfig.d.ts +16 -0
  348. package/lib/typescript/src/libs/MentionConfig.d.ts +24 -0
  349. package/lib/typescript/src/libs/MentionManager.d.ts +61 -0
  350. package/lib/typescript/src/libs/SBUUtils.d.ts +6 -0
  351. package/lib/typescript/src/localization/StringSet.type.d.ts +19 -2
  352. package/lib/typescript/src/platform/createMediaService.expo.d.ts +6 -2
  353. package/lib/typescript/src/platform/createMediaService.native.d.ts +8 -6
  354. package/lib/typescript/src/platform/dynamicModule.d.ts +8 -13
  355. package/lib/typescript/src/platform/types.d.ts +33 -8
  356. package/lib/typescript/src/types.d.ts +13 -4
  357. package/lib/typescript/src/version.d.ts +1 -1
  358. package/package.json +16 -6
  359. package/src/components/ChatFlatList.tsx +2 -1
  360. package/src/components/FileViewer.tsx +2 -5
  361. package/src/components/MessageRenderer/FileMessage/BaseFileMessage.tsx +17 -12
  362. package/src/components/MessageRenderer/FileMessage/ImageFileMessage.tsx +30 -18
  363. package/src/components/MessageRenderer/FileMessage/VideoFileMessage.tsx +21 -11
  364. package/src/components/MessageRenderer/FileMessage/index.tsx +1 -4
  365. package/src/components/MessageRenderer/UserMessage/BaseUserMessage.tsx +82 -14
  366. package/src/components/MessageRenderer/UserMessage/OpenGraphUserMessage.tsx +136 -62
  367. package/src/components/MessageRenderer/UserMessage/index.tsx +8 -1
  368. package/src/components/MessageRenderer/index.tsx +39 -7
  369. package/src/components/ReactionAddons/BottomSheetReactionAddon.tsx +106 -0
  370. package/src/components/ReactionAddons/MessageReactionAddon.tsx +123 -0
  371. package/src/components/ReactionAddons/ReactionRoundedButton.tsx +71 -0
  372. package/src/components/ReactionAddons/index.tsx +7 -0
  373. package/src/components/ReactionBottomSheets/ReactionListBottomSheet.tsx +113 -0
  374. package/src/components/ReactionBottomSheets/ReactionUserListBottomSheet.tsx +249 -0
  375. package/src/components/ReactionBottomSheets/index.tsx +24 -0
  376. package/src/constants.ts +2 -0
  377. package/src/containers/GroupChannelPreviewContainer.tsx +3 -1
  378. package/src/containers/SendbirdUIKitContainer.tsx +165 -88
  379. package/src/contexts/PlatformServiceCtx.tsx +9 -2
  380. package/src/contexts/ReactionCtx.tsx +102 -0
  381. package/src/contexts/SendbirdChatCtx.tsx +46 -21
  382. package/src/contexts/UserProfileCtx.tsx +9 -0
  383. package/src/domain/groupChannel/component/GroupChannelInput/EditInput.tsx +56 -30
  384. package/src/domain/groupChannel/component/GroupChannelInput/SendInput.tsx +129 -32
  385. package/src/domain/groupChannel/component/GroupChannelInput/index.tsx +138 -43
  386. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +30 -12
  387. package/src/domain/groupChannel/component/GroupChannelSuggestedMentionList.tsx +173 -0
  388. package/src/domain/groupChannel/index.ts +1 -0
  389. package/src/domain/groupChannel/module/createGroupChannelModule.tsx +12 -1
  390. package/src/domain/groupChannel/module/moduleContext.tsx +4 -4
  391. package/src/domain/groupChannel/types.ts +28 -5
  392. package/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.tsx +3 -2
  393. package/src/domain/groupChannelList/component/GroupChannelListList.tsx +2 -1
  394. package/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.tsx +2 -1
  395. package/src/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.tsx +14 -0
  396. package/src/domain/groupChannelNotifications/component/GroupChannelNotificationsView.tsx +128 -0
  397. package/src/domain/groupChannelNotifications/index.ts +4 -0
  398. package/src/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.tsx +15 -0
  399. package/src/domain/groupChannelNotifications/module/moduleContext.tsx +31 -0
  400. package/src/domain/groupChannelNotifications/types.ts +38 -0
  401. package/src/domain/groupChannelOperators/component/GroupChannelOperatorsList.tsx +2 -1
  402. package/src/domain/groupChannelSettings/component/GroupChannelSettingsMenu.tsx +42 -3
  403. package/src/domain/groupChannelSettings/module/moduleContext.tsx +17 -14
  404. package/src/domain/groupChannelSettings/types.ts +2 -0
  405. package/src/domain/groupChannelUserList/types.ts +7 -2
  406. package/src/domain/userList/component/UserListList.tsx +5 -1
  407. package/src/domain/userList/module/createUserListModule.tsx +3 -1
  408. package/src/fragments/createGroupChannelCreateFragment.tsx +8 -2
  409. package/src/fragments/createGroupChannelFragment.tsx +19 -6
  410. package/src/fragments/createGroupChannelInviteFragment.tsx +2 -2
  411. package/src/fragments/createGroupChannelListFragment.tsx +5 -9
  412. package/src/fragments/createGroupChannelNotificationsFragment.tsx +27 -0
  413. package/src/fragments/createGroupChannelSettingsFragment.tsx +2 -0
  414. package/src/hooks/useConnection.ts +3 -1
  415. package/src/hooks/useContext.ts +7 -0
  416. package/src/hooks/useKeyboardStatus.ts +59 -0
  417. package/src/hooks/useMentionSuggestion.ts +106 -0
  418. package/src/hooks/useMentionTextInput.ts +139 -0
  419. package/src/index.ts +14 -2
  420. package/src/libs/EmojiManager.ts +80 -0
  421. package/src/libs/ImageCompressionConfig.ts +31 -0
  422. package/src/libs/MentionConfig.ts +40 -0
  423. package/src/libs/MentionManager.tsx +240 -0
  424. package/src/libs/SBUUtils.ts +28 -1
  425. package/src/localization/StringSet.type.ts +45 -8
  426. package/src/platform/createMediaService.expo.tsx +24 -1
  427. package/src/platform/createMediaService.native.tsx +31 -9
  428. package/src/platform/dynamicModule.ts +17 -59
  429. package/src/platform/types.ts +29 -7
  430. package/src/types.ts +12 -0
  431. package/src/version.ts +1 -1
@@ -1,60 +1,86 @@
1
- import React, { useEffect, useRef } from 'react';
2
- import { Platform, TextInput as RNTextInput, View } from 'react-native';
1
+ import React, { forwardRef } from 'react';
2
+ import {
3
+ NativeSyntheticEvent,
4
+ Platform,
5
+ TextInput as RNTextInput,
6
+ TextInputSelectionChangeEventData,
7
+ View,
8
+ } from 'react-native';
3
9
 
10
+ import { MentionType } from '@sendbird/chat/message';
4
11
  import { Button, TextInput, createStyleSheet, useToast } from '@sendbird/uikit-react-native-foundation';
5
12
  import type { SendbirdFileMessage, SendbirdUserMessage } from '@sendbird/uikit-utils';
6
13
 
7
- import { useLocalization } from '../../../../hooks/useContext';
14
+ import { useLocalization, useSendbirdChat } from '../../../../hooks/useContext';
15
+ import type { MentionedUser } from '../../../../types';
8
16
  import type { GroupChannelProps } from '../../types';
9
17
 
10
18
  type EditInputProps = GroupChannelProps['Input'] & {
11
19
  text: string;
12
- setText: (val: string) => void;
13
- editMessage: SendbirdUserMessage | SendbirdFileMessage;
14
- setEditMessage: (msg?: SendbirdUserMessage | SendbirdFileMessage) => void;
20
+ onChangeText: (val: string) => void;
21
+ messageToEdit: SendbirdUserMessage | SendbirdFileMessage;
22
+ setMessageToEdit: (msg?: SendbirdUserMessage | SendbirdFileMessage) => void;
23
+ onSelectionChange: (e: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => void;
15
24
  disabled: boolean;
25
+ autoFocus: boolean;
26
+ mentionedUsers: MentionedUser[];
16
27
  };
17
28
 
18
- const AUTO_FOCUS = Platform.select({ ios: false, android: true, default: false });
19
- const EditInput = ({ text, setText, editMessage, setEditMessage, onUpdateUserMessage, disabled }: EditInputProps) => {
29
+ const EditInput = forwardRef<RNTextInput, EditInputProps>(function EditInput(
30
+ {
31
+ text,
32
+ onChangeText,
33
+ messageToEdit,
34
+ setMessageToEdit,
35
+ onUpdateUserMessage,
36
+ onSelectionChange,
37
+ disabled,
38
+ autoFocus,
39
+ mentionedUsers,
40
+ },
41
+ ref,
42
+ ) {
43
+ const { mentionManager } = useSendbirdChat();
20
44
  const { STRINGS } = useLocalization();
21
- const inputRef = useRef<RNTextInput>(null);
22
45
  const toast = useToast();
23
46
 
24
- useEffect(() => {
25
- if (editMessage.isUserMessage()) {
26
- setText(editMessage.message ?? '');
27
-
28
- if (!AUTO_FOCUS) setTimeout(() => inputRef.current?.focus(), 500);
29
- }
30
- }, [editMessage]);
31
-
32
47
  const onPressCancel = () => {
33
- setEditMessage();
34
- setText('');
48
+ setMessageToEdit();
49
+ onChangeText('');
35
50
  };
36
51
 
37
52
  const onPressSave = () => {
38
- if (editMessage.isUserMessage()) {
39
- onUpdateUserMessage(text, editMessage).catch(() => toast.show(STRINGS.TOAST.UPDATE_MSG_ERROR, 'error'));
53
+ if (messageToEdit.isUserMessage()) {
54
+ const mention = {
55
+ userIds: mentionedUsers.map((it) => it.user.userId),
56
+ messageTemplate: mentionManager.textToMentionedMessageTemplate(text, mentionedUsers),
57
+ type: MentionType.USERS,
58
+ };
59
+
60
+ onUpdateUserMessage(text, messageToEdit, mention).catch(() =>
61
+ toast.show(STRINGS.TOAST.UPDATE_MSG_ERROR, 'error'),
62
+ );
40
63
  }
41
- setEditMessage();
42
- setText('');
64
+ setMessageToEdit();
65
+ onChangeText('');
43
66
  };
44
67
 
45
68
  return (
46
69
  <View style={styles.editInputContainer}>
47
70
  <View style={styles.inputWrapper}>
48
71
  <TextInput
49
- editable={!disabled}
50
- autoFocus={AUTO_FOCUS}
51
- ref={inputRef}
72
+ ref={ref}
52
73
  multiline
53
- value={text}
54
- onChangeText={setText}
74
+ disableFullscreenUI
75
+ editable={!disabled}
76
+ autoFocus={autoFocus}
77
+ onChangeText={onChangeText}
55
78
  style={styles.input}
56
79
  placeholder={STRINGS.GROUP_CHANNEL.INPUT_PLACEHOLDER_ACTIVE}
57
- />
80
+ onSelectionChange={onSelectionChange}
81
+ >
82
+ {mentionManager.textToMentionedComponents(text, mentionedUsers)}
83
+ </TextInput>
58
84
  </View>
59
85
  <View style={{ marginTop: 8, flexDirection: 'row' }}>
60
86
  <Button variant={'text'} onPress={onPressCancel}>
@@ -67,7 +93,7 @@ const EditInput = ({ text, setText, editMessage, setEditMessage, onUpdateUserMes
67
93
  </View>
68
94
  </View>
69
95
  );
70
- };
96
+ });
71
97
 
72
98
  const styles = createStyleSheet({
73
99
  editInputContainer: {
@@ -1,6 +1,14 @@
1
- import React from 'react';
2
- import { Platform, TouchableOpacity, View } from 'react-native';
1
+ import React, { forwardRef } from 'react';
2
+ import {
3
+ NativeSyntheticEvent,
4
+ Platform,
5
+ TextInput as RNTextInput,
6
+ TextInputSelectionChangeEventData,
7
+ TouchableOpacity,
8
+ View,
9
+ } from 'react-native';
3
10
 
11
+ import { MentionType } from '@sendbird/chat/message';
4
12
  import {
5
13
  Icon,
6
14
  TextInput,
@@ -10,40 +18,56 @@ import {
10
18
  useToast,
11
19
  useUIKitTheme,
12
20
  } from '@sendbird/uikit-react-native-foundation';
13
- import { conditionChaining } from '@sendbird/uikit-utils';
21
+ import { conditionChaining, isImage, shouldCompressImage } from '@sendbird/uikit-utils';
14
22
 
15
- import { useLocalization, usePlatformService } from '../../../../hooks/useContext';
23
+ import { useLocalization, usePlatformService, useSendbirdChat } from '../../../../hooks/useContext';
16
24
  import SBUError from '../../../../libs/SBUError';
17
25
  import SBUUtils from '../../../../libs/SBUUtils';
26
+ import type { MentionedUser } from '../../../../types';
18
27
  import type { GroupChannelProps } from '../../types';
19
28
 
20
29
  type SendInputProps = GroupChannelProps['Input'] & {
21
30
  text: string;
22
- setText: (val: string) => void;
31
+ onChangeText: (val: string) => void;
23
32
  frozen: boolean;
24
33
  muted: boolean;
25
34
  disabled: boolean;
35
+ onSelectionChange: (e: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => void;
36
+ mentionedUsers: MentionedUser[];
26
37
  };
27
- const SendInput = ({
28
- onSendUserMessage,
29
- onSendFileMessage,
30
- text,
31
- setText,
32
- disabled,
33
- frozen,
34
- muted,
35
- }: SendInputProps) => {
38
+ const SendInput = forwardRef<RNTextInput, SendInputProps>(function SendInput(
39
+ {
40
+ onSendUserMessage,
41
+ onSendFileMessage,
42
+ text,
43
+ onChangeText,
44
+ disabled,
45
+ frozen,
46
+ muted,
47
+ onSelectionChange,
48
+ mentionedUsers,
49
+ },
50
+ ref,
51
+ ) {
52
+ const { mentionManager, imageCompressionConfig, features } = useSendbirdChat();
36
53
  const { STRINGS } = useLocalization();
37
- const { fileService } = usePlatformService();
54
+ const { fileService, mediaService } = usePlatformService();
38
55
  const { colors } = useUIKitTheme();
39
56
  const { openSheet } = useBottomSheet();
40
57
  const { alert } = useAlert();
41
58
  const toast = useToast();
42
59
 
43
60
  const onPressSend = () => {
44
- onSendUserMessage(text).catch(() => toast.show(STRINGS.TOAST.SEND_MSG_ERROR, 'error'));
45
- setText('');
61
+ const mention = {
62
+ userIds: mentionedUsers.map((it) => it.user.userId),
63
+ messageTemplate: mentionManager.textToMentionedMessageTemplate(text, mentionedUsers),
64
+ type: MentionType.USERS,
65
+ };
66
+
67
+ onSendUserMessage(text, mention).catch(() => toast.show(STRINGS.TOAST.SEND_MSG_ERROR, 'error'));
68
+ onChangeText('');
46
69
  };
70
+
47
71
  const onPressAttachment = () => {
48
72
  openSheet({
49
73
  sheetItems: [
@@ -51,13 +75,16 @@ const SendInput = ({
51
75
  title: STRINGS.GROUP_CHANNEL.DIALOG_ATTACHMENT_CAMERA,
52
76
  icon: 'camera',
53
77
  onPress: async () => {
54
- const photo = await fileService.openCamera({
78
+ const mediaFile = await fileService.openCamera({
55
79
  mediaType: 'all',
56
80
  onOpenFailure: (error) => {
57
81
  if (error.code === SBUError.CODE.ERR_PERMISSIONS_DENIED) {
58
82
  alert({
59
83
  title: STRINGS.DIALOG.ALERT_PERMISSIONS_TITLE,
60
- message: STRINGS.DIALOG.ALERT_PERMISSIONS_MESSAGE('camera', 'UIKitSample'),
84
+ message: STRINGS.DIALOG.ALERT_PERMISSIONS_MESSAGE(
85
+ STRINGS.LABELS.PERMISSION_CAMERA,
86
+ STRINGS.LABELS.PERMISSION_APP_NAME,
87
+ ),
61
88
  buttons: [{ text: STRINGS.DIALOG.ALERT_PERMISSIONS_OK, onPress: () => SBUUtils.openSettings() }],
62
89
  });
63
90
  } else {
@@ -66,8 +93,28 @@ const SendInput = ({
66
93
  },
67
94
  });
68
95
 
69
- if (photo) {
70
- onSendFileMessage(photo).catch(() => toast.show(STRINGS.TOAST.SEND_MSG_ERROR, 'error'));
96
+ if (mediaFile) {
97
+ // Image compression
98
+ if (
99
+ isImage(mediaFile.uri, mediaFile.type) &&
100
+ shouldCompressImage(mediaFile.uri, features.imageCompressionEnabled)
101
+ ) {
102
+ await SBUUtils.safeRun(async () => {
103
+ const compressed = await mediaService.compressImage({
104
+ uri: mediaFile.uri,
105
+ maxWidth: imageCompressionConfig.width,
106
+ maxHeight: imageCompressionConfig.height,
107
+ compressionRate: imageCompressionConfig.compressionRate,
108
+ });
109
+
110
+ if (compressed) {
111
+ mediaFile.uri = compressed.uri;
112
+ mediaFile.size = compressed.size;
113
+ }
114
+ });
115
+ }
116
+
117
+ onSendFileMessage(mediaFile).catch(() => toast.show(STRINGS.TOAST.SEND_MSG_ERROR, 'error'));
71
118
  }
72
119
  },
73
120
  },
@@ -75,14 +122,17 @@ const SendInput = ({
75
122
  title: STRINGS.GROUP_CHANNEL.DIALOG_ATTACHMENT_PHOTO_LIBRARY,
76
123
  icon: 'photo',
77
124
  onPress: async () => {
78
- const photo = await fileService.openMediaLibrary({
125
+ const mediaFiles = await fileService.openMediaLibrary({
79
126
  selectionLimit: 1,
80
127
  mediaType: 'all',
81
128
  onOpenFailure: (error) => {
82
129
  if (error.code === SBUError.CODE.ERR_PERMISSIONS_DENIED) {
83
130
  alert({
84
131
  title: STRINGS.DIALOG.ALERT_PERMISSIONS_TITLE,
85
- message: STRINGS.DIALOG.ALERT_PERMISSIONS_MESSAGE('device storage', 'UIKitSample'),
132
+ message: STRINGS.DIALOG.ALERT_PERMISSIONS_MESSAGE(
133
+ STRINGS.LABELS.PERMISSION_DEVICE_STORAGE,
134
+ STRINGS.LABELS.PERMISSION_APP_NAME,
135
+ ),
86
136
  buttons: [{ text: STRINGS.DIALOG.ALERT_PERMISSIONS_OK, onPress: () => SBUUtils.openSettings() }],
87
137
  });
88
138
  } else {
@@ -91,8 +141,30 @@ const SendInput = ({
91
141
  },
92
142
  });
93
143
 
94
- if (photo && photo[0]) {
95
- onSendFileMessage(photo[0]).catch(() => toast.show(STRINGS.TOAST.SEND_MSG_ERROR, 'error'));
144
+ if (mediaFiles && mediaFiles[0]) {
145
+ const mediaFile = mediaFiles[0];
146
+
147
+ // Image compression
148
+ if (
149
+ isImage(mediaFile.uri, mediaFile.type) &&
150
+ shouldCompressImage(mediaFile.uri, features.imageCompressionEnabled)
151
+ ) {
152
+ await SBUUtils.safeRun(async () => {
153
+ const compressed = await mediaService.compressImage({
154
+ uri: mediaFile.uri,
155
+ maxWidth: imageCompressionConfig.width,
156
+ maxHeight: imageCompressionConfig.height,
157
+ compressionRate: imageCompressionConfig.compressionRate,
158
+ });
159
+
160
+ if (compressed) {
161
+ mediaFile.uri = compressed.uri;
162
+ mediaFile.size = compressed.size;
163
+ }
164
+ });
165
+ }
166
+
167
+ onSendFileMessage(mediaFiles[0]).catch(() => toast.show(STRINGS.TOAST.SEND_MSG_ERROR, 'error'));
96
168
  }
97
169
  },
98
170
  },
@@ -100,12 +172,32 @@ const SendInput = ({
100
172
  title: STRINGS.GROUP_CHANNEL.DIALOG_ATTACHMENT_FILES,
101
173
  icon: 'document',
102
174
  onPress: async () => {
103
- const file = await fileService.openDocument({
175
+ const documentFile = await fileService.openDocument({
104
176
  onOpenFailure: () => toast.show(STRINGS.TOAST.OPEN_FILES_ERROR, 'error'),
105
177
  });
106
178
 
107
- if (file) {
108
- onSendFileMessage(file).catch(() => toast.show(STRINGS.TOAST.SEND_MSG_ERROR, 'error'));
179
+ if (documentFile) {
180
+ // Image compression
181
+ if (
182
+ isImage(documentFile.uri, documentFile.type) &&
183
+ shouldCompressImage(documentFile.uri, features.imageCompressionEnabled)
184
+ ) {
185
+ await SBUUtils.safeRun(async () => {
186
+ const compressed = await mediaService.compressImage({
187
+ uri: documentFile.uri,
188
+ maxWidth: imageCompressionConfig.width,
189
+ maxHeight: imageCompressionConfig.height,
190
+ compressionRate: imageCompressionConfig.compressionRate,
191
+ });
192
+
193
+ if (compressed) {
194
+ documentFile.uri = compressed.uri;
195
+ documentFile.size = compressed.size;
196
+ }
197
+ });
198
+ }
199
+
200
+ onSendFileMessage(documentFile).catch(() => toast.show(STRINGS.TOAST.SEND_MSG_ERROR, 'error'));
109
201
  }
110
202
  },
111
203
  },
@@ -124,10 +216,12 @@ const SendInput = ({
124
216
  />
125
217
  </TouchableOpacity>
126
218
  <TextInput
219
+ ref={ref}
127
220
  multiline
221
+ disableFullscreenUI
222
+ onSelectionChange={onSelectionChange}
128
223
  editable={!disabled}
129
- value={text}
130
- onChangeText={setText}
224
+ onChangeText={onChangeText}
131
225
  style={styles.input}
132
226
  placeholder={conditionChaining(
133
227
  [frozen, muted],
@@ -137,7 +231,10 @@ const SendInput = ({
137
231
  STRINGS.GROUP_CHANNEL.INPUT_PLACEHOLDER_ACTIVE,
138
232
  ],
139
233
  )}
140
- />
234
+ >
235
+ {mentionManager.textToMentionedComponents(text, mentionedUsers)}
236
+ </TextInput>
237
+
141
238
  {Boolean(text.trim()) && (
142
239
  <TouchableOpacity onPress={onPressSend} disabled={disabled}>
143
240
  <Icon
@@ -150,7 +247,7 @@ const SendInput = ({
150
247
  )}
151
248
  </View>
152
249
  );
153
- };
250
+ });
154
251
 
155
252
  const styles = createStyleSheet({
156
253
  sendInputContainer: {
@@ -1,75 +1,170 @@
1
- import React, { useContext, useEffect, useRef, useState } from 'react';
2
- import { KeyboardAvoidingView, Platform, View } from 'react-native';
1
+ import React, { MutableRefObject, useContext, useEffect, useRef, useState } from 'react';
2
+ import { KeyboardAvoidingView, Platform, TextInput, View } from 'react-native';
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
4
 
5
- import { useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
6
- import { getGroupChannelChatAvailableState, useIIFE } from '@sendbird/uikit-utils';
5
+ import { createStyleSheet, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
6
+ import {
7
+ SendbirdFileMessage,
8
+ SendbirdGroupChannel,
9
+ SendbirdUserMessage,
10
+ getGroupChannelChatAvailableState,
11
+ replace,
12
+ useIIFE,
13
+ } from '@sendbird/uikit-utils';
7
14
 
15
+ import { useSendbirdChat } from '../../../../hooks/useContext';
16
+ import useMentionTextInput from '../../../../hooks/useMentionTextInput';
8
17
  import { GroupChannelContexts } from '../../module/moduleContext';
9
18
  import type { GroupChannelProps } from '../../types';
10
19
  import EditInput from './EditInput';
11
20
  import SendInput from './SendInput';
12
21
 
22
+ const AUTO_FOCUS = Platform.select({ ios: false, android: true, default: false });
13
23
  const KEYBOARD_AVOID_VIEW_BEHAVIOR = Platform.select({ ios: 'padding' as const, default: undefined });
24
+
25
+ // FIXME(iOS): Dynamic style does not work properly when typing the CJK. (https://github.com/facebook/react-native/issues/26107)
26
+ // To workaround temporarily, change the key for re-mount the component.
27
+ // -> This will affect to keyboard blur when add/remove first mentioned user.
28
+ const GET_INPUT_KEY = (shouldReset: boolean) => (shouldReset ? 'uikit-input-clear' : 'uikit-input');
29
+
30
+ // TODO: Refactor 'Edit' mode to clearly
14
31
  const GroupChannelInput = (props: GroupChannelProps['Input']) => {
15
- const { left, right, bottom } = useSafeAreaInsets();
32
+ const { top, left, right, bottom } = useSafeAreaInsets();
16
33
  const { colors } = useUIKitTheme();
17
- const { channel, editMessage, setEditMessage, keyboardAvoidOffset = 0 } = useContext(GroupChannelContexts.Fragment);
34
+ const { features, mentionManager } = useSendbirdChat();
35
+ const {
36
+ channel,
37
+ messageToEdit,
38
+ setMessageToEdit,
39
+ keyboardAvoidOffset = 0,
40
+ } = useContext(GroupChannelContexts.Fragment);
18
41
 
19
- const [text, setText] = useState('');
20
- const textTmpRef = useRef('');
21
42
  const chatAvailableState = getGroupChannelChatAvailableState(channel);
43
+ const mentionAvailable = features.userMentionEnabled && channel.isGroupChannel() && !channel.isBroadcast;
44
+ const inputMode = useIIFE(() => {
45
+ if (!messageToEdit) return 'send';
46
+ if (messageToEdit.isFileMessage()) return 'send';
47
+ return 'edit';
48
+ });
49
+
50
+ const [inputHeight, setInputHeight] = useState(styles.inputDefault.height);
51
+
52
+ const { selection, onSelectionChange, textInputRef, text, onChangeText, mentionedUsers } = useMentionTextInput({
53
+ messageToEdit: messageToEdit,
54
+ });
55
+
56
+ useTypingTrigger(text, channel);
57
+ useTextPersistenceOnDisabled(text, onChangeText, chatAvailableState.disabled);
58
+ useAutoFocusOnEditMode(textInputRef, messageToEdit);
59
+
60
+ const onPressToMention: GroupChannelProps['SuggestedMentionList']['onPressToMention'] = (user, searchStringRange) => {
61
+ const mentionedMessageText = mentionManager.asMentionedMessageText(user, true);
62
+ const range = { start: searchStringRange.start, end: searchStringRange.start + mentionedMessageText.length - 1 };
63
+
64
+ onChangeText(replace(text, searchStringRange.start, searchStringRange.end, mentionedMessageText), { user, range });
65
+ };
66
+
67
+ if (!props.shouldRenderInput) {
68
+ return <SafeAreaBottom height={bottom} />;
69
+ }
70
+
71
+ return (
72
+ <>
73
+ <KeyboardAvoidingView
74
+ keyboardVerticalOffset={-bottom + keyboardAvoidOffset}
75
+ behavior={KEYBOARD_AVOID_VIEW_BEHAVIOR}
76
+ >
77
+ <View style={{ paddingLeft: left, paddingRight: right, backgroundColor: colors.background }}>
78
+ <View onLayout={(e) => setInputHeight(e.nativeEvent.layout.height)} style={styles.inputContainer}>
79
+ {inputMode === 'send' && (
80
+ <SendInput
81
+ {...props}
82
+ {...chatAvailableState}
83
+ key={GET_INPUT_KEY(mentionedUsers.length === 0)}
84
+ ref={textInputRef as never}
85
+ text={text}
86
+ onChangeText={onChangeText}
87
+ onSelectionChange={onSelectionChange}
88
+ mentionedUsers={mentionedUsers}
89
+ />
90
+ )}
91
+ {inputMode === 'edit' && messageToEdit && (
92
+ <EditInput
93
+ {...props}
94
+ key={GET_INPUT_KEY(mentionedUsers.length === 0)}
95
+ ref={textInputRef as never}
96
+ autoFocus={AUTO_FOCUS}
97
+ text={text}
98
+ onChangeText={onChangeText}
99
+ messageToEdit={messageToEdit}
100
+ setMessageToEdit={setMessageToEdit}
101
+ disabled={chatAvailableState.disabled}
102
+ onSelectionChange={onSelectionChange}
103
+ mentionedUsers={mentionedUsers}
104
+ />
105
+ )}
106
+ </View>
107
+ <SafeAreaBottom height={bottom} />
108
+ </View>
109
+ </KeyboardAvoidingView>
110
+ {mentionAvailable && (
111
+ <props.SuggestedMentionList
112
+ text={text}
113
+ selection={selection}
114
+ inputHeight={inputHeight}
115
+ topInset={top}
116
+ bottomInset={bottom}
117
+ onPressToMention={onPressToMention}
118
+ mentionedUsers={mentionedUsers}
119
+ />
120
+ )}
121
+ </>
122
+ );
123
+ };
22
124
 
125
+ const useTypingTrigger = (text: string, channel: SendbirdGroupChannel) => {
23
126
  useEffect(() => {
24
127
  if (text.length === 0) channel.endTyping();
25
128
  else channel.startTyping();
26
129
  }, [text]);
130
+ };
131
+
132
+ const useTextPersistenceOnDisabled = (text: string, setText: (val: string) => void, chatDisabled: boolean) => {
133
+ const textTmpRef = useRef('');
27
134
 
28
135
  useEffect(() => {
29
- if (chatAvailableState.disabled) {
136
+ if (chatDisabled) {
30
137
  textTmpRef.current = text;
31
138
  setText('');
32
139
  } else {
33
140
  setText(textTmpRef.current);
34
141
  }
35
- }, [chatAvailableState.disabled]);
36
-
37
- const inputMode = useIIFE(() => {
38
- if (!editMessage) return 'send';
39
- if (editMessage.isFileMessage()) return 'send';
40
- return 'edit';
41
- });
42
-
43
- if (!props.shouldRenderInput) {
44
- return <SafeAreaBottom height={bottom} />;
45
- }
142
+ }, [chatDisabled]);
143
+ };
46
144
 
47
- return (
48
- <KeyboardAvoidingView
49
- keyboardVerticalOffset={-bottom + keyboardAvoidOffset}
50
- behavior={KEYBOARD_AVOID_VIEW_BEHAVIOR}
51
- >
52
- <View style={{ paddingLeft: left, paddingRight: right, backgroundColor: colors.background }}>
53
- <View style={{ justifyContent: 'center', width: '100%' }}>
54
- {inputMode === 'send' && <SendInput {...props} text={text} setText={setText} {...chatAvailableState} />}
55
- {inputMode === 'edit' && editMessage && (
56
- <EditInput
57
- {...props}
58
- text={text}
59
- setText={setText}
60
- editMessage={editMessage}
61
- setEditMessage={setEditMessage}
62
- disabled={chatAvailableState.disabled}
63
- />
64
- )}
65
- </View>
66
- <SafeAreaBottom height={bottom} />
67
- </View>
68
- </KeyboardAvoidingView>
69
- );
145
+ const useAutoFocusOnEditMode = (
146
+ textInputRef: MutableRefObject<TextInput | undefined>,
147
+ messageToEdit?: SendbirdUserMessage | SendbirdFileMessage,
148
+ ) => {
149
+ useEffect(() => {
150
+ if (messageToEdit?.isUserMessage()) {
151
+ if (!AUTO_FOCUS) setTimeout(() => textInputRef.current?.focus(), 500);
152
+ }
153
+ }, [messageToEdit]);
70
154
  };
155
+
71
156
  const SafeAreaBottom = ({ height }: { height: number }) => {
72
157
  return <View style={{ height }} />;
73
158
  };
74
159
 
160
+ const styles = createStyleSheet({
161
+ inputContainer: {
162
+ justifyContent: 'center',
163
+ width: '100%',
164
+ },
165
+ inputDefault: {
166
+ height: 56,
167
+ },
168
+ });
169
+
75
170
  export default React.memo(GroupChannelInput);