@sendbird/uikit-react-native 3.1.2 → 3.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 (337) hide show
  1. package/README.md +67 -42
  2. package/lib/commonjs/components/ChannelInput/EditInput.js +2 -11
  3. package/lib/commonjs/components/ChannelInput/EditInput.js.map +1 -1
  4. package/lib/commonjs/components/ChannelInput/MessageToReplyPreview.js +145 -0
  5. package/lib/commonjs/components/ChannelInput/MessageToReplyPreview.js.map +1 -0
  6. package/lib/commonjs/components/ChannelInput/SendInput.js +149 -323
  7. package/lib/commonjs/components/ChannelInput/SendInput.js.map +1 -1
  8. package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js +238 -0
  9. package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js.map +1 -0
  10. package/lib/commonjs/components/ChannelInput/index.js +34 -3
  11. package/lib/commonjs/components/ChannelInput/index.js.map +1 -1
  12. package/lib/commonjs/components/ChannelMessageList/index.js +148 -116
  13. package/lib/commonjs/components/ChannelMessageList/index.js.map +1 -1
  14. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js +24 -13
  15. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js.map +1 -1
  16. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js +134 -6
  17. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js.map +1 -1
  18. package/lib/commonjs/components/MessageSearchResultItem.js +1 -0
  19. package/lib/commonjs/components/MessageSearchResultItem.js.map +1 -1
  20. package/lib/commonjs/components/OpenChannelMessageRenderer/index.js +1 -0
  21. package/lib/commonjs/components/OpenChannelMessageRenderer/index.js.map +1 -1
  22. package/lib/commonjs/components/ReactionBottomSheets/ReactionUserListBottomSheet.js +2 -2
  23. package/lib/commonjs/components/ReactionBottomSheets/ReactionUserListBottomSheet.js.map +1 -1
  24. package/lib/commonjs/components/ReactionBottomSheets/index.js.map +1 -1
  25. package/lib/commonjs/components/StatusComposition.js.map +1 -1
  26. package/lib/commonjs/constants.js +5 -1
  27. package/lib/commonjs/constants.js.map +1 -1
  28. package/lib/commonjs/containers/GroupChannelPreviewContainer.js +1 -0
  29. package/lib/commonjs/containers/GroupChannelPreviewContainer.js.map +1 -1
  30. package/lib/commonjs/containers/InternalErrorBoundaryContainer.js.map +1 -1
  31. package/lib/commonjs/containers/SendbirdUIKitContainer.js +72 -34
  32. package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -1
  33. package/lib/commonjs/contexts/PlatformServiceCtx.js +16 -12
  34. package/lib/commonjs/contexts/PlatformServiceCtx.js.map +1 -1
  35. package/lib/commonjs/contexts/ReactionCtx.js +3 -2
  36. package/lib/commonjs/contexts/ReactionCtx.js.map +1 -1
  37. package/lib/commonjs/contexts/SendbirdChatCtx.js +2 -0
  38. package/lib/commonjs/contexts/SendbirdChatCtx.js.map +1 -1
  39. package/lib/commonjs/domain/groupChannel/component/GroupChannelHeader.js +14 -4
  40. package/lib/commonjs/domain/groupChannel/component/GroupChannelHeader.js.map +1 -1
  41. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +28 -42
  42. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  43. package/lib/commonjs/domain/groupChannel/module/moduleContext.js +109 -5
  44. package/lib/commonjs/domain/groupChannel/module/moduleContext.js.map +1 -1
  45. package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
  46. package/lib/commonjs/domain/userList/types.js.map +1 -1
  47. package/lib/commonjs/fragments/createGroupChannelFragment.js +34 -7
  48. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  49. package/lib/commonjs/fragments/createMessageSearchFragment.js +1 -1
  50. package/lib/commonjs/fragments/createMessageSearchFragment.js.map +1 -1
  51. package/lib/commonjs/hooks/useChannelInputItems.js +211 -0
  52. package/lib/commonjs/hooks/useChannelInputItems.js.map +1 -0
  53. package/lib/commonjs/hooks/useConnection.js +1 -1
  54. package/lib/commonjs/hooks/useConnection.js.map +1 -1
  55. package/lib/commonjs/hooks/useVoiceMessageInput.js +207 -0
  56. package/lib/commonjs/hooks/useVoiceMessageInput.js.map +1 -0
  57. package/lib/commonjs/index.js +36 -0
  58. package/lib/commonjs/index.js.map +1 -1
  59. package/lib/commonjs/libs/MentionManager.js.map +1 -1
  60. package/lib/commonjs/libs/SBUUtils.js +4 -0
  61. package/lib/commonjs/libs/SBUUtils.js.map +1 -1
  62. package/lib/commonjs/libs/VoiceMessageConfig.js +30 -0
  63. package/lib/commonjs/libs/VoiceMessageConfig.js.map +1 -0
  64. package/lib/commonjs/localization/StringSet.type.js.map +1 -1
  65. package/lib/commonjs/localization/createBaseStringSet.js +24 -9
  66. package/lib/commonjs/localization/createBaseStringSet.js.map +1 -1
  67. package/lib/commonjs/platform/createFileService.expo.js +10 -0
  68. package/lib/commonjs/platform/createFileService.expo.js.map +1 -1
  69. package/lib/commonjs/platform/createFileService.native.js +19 -0
  70. package/lib/commonjs/platform/createFileService.native.js.map +1 -1
  71. package/lib/commonjs/platform/createPlayerService.expo.js +137 -0
  72. package/lib/commonjs/platform/createPlayerService.expo.js.map +1 -0
  73. package/lib/commonjs/platform/createPlayerService.native.js +139 -0
  74. package/lib/commonjs/platform/createPlayerService.native.js.map +1 -0
  75. package/lib/commonjs/platform/createRecorderService.expo.js +158 -0
  76. package/lib/commonjs/platform/createRecorderService.expo.js.map +1 -0
  77. package/lib/commonjs/platform/createRecorderService.native.js +157 -0
  78. package/lib/commonjs/platform/createRecorderService.native.js.map +1 -0
  79. package/lib/commonjs/platform/types.js.map +1 -1
  80. package/lib/commonjs/types.js +7 -0
  81. package/lib/commonjs/types.js.map +1 -1
  82. package/lib/commonjs/utils/promise.js +138 -0
  83. package/lib/commonjs/utils/promise.js.map +1 -0
  84. package/lib/commonjs/version.js +1 -1
  85. package/lib/commonjs/version.js.map +1 -1
  86. package/lib/module/components/ChannelInput/EditInput.js +3 -12
  87. package/lib/module/components/ChannelInput/EditInput.js.map +1 -1
  88. package/lib/module/components/ChannelInput/MessageToReplyPreview.js +137 -0
  89. package/lib/module/components/ChannelInput/MessageToReplyPreview.js.map +1 -0
  90. package/lib/module/components/ChannelInput/SendInput.js +152 -326
  91. package/lib/module/components/ChannelInput/SendInput.js.map +1 -1
  92. package/lib/module/components/ChannelInput/VoiceMessageInput.js +228 -0
  93. package/lib/module/components/ChannelInput/VoiceMessageInput.js.map +1 -0
  94. package/lib/module/components/ChannelInput/index.js +36 -5
  95. package/lib/module/components/ChannelInput/index.js.map +1 -1
  96. package/lib/module/components/ChannelMessageList/index.js +149 -117
  97. package/lib/module/components/ChannelMessageList/index.js.map +1 -1
  98. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js +24 -13
  99. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js.map +1 -1
  100. package/lib/module/components/GroupChannelMessageRenderer/index.js +132 -7
  101. package/lib/module/components/GroupChannelMessageRenderer/index.js.map +1 -1
  102. package/lib/module/components/MessageSearchResultItem.js +2 -1
  103. package/lib/module/components/MessageSearchResultItem.js.map +1 -1
  104. package/lib/module/components/OpenChannelMessageRenderer/index.js +1 -0
  105. package/lib/module/components/OpenChannelMessageRenderer/index.js.map +1 -1
  106. package/lib/module/components/ReactionBottomSheets/ReactionUserListBottomSheet.js +2 -2
  107. package/lib/module/components/ReactionBottomSheets/ReactionUserListBottomSheet.js.map +1 -1
  108. package/lib/module/components/ReactionBottomSheets/index.js.map +1 -1
  109. package/lib/module/components/StatusComposition.js.map +1 -1
  110. package/lib/module/constants.js +2 -0
  111. package/lib/module/constants.js.map +1 -1
  112. package/lib/module/containers/GroupChannelPreviewContainer.js +2 -1
  113. package/lib/module/containers/GroupChannelPreviewContainer.js.map +1 -1
  114. package/lib/module/containers/InternalErrorBoundaryContainer.js.map +1 -1
  115. package/lib/module/containers/SendbirdUIKitContainer.js +74 -36
  116. package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -1
  117. package/lib/module/contexts/PlatformServiceCtx.js +14 -11
  118. package/lib/module/contexts/PlatformServiceCtx.js.map +1 -1
  119. package/lib/module/contexts/ReactionCtx.js +3 -2
  120. package/lib/module/contexts/ReactionCtx.js.map +1 -1
  121. package/lib/module/contexts/SendbirdChatCtx.js +2 -0
  122. package/lib/module/contexts/SendbirdChatCtx.js.map +1 -1
  123. package/lib/module/domain/groupChannel/component/GroupChannelHeader.js +15 -5
  124. package/lib/module/domain/groupChannel/component/GroupChannelHeader.js.map +1 -1
  125. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +29 -43
  126. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  127. package/lib/module/domain/groupChannel/module/moduleContext.js +111 -7
  128. package/lib/module/domain/groupChannel/module/moduleContext.js.map +1 -1
  129. package/lib/module/domain/groupChannel/types.js.map +1 -1
  130. package/lib/module/domain/userList/types.js.map +1 -1
  131. package/lib/module/fragments/createGroupChannelFragment.js +36 -9
  132. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  133. package/lib/module/fragments/createMessageSearchFragment.js +1 -1
  134. package/lib/module/fragments/createMessageSearchFragment.js.map +1 -1
  135. package/lib/module/hooks/useChannelInputItems.js +203 -0
  136. package/lib/module/hooks/useChannelInputItems.js.map +1 -0
  137. package/lib/module/hooks/useConnection.js +1 -1
  138. package/lib/module/hooks/useConnection.js.map +1 -1
  139. package/lib/module/hooks/useVoiceMessageInput.js +199 -0
  140. package/lib/module/hooks/useVoiceMessageInput.js.map +1 -0
  141. package/lib/module/index.js +8 -0
  142. package/lib/module/index.js.map +1 -1
  143. package/lib/module/libs/MentionManager.js.map +1 -1
  144. package/lib/module/libs/SBUUtils.js +4 -0
  145. package/lib/module/libs/SBUUtils.js.map +1 -1
  146. package/lib/module/libs/VoiceMessageConfig.js +23 -0
  147. package/lib/module/libs/VoiceMessageConfig.js.map +1 -0
  148. package/lib/module/localization/StringSet.type.js.map +1 -1
  149. package/lib/module/localization/createBaseStringSet.js +25 -10
  150. package/lib/module/localization/createBaseStringSet.js.map +1 -1
  151. package/lib/module/platform/createFileService.expo.js +10 -0
  152. package/lib/module/platform/createFileService.expo.js.map +1 -1
  153. package/lib/module/platform/createFileService.native.js +19 -0
  154. package/lib/module/platform/createFileService.native.js.map +1 -1
  155. package/lib/module/platform/createPlayerService.expo.js +129 -0
  156. package/lib/module/platform/createPlayerService.expo.js.map +1 -0
  157. package/lib/module/platform/createPlayerService.native.js +132 -0
  158. package/lib/module/platform/createPlayerService.native.js.map +1 -0
  159. package/lib/module/platform/createRecorderService.expo.js +150 -0
  160. package/lib/module/platform/createRecorderService.expo.js.map +1 -0
  161. package/lib/module/platform/createRecorderService.native.js +149 -0
  162. package/lib/module/platform/createRecorderService.native.js.map +1 -0
  163. package/lib/module/platform/types.js.map +1 -1
  164. package/lib/module/types.js +5 -1
  165. package/lib/module/types.js.map +1 -1
  166. package/lib/module/utils/promise.js +132 -0
  167. package/lib/module/utils/promise.js.map +1 -0
  168. package/lib/module/version.js +1 -1
  169. package/lib/module/version.js.map +1 -1
  170. package/lib/typescript/src/components/ChannelCover.d.ts +2 -1
  171. package/lib/typescript/src/components/ChannelInput/AttachmentsButton.d.ts +2 -1
  172. package/lib/typescript/src/components/ChannelInput/MessageToReplyPreview.d.ts +7 -0
  173. package/lib/typescript/src/components/ChannelInput/VoiceMessageInput.d.ts +11 -0
  174. package/lib/typescript/src/components/ChannelInput/index.d.ts +9 -3
  175. package/lib/typescript/src/components/ChannelMessageList/index.d.ts +4 -1
  176. package/lib/typescript/src/components/FileViewer.d.ts +2 -1
  177. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageDateSeparator.d.ts +2 -1
  178. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageFocusAnimation.d.ts +1 -1
  179. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageOutgoingStatus.d.ts +1 -1
  180. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.d.ts +4 -2
  181. package/lib/typescript/src/components/GroupChannelMessageRenderer/index.d.ts +3 -0
  182. package/lib/typescript/src/components/NewMessagesButton.d.ts +1 -1
  183. package/lib/typescript/src/components/OpenChannelMessageRenderer/OpenChannelMessageDateSeparator.d.ts +2 -1
  184. package/lib/typescript/src/components/OpenChannelMessageRenderer/index.d.ts +2 -0
  185. package/lib/typescript/src/components/ProviderLayout.d.ts +1 -1
  186. package/lib/typescript/src/components/ReactionAddons/BottomSheetReactionAddon.d.ts +2 -1
  187. package/lib/typescript/src/components/ReactionAddons/MessageReactionAddon.d.ts +2 -1
  188. package/lib/typescript/src/components/ReactionAddons/ReactionRoundedButton.d.ts +3 -2
  189. package/lib/typescript/src/components/ReactionAddons/index.d.ts +3 -2
  190. package/lib/typescript/src/components/ReactionBottomSheets/ReactionListBottomSheet.d.ts +2 -1
  191. package/lib/typescript/src/components/ReactionBottomSheets/ReactionUserListBottomSheet.d.ts +2 -1
  192. package/lib/typescript/src/components/ReactionBottomSheets/index.d.ts +4 -4
  193. package/lib/typescript/src/components/ScrollToBottomButton.d.ts +1 -1
  194. package/lib/typescript/src/components/StatusComposition.d.ts +4 -4
  195. package/lib/typescript/src/components/TypedPlaceholder.d.ts +2 -1
  196. package/lib/typescript/src/components/UserActionBar.d.ts +2 -1
  197. package/lib/typescript/src/components/UserSelectableBar.d.ts +2 -1
  198. package/lib/typescript/src/constants.d.ts +2 -0
  199. package/lib/typescript/src/containers/GroupChannelPreviewContainer.d.ts +2 -1
  200. package/lib/typescript/src/containers/InternalErrorBoundaryContainer.d.ts +3 -3
  201. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +19 -8
  202. package/lib/typescript/src/contexts/LocalizationCtx.d.ts +1 -1
  203. package/lib/typescript/src/contexts/PlatformServiceCtx.d.ts +8 -8
  204. package/lib/typescript/src/contexts/ReactionCtx.d.ts +5 -2
  205. package/lib/typescript/src/contexts/SendbirdChatCtx.d.ts +6 -3
  206. package/lib/typescript/src/contexts/UserProfileCtx.d.ts +1 -1
  207. package/lib/typescript/src/domain/groupChannel/component/GroupChannelHeader.d.ts +2 -1
  208. package/lib/typescript/src/domain/groupChannel/component/GroupChannelInput.d.ts +1 -1
  209. package/lib/typescript/src/domain/groupChannel/component/GroupChannelMessageList.d.ts +1 -1
  210. package/lib/typescript/src/domain/groupChannel/component/GroupChannelStatusEmpty.d.ts +2 -1
  211. package/lib/typescript/src/domain/groupChannel/component/GroupChannelStatusLoading.d.ts +2 -1
  212. package/lib/typescript/src/domain/groupChannel/component/GroupChannelSuggestedMentionList.d.ts +2 -1
  213. package/lib/typescript/src/domain/groupChannel/types.d.ts +48 -0
  214. package/lib/typescript/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersHeader.d.ts +2 -1
  215. package/lib/typescript/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.d.ts +2 -1
  216. package/lib/typescript/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersStatusEmpty.d.ts +2 -1
  217. package/lib/typescript/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersStatusLoading.d.ts +2 -1
  218. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListHeader.d.ts +2 -1
  219. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListList.d.ts +2 -1
  220. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListStatusEmpty.d.ts +2 -1
  221. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListStatusLoading.d.ts +2 -1
  222. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListTypeSelector.d.ts +2 -1
  223. package/lib/typescript/src/domain/groupChannelModeration/component/GroupChannelModerationHeader.d.ts +2 -1
  224. package/lib/typescript/src/domain/groupChannelModeration/component/GroupChannelModerationMenu.d.ts +2 -1
  225. package/lib/typescript/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersHeader.d.ts +2 -1
  226. package/lib/typescript/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.d.ts +2 -1
  227. package/lib/typescript/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersStatusEmpty.d.ts +2 -1
  228. package/lib/typescript/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersStatusLoading.d.ts +2 -1
  229. package/lib/typescript/src/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.d.ts +2 -1
  230. package/lib/typescript/src/domain/groupChannelNotifications/component/GroupChannelNotificationsView.d.ts +2 -1
  231. package/lib/typescript/src/domain/groupChannelOperators/component/GroupChannelOperatorsHeader.d.ts +2 -1
  232. package/lib/typescript/src/domain/groupChannelOperators/component/GroupChannelOperatorsList.d.ts +2 -1
  233. package/lib/typescript/src/domain/groupChannelOperators/component/GroupChannelOperatorsStatusEmpty.d.ts +2 -1
  234. package/lib/typescript/src/domain/groupChannelOperators/component/GroupChannelOperatorsStatusLoading.d.ts +2 -1
  235. package/lib/typescript/src/domain/groupChannelSettings/component/GroupChannelSettingsHeader.d.ts +2 -1
  236. package/lib/typescript/src/domain/groupChannelSettings/component/GroupChannelSettingsInfo.d.ts +2 -1
  237. package/lib/typescript/src/domain/groupChannelSettings/component/GroupChannelSettingsMenu.d.ts +2 -1
  238. package/lib/typescript/src/domain/messageSearch/component/MessageSearchHeader.d.ts +2 -1
  239. package/lib/typescript/src/domain/messageSearch/component/MessageSearchList.d.ts +2 -1
  240. package/lib/typescript/src/domain/messageSearch/component/MessageSearchStatusEmpty.d.ts +2 -1
  241. package/lib/typescript/src/domain/messageSearch/component/MessageSearchStatusLoading.d.ts +2 -1
  242. package/lib/typescript/src/domain/openChannel/component/OpenChannelHeader.d.ts +2 -2
  243. package/lib/typescript/src/domain/openChannel/component/OpenChannelInput.d.ts +1 -1
  244. package/lib/typescript/src/domain/openChannel/component/OpenChannelMessageList.d.ts +1 -1
  245. package/lib/typescript/src/domain/openChannel/component/OpenChannelStatusEmpty.d.ts +2 -1
  246. package/lib/typescript/src/domain/openChannel/component/OpenChannelStatusLoading.d.ts +2 -1
  247. package/lib/typescript/src/domain/openChannelBannedUsers/component/OpenChannelBannedUsersHeader.d.ts +2 -1
  248. package/lib/typescript/src/domain/openChannelBannedUsers/component/OpenChannelBannedUsersList.d.ts +2 -1
  249. package/lib/typescript/src/domain/openChannelBannedUsers/component/OpenChannelBannedUsersStatusEmpty.d.ts +2 -1
  250. package/lib/typescript/src/domain/openChannelBannedUsers/component/OpenChannelBannedUsersStatusLoading.d.ts +2 -1
  251. package/lib/typescript/src/domain/openChannelCreate/component/OpenChannelCreateHeader.d.ts +2 -1
  252. package/lib/typescript/src/domain/openChannelCreate/component/OpenChannelCreateProfileInput.d.ts +2 -1
  253. package/lib/typescript/src/domain/openChannelCreate/component/OpenChannelCreateStatusLoading.d.ts +2 -1
  254. package/lib/typescript/src/domain/openChannelList/component/OpenChannelListHeader.d.ts +2 -1
  255. package/lib/typescript/src/domain/openChannelList/component/OpenChannelListList.d.ts +2 -1
  256. package/lib/typescript/src/domain/openChannelList/component/OpenChannelListStatusEmpty.d.ts +2 -1
  257. package/lib/typescript/src/domain/openChannelList/component/OpenChannelListStatusLoading.d.ts +2 -1
  258. package/lib/typescript/src/domain/openChannelModeration/component/OpenChannelModerationHeader.d.ts +2 -1
  259. package/lib/typescript/src/domain/openChannelModeration/component/OpenChannelModerationMenu.d.ts +2 -1
  260. package/lib/typescript/src/domain/openChannelMutedParticipants/component/OpenChannelMutedParticipantsHeader.d.ts +2 -1
  261. package/lib/typescript/src/domain/openChannelMutedParticipants/component/OpenChannelMutedParticipantsList.d.ts +2 -1
  262. package/lib/typescript/src/domain/openChannelMutedParticipants/component/OpenChannelMutedParticipantsStatusEmpty.d.ts +2 -1
  263. package/lib/typescript/src/domain/openChannelMutedParticipants/component/OpenChannelMutedParticipantsStatusLoading.d.ts +2 -1
  264. package/lib/typescript/src/domain/openChannelOperators/component/OpenChannelOperatorsHeader.d.ts +2 -1
  265. package/lib/typescript/src/domain/openChannelOperators/component/OpenChannelOperatorsList.d.ts +2 -1
  266. package/lib/typescript/src/domain/openChannelOperators/component/OpenChannelOperatorsStatusEmpty.d.ts +2 -1
  267. package/lib/typescript/src/domain/openChannelOperators/component/OpenChannelOperatorsStatusLoading.d.ts +2 -1
  268. package/lib/typescript/src/domain/openChannelSettings/component/OpenChannelSettingsHeader.d.ts +2 -1
  269. package/lib/typescript/src/domain/openChannelSettings/component/OpenChannelSettingsInfo.d.ts +2 -1
  270. package/lib/typescript/src/domain/openChannelSettings/component/OpenChannelSettingsMenu.d.ts +2 -1
  271. package/lib/typescript/src/domain/userList/component/UserListHeader.d.ts +3 -3
  272. package/lib/typescript/src/domain/userList/component/UserListList.d.ts +1 -1
  273. package/lib/typescript/src/domain/userList/component/UserListStatusEmpty.d.ts +2 -1
  274. package/lib/typescript/src/domain/userList/component/UserListStatusLoading.d.ts +2 -1
  275. package/lib/typescript/src/domain/userList/types.d.ts +2 -2
  276. package/lib/typescript/src/hooks/useChannelInputItems.d.ts +10 -0
  277. package/lib/typescript/src/hooks/useVoiceMessageInput.d.ts +53 -0
  278. package/lib/typescript/src/index.d.ts +4 -0
  279. package/lib/typescript/src/libs/MentionManager.d.ts +2 -1
  280. package/lib/typescript/src/libs/SBUUtils.d.ts +1 -0
  281. package/lib/typescript/src/libs/VoiceMessageConfig.d.ts +25 -0
  282. package/lib/typescript/src/localization/StringSet.type.d.ts +7 -0
  283. package/lib/typescript/src/platform/createPlayerService.expo.d.ts +7 -0
  284. package/lib/typescript/src/platform/createPlayerService.native.d.ts +9 -0
  285. package/lib/typescript/src/platform/createRecorderService.expo.d.ts +7 -0
  286. package/lib/typescript/src/platform/createRecorderService.native.d.ts +9 -0
  287. package/lib/typescript/src/platform/types.d.ts +100 -1
  288. package/lib/typescript/src/types.d.ts +5 -1
  289. package/lib/typescript/src/utils/promise.d.ts +7 -0
  290. package/lib/typescript/src/version.d.ts +1 -1
  291. package/package.json +10 -12
  292. package/src/components/ChannelInput/EditInput.tsx +3 -15
  293. package/src/components/ChannelInput/MessageToReplyPreview.tsx +133 -0
  294. package/src/components/ChannelInput/SendInput.tsx +131 -329
  295. package/src/components/ChannelInput/VoiceMessageInput.tsx +206 -0
  296. package/src/components/ChannelInput/index.tsx +37 -6
  297. package/src/components/ChannelMessageList/index.tsx +145 -113
  298. package/src/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.tsx +24 -11
  299. package/src/components/GroupChannelMessageRenderer/index.tsx +113 -4
  300. package/src/components/MessageSearchResultItem.tsx +2 -1
  301. package/src/components/OpenChannelMessageRenderer/index.tsx +1 -0
  302. package/src/components/ReactionBottomSheets/ReactionUserListBottomSheet.tsx +2 -2
  303. package/src/components/ReactionBottomSheets/index.tsx +3 -2
  304. package/src/components/StatusComposition.tsx +3 -3
  305. package/src/constants.ts +2 -0
  306. package/src/containers/GroupChannelPreviewContainer.tsx +2 -0
  307. package/src/containers/InternalErrorBoundaryContainer.tsx +1 -1
  308. package/src/containers/SendbirdUIKitContainer.tsx +103 -59
  309. package/src/contexts/PlatformServiceCtx.tsx +22 -20
  310. package/src/contexts/ReactionCtx.tsx +7 -5
  311. package/src/contexts/SendbirdChatCtx.tsx +10 -2
  312. package/src/domain/groupChannel/component/GroupChannelHeader.tsx +14 -3
  313. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +30 -43
  314. package/src/domain/groupChannel/module/moduleContext.tsx +119 -7
  315. package/src/domain/groupChannel/types.ts +45 -0
  316. package/src/domain/userList/types.ts +2 -2
  317. package/src/fragments/createGroupChannelFragment.tsx +43 -8
  318. package/src/fragments/createMessageSearchFragment.tsx +1 -1
  319. package/src/hooks/useChannelInputItems.ts +215 -0
  320. package/src/hooks/useConnection.ts +1 -1
  321. package/src/hooks/useVoiceMessageInput.ts +237 -0
  322. package/src/index.ts +9 -1
  323. package/src/libs/MentionManager.tsx +1 -1
  324. package/src/libs/SBUUtils.ts +5 -0
  325. package/src/libs/VoiceMessageConfig.ts +28 -0
  326. package/src/localization/StringSet.type.ts +8 -0
  327. package/src/localization/createBaseStringSet.ts +27 -11
  328. package/src/platform/createFileService.expo.ts +10 -0
  329. package/src/platform/createFileService.native.ts +19 -0
  330. package/src/platform/createPlayerService.expo.tsx +142 -0
  331. package/src/platform/createPlayerService.native.tsx +148 -0
  332. package/src/platform/createRecorderService.expo.tsx +160 -0
  333. package/src/platform/createRecorderService.native.tsx +170 -0
  334. package/src/platform/types.ts +114 -1
  335. package/src/types.ts +6 -1
  336. package/src/utils/promise.ts +139 -0
  337. package/src/version.ts +1 -1
@@ -12,6 +12,7 @@ import {
12
12
  } from '@sendbird/uikit-react-native-foundation';
13
13
  import {
14
14
  SendbirdFileMessage,
15
+ SendbirdGroupChannel,
15
16
  SendbirdMessage,
16
17
  SendbirdUserMessage,
17
18
  getFileIconFromMessageType,
@@ -26,12 +27,13 @@ import { useLocalization, usePlatformService, useSendbirdChat } from '../../hook
26
27
 
27
28
  type Props = {
28
29
  variant: 'outgoing' | 'incoming';
30
+ channel: SendbirdGroupChannel;
29
31
  message: SendbirdUserMessage | SendbirdFileMessage;
30
32
  childMessage: SendbirdUserMessage | SendbirdFileMessage;
31
33
  onPress?: (message: SendbirdMessage) => void;
32
34
  };
33
35
 
34
- const GroupChannelMessageParentMessage = ({ variant, message, childMessage, onPress }: Props) => {
36
+ const GroupChannelMessageParentMessage = ({ variant, channel, message, childMessage, onPress }: Props) => {
35
37
  const { currentUser } = useSendbirdChat();
36
38
  const groupChannelPubSub = useContext(GroupChannelContexts.PubSub);
37
39
  const { select, colors, palette } = useUIKitTheme();
@@ -52,6 +54,19 @@ const GroupChannelMessageParentMessage = ({ variant, message, childMessage, onPr
52
54
  });
53
55
  }, []);
54
56
 
57
+ const renderMessageWithText = (message: string) => {
58
+ return (
59
+ <Box
60
+ style={styles.bubbleContainer}
61
+ backgroundColor={select({ light: palette.background100, dark: palette.background400 })}
62
+ >
63
+ <Text body3 color={colors.onBackground03} suppressHighlighting numberOfLines={2} ellipsizeMode={'tail'}>
64
+ {message}
65
+ </Text>
66
+ </Box>
67
+ );
68
+ };
69
+
55
70
  const renderFileMessageAsVideoThumbnail = (url: string) => {
56
71
  return (
57
72
  <VideoThumbnail
@@ -85,19 +100,14 @@ const GroupChannelMessageParentMessage = ({ variant, message, childMessage, onPr
85
100
  };
86
101
 
87
102
  const parentMessageComponent = useIIFE(() => {
103
+ if (channel.messageOffsetTimestamp > parentMessage.createdAt) {
104
+ return renderMessageWithText(STRINGS.LABELS.MESSAGE_UNAVAILABLE);
105
+ }
106
+
88
107
  switch (type) {
89
108
  case 'user':
90
109
  case 'user.opengraph': {
91
- return (
92
- <Box
93
- style={styles.bubbleContainer}
94
- backgroundColor={select({ light: palette.background100, dark: palette.background400 })}
95
- >
96
- <Text body3 color={colors.onBackground03} suppressHighlighting numberOfLines={2} ellipsizeMode={'tail'}>
97
- {(parentMessage as SendbirdUserMessage).message}
98
- </Text>
99
- </Box>
100
- );
110
+ return renderMessageWithText((parentMessage as SendbirdUserMessage).message);
101
111
  }
102
112
  case 'file':
103
113
  case 'file.audio': {
@@ -109,6 +119,9 @@ const GroupChannelMessageParentMessage = ({ variant, message, childMessage, onPr
109
119
  case 'file.image': {
110
120
  return renderFileMessageAsPreview(getThumbnailUriFromFileMessage(parentMessage as SendbirdFileMessage));
111
121
  }
122
+ case 'file.voice': {
123
+ return renderMessageWithText(STRINGS.LABELS.VOICE_MESSAGE);
124
+ }
112
125
  default: {
113
126
  return null;
114
127
  }
@@ -1,7 +1,13 @@
1
- import React from 'react';
1
+ import React, { useContext, useEffect, useRef } from 'react';
2
2
 
3
3
  import type { GroupChannelMessageProps, RegexTextPattern } from '@sendbird/uikit-react-native-foundation';
4
- import { Box, GroupChannelMessage, Text, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
4
+ import {
5
+ Box,
6
+ GroupChannelMessage,
7
+ Text,
8
+ TypingIndicatorBubble,
9
+ useUIKitTheme,
10
+ } from '@sendbird/uikit-react-native-foundation';
5
11
  import {
6
12
  SendbirdAdminMessage,
7
13
  SendbirdFileMessage,
@@ -10,14 +16,18 @@ import {
10
16
  calcMessageGrouping,
11
17
  getMessageType,
12
18
  isMyMessage,
19
+ isVoiceMessage,
13
20
  shouldRenderParentMessage,
14
21
  shouldRenderReaction,
15
22
  useIIFE,
16
23
  } from '@sendbird/uikit-utils';
17
24
 
25
+ import { VOICE_MESSAGE_META_ARRAY_DURATION_KEY } from '../../constants';
26
+ import { GroupChannelContexts } from '../../domain/groupChannel/module/moduleContext';
18
27
  import type { GroupChannelProps } from '../../domain/groupChannel/types';
19
28
  import { useLocalization, usePlatformService, useSendbirdChat } from '../../hooks/useContext';
20
29
  import SBUUtils from '../../libs/SBUUtils';
30
+ import { TypingIndicatorType } from '../../types';
21
31
  import { ReactionAddons } from '../ReactionAddons';
22
32
  import GroupChannelMessageDateSeparator from './GroupChannelMessageDateSeparator';
23
33
  import GroupChannelMessageFocusAnimation from './GroupChannelMessageFocusAnimation';
@@ -36,10 +46,11 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
36
46
  prevMessage,
37
47
  nextMessage,
38
48
  }) => {
49
+ const playerUnsubscribes = useRef<(() => void)[]>([]);
39
50
  const { palette } = useUIKitTheme();
40
51
  const { sbOptions, currentUser, mentionManager } = useSendbirdChat();
41
52
  const { STRINGS } = useLocalization();
42
- const { mediaService } = usePlatformService();
53
+ const { mediaService, playerService } = usePlatformService();
43
54
  const { groupWithPrev, groupWithNext } = calcMessageGrouping(
44
55
  Boolean(enableMessageGrouping),
45
56
  message,
@@ -58,6 +69,16 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
58
69
  return null;
59
70
  });
60
71
 
72
+ const resetPlayer = async () => {
73
+ playerUnsubscribes.current.forEach((unsubscribe) => {
74
+ try {
75
+ unsubscribe();
76
+ } catch {}
77
+ });
78
+ playerUnsubscribes.current.length = 0;
79
+ await playerService.reset();
80
+ };
81
+
61
82
  const variant = isMyMessage(message, currentUser?.userId) ? 'outgoing' : 'incoming';
62
83
 
63
84
  const messageProps: Omit<GroupChannelMessageProps<SendbirdMessage>, 'message'> = {
@@ -72,6 +93,55 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
72
93
  onPressMentionedUser: (mentionedUser) => {
73
94
  if (mentionedUser) onShowUserProfile?.(mentionedUser);
74
95
  },
96
+ onToggleVoiceMessage: async (state, setState) => {
97
+ if (isVoiceMessage(message) && message.sendingStatus === 'succeeded') {
98
+ if (playerService.uri === message.url) {
99
+ if (playerService.state === 'playing') {
100
+ await playerService.pause();
101
+ } else {
102
+ await playerService.play(message.url);
103
+ }
104
+ } else {
105
+ if (playerService.state !== 'idle') {
106
+ await resetPlayer();
107
+ }
108
+
109
+ const shouldSeekToTime = state.duration > state.currentTime && state.currentTime > 0;
110
+ let seekFinished = !shouldSeekToTime;
111
+
112
+ const forPlayback = playerService.addPlaybackListener(({ stopped, currentTime, duration }) => {
113
+ if (seekFinished) {
114
+ setState((prevState) => ({ ...prevState, currentTime: stopped ? 0 : currentTime, duration }));
115
+ }
116
+ });
117
+ const forState = playerService.addStateListener((state) => {
118
+ switch (state) {
119
+ case 'preparing':
120
+ setState((prevState) => ({ ...prevState, status: 'preparing' }));
121
+ break;
122
+ case 'playing':
123
+ setState((prevState) => ({ ...prevState, status: 'playing' }));
124
+ break;
125
+ case 'idle':
126
+ case 'paused': {
127
+ setState((prevState) => ({ ...prevState, status: 'paused' }));
128
+ break;
129
+ }
130
+ case 'stopped':
131
+ setState((prevState) => ({ ...prevState, status: 'paused' }));
132
+ break;
133
+ }
134
+ });
135
+ playerUnsubscribes.current.push(forPlayback, forState);
136
+
137
+ await playerService.play(message.url);
138
+ if (shouldSeekToTime) {
139
+ await playerService.seek(state.currentTime);
140
+ seekFinished = true;
141
+ }
142
+ }
143
+ }
144
+ },
75
145
  groupedWithPrev: groupWithPrev,
76
146
  groupedWithNext: groupWithNext,
77
147
  children: reactionChildren,
@@ -80,9 +150,10 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
80
150
  ) : null,
81
151
  parentMessage: shouldRenderParentMessage(message) ? (
82
152
  <GroupChannelMessageParentMessage
153
+ channel={channel}
154
+ message={message.parentMessage}
83
155
  variant={variant}
84
156
  childMessage={message}
85
- message={message.parentMessage}
86
157
  onPress={onPressParentMessage}
87
158
  />
88
159
  ) : null,
@@ -184,6 +255,20 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
184
255
  />
185
256
  );
186
257
  }
258
+ case 'file.voice': {
259
+ return (
260
+ <GroupChannelMessage.VoiceFile
261
+ message={message as SendbirdFileMessage}
262
+ durationMetaArrayKey={VOICE_MESSAGE_META_ARRAY_DURATION_KEY}
263
+ onUnmount={() => {
264
+ if (isVoiceMessage(message) && playerService.uri === message.url) {
265
+ resetPlayer();
266
+ }
267
+ }}
268
+ {...messageProps}
269
+ />
270
+ );
271
+ }
187
272
  case 'unknown':
188
273
  default: {
189
274
  return <GroupChannelMessage.Unknown message={message} {...messageProps} />;
@@ -215,4 +300,28 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
215
300
  );
216
301
  };
217
302
 
303
+ export const GroupChannelTypingIndicatorBubble = () => {
304
+ const { sbOptions } = useSendbirdChat();
305
+ const { publish } = useContext(GroupChannelContexts.PubSub);
306
+ const { typingUsers } = useContext(GroupChannelContexts.TypingIndicator);
307
+
308
+ const shouldRenderBubble = useIIFE(() => {
309
+ if (typingUsers.length === 0) return false;
310
+ if (!sbOptions.uikit.groupChannel.channel.enableTypingIndicator) return false;
311
+ if (!sbOptions.uikit.groupChannel.channel.typingIndicatorTypes.has(TypingIndicatorType.Bubble)) return false;
312
+ return true;
313
+ });
314
+
315
+ useEffect(() => {
316
+ if (shouldRenderBubble) publish({ type: 'TYPING_BUBBLE_RENDERED' });
317
+ }, [shouldRenderBubble]);
318
+
319
+ if (!shouldRenderBubble) return null;
320
+ return (
321
+ <Box paddingHorizontal={16} marginTop={4} marginBottom={16}>
322
+ <TypingIndicatorBubble typingUsers={typingUsers} />
323
+ </Box>
324
+ );
325
+ };
326
+
218
327
  export default React.memo(GroupChannelMessageRenderer);
@@ -10,7 +10,7 @@ import {
10
10
  useUIKitTheme,
11
11
  } from '@sendbird/uikit-react-native-foundation';
12
12
  import type { SendbirdBaseMessage } from '@sendbird/uikit-utils';
13
- import { getFileIconFromMessage, useIIFE } from '@sendbird/uikit-utils';
13
+ import { getFileIconFromMessage, isVoiceMessage, useIIFE } from '@sendbird/uikit-utils';
14
14
 
15
15
  import type { MessageSearchProps } from '../domain/messageSearch/types';
16
16
  import { useLocalization } from '../hooks/useContext';
@@ -21,6 +21,7 @@ const MessageSearchResultItem: MessageSearchProps['List']['renderSearchResultIte
21
21
 
22
22
  const fileIcon = useIIFE(() => {
23
23
  if (!message?.isFileMessage()) return undefined;
24
+ if (isVoiceMessage(message)) return undefined;
24
25
  return getFileIconFromMessage(message);
25
26
  });
26
27
 
@@ -63,6 +63,7 @@ const OpenChannelMessageRenderer: OpenChannelProps['Fragment']['renderMessage']
63
63
  }
64
64
  }
65
65
  case 'file':
66
+ case 'file.voice':
66
67
  case 'file.audio': {
67
68
  return <OpenChannelMessage.File message={message as SendbirdFileMessage} {...messageProps} />;
68
69
  }
@@ -22,7 +22,7 @@ const ReactionUserListBottomSheet = ({
22
22
  reactionCtx,
23
23
  chatCtx,
24
24
  localizationCtx,
25
- userProfileCtx,
25
+ onPressUserProfile,
26
26
  }: ReactionBottomSheetProps) => {
27
27
  const { width } = useWindowDimensions();
28
28
  const { bottom, left, right } = useSafeAreaInsets();
@@ -134,7 +134,7 @@ const ReactionUserListBottomSheet = ({
134
134
  onPress={async () => {
135
135
  if (user) {
136
136
  await onClose();
137
- userProfileCtx.show(user);
137
+ onPressUserProfile(user);
138
138
  }
139
139
  }}
140
140
  style={styles.pageItem}
@@ -1,9 +1,10 @@
1
1
  import type React from 'react';
2
2
 
3
+ import type { SendbirdMember, SendbirdUser } from '@sendbird/uikit-utils';
4
+
3
5
  import type { LocalizationContext } from '../../contexts/LocalizationCtx';
4
6
  import type { ReactionContext } from '../../contexts/ReactionCtx';
5
7
  import type { SendbirdChatContext } from '../../contexts/SendbirdChatCtx';
6
- import type { UserProfileContext } from '../../contexts/UserProfileCtx';
7
8
  import ReactionList from './ReactionListBottomSheet';
8
9
  import UserList from './ReactionUserListBottomSheet';
9
10
 
@@ -12,10 +13,10 @@ export type ReactionBottomSheetProps = {
12
13
  visible: boolean;
13
14
  onDismiss: () => void;
14
15
  onClose: () => Promise<void>;
16
+ onPressUserProfile: (user: SendbirdUser | SendbirdMember) => void;
15
17
  chatCtx: GetFromContext<typeof SendbirdChatContext>;
16
18
  reactionCtx: GetFromContext<typeof ReactionContext>;
17
19
  localizationCtx: GetFromContext<typeof LocalizationContext>;
18
- userProfileCtx: GetFromContext<typeof UserProfileContext>;
19
20
  };
20
21
 
21
22
  export const ReactionBottomSheets = {
@@ -1,10 +1,10 @@
1
- import React from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
 
3
3
  type Props = {
4
4
  loading?: boolean;
5
- LoadingComponent?: JSX.Element;
5
+ LoadingComponent?: ReactNode;
6
6
  error?: boolean;
7
- ErrorComponent?: JSX.Element;
7
+ ErrorComponent?: ReactNode;
8
8
  children: React.ReactNode;
9
9
  };
10
10
  const StatusComposition = ({ children, error, ErrorComponent, LoadingComponent, loading }: Props) => {
package/src/constants.ts CHANGED
@@ -3,3 +3,5 @@ export const MESSAGE_SEARCH_SAFE_SCROLL_DELAY = 500;
3
3
  export const MESSAGE_FOCUS_ANIMATION_DELAY = 250;
4
4
 
5
5
  export const UNKNOWN_USER_ID = '##__USER_ID_IS_NOT_PROVIDED__##';
6
+ export const VOICE_MESSAGE_META_ARRAY_DURATION_KEY = 'KEY_VOICE_MESSAGE_DURATION';
7
+ export const VOICE_MESSAGE_META_ARRAY_MESSAGE_TYPE_KEY = 'KEY_INTERNAL_MESSAGE_TYPE';
@@ -17,6 +17,7 @@ import {
17
17
  getFileTypeFromMessage,
18
18
  isDifferentChannel,
19
19
  isMyMessage,
20
+ isVoiceMessage,
20
21
  useIIFE,
21
22
  useUniqHandlerId,
22
23
  } from '@sendbird/uikit-utils';
@@ -56,6 +57,7 @@ const GroupChannelPreviewContainer = ({ onPress, onLongPress, channel }: Props)
56
57
  const fileType = useIIFE(() => {
57
58
  if (!channel.lastMessage?.isFileMessage()) return undefined;
58
59
  if (typingUsers.length > 0) return undefined;
60
+ if (isVoiceMessage(channel.lastMessage)) return undefined;
59
61
  return getFileTypeFromMessage(channel.lastMessage);
60
62
  });
61
63
 
@@ -14,7 +14,7 @@ const DefaultErrorBoundaryComponent = (props: ErrorBoundaryProps) => {
14
14
 
15
15
  class InternalErrorBoundaryContainer extends React.PureComponent<{
16
16
  onError?: (props: ErrorBoundaryProps) => void;
17
- ErrorInfoComponent?: (props: ErrorBoundaryProps) => JSX.Element;
17
+ ErrorInfoComponent?: (props: ErrorBoundaryProps) => React.ReactNode;
18
18
  children?: React.ReactNode;
19
19
  }> {
20
20
  static defaultProps = {
@@ -2,7 +2,7 @@ import React, { useLayoutEffect, useMemo, useRef, useState } from 'react';
2
2
  import { Platform } from 'react-native';
3
3
  import { SafeAreaProvider } from 'react-native-safe-area-context';
4
4
 
5
- import Sendbird, { DeviceOsPlatform, SendbirdPlatform, SendbirdProduct } from '@sendbird/chat';
5
+ import SendbirdChat, { DeviceOsPlatform, SendbirdChatParams, SendbirdPlatform, SendbirdProduct } from '@sendbird/chat';
6
6
  import { GroupChannelModule } from '@sendbird/chat/groupChannel';
7
7
  import { OpenChannelModule } from '@sendbird/chat/openChannel';
8
8
  import type { HeaderStyleContextType, UIKitTheme } from '@sendbird/uikit-react-native-foundation';
@@ -18,7 +18,6 @@ import { SBUConfig, UIKitConfigProvider } from '@sendbird/uikit-tools';
18
18
  import type {
19
19
  PartialDeep,
20
20
  SendbirdChatSDK,
21
- SendbirdEncryption,
22
21
  SendbirdGroupChannel,
23
22
  SendbirdGroupChannelCreateParams,
24
23
  SendbirdMember,
@@ -38,6 +37,7 @@ import ImageCompressionConfig from '../libs/ImageCompressionConfig';
38
37
  import InternalLocalCacheStorage from '../libs/InternalLocalCacheStorage';
39
38
  import MentionConfig, { MentionConfigInterface } from '../libs/MentionConfig';
40
39
  import MentionManager from '../libs/MentionManager';
40
+ import VoiceMessageConfig, { VoiceMessageConfigInterface } from '../libs/VoiceMessageConfig';
41
41
  import StringSetEn from '../localization/StringSet.en';
42
42
  import type { StringSet } from '../localization/StringSet.type';
43
43
  import SBUDynamicModule from '../platform/dynamicModule';
@@ -46,13 +46,14 @@ import type {
46
46
  FileServiceInterface,
47
47
  MediaServiceInterface,
48
48
  NotificationServiceInterface,
49
+ PlayerServiceInterface,
50
+ RecorderServiceInterface,
49
51
  } from '../platform/types';
50
52
  import type { ErrorBoundaryProps, LocalCacheStorage } from '../types';
51
53
  import VERSION from '../version';
52
54
  import InternalErrorBoundaryContainer from './InternalErrorBoundaryContainer';
53
55
 
54
56
  const NetInfo = SBUDynamicModule.get('@react-native-community/netinfo', 'warn');
55
- type UnimplementedFeatures = 'enableVoiceMessage' | 'threadReplySelectType' | 'replyType';
56
57
  export const SendbirdUIKit = Object.freeze({
57
58
  VERSION,
58
59
  PLATFORM: Platform.OS.toLowerCase(),
@@ -63,6 +64,27 @@ export const SendbirdUIKit = Object.freeze({
63
64
  },
64
65
  });
65
66
 
67
+ type UnimplementedFeatures = 'threadReplySelectType' | 'replyType';
68
+ export type ChatOmittedInitParams = Omit<
69
+ SendbirdChatParams<[GroupChannelModule, OpenChannelModule]>,
70
+ (typeof chatOmitKeys)[number]
71
+ >;
72
+
73
+ const chatOmitKeys = [
74
+ 'appId',
75
+ 'newInstance',
76
+ 'modules',
77
+ 'debugMode',
78
+ 'appVersion',
79
+ 'localCacheEnabled',
80
+ 'useAsyncStorageStore',
81
+ ] as const;
82
+ function sanitizeChatOptions<T extends Record<string, unknown>>(chatOptions: T): T {
83
+ const opts = { ...chatOptions };
84
+ chatOmitKeys.forEach((key) => delete opts[key]);
85
+ return opts;
86
+ }
87
+
66
88
  export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
67
89
  appId: string;
68
90
  platformServices: {
@@ -70,12 +92,14 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
70
92
  notification: NotificationServiceInterface;
71
93
  clipboard: ClipboardServiceInterface;
72
94
  media: MediaServiceInterface;
95
+ player: PlayerServiceInterface;
96
+ recorder: RecorderServiceInterface;
73
97
  };
74
98
  chatOptions: {
75
99
  localCacheStorage: LocalCacheStorage;
76
- localCacheEncryption?: SendbirdEncryption;
77
100
  onInitialized?: (sdkInstance: SendbirdChatSDK) => SendbirdChatSDK;
78
- } & Partial<ChatRelatedFeaturesInUIKit>;
101
+ } & Partial<ChatOmittedInitParams> &
102
+ Partial<ChatRelatedFeaturesInUIKit>;
79
103
  uikitOptions?: PartialDeep<{
80
104
  common: SBUConfig['common'];
81
105
  groupChannel: Omit<SBUConfig['groupChannel']['channel'], UnimplementedFeatures> & {
@@ -98,7 +122,7 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
98
122
  errorBoundary?: {
99
123
  disabled?: boolean;
100
124
  onError?: (props: ErrorBoundaryProps) => void;
101
- ErrorInfoComponent?: (props: ErrorBoundaryProps) => JSX.Element;
125
+ ErrorInfoComponent?: (props: ErrorBoundaryProps) => React.ReactNode;
102
126
  };
103
127
  toast?: {
104
128
  dismissTimeout?: number;
@@ -110,24 +134,29 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
110
134
  users: SendbirdUser[] | SendbirdMember[],
111
135
  ) => SendbirdGroupChannelCreateParams | Promise<SendbirdGroupChannelCreateParams>;
112
136
  };
137
+ reaction?: {
138
+ onPressUserProfile?: (user: SendbirdUser | SendbirdMember) => void;
139
+ };
113
140
  userMention?: Pick<Partial<MentionConfigInterface>, 'mentionLimit' | 'suggestionLimit' | 'debounceMills'>;
114
141
  imageCompression?: Partial<ImageCompressionConfigInterface>;
142
+ voiceMessage?: PartialDeep<VoiceMessageConfigInterface>;
115
143
  }>;
116
144
 
117
- const SendbirdUIKitContainer = ({
118
- children,
119
- appId,
120
- chatOptions,
121
- uikitOptions,
122
- platformServices,
123
- localization,
124
- styles,
125
- errorBoundary,
126
- toast,
127
- userProfile,
128
- userMention,
129
- imageCompression,
130
- }: SendbirdUIKitContainerProps) => {
145
+ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
146
+ const {
147
+ children,
148
+ appId,
149
+ chatOptions,
150
+ uikitOptions,
151
+ platformServices,
152
+ localization,
153
+ styles,
154
+ errorBoundary,
155
+ toast,
156
+ userProfile,
157
+ reaction,
158
+ } = props;
159
+
131
160
  if (!chatOptions.localCacheStorage) {
132
161
  throw new Error('SendbirdUIKitContainer: chatOptions.localCacheStorage is required');
133
162
  }
@@ -139,35 +168,18 @@ const SendbirdUIKitContainer = ({
139
168
 
140
169
  const [internalStorage] = useState(() => new InternalLocalCacheStorage(chatOptions.localCacheStorage));
141
170
  const [sdkInstance, setSdkInstance] = useState<SendbirdChatSDK>(() => {
142
- const sendbird = initializeSendbird(appId, { internalStorage, ...chatOptions });
171
+ const sendbird = initializeSendbird(appId, { internalStorage, ...sanitizeChatOptions(chatOptions) });
143
172
  unsubscribes.current = sendbird.unsubscribes;
144
173
  return sendbird.chatSDK;
145
174
  });
146
175
 
176
+ const { imageCompressionConfig, voiceMessageConfig, mentionConfig } = useConfigInstance(props);
147
177
  const emojiManager = useMemo(() => new EmojiManager(internalStorage), [internalStorage]);
148
-
149
- const mentionManager = useMemo(() => {
150
- const config = new MentionConfig({
151
- mentionLimit: userMention?.mentionLimit || MentionConfig.DEFAULT.MENTION_LIMIT,
152
- suggestionLimit: userMention?.suggestionLimit || MentionConfig.DEFAULT.SUGGESTION_LIMIT,
153
- debounceMills: userMention?.debounceMills ?? MentionConfig.DEFAULT.DEBOUNCE_MILLS,
154
- delimiter: MentionConfig.DEFAULT.DELIMITER,
155
- trigger: MentionConfig.DEFAULT.TRIGGER,
156
- });
157
- return new MentionManager(config);
158
- }, [userMention?.mentionLimit, userMention?.suggestionLimit, userMention?.debounceMills]);
159
-
160
- const imageCompressionConfig = useMemo(() => {
161
- return new ImageCompressionConfig({
162
- compressionRate: imageCompression?.compressionRate || ImageCompressionConfig.DEFAULT.COMPRESSION_RATE,
163
- width: imageCompression?.width,
164
- height: imageCompression?.height,
165
- });
166
- }, [imageCompression?.compressionRate, imageCompression?.width, imageCompression?.height]);
178
+ const mentionManager = useMemo(() => new MentionManager(mentionConfig), [mentionConfig]);
167
179
 
168
180
  useLayoutEffect(() => {
169
181
  if (!isFirstMount) {
170
- const sendbird = initializeSendbird(appId, { internalStorage, ...chatOptions });
182
+ const sendbird = initializeSendbird(appId, { internalStorage, ...sanitizeChatOptions(chatOptions) });
171
183
  setSdkInstance(sendbird.chatSDK);
172
184
  unsubscribes.current = sendbird.unsubscribes;
173
185
  }
@@ -210,6 +222,7 @@ const SendbirdUIKitContainer = ({
210
222
  emojiManager={emojiManager}
211
223
  mentionManager={mentionManager}
212
224
  imageCompressionConfig={imageCompressionConfig}
225
+ voiceMessageConfig={voiceMessageConfig}
213
226
  enableAutoPushTokenRegistration={
214
227
  chatOptions.enableAutoPushTokenRegistration ?? SendbirdUIKit.DEFAULT.AUTO_PUSH_TOKEN_REGISTRATION
215
228
  }
@@ -224,6 +237,9 @@ const SendbirdUIKitContainer = ({
224
237
  notificationService={platformServices.notification}
225
238
  clipboardService={platformServices.clipboard}
226
239
  mediaService={platformServices.media}
240
+ playerService={platformServices.player}
241
+ recorderService={platformServices.recorder}
242
+ voiceMessageConfig={voiceMessageConfig}
227
243
  >
228
244
  <UIKitThemeProvider theme={styles?.theme ?? LightUIKitTheme}>
229
245
  <HeaderStyleProvider
@@ -232,12 +248,8 @@ const SendbirdUIKitContainer = ({
232
248
  statusBarTranslucent={styles?.statusBarTranslucent ?? true}
233
249
  >
234
250
  <ToastProvider dismissTimeout={toast?.dismissTimeout}>
235
- <UserProfileProvider
236
- onCreateChannel={userProfile?.onCreateChannel}
237
- onBeforeCreateChannel={userProfile?.onBeforeCreateChannel}
238
- statusBarTranslucent={styles?.statusBarTranslucent ?? true}
239
- >
240
- <ReactionProvider>
251
+ <UserProfileProvider {...userProfile} statusBarTranslucent={styles?.statusBarTranslucent ?? true}>
252
+ <ReactionProvider {...reaction}>
241
253
  <LocalizationContext.Consumer>
242
254
  {(value) => {
243
255
  const STRINGS = value?.STRINGS || defaultStringSet;
@@ -270,25 +282,22 @@ const SendbirdUIKitContainer = ({
270
282
  );
271
283
  };
272
284
 
273
- const initializeSendbird = (
274
- appId: string,
275
- options: {
276
- internalStorage?: InternalLocalCacheStorage;
277
- onInitialized?: (sdk: SendbirdChatSDK) => SendbirdChatSDK;
278
- localCacheEncryption?: SendbirdEncryption;
279
- },
280
- ) => {
285
+ interface InitOptions extends ChatOmittedInitParams {
286
+ internalStorage: InternalLocalCacheStorage;
287
+ onInitialized?: (sdk: SendbirdChatSDK) => SendbirdChatSDK;
288
+ }
289
+ const initializeSendbird = (appId: string, options: InitOptions) => {
281
290
  let chatSDK: SendbirdChatSDK;
282
291
  const unsubscribes: Array<() => void> = [];
283
- const { internalStorage, localCacheEncryption, onInitialized } = options;
292
+ const { internalStorage, onInitialized, ...chatInitParams } = options;
284
293
 
285
- chatSDK = Sendbird.init({
294
+ chatSDK = SendbirdChat.init({
295
+ ...chatInitParams,
286
296
  appId,
287
297
  newInstance: true,
288
298
  modules: [new GroupChannelModule(), new OpenChannelModule()],
289
- localCacheEnabled: Boolean(internalStorage),
299
+ localCacheEnabled: true,
290
300
  useAsyncStorageStore: internalStorage as never,
291
- localCacheEncryption,
292
301
  });
293
302
 
294
303
  if (onInitialized) {
@@ -368,4 +377,39 @@ function getReactNativeVersion() {
368
377
  return `${major}.${minor}.${patch}`;
369
378
  }
370
379
 
380
+ const useConfigInstance = ({ imageCompression, userMention, voiceMessage }: SendbirdUIKitContainerProps) => {
381
+ const mentionConfig = useMemo(() => {
382
+ return new MentionConfig({
383
+ mentionLimit: userMention?.mentionLimit || MentionConfig.DEFAULT.MENTION_LIMIT,
384
+ suggestionLimit: userMention?.suggestionLimit || MentionConfig.DEFAULT.SUGGESTION_LIMIT,
385
+ debounceMills: userMention?.debounceMills ?? MentionConfig.DEFAULT.DEBOUNCE_MILLS,
386
+ delimiter: MentionConfig.DEFAULT.DELIMITER,
387
+ trigger: MentionConfig.DEFAULT.TRIGGER,
388
+ });
389
+ }, [userMention?.mentionLimit, userMention?.suggestionLimit, userMention?.debounceMills]);
390
+
391
+ const imageCompressionConfig = useMemo(() => {
392
+ return new ImageCompressionConfig({
393
+ compressionRate: imageCompression?.compressionRate || ImageCompressionConfig.DEFAULT.COMPRESSION_RATE,
394
+ width: imageCompression?.width,
395
+ height: imageCompression?.height,
396
+ });
397
+ }, [imageCompression?.compressionRate, imageCompression?.width, imageCompression?.height]);
398
+
399
+ const voiceMessageConfig = useMemo(() => {
400
+ return new VoiceMessageConfig({
401
+ recorder: {
402
+ minDuration: voiceMessage?.recorder?.minDuration ?? VoiceMessageConfig.DEFAULT.RECORDER.MIN_DURATION,
403
+ maxDuration: voiceMessage?.recorder?.maxDuration ?? VoiceMessageConfig.DEFAULT.RECORDER.MAX_DURATION,
404
+ },
405
+ });
406
+ }, [voiceMessage?.recorder?.minDuration, voiceMessage?.recorder?.maxDuration]);
407
+
408
+ return {
409
+ mentionConfig,
410
+ imageCompressionConfig,
411
+ voiceMessageConfig,
412
+ };
413
+ };
414
+
371
415
  export default SendbirdUIKitContainer;