@sendbird/uikit-react-native 3.1.2 → 3.2.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 (317) hide show
  1. package/README.md +67 -42
  2. package/lib/commonjs/components/ChannelInput/MessageToReplyPreview.js +145 -0
  3. package/lib/commonjs/components/ChannelInput/MessageToReplyPreview.js.map +1 -0
  4. package/lib/commonjs/components/ChannelInput/SendInput.js +147 -312
  5. package/lib/commonjs/components/ChannelInput/SendInput.js.map +1 -1
  6. package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js +238 -0
  7. package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js.map +1 -0
  8. package/lib/commonjs/components/ChannelInput/index.js +5 -1
  9. package/lib/commonjs/components/ChannelInput/index.js.map +1 -1
  10. package/lib/commonjs/components/ChannelMessageList/index.js +1 -1
  11. package/lib/commonjs/components/ChannelMessageList/index.js.map +1 -1
  12. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js +24 -13
  13. package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js.map +1 -1
  14. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js +100 -5
  15. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js.map +1 -1
  16. package/lib/commonjs/components/MessageSearchResultItem.js +1 -0
  17. package/lib/commonjs/components/MessageSearchResultItem.js.map +1 -1
  18. package/lib/commonjs/components/OpenChannelMessageRenderer/index.js +1 -0
  19. package/lib/commonjs/components/OpenChannelMessageRenderer/index.js.map +1 -1
  20. package/lib/commonjs/components/ReactionBottomSheets/ReactionUserListBottomSheet.js +2 -2
  21. package/lib/commonjs/components/ReactionBottomSheets/ReactionUserListBottomSheet.js.map +1 -1
  22. package/lib/commonjs/components/ReactionBottomSheets/index.js.map +1 -1
  23. package/lib/commonjs/components/StatusComposition.js.map +1 -1
  24. package/lib/commonjs/constants.js +5 -1
  25. package/lib/commonjs/constants.js.map +1 -1
  26. package/lib/commonjs/containers/GroupChannelPreviewContainer.js +1 -0
  27. package/lib/commonjs/containers/GroupChannelPreviewContainer.js.map +1 -1
  28. package/lib/commonjs/containers/InternalErrorBoundaryContainer.js.map +1 -1
  29. package/lib/commonjs/containers/SendbirdUIKitContainer.js +72 -34
  30. package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -1
  31. package/lib/commonjs/contexts/PlatformServiceCtx.js +16 -12
  32. package/lib/commonjs/contexts/PlatformServiceCtx.js.map +1 -1
  33. package/lib/commonjs/contexts/ReactionCtx.js +3 -2
  34. package/lib/commonjs/contexts/ReactionCtx.js.map +1 -1
  35. package/lib/commonjs/contexts/SendbirdChatCtx.js +2 -0
  36. package/lib/commonjs/contexts/SendbirdChatCtx.js.map +1 -1
  37. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +27 -42
  38. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  39. package/lib/commonjs/domain/groupChannel/module/moduleContext.js +109 -5
  40. package/lib/commonjs/domain/groupChannel/module/moduleContext.js.map +1 -1
  41. package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
  42. package/lib/commonjs/domain/userList/types.js.map +1 -1
  43. package/lib/commonjs/fragments/createGroupChannelFragment.js +30 -4
  44. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  45. package/lib/commonjs/fragments/createMessageSearchFragment.js +1 -1
  46. package/lib/commonjs/fragments/createMessageSearchFragment.js.map +1 -1
  47. package/lib/commonjs/hooks/useChannelInputItems.js +211 -0
  48. package/lib/commonjs/hooks/useChannelInputItems.js.map +1 -0
  49. package/lib/commonjs/hooks/useConnection.js +1 -1
  50. package/lib/commonjs/hooks/useConnection.js.map +1 -1
  51. package/lib/commonjs/hooks/useVoiceMessageInput.js +207 -0
  52. package/lib/commonjs/hooks/useVoiceMessageInput.js.map +1 -0
  53. package/lib/commonjs/index.js +32 -0
  54. package/lib/commonjs/index.js.map +1 -1
  55. package/lib/commonjs/libs/MentionManager.js.map +1 -1
  56. package/lib/commonjs/libs/SBUUtils.js +4 -0
  57. package/lib/commonjs/libs/SBUUtils.js.map +1 -1
  58. package/lib/commonjs/libs/VoiceMessageConfig.js +30 -0
  59. package/lib/commonjs/libs/VoiceMessageConfig.js.map +1 -0
  60. package/lib/commonjs/localization/StringSet.type.js.map +1 -1
  61. package/lib/commonjs/localization/createBaseStringSet.js +24 -9
  62. package/lib/commonjs/localization/createBaseStringSet.js.map +1 -1
  63. package/lib/commonjs/platform/createFileService.expo.js +10 -0
  64. package/lib/commonjs/platform/createFileService.expo.js.map +1 -1
  65. package/lib/commonjs/platform/createFileService.native.js +19 -0
  66. package/lib/commonjs/platform/createFileService.native.js.map +1 -1
  67. package/lib/commonjs/platform/createPlayerService.expo.js +137 -0
  68. package/lib/commonjs/platform/createPlayerService.expo.js.map +1 -0
  69. package/lib/commonjs/platform/createPlayerService.native.js +139 -0
  70. package/lib/commonjs/platform/createPlayerService.native.js.map +1 -0
  71. package/lib/commonjs/platform/createRecorderService.expo.js +158 -0
  72. package/lib/commonjs/platform/createRecorderService.expo.js.map +1 -0
  73. package/lib/commonjs/platform/createRecorderService.native.js +157 -0
  74. package/lib/commonjs/platform/createRecorderService.native.js.map +1 -0
  75. package/lib/commonjs/platform/types.js.map +1 -1
  76. package/lib/commonjs/types.js.map +1 -1
  77. package/lib/commonjs/version.js +1 -1
  78. package/lib/commonjs/version.js.map +1 -1
  79. package/lib/module/components/ChannelInput/MessageToReplyPreview.js +137 -0
  80. package/lib/module/components/ChannelInput/MessageToReplyPreview.js.map +1 -0
  81. package/lib/module/components/ChannelInput/SendInput.js +149 -314
  82. package/lib/module/components/ChannelInput/SendInput.js.map +1 -1
  83. package/lib/module/components/ChannelInput/VoiceMessageInput.js +228 -0
  84. package/lib/module/components/ChannelInput/VoiceMessageInput.js.map +1 -0
  85. package/lib/module/components/ChannelInput/index.js +5 -1
  86. package/lib/module/components/ChannelInput/index.js.map +1 -1
  87. package/lib/module/components/ChannelMessageList/index.js +2 -2
  88. package/lib/module/components/ChannelMessageList/index.js.map +1 -1
  89. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js +24 -13
  90. package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js.map +1 -1
  91. package/lib/module/components/GroupChannelMessageRenderer/index.js +99 -6
  92. package/lib/module/components/GroupChannelMessageRenderer/index.js.map +1 -1
  93. package/lib/module/components/MessageSearchResultItem.js +2 -1
  94. package/lib/module/components/MessageSearchResultItem.js.map +1 -1
  95. package/lib/module/components/OpenChannelMessageRenderer/index.js +1 -0
  96. package/lib/module/components/OpenChannelMessageRenderer/index.js.map +1 -1
  97. package/lib/module/components/ReactionBottomSheets/ReactionUserListBottomSheet.js +2 -2
  98. package/lib/module/components/ReactionBottomSheets/ReactionUserListBottomSheet.js.map +1 -1
  99. package/lib/module/components/ReactionBottomSheets/index.js.map +1 -1
  100. package/lib/module/components/StatusComposition.js.map +1 -1
  101. package/lib/module/constants.js +2 -0
  102. package/lib/module/constants.js.map +1 -1
  103. package/lib/module/containers/GroupChannelPreviewContainer.js +2 -1
  104. package/lib/module/containers/GroupChannelPreviewContainer.js.map +1 -1
  105. package/lib/module/containers/InternalErrorBoundaryContainer.js.map +1 -1
  106. package/lib/module/containers/SendbirdUIKitContainer.js +74 -36
  107. package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -1
  108. package/lib/module/contexts/PlatformServiceCtx.js +14 -11
  109. package/lib/module/contexts/PlatformServiceCtx.js.map +1 -1
  110. package/lib/module/contexts/ReactionCtx.js +3 -2
  111. package/lib/module/contexts/ReactionCtx.js.map +1 -1
  112. package/lib/module/contexts/SendbirdChatCtx.js +2 -0
  113. package/lib/module/contexts/SendbirdChatCtx.js.map +1 -1
  114. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +28 -43
  115. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  116. package/lib/module/domain/groupChannel/module/moduleContext.js +111 -7
  117. package/lib/module/domain/groupChannel/module/moduleContext.js.map +1 -1
  118. package/lib/module/domain/groupChannel/types.js.map +1 -1
  119. package/lib/module/domain/userList/types.js.map +1 -1
  120. package/lib/module/fragments/createGroupChannelFragment.js +32 -6
  121. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  122. package/lib/module/fragments/createMessageSearchFragment.js +1 -1
  123. package/lib/module/fragments/createMessageSearchFragment.js.map +1 -1
  124. package/lib/module/hooks/useChannelInputItems.js +203 -0
  125. package/lib/module/hooks/useChannelInputItems.js.map +1 -0
  126. package/lib/module/hooks/useConnection.js +1 -1
  127. package/lib/module/hooks/useConnection.js.map +1 -1
  128. package/lib/module/hooks/useVoiceMessageInput.js +199 -0
  129. package/lib/module/hooks/useVoiceMessageInput.js.map +1 -0
  130. package/lib/module/index.js +4 -0
  131. package/lib/module/index.js.map +1 -1
  132. package/lib/module/libs/MentionManager.js.map +1 -1
  133. package/lib/module/libs/SBUUtils.js +4 -0
  134. package/lib/module/libs/SBUUtils.js.map +1 -1
  135. package/lib/module/libs/VoiceMessageConfig.js +23 -0
  136. package/lib/module/libs/VoiceMessageConfig.js.map +1 -0
  137. package/lib/module/localization/StringSet.type.js.map +1 -1
  138. package/lib/module/localization/createBaseStringSet.js +25 -10
  139. package/lib/module/localization/createBaseStringSet.js.map +1 -1
  140. package/lib/module/platform/createFileService.expo.js +10 -0
  141. package/lib/module/platform/createFileService.expo.js.map +1 -1
  142. package/lib/module/platform/createFileService.native.js +19 -0
  143. package/lib/module/platform/createFileService.native.js.map +1 -1
  144. package/lib/module/platform/createPlayerService.expo.js +129 -0
  145. package/lib/module/platform/createPlayerService.expo.js.map +1 -0
  146. package/lib/module/platform/createPlayerService.native.js +132 -0
  147. package/lib/module/platform/createPlayerService.native.js.map +1 -0
  148. package/lib/module/platform/createRecorderService.expo.js +150 -0
  149. package/lib/module/platform/createRecorderService.expo.js.map +1 -0
  150. package/lib/module/platform/createRecorderService.native.js +149 -0
  151. package/lib/module/platform/createRecorderService.native.js.map +1 -0
  152. package/lib/module/platform/types.js.map +1 -1
  153. package/lib/module/types.js.map +1 -1
  154. package/lib/module/version.js +1 -1
  155. package/lib/module/version.js.map +1 -1
  156. package/lib/typescript/src/components/ChannelCover.d.ts +2 -1
  157. package/lib/typescript/src/components/ChannelInput/AttachmentsButton.d.ts +2 -1
  158. package/lib/typescript/src/components/ChannelInput/MessageToReplyPreview.d.ts +7 -0
  159. package/lib/typescript/src/components/ChannelInput/VoiceMessageInput.d.ts +11 -0
  160. package/lib/typescript/src/components/ChannelInput/index.d.ts +7 -3
  161. package/lib/typescript/src/components/ChannelMessageList/index.d.ts +1 -1
  162. package/lib/typescript/src/components/FileViewer.d.ts +2 -1
  163. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageDateSeparator.d.ts +2 -1
  164. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageFocusAnimation.d.ts +1 -1
  165. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageOutgoingStatus.d.ts +1 -1
  166. package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.d.ts +4 -2
  167. package/lib/typescript/src/components/NewMessagesButton.d.ts +1 -1
  168. package/lib/typescript/src/components/OpenChannelMessageRenderer/OpenChannelMessageDateSeparator.d.ts +2 -1
  169. package/lib/typescript/src/components/ProviderLayout.d.ts +1 -1
  170. package/lib/typescript/src/components/ReactionAddons/BottomSheetReactionAddon.d.ts +2 -1
  171. package/lib/typescript/src/components/ReactionAddons/MessageReactionAddon.d.ts +2 -1
  172. package/lib/typescript/src/components/ReactionAddons/ReactionRoundedButton.d.ts +3 -2
  173. package/lib/typescript/src/components/ReactionAddons/index.d.ts +3 -2
  174. package/lib/typescript/src/components/ReactionBottomSheets/ReactionListBottomSheet.d.ts +2 -1
  175. package/lib/typescript/src/components/ReactionBottomSheets/ReactionUserListBottomSheet.d.ts +2 -1
  176. package/lib/typescript/src/components/ReactionBottomSheets/index.d.ts +4 -4
  177. package/lib/typescript/src/components/ScrollToBottomButton.d.ts +1 -1
  178. package/lib/typescript/src/components/StatusComposition.d.ts +4 -4
  179. package/lib/typescript/src/components/TypedPlaceholder.d.ts +2 -1
  180. package/lib/typescript/src/components/UserActionBar.d.ts +2 -1
  181. package/lib/typescript/src/components/UserSelectableBar.d.ts +2 -1
  182. package/lib/typescript/src/constants.d.ts +2 -0
  183. package/lib/typescript/src/containers/GroupChannelPreviewContainer.d.ts +2 -1
  184. package/lib/typescript/src/containers/InternalErrorBoundaryContainer.d.ts +3 -3
  185. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +19 -8
  186. package/lib/typescript/src/contexts/LocalizationCtx.d.ts +1 -1
  187. package/lib/typescript/src/contexts/PlatformServiceCtx.d.ts +8 -8
  188. package/lib/typescript/src/contexts/ReactionCtx.d.ts +5 -2
  189. package/lib/typescript/src/contexts/SendbirdChatCtx.d.ts +6 -3
  190. package/lib/typescript/src/contexts/UserProfileCtx.d.ts +1 -1
  191. package/lib/typescript/src/domain/groupChannel/component/GroupChannelHeader.d.ts +2 -1
  192. package/lib/typescript/src/domain/groupChannel/component/GroupChannelInput.d.ts +1 -1
  193. package/lib/typescript/src/domain/groupChannel/component/GroupChannelMessageList.d.ts +1 -1
  194. package/lib/typescript/src/domain/groupChannel/component/GroupChannelStatusEmpty.d.ts +2 -1
  195. package/lib/typescript/src/domain/groupChannel/component/GroupChannelStatusLoading.d.ts +2 -1
  196. package/lib/typescript/src/domain/groupChannel/component/GroupChannelSuggestedMentionList.d.ts +2 -1
  197. package/lib/typescript/src/domain/groupChannel/types.d.ts +45 -0
  198. package/lib/typescript/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersHeader.d.ts +2 -1
  199. package/lib/typescript/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.d.ts +2 -1
  200. package/lib/typescript/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersStatusEmpty.d.ts +2 -1
  201. package/lib/typescript/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersStatusLoading.d.ts +2 -1
  202. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListHeader.d.ts +2 -1
  203. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListList.d.ts +2 -1
  204. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListStatusEmpty.d.ts +2 -1
  205. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListStatusLoading.d.ts +2 -1
  206. package/lib/typescript/src/domain/groupChannelList/component/GroupChannelListTypeSelector.d.ts +2 -1
  207. package/lib/typescript/src/domain/groupChannelModeration/component/GroupChannelModerationHeader.d.ts +2 -1
  208. package/lib/typescript/src/domain/groupChannelModeration/component/GroupChannelModerationMenu.d.ts +2 -1
  209. package/lib/typescript/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersHeader.d.ts +2 -1
  210. package/lib/typescript/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.d.ts +2 -1
  211. package/lib/typescript/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersStatusEmpty.d.ts +2 -1
  212. package/lib/typescript/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersStatusLoading.d.ts +2 -1
  213. package/lib/typescript/src/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.d.ts +2 -1
  214. package/lib/typescript/src/domain/groupChannelNotifications/component/GroupChannelNotificationsView.d.ts +2 -1
  215. package/lib/typescript/src/domain/groupChannelOperators/component/GroupChannelOperatorsHeader.d.ts +2 -1
  216. package/lib/typescript/src/domain/groupChannelOperators/component/GroupChannelOperatorsList.d.ts +2 -1
  217. package/lib/typescript/src/domain/groupChannelOperators/component/GroupChannelOperatorsStatusEmpty.d.ts +2 -1
  218. package/lib/typescript/src/domain/groupChannelOperators/component/GroupChannelOperatorsStatusLoading.d.ts +2 -1
  219. package/lib/typescript/src/domain/groupChannelSettings/component/GroupChannelSettingsHeader.d.ts +2 -1
  220. package/lib/typescript/src/domain/groupChannelSettings/component/GroupChannelSettingsInfo.d.ts +2 -1
  221. package/lib/typescript/src/domain/groupChannelSettings/component/GroupChannelSettingsMenu.d.ts +2 -1
  222. package/lib/typescript/src/domain/messageSearch/component/MessageSearchHeader.d.ts +2 -1
  223. package/lib/typescript/src/domain/messageSearch/component/MessageSearchList.d.ts +2 -1
  224. package/lib/typescript/src/domain/messageSearch/component/MessageSearchStatusEmpty.d.ts +2 -1
  225. package/lib/typescript/src/domain/messageSearch/component/MessageSearchStatusLoading.d.ts +2 -1
  226. package/lib/typescript/src/domain/openChannel/component/OpenChannelHeader.d.ts +2 -2
  227. package/lib/typescript/src/domain/openChannel/component/OpenChannelInput.d.ts +1 -1
  228. package/lib/typescript/src/domain/openChannel/component/OpenChannelMessageList.d.ts +1 -1
  229. package/lib/typescript/src/domain/openChannel/component/OpenChannelStatusEmpty.d.ts +2 -1
  230. package/lib/typescript/src/domain/openChannel/component/OpenChannelStatusLoading.d.ts +2 -1
  231. package/lib/typescript/src/domain/openChannelBannedUsers/component/OpenChannelBannedUsersHeader.d.ts +2 -1
  232. package/lib/typescript/src/domain/openChannelBannedUsers/component/OpenChannelBannedUsersList.d.ts +2 -1
  233. package/lib/typescript/src/domain/openChannelBannedUsers/component/OpenChannelBannedUsersStatusEmpty.d.ts +2 -1
  234. package/lib/typescript/src/domain/openChannelBannedUsers/component/OpenChannelBannedUsersStatusLoading.d.ts +2 -1
  235. package/lib/typescript/src/domain/openChannelCreate/component/OpenChannelCreateHeader.d.ts +2 -1
  236. package/lib/typescript/src/domain/openChannelCreate/component/OpenChannelCreateProfileInput.d.ts +2 -1
  237. package/lib/typescript/src/domain/openChannelCreate/component/OpenChannelCreateStatusLoading.d.ts +2 -1
  238. package/lib/typescript/src/domain/openChannelList/component/OpenChannelListHeader.d.ts +2 -1
  239. package/lib/typescript/src/domain/openChannelList/component/OpenChannelListList.d.ts +2 -1
  240. package/lib/typescript/src/domain/openChannelList/component/OpenChannelListStatusEmpty.d.ts +2 -1
  241. package/lib/typescript/src/domain/openChannelList/component/OpenChannelListStatusLoading.d.ts +2 -1
  242. package/lib/typescript/src/domain/openChannelModeration/component/OpenChannelModerationHeader.d.ts +2 -1
  243. package/lib/typescript/src/domain/openChannelModeration/component/OpenChannelModerationMenu.d.ts +2 -1
  244. package/lib/typescript/src/domain/openChannelMutedParticipants/component/OpenChannelMutedParticipantsHeader.d.ts +2 -1
  245. package/lib/typescript/src/domain/openChannelMutedParticipants/component/OpenChannelMutedParticipantsList.d.ts +2 -1
  246. package/lib/typescript/src/domain/openChannelMutedParticipants/component/OpenChannelMutedParticipantsStatusEmpty.d.ts +2 -1
  247. package/lib/typescript/src/domain/openChannelMutedParticipants/component/OpenChannelMutedParticipantsStatusLoading.d.ts +2 -1
  248. package/lib/typescript/src/domain/openChannelOperators/component/OpenChannelOperatorsHeader.d.ts +2 -1
  249. package/lib/typescript/src/domain/openChannelOperators/component/OpenChannelOperatorsList.d.ts +2 -1
  250. package/lib/typescript/src/domain/openChannelOperators/component/OpenChannelOperatorsStatusEmpty.d.ts +2 -1
  251. package/lib/typescript/src/domain/openChannelOperators/component/OpenChannelOperatorsStatusLoading.d.ts +2 -1
  252. package/lib/typescript/src/domain/openChannelSettings/component/OpenChannelSettingsHeader.d.ts +2 -1
  253. package/lib/typescript/src/domain/openChannelSettings/component/OpenChannelSettingsInfo.d.ts +2 -1
  254. package/lib/typescript/src/domain/openChannelSettings/component/OpenChannelSettingsMenu.d.ts +2 -1
  255. package/lib/typescript/src/domain/userList/component/UserListHeader.d.ts +3 -3
  256. package/lib/typescript/src/domain/userList/component/UserListList.d.ts +1 -1
  257. package/lib/typescript/src/domain/userList/component/UserListStatusEmpty.d.ts +2 -1
  258. package/lib/typescript/src/domain/userList/component/UserListStatusLoading.d.ts +2 -1
  259. package/lib/typescript/src/domain/userList/types.d.ts +2 -2
  260. package/lib/typescript/src/hooks/useChannelInputItems.d.ts +10 -0
  261. package/lib/typescript/src/hooks/useVoiceMessageInput.d.ts +53 -0
  262. package/lib/typescript/src/index.d.ts +4 -0
  263. package/lib/typescript/src/libs/MentionManager.d.ts +2 -1
  264. package/lib/typescript/src/libs/SBUUtils.d.ts +1 -0
  265. package/lib/typescript/src/libs/VoiceMessageConfig.d.ts +25 -0
  266. package/lib/typescript/src/localization/StringSet.type.d.ts +7 -0
  267. package/lib/typescript/src/platform/createPlayerService.expo.d.ts +7 -0
  268. package/lib/typescript/src/platform/createPlayerService.native.d.ts +9 -0
  269. package/lib/typescript/src/platform/createRecorderService.expo.d.ts +7 -0
  270. package/lib/typescript/src/platform/createRecorderService.native.d.ts +9 -0
  271. package/lib/typescript/src/platform/types.d.ts +100 -1
  272. package/lib/typescript/src/types.d.ts +1 -1
  273. package/lib/typescript/src/version.d.ts +1 -1
  274. package/package.json +9 -11
  275. package/src/components/ChannelInput/MessageToReplyPreview.tsx +133 -0
  276. package/src/components/ChannelInput/SendInput.tsx +129 -320
  277. package/src/components/ChannelInput/VoiceMessageInput.tsx +206 -0
  278. package/src/components/ChannelInput/index.tsx +12 -4
  279. package/src/components/ChannelMessageList/index.tsx +3 -1
  280. package/src/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.tsx +24 -11
  281. package/src/components/GroupChannelMessageRenderer/index.tsx +80 -3
  282. package/src/components/MessageSearchResultItem.tsx +2 -1
  283. package/src/components/OpenChannelMessageRenderer/index.tsx +1 -0
  284. package/src/components/ReactionBottomSheets/ReactionUserListBottomSheet.tsx +2 -2
  285. package/src/components/ReactionBottomSheets/index.tsx +3 -2
  286. package/src/components/StatusComposition.tsx +3 -3
  287. package/src/constants.ts +2 -0
  288. package/src/containers/GroupChannelPreviewContainer.tsx +2 -0
  289. package/src/containers/InternalErrorBoundaryContainer.tsx +1 -1
  290. package/src/containers/SendbirdUIKitContainer.tsx +103 -59
  291. package/src/contexts/PlatformServiceCtx.tsx +22 -20
  292. package/src/contexts/ReactionCtx.tsx +7 -5
  293. package/src/contexts/SendbirdChatCtx.tsx +10 -2
  294. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +29 -43
  295. package/src/domain/groupChannel/module/moduleContext.tsx +119 -7
  296. package/src/domain/groupChannel/types.ts +41 -0
  297. package/src/domain/userList/types.ts +2 -2
  298. package/src/fragments/createGroupChannelFragment.tsx +32 -5
  299. package/src/fragments/createMessageSearchFragment.tsx +1 -1
  300. package/src/hooks/useChannelInputItems.ts +215 -0
  301. package/src/hooks/useConnection.ts +1 -1
  302. package/src/hooks/useVoiceMessageInput.ts +237 -0
  303. package/src/index.ts +4 -0
  304. package/src/libs/MentionManager.tsx +1 -1
  305. package/src/libs/SBUUtils.ts +5 -0
  306. package/src/libs/VoiceMessageConfig.ts +28 -0
  307. package/src/localization/StringSet.type.ts +8 -0
  308. package/src/localization/createBaseStringSet.ts +27 -11
  309. package/src/platform/createFileService.expo.ts +10 -0
  310. package/src/platform/createFileService.native.ts +19 -0
  311. package/src/platform/createPlayerService.expo.tsx +142 -0
  312. package/src/platform/createPlayerService.native.tsx +148 -0
  313. package/src/platform/createRecorderService.expo.tsx +160 -0
  314. package/src/platform/createRecorderService.native.tsx +170 -0
  315. package/src/platform/types.ts +114 -1
  316. package/src/types.ts +1 -1
  317. package/src/version.ts +1 -1
@@ -0,0 +1,206 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated } from 'react-native';
3
+
4
+ import {
5
+ Box,
6
+ Icon,
7
+ PressBox,
8
+ ProgressBar,
9
+ Text,
10
+ createStyleSheet,
11
+ useUIKitTheme,
12
+ } from '@sendbird/uikit-react-native-foundation';
13
+ import { conditionChaining, millsToMMSS } from '@sendbird/uikit-utils';
14
+
15
+ import { useLocalization } from '../../hooks/useContext';
16
+ import useVoiceMessageInput from '../../hooks/useVoiceMessageInput';
17
+ import type { FileType } from '../../platform/types';
18
+
19
+ export type VoiceMessageInputProps = {
20
+ onClose: () => Promise<void>;
21
+ onSend: (params: { file: FileType; duration: number }) => void;
22
+ };
23
+
24
+ const VoiceMessageInput = ({ onClose, onSend }: VoiceMessageInputProps) => {
25
+ const { STRINGS } = useLocalization();
26
+ const { colors } = useUIKitTheme();
27
+ const { actions, state } = useVoiceMessageInput({
28
+ onSend: (file, duration) => onSend({ file, duration }),
29
+ onClose,
30
+ });
31
+
32
+ const uiColors = colors.ui.voiceMessageInput.default[state.status !== 'idle' ? 'active' : 'inactive'];
33
+
34
+ const onPressCancel = async () => {
35
+ actions.cancel();
36
+ onClose();
37
+ };
38
+
39
+ const onPressSend = async () => {
40
+ actions.send();
41
+ onClose();
42
+ };
43
+
44
+ const onPressVoiceMessageAction = () => {
45
+ switch (state.status) {
46
+ case 'idle':
47
+ actions.startRecording();
48
+ break;
49
+ case 'recording':
50
+ if (lessThanMinimumDuration) {
51
+ actions.cancel();
52
+ } else {
53
+ actions.stopRecording();
54
+ }
55
+ break;
56
+ case 'recording_completed':
57
+ case 'playing_paused':
58
+ actions.playPlayer();
59
+ break;
60
+ case 'playing':
61
+ actions.pausePlayer();
62
+ break;
63
+ }
64
+ };
65
+ const renderActionIcon = () => {
66
+ switch (state.status) {
67
+ case 'idle':
68
+ return <Icon icon={'recording'} size={20} color={uiColors.recording} />;
69
+ case 'recording':
70
+ return <Icon icon={'stop'} size={20} color={uiColors.actionIcon} />;
71
+ case 'recording_completed':
72
+ case 'playing_paused':
73
+ return <Icon icon={'play'} size={20} color={uiColors.actionIcon} />;
74
+ case 'playing':
75
+ return <Icon icon={'pause'} size={20} color={uiColors.actionIcon} />;
76
+ }
77
+ };
78
+
79
+ const isRecorderState = state.status === 'recording' || state.status === 'recording_completed';
80
+ const lessThanMinimumDuration = state.recordingTime.currentTime < state.recordingTime.minDuration;
81
+ const remainingTime = state.playingTime.duration - state.playingTime.currentTime;
82
+
83
+ return (
84
+ <Box backgroundColor={uiColors.background} paddingVertical={24} paddingHorizontal={16} style={styles.container}>
85
+ {/** Progress bar **/}
86
+ <ProgressBar
87
+ style={styles.progressBar}
88
+ current={conditionChaining(
89
+ [state.status === 'recording', state.status === 'recording_completed'],
90
+ [state.recordingTime.currentTime, 0, state.playingTime.currentTime],
91
+ )}
92
+ total={(isRecorderState ? state.recordingTime.maxDuration : state.playingTime.duration) || 1}
93
+ trackColor={uiColors.progressTrack}
94
+ overlay={
95
+ <Box flex={1} flexDirection={'row'} alignItems={'center'} justifyContent={'flex-end'} paddingRight={16}>
96
+ <RecordingLight visible={state.status === 'recording'} />
97
+ <Text caption1 style={{ lineHeight: undefined, marginLeft: 6 }} color={uiColors.textTime}>
98
+ {millsToMMSS(isRecorderState ? state.recordingTime.currentTime : remainingTime)}
99
+ </Text>
100
+ </Box>
101
+ }
102
+ />
103
+
104
+ <Box height={34} alignItems={'center'} justifyContent={'center'}>
105
+ {/** Cancel / Send **/}
106
+ <Box flexDirection={'row'}>
107
+ <CancelButton label={STRINGS.LABELS.VOICE_MESSAGE_INPUT_CANCEL} onPress={onPressCancel} />
108
+ <Box flex={1} />
109
+ <SendButton disabled={state.status === 'idle' || lessThanMinimumDuration} onPress={onPressSend} />
110
+ </Box>
111
+
112
+ {/** Record / Stop / Play / Pause **/}
113
+ <Box style={{ position: 'absolute' }} alignItems={'center'} justifyContent={'center'}>
114
+ <PressBox activeOpacity={0.5} onPress={onPressVoiceMessageAction}>
115
+ <Box
116
+ width={34}
117
+ height={34}
118
+ borderRadius={17}
119
+ alignItems={'center'}
120
+ justifyContent={'center'}
121
+ backgroundColor={uiColors.actionIconBackground}
122
+ >
123
+ {renderActionIcon()}
124
+ </Box>
125
+ </PressBox>
126
+ </Box>
127
+ </Box>
128
+ </Box>
129
+ );
130
+ };
131
+
132
+ const RecordingLight = (props: { visible: boolean }) => {
133
+ const { colors } = useUIKitTheme();
134
+
135
+ const value = useRef(new Animated.Value(0)).current;
136
+ const animation = useRef(
137
+ Animated.loop(
138
+ Animated.sequence([
139
+ Animated.timing(value, { toValue: 1, duration: 500, useNativeDriver: true }),
140
+ Animated.timing(value, { toValue: 0, duration: 500, useNativeDriver: true }),
141
+ ]),
142
+ ),
143
+ ).current;
144
+
145
+ useEffect(() => {
146
+ if (props.visible) animation.start();
147
+ return () => {
148
+ animation.reset();
149
+ };
150
+ }, [props.visible]);
151
+
152
+ if (!props.visible) return null;
153
+ return (
154
+ <Animated.View
155
+ style={{
156
+ width: 12,
157
+ height: 12,
158
+ borderRadius: 6,
159
+ opacity: value,
160
+ backgroundColor: colors.ui.voiceMessageInput.default.active.recording,
161
+ }}
162
+ />
163
+ );
164
+ };
165
+
166
+ const CancelButton = (props: { onPress: () => void; label: string }) => {
167
+ const { colors } = useUIKitTheme();
168
+
169
+ return (
170
+ <PressBox activeOpacity={0.8} onPress={props.onPress}>
171
+ <Box paddingHorizontal={12} height={'100%'} alignItems={'center'} justifyContent={'center'}>
172
+ <Text button color={colors.ui.voiceMessageInput.default.active.textCancel} numberOfLines={1}>
173
+ {props.label}
174
+ </Text>
175
+ </Box>
176
+ </PressBox>
177
+ );
178
+ };
179
+
180
+ const SendButton = (props: { onPress: () => void; disabled: boolean }) => {
181
+ const { colors } = useUIKitTheme();
182
+
183
+ const uiColors = colors.ui.voiceMessageInput.default[props.disabled ? 'inactive' : 'active'];
184
+
185
+ return (
186
+ <PressBox disabled={props.disabled} activeOpacity={0.8} onPress={props.onPress}>
187
+ <Box backgroundColor={uiColors.sendIconBackground} padding={7} borderRadius={40}>
188
+ <Icon icon={'send'} size={20} color={uiColors.sendIcon} />
189
+ </Box>
190
+ </PressBox>
191
+ );
192
+ };
193
+
194
+ const styles = createStyleSheet({
195
+ container: {
196
+ borderTopLeftRadius: 8,
197
+ borderTopRightRadius: 8,
198
+ },
199
+ progressBar: {
200
+ height: 36,
201
+ marginBottom: 16,
202
+ borderRadius: 18,
203
+ },
204
+ });
205
+
206
+ export default VoiceMessageInput;
@@ -1,4 +1,4 @@
1
- import React, { MutableRefObject, useEffect, useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { KeyboardAvoidingView, Platform, TextInput, View } from 'react-native';
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
4
 
@@ -23,7 +23,10 @@ import type { MentionedUser, Range } from '../../types';
23
23
  import type { AttachmentsButtonProps } from './AttachmentsButton';
24
24
  import AttachmentsButton from './AttachmentsButton';
25
25
  import EditInput from './EditInput';
26
+ import type { MessageToReplyPreviewProps } from './MessageToReplyPreview';
27
+ import { MessageToReplyPreview } from './MessageToReplyPreview';
26
28
  import SendInput from './SendInput';
29
+ import VoiceMessageInput, { VoiceMessageInputProps } from './VoiceMessageInput';
27
30
 
28
31
  export type SuggestedMentionListProps = {
29
32
  text: string;
@@ -61,10 +64,12 @@ export type ChannelInputProps = {
61
64
  setMessageToReply?: (message?: undefined | SendbirdUserMessage | SendbirdFileMessage) => void;
62
65
 
63
66
  // mention
64
- SuggestedMentionList?: (props: SuggestedMentionListProps) => JSX.Element | null;
67
+ SuggestedMentionList?: (props: SuggestedMentionListProps) => React.ReactNode | null;
65
68
 
66
69
  // sub-components
67
- AttachmentsButton?: (props: AttachmentsButtonProps) => JSX.Element | null;
70
+ AttachmentsButton?: (props: AttachmentsButtonProps) => React.ReactNode | null;
71
+ MessageToReplyPreview?: (props: MessageToReplyPreviewProps) => React.ReactNode | null;
72
+ VoiceMessageInput?: (props: VoiceMessageInputProps) => React.ReactNode | null;
68
73
  };
69
74
 
70
75
  const AUTO_FOCUS = Platform.select({ ios: false, android: true, default: false });
@@ -93,6 +98,7 @@ const ChannelInput = (props: ChannelInputProps) => {
93
98
 
94
99
  const mentionAvailable =
95
100
  sbOptions.uikit.groupChannel.channel.enableMention && channel.isGroupChannel() && !channel.isBroadcast;
101
+
96
102
  const inputKeyToRemount = GET_INPUT_KEY(mentionAvailable ? mentionedUsers.length === 0 : false);
97
103
 
98
104
  const [inputHeight, setInputHeight] = useState(styles.inputDefault.height);
@@ -129,7 +135,9 @@ const ChannelInput = (props: ChannelInputProps) => {
129
135
  onChangeText={onChangeText}
130
136
  onSelectionChange={onSelectionChange}
131
137
  mentionedUsers={mentionedUsers}
138
+ VoiceMessageInput={props.VoiceMessageInput ?? VoiceMessageInput}
132
139
  AttachmentsButton={props.AttachmentsButton ?? AttachmentsButton}
140
+ MessageToReplyPreview={props.MessageToReplyPreview ?? MessageToReplyPreview}
133
141
  />
134
142
  )}
135
143
  {inputMode === 'edit' && messageToEdit && (
@@ -181,7 +189,7 @@ const useTextClearOnDisabled = (setText: (val: string) => void, chatDisabled: bo
181
189
  };
182
190
 
183
191
  const useAutoFocusOnEditMode = (
184
- textInputRef: MutableRefObject<TextInput | undefined>,
192
+ textInputRef: React.MutableRefObject<TextInput | undefined>,
185
193
  messageToEdit?: SendbirdBaseMessage,
186
194
  ) => {
187
195
  useEffect(() => {
@@ -22,6 +22,7 @@ import {
22
22
  getFileExtension,
23
23
  getFileType,
24
24
  isMyMessage,
25
+ isVoiceMessage,
25
26
  messageKeyExtractor,
26
27
  shouldRenderReaction,
27
28
  toMegabyte,
@@ -277,7 +278,7 @@ const useGetMessagePressActions = <T extends SendbirdGroupChannel | SendbirdOpen
277
278
  },
278
279
  });
279
280
  }
280
- if (msg.isFileMessage()) {
281
+ if (!isVoiceMessage(msg) && msg.isFileMessage()) {
281
282
  sheetItems.push({
282
283
  icon: 'download',
283
284
  title: STRINGS.LABELS.CHANNEL_MESSAGE_SAVE,
@@ -299,6 +300,7 @@ const useGetMessagePressActions = <T extends SendbirdGroupChannel | SendbirdOpen
299
300
  },
300
301
  });
301
302
  }
303
+
302
304
  if (!channel.isEphemeral) {
303
305
  if (isMyMessage(msg, currentUserId) && msg.sendingStatus === 'succeeded') {
304
306
  if (msg.isUserMessage()) {
@@ -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,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useRef } from 'react';
2
2
 
3
3
  import type { GroupChannelMessageProps, RegexTextPattern } from '@sendbird/uikit-react-native-foundation';
4
4
  import { Box, GroupChannelMessage, Text, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
@@ -10,11 +10,13 @@ import {
10
10
  calcMessageGrouping,
11
11
  getMessageType,
12
12
  isMyMessage,
13
+ isVoiceMessage,
13
14
  shouldRenderParentMessage,
14
15
  shouldRenderReaction,
15
16
  useIIFE,
16
17
  } from '@sendbird/uikit-utils';
17
18
 
19
+ import { VOICE_MESSAGE_META_ARRAY_DURATION_KEY } from '../../constants';
18
20
  import type { GroupChannelProps } from '../../domain/groupChannel/types';
19
21
  import { useLocalization, usePlatformService, useSendbirdChat } from '../../hooks/useContext';
20
22
  import SBUUtils from '../../libs/SBUUtils';
@@ -36,10 +38,11 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
36
38
  prevMessage,
37
39
  nextMessage,
38
40
  }) => {
41
+ const playerUnsubscribes = useRef<(() => void)[]>([]);
39
42
  const { palette } = useUIKitTheme();
40
43
  const { sbOptions, currentUser, mentionManager } = useSendbirdChat();
41
44
  const { STRINGS } = useLocalization();
42
- const { mediaService } = usePlatformService();
45
+ const { mediaService, playerService } = usePlatformService();
43
46
  const { groupWithPrev, groupWithNext } = calcMessageGrouping(
44
47
  Boolean(enableMessageGrouping),
45
48
  message,
@@ -58,6 +61,16 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
58
61
  return null;
59
62
  });
60
63
 
64
+ const resetPlayer = async () => {
65
+ playerUnsubscribes.current.forEach((unsubscribe) => {
66
+ try {
67
+ unsubscribe();
68
+ } catch {}
69
+ });
70
+ playerUnsubscribes.current.length = 0;
71
+ await playerService.reset();
72
+ };
73
+
61
74
  const variant = isMyMessage(message, currentUser?.userId) ? 'outgoing' : 'incoming';
62
75
 
63
76
  const messageProps: Omit<GroupChannelMessageProps<SendbirdMessage>, 'message'> = {
@@ -72,6 +85,55 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
72
85
  onPressMentionedUser: (mentionedUser) => {
73
86
  if (mentionedUser) onShowUserProfile?.(mentionedUser);
74
87
  },
88
+ onToggleVoiceMessage: async (state, setState) => {
89
+ if (isVoiceMessage(message) && message.sendingStatus === 'succeeded') {
90
+ if (playerService.uri === message.url) {
91
+ if (playerService.state === 'playing') {
92
+ await playerService.pause();
93
+ } else {
94
+ await playerService.play(message.url);
95
+ }
96
+ } else {
97
+ if (playerService.state !== 'idle') {
98
+ await resetPlayer();
99
+ }
100
+
101
+ const shouldSeekToTime = state.duration > state.currentTime && state.currentTime > 0;
102
+ let seekFinished = !shouldSeekToTime;
103
+
104
+ const forPlayback = playerService.addPlaybackListener(({ stopped, currentTime, duration }) => {
105
+ if (seekFinished) {
106
+ setState((prevState) => ({ ...prevState, currentTime: stopped ? 0 : currentTime, duration }));
107
+ }
108
+ });
109
+ const forState = playerService.addStateListener((state) => {
110
+ switch (state) {
111
+ case 'preparing':
112
+ setState((prevState) => ({ ...prevState, status: 'preparing' }));
113
+ break;
114
+ case 'playing':
115
+ setState((prevState) => ({ ...prevState, status: 'playing' }));
116
+ break;
117
+ case 'idle':
118
+ case 'paused': {
119
+ setState((prevState) => ({ ...prevState, status: 'paused' }));
120
+ break;
121
+ }
122
+ case 'stopped':
123
+ setState((prevState) => ({ ...prevState, status: 'paused' }));
124
+ break;
125
+ }
126
+ });
127
+ playerUnsubscribes.current.push(forPlayback, forState);
128
+
129
+ await playerService.play(message.url);
130
+ if (shouldSeekToTime) {
131
+ await playerService.seek(state.currentTime);
132
+ seekFinished = true;
133
+ }
134
+ }
135
+ }
136
+ },
75
137
  groupedWithPrev: groupWithPrev,
76
138
  groupedWithNext: groupWithNext,
77
139
  children: reactionChildren,
@@ -80,9 +142,10 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
80
142
  ) : null,
81
143
  parentMessage: shouldRenderParentMessage(message) ? (
82
144
  <GroupChannelMessageParentMessage
145
+ channel={channel}
146
+ message={message.parentMessage}
83
147
  variant={variant}
84
148
  childMessage={message}
85
- message={message.parentMessage}
86
149
  onPress={onPressParentMessage}
87
150
  />
88
151
  ) : null,
@@ -184,6 +247,20 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
184
247
  />
185
248
  );
186
249
  }
250
+ case 'file.voice': {
251
+ return (
252
+ <GroupChannelMessage.VoiceFile
253
+ message={message as SendbirdFileMessage}
254
+ durationMetaArrayKey={VOICE_MESSAGE_META_ARRAY_DURATION_KEY}
255
+ onUnmount={() => {
256
+ if (isVoiceMessage(message) && playerService.uri === message.url) {
257
+ resetPlayer();
258
+ }
259
+ }}
260
+ {...messageProps}
261
+ />
262
+ );
263
+ }
187
264
  case 'unknown':
188
265
  default: {
189
266
  return <GroupChannelMessage.Unknown message={message} {...messageProps} />;
@@ -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 = {