@sendbird/uikit-react-native 2.1.0 → 2.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 (388) hide show
  1. package/lib/commonjs/components/ChatFlatList.js +2 -1
  2. package/lib/commonjs/components/ChatFlatList.js.map +1 -1
  3. package/lib/commonjs/components/MessageRenderer/FileMessage/BaseFileMessage.js +11 -6
  4. package/lib/commonjs/components/MessageRenderer/FileMessage/BaseFileMessage.js.map +1 -1
  5. package/lib/commonjs/components/MessageRenderer/FileMessage/ImageFileMessage.js +12 -2
  6. package/lib/commonjs/components/MessageRenderer/FileMessage/ImageFileMessage.js.map +1 -1
  7. package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js +25 -10
  8. package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -1
  9. package/lib/commonjs/components/MessageRenderer/UserMessage/BaseUserMessage.js +86 -10
  10. package/lib/commonjs/components/MessageRenderer/UserMessage/BaseUserMessage.js.map +1 -1
  11. package/lib/commonjs/components/MessageRenderer/UserMessage/OpenGraphUserMessage.js +99 -14
  12. package/lib/commonjs/components/MessageRenderer/UserMessage/OpenGraphUserMessage.js.map +1 -1
  13. package/lib/commonjs/components/MessageRenderer/UserMessage/index.js.map +1 -1
  14. package/lib/commonjs/components/MessageRenderer/index.js +22 -3
  15. package/lib/commonjs/components/MessageRenderer/index.js.map +1 -1
  16. package/lib/commonjs/components/ReactionAddons/BottomSheetReactionAddon.js +150 -0
  17. package/lib/commonjs/components/ReactionAddons/BottomSheetReactionAddon.js.map +1 -0
  18. package/lib/commonjs/components/ReactionAddons/MessageReactionAddon.js +135 -0
  19. package/lib/commonjs/components/ReactionAddons/MessageReactionAddon.js.map +1 -0
  20. package/lib/commonjs/components/ReactionAddons/ReactionRoundedButton.js +87 -0
  21. package/lib/commonjs/components/ReactionAddons/ReactionRoundedButton.js.map +1 -0
  22. package/lib/commonjs/components/ReactionAddons/index.js +19 -0
  23. package/lib/commonjs/components/ReactionAddons/index.js.map +1 -0
  24. package/lib/commonjs/components/ReactionBottomSheets/ReactionListBottomSheet.js +150 -0
  25. package/lib/commonjs/components/ReactionBottomSheets/ReactionListBottomSheet.js.map +1 -0
  26. package/lib/commonjs/components/ReactionBottomSheets/ReactionUserListBottomSheet.js +276 -0
  27. package/lib/commonjs/components/ReactionBottomSheets/ReactionUserListBottomSheet.js.map +1 -0
  28. package/lib/commonjs/components/ReactionBottomSheets/index.js +19 -0
  29. package/lib/commonjs/components/ReactionBottomSheets/index.js.map +1 -0
  30. package/lib/commonjs/constants.js +3 -1
  31. package/lib/commonjs/constants.js.map +1 -1
  32. package/lib/commonjs/containers/GroupChannelPreviewContainer.js +4 -1
  33. package/lib/commonjs/containers/GroupChannelPreviewContainer.js.map +1 -1
  34. package/lib/commonjs/containers/SendbirdUIKitContainer.js +118 -78
  35. package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -1
  36. package/lib/commonjs/contexts/ReactionCtx.js +107 -0
  37. package/lib/commonjs/contexts/ReactionCtx.js.map +1 -0
  38. package/lib/commonjs/contexts/SendbirdChatCtx.js +18 -6
  39. package/lib/commonjs/contexts/SendbirdChatCtx.js.map +1 -1
  40. package/lib/commonjs/contexts/UserProfileCtx.js +9 -0
  41. package/lib/commonjs/contexts/UserProfileCtx.js.map +1 -1
  42. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/EditInput.js +33 -37
  43. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/EditInput.js.map +1 -1
  44. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js +28 -11
  45. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
  46. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/index.js +120 -31
  47. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/index.js.map +1 -1
  48. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +31 -12
  49. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  50. package/lib/commonjs/domain/groupChannel/component/GroupChannelSuggestedMentionList.js +210 -0
  51. package/lib/commonjs/domain/groupChannel/component/GroupChannelSuggestedMentionList.js.map +1 -0
  52. package/lib/commonjs/domain/groupChannel/index.js +8 -0
  53. package/lib/commonjs/domain/groupChannel/index.js.map +1 -1
  54. package/lib/commonjs/domain/groupChannel/module/createGroupChannelModule.js +4 -0
  55. package/lib/commonjs/domain/groupChannel/module/createGroupChannelModule.js.map +1 -1
  56. package/lib/commonjs/domain/groupChannel/module/moduleContext.js +4 -4
  57. package/lib/commonjs/domain/groupChannel/module/moduleContext.js.map +1 -1
  58. package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
  59. package/lib/commonjs/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.js +3 -2
  60. package/lib/commonjs/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.js.map +1 -1
  61. package/lib/commonjs/domain/groupChannelList/component/GroupChannelListList.js +2 -1
  62. package/lib/commonjs/domain/groupChannelList/component/GroupChannelListList.js.map +1 -1
  63. package/lib/commonjs/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.js +2 -1
  64. package/lib/commonjs/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.js.map +1 -1
  65. package/lib/commonjs/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.js +39 -0
  66. package/lib/commonjs/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.js.map +1 -0
  67. package/lib/commonjs/domain/groupChannelNotifications/component/GroupChannelNotificationsView.js +140 -0
  68. package/lib/commonjs/domain/groupChannelNotifications/component/GroupChannelNotificationsView.js.map +1 -0
  69. package/lib/commonjs/domain/groupChannelNotifications/index.js +46 -0
  70. package/lib/commonjs/domain/groupChannelNotifications/index.js.map +1 -0
  71. package/lib/commonjs/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.js +33 -0
  72. package/lib/commonjs/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.js.map +1 -0
  73. package/lib/commonjs/domain/groupChannelNotifications/module/moduleContext.js +45 -0
  74. package/lib/commonjs/domain/groupChannelNotifications/module/moduleContext.js.map +1 -0
  75. package/lib/commonjs/domain/groupChannelNotifications/types.js +6 -0
  76. package/lib/commonjs/domain/groupChannelNotifications/types.js.map +1 -0
  77. package/lib/commonjs/domain/groupChannelOperators/component/GroupChannelOperatorsList.js +2 -1
  78. package/lib/commonjs/domain/groupChannelOperators/component/GroupChannelOperatorsList.js.map +1 -1
  79. package/lib/commonjs/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js +49 -6
  80. package/lib/commonjs/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js.map +1 -1
  81. package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js +9 -14
  82. package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
  83. package/lib/commonjs/domain/groupChannelSettings/types.js.map +1 -1
  84. package/lib/commonjs/domain/groupChannelUserList/types.js.map +1 -1
  85. package/lib/commonjs/domain/userList/component/UserListList.js +4 -1
  86. package/lib/commonjs/domain/userList/component/UserListList.js.map +1 -1
  87. package/lib/commonjs/domain/userList/module/createUserListModule.js.map +1 -1
  88. package/lib/commonjs/fragments/createGroupChannelCreateFragment.js.map +1 -1
  89. package/lib/commonjs/fragments/createGroupChannelFragment.js +11 -4
  90. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  91. package/lib/commonjs/fragments/createGroupChannelInviteFragment.js.map +1 -1
  92. package/lib/commonjs/fragments/createGroupChannelNotificationsFragment.js +34 -0
  93. package/lib/commonjs/fragments/createGroupChannelNotificationsFragment.js.map +1 -0
  94. package/lib/commonjs/fragments/createGroupChannelSettingsFragment.js +3 -1
  95. package/lib/commonjs/fragments/createGroupChannelSettingsFragment.js.map +1 -1
  96. package/lib/commonjs/hooks/useConnection.js +3 -0
  97. package/lib/commonjs/hooks/useConnection.js.map +1 -1
  98. package/lib/commonjs/hooks/useContext.js +11 -1
  99. package/lib/commonjs/hooks/useContext.js.map +1 -1
  100. package/lib/commonjs/hooks/useKeyboardStatus.js +93 -0
  101. package/lib/commonjs/hooks/useKeyboardStatus.js.map +1 -0
  102. package/lib/commonjs/hooks/useMentionSuggestion.js +110 -0
  103. package/lib/commonjs/hooks/useMentionSuggestion.js.map +1 -0
  104. package/lib/commonjs/hooks/useMentionTextInput.js +139 -0
  105. package/lib/commonjs/hooks/useMentionTextInput.js.map +1 -0
  106. package/lib/commonjs/index.js +95 -40
  107. package/lib/commonjs/index.js.map +1 -1
  108. package/lib/commonjs/libs/EmojiManager.js +100 -0
  109. package/lib/commonjs/libs/EmojiManager.js.map +1 -0
  110. package/lib/commonjs/libs/MentionConfig.js +47 -0
  111. package/lib/commonjs/libs/MentionConfig.js.map +1 -0
  112. package/lib/commonjs/libs/MentionManager.js +235 -0
  113. package/lib/commonjs/libs/MentionManager.js.map +1 -0
  114. package/lib/commonjs/localization/StringSet.type.js +17 -5
  115. package/lib/commonjs/localization/StringSet.type.js.map +1 -1
  116. package/lib/commonjs/types.js.map +1 -1
  117. package/lib/commonjs/utils/common.js +19 -0
  118. package/lib/commonjs/utils/common.js.map +1 -0
  119. package/lib/commonjs/version.js +1 -1
  120. package/lib/commonjs/version.js.map +1 -1
  121. package/lib/module/components/ChatFlatList.js +3 -2
  122. package/lib/module/components/ChatFlatList.js.map +1 -1
  123. package/lib/module/components/MessageRenderer/FileMessage/BaseFileMessage.js +11 -6
  124. package/lib/module/components/MessageRenderer/FileMessage/BaseFileMessage.js.map +1 -1
  125. package/lib/module/components/MessageRenderer/FileMessage/ImageFileMessage.js +12 -2
  126. package/lib/module/components/MessageRenderer/FileMessage/ImageFileMessage.js.map +1 -1
  127. package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js +25 -10
  128. package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -1
  129. package/lib/module/components/MessageRenderer/UserMessage/BaseUserMessage.js +86 -12
  130. package/lib/module/components/MessageRenderer/UserMessage/BaseUserMessage.js.map +1 -1
  131. package/lib/module/components/MessageRenderer/UserMessage/OpenGraphUserMessage.js +101 -17
  132. package/lib/module/components/MessageRenderer/UserMessage/OpenGraphUserMessage.js.map +1 -1
  133. package/lib/module/components/MessageRenderer/UserMessage/index.js.map +1 -1
  134. package/lib/module/components/MessageRenderer/index.js +21 -4
  135. package/lib/module/components/MessageRenderer/index.js.map +1 -1
  136. package/lib/module/components/ReactionAddons/BottomSheetReactionAddon.js +132 -0
  137. package/lib/module/components/ReactionAddons/BottomSheetReactionAddon.js.map +1 -0
  138. package/lib/module/components/ReactionAddons/MessageReactionAddon.js +118 -0
  139. package/lib/module/components/ReactionAddons/MessageReactionAddon.js.map +1 -0
  140. package/lib/module/components/ReactionAddons/ReactionRoundedButton.js +74 -0
  141. package/lib/module/components/ReactionAddons/ReactionRoundedButton.js.map +1 -0
  142. package/lib/module/components/ReactionAddons/index.js +7 -0
  143. package/lib/module/components/ReactionAddons/index.js.map +1 -0
  144. package/lib/module/components/ReactionBottomSheets/ReactionListBottomSheet.js +135 -0
  145. package/lib/module/components/ReactionBottomSheets/ReactionListBottomSheet.js.map +1 -0
  146. package/lib/module/components/ReactionBottomSheets/ReactionUserListBottomSheet.js +259 -0
  147. package/lib/module/components/ReactionBottomSheets/ReactionUserListBottomSheet.js.map +1 -0
  148. package/lib/module/components/ReactionBottomSheets/index.js +7 -0
  149. package/lib/module/components/ReactionBottomSheets/index.js.map +1 -0
  150. package/lib/module/constants.js +1 -0
  151. package/lib/module/constants.js.map +1 -1
  152. package/lib/module/containers/GroupChannelPreviewContainer.js +4 -1
  153. package/lib/module/containers/GroupChannelPreviewContainer.js.map +1 -1
  154. package/lib/module/containers/SendbirdUIKitContainer.js +116 -80
  155. package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -1
  156. package/lib/module/contexts/ReactionCtx.js +85 -0
  157. package/lib/module/contexts/ReactionCtx.js.map +1 -0
  158. package/lib/module/contexts/SendbirdChatCtx.js +18 -6
  159. package/lib/module/contexts/SendbirdChatCtx.js.map +1 -1
  160. package/lib/module/contexts/UserProfileCtx.js +7 -0
  161. package/lib/module/contexts/UserProfileCtx.js.map +1 -1
  162. package/lib/module/domain/groupChannel/component/GroupChannelInput/EditInput.js +34 -39
  163. package/lib/module/domain/groupChannel/component/GroupChannelInput/EditInput.js.map +1 -1
  164. package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js +24 -13
  165. package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
  166. package/lib/module/domain/groupChannel/component/GroupChannelInput/index.js +117 -33
  167. package/lib/module/domain/groupChannel/component/GroupChannelInput/index.js.map +1 -1
  168. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +32 -14
  169. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  170. package/lib/module/domain/groupChannel/component/GroupChannelSuggestedMentionList.js +188 -0
  171. package/lib/module/domain/groupChannel/component/GroupChannelSuggestedMentionList.js.map +1 -0
  172. package/lib/module/domain/groupChannel/index.js +1 -0
  173. package/lib/module/domain/groupChannel/index.js.map +1 -1
  174. package/lib/module/domain/groupChannel/module/createGroupChannelModule.js +3 -0
  175. package/lib/module/domain/groupChannel/module/createGroupChannelModule.js.map +1 -1
  176. package/lib/module/domain/groupChannel/module/moduleContext.js +4 -4
  177. package/lib/module/domain/groupChannel/module/moduleContext.js.map +1 -1
  178. package/lib/module/domain/groupChannel/types.js.map +1 -1
  179. package/lib/module/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.js +4 -3
  180. package/lib/module/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.js.map +1 -1
  181. package/lib/module/domain/groupChannelList/component/GroupChannelListList.js +3 -2
  182. package/lib/module/domain/groupChannelList/component/GroupChannelListList.js.map +1 -1
  183. package/lib/module/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.js +3 -2
  184. package/lib/module/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.js.map +1 -1
  185. package/lib/module/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.js +25 -0
  186. package/lib/module/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.js.map +1 -0
  187. package/lib/module/domain/groupChannelNotifications/component/GroupChannelNotificationsView.js +122 -0
  188. package/lib/module/domain/groupChannelNotifications/component/GroupChannelNotificationsView.js.map +1 -0
  189. package/lib/module/domain/groupChannelNotifications/index.js +5 -0
  190. package/lib/module/domain/groupChannelNotifications/index.js.map +1 -0
  191. package/lib/module/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.js +21 -0
  192. package/lib/module/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.js.map +1 -0
  193. package/lib/module/domain/groupChannelNotifications/module/moduleContext.js +25 -0
  194. package/lib/module/domain/groupChannelNotifications/module/moduleContext.js.map +1 -0
  195. package/lib/module/domain/groupChannelNotifications/types.js +2 -0
  196. package/lib/module/domain/groupChannelNotifications/types.js.map +1 -0
  197. package/lib/module/domain/groupChannelOperators/component/GroupChannelOperatorsList.js +3 -2
  198. package/lib/module/domain/groupChannelOperators/component/GroupChannelOperatorsList.js.map +1 -1
  199. package/lib/module/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js +46 -6
  200. package/lib/module/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js.map +1 -1
  201. package/lib/module/domain/groupChannelSettings/module/moduleContext.js +10 -15
  202. package/lib/module/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
  203. package/lib/module/domain/groupChannelSettings/types.js.map +1 -1
  204. package/lib/module/domain/groupChannelUserList/types.js.map +1 -1
  205. package/lib/module/domain/userList/component/UserListList.js +3 -1
  206. package/lib/module/domain/userList/component/UserListList.js.map +1 -1
  207. package/lib/module/domain/userList/module/createUserListModule.js.map +1 -1
  208. package/lib/module/fragments/createGroupChannelCreateFragment.js.map +1 -1
  209. package/lib/module/fragments/createGroupChannelFragment.js +11 -4
  210. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  211. package/lib/module/fragments/createGroupChannelInviteFragment.js.map +1 -1
  212. package/lib/module/fragments/createGroupChannelNotificationsFragment.js +22 -0
  213. package/lib/module/fragments/createGroupChannelNotificationsFragment.js.map +1 -0
  214. package/lib/module/fragments/createGroupChannelSettingsFragment.js +3 -1
  215. package/lib/module/fragments/createGroupChannelSettingsFragment.js.map +1 -1
  216. package/lib/module/hooks/useConnection.js +3 -0
  217. package/lib/module/hooks/useConnection.js.map +1 -1
  218. package/lib/module/hooks/useContext.js +6 -0
  219. package/lib/module/hooks/useContext.js.map +1 -1
  220. package/lib/module/hooks/useKeyboardStatus.js +75 -0
  221. package/lib/module/hooks/useKeyboardStatus.js.map +1 -0
  222. package/lib/module/hooks/useMentionSuggestion.js +100 -0
  223. package/lib/module/hooks/useMentionSuggestion.js.map +1 -0
  224. package/lib/module/hooks/useMentionTextInput.js +128 -0
  225. package/lib/module/hooks/useMentionTextInput.js.map +1 -0
  226. package/lib/module/index.js +8 -3
  227. package/lib/module/index.js.map +1 -1
  228. package/lib/module/libs/EmojiManager.js +90 -0
  229. package/lib/module/libs/EmojiManager.js.map +1 -0
  230. package/lib/module/libs/MentionConfig.js +39 -0
  231. package/lib/module/libs/MentionConfig.js.map +1 -0
  232. package/lib/module/libs/MentionManager.js +223 -0
  233. package/lib/module/libs/MentionManager.js.map +1 -0
  234. package/lib/module/localization/StringSet.type.js +18 -6
  235. package/lib/module/localization/StringSet.type.js.map +1 -1
  236. package/lib/module/types.js.map +1 -1
  237. package/lib/module/utils/common.js +7 -0
  238. package/lib/module/utils/common.js.map +1 -0
  239. package/lib/module/version.js +1 -1
  240. package/lib/module/version.js.map +1 -1
  241. package/lib/typescript/__template__/types.d.ts +3 -3
  242. package/lib/typescript/src/components/ChannelCover.d.ts +1 -1
  243. package/lib/typescript/src/components/ChatFlatList.d.ts +1 -1
  244. package/lib/typescript/src/components/FileViewer.d.ts +1 -1
  245. package/lib/typescript/src/components/MessageRenderer/AdminMessage/index.d.ts +1 -1
  246. package/lib/typescript/src/components/MessageRenderer/FileMessage/BaseFileMessage.d.ts +2 -2
  247. package/lib/typescript/src/components/MessageRenderer/FileMessage/ImageFileMessage.d.ts +1 -1
  248. package/lib/typescript/src/components/MessageRenderer/FileMessage/VideoFileMessage.d.ts +1 -1
  249. package/lib/typescript/src/components/MessageRenderer/FileMessage/index.d.ts +11 -2
  250. package/lib/typescript/src/components/MessageRenderer/MessageDateSeparator.d.ts +1 -1
  251. package/lib/typescript/src/components/MessageRenderer/MessageIncomingAvatar.d.ts +1 -1
  252. package/lib/typescript/src/components/MessageRenderer/MessageIncomingSenderName.d.ts +1 -1
  253. package/lib/typescript/src/components/MessageRenderer/MessageOutgoingStatus.d.ts +1 -1
  254. package/lib/typescript/src/components/MessageRenderer/MessageTime.d.ts +1 -1
  255. package/lib/typescript/src/components/MessageRenderer/UnknownMessage/index.d.ts +1 -1
  256. package/lib/typescript/src/components/MessageRenderer/UserMessage/BaseUserMessage.d.ts +1 -1
  257. package/lib/typescript/src/components/MessageRenderer/UserMessage/OpenGraphUserMessage.d.ts +2 -2
  258. package/lib/typescript/src/components/MessageRenderer/UserMessage/index.d.ts +4 -1
  259. package/lib/typescript/src/components/MessageRenderer/index.d.ts +4 -3
  260. package/lib/typescript/src/components/NewMessagesButton.d.ts +1 -1
  261. package/lib/typescript/src/components/ReactionAddons/BottomSheetReactionAddon.d.ts +8 -0
  262. package/lib/typescript/src/components/ReactionAddons/MessageReactionAddon.d.ts +6 -0
  263. package/lib/typescript/src/components/ReactionAddons/ReactionRoundedButton.d.ts +14 -0
  264. package/lib/typescript/src/components/ReactionAddons/index.d.ts +11 -0
  265. package/lib/typescript/src/components/ReactionBottomSheets/ReactionListBottomSheet.d.ts +3 -0
  266. package/lib/typescript/src/components/ReactionBottomSheets/ReactionUserListBottomSheet.d.ts +3 -0
  267. package/lib/typescript/src/components/ReactionBottomSheets/index.d.ts +20 -0
  268. package/lib/typescript/src/components/ScrollToBottomButton.d.ts +1 -1
  269. package/lib/typescript/src/components/StatusComposition.d.ts +1 -1
  270. package/lib/typescript/src/components/TypedPlaceholder.d.ts +1 -1
  271. package/lib/typescript/src/components/UserActionBar.d.ts +1 -1
  272. package/lib/typescript/src/components/UserSelectableBar.d.ts +1 -1
  273. package/lib/typescript/src/constants.d.ts +1 -0
  274. package/lib/typescript/src/containers/GroupChannelPreviewContainer.d.ts +1 -1
  275. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +12 -3
  276. package/lib/typescript/src/contexts/LocalizationCtx.d.ts +2 -2
  277. package/lib/typescript/src/contexts/PlatformServiceCtx.d.ts +1 -1
  278. package/lib/typescript/src/contexts/ReactionCtx.d.ts +18 -0
  279. package/lib/typescript/src/contexts/SendbirdChatCtx.d.ts +10 -2
  280. package/lib/typescript/src/contexts/UserProfileCtx.d.ts +4 -4
  281. package/lib/typescript/src/domain/groupChannel/component/GroupChannelInput/EditInput.d.ts +35 -7
  282. package/lib/typescript/src/domain/groupChannel/component/GroupChannelInput/SendInput.d.ts +32 -5
  283. package/lib/typescript/src/domain/groupChannel/component/GroupChannelInput/index.d.ts +19 -2
  284. package/lib/typescript/src/domain/groupChannel/component/GroupChannelSuggestedMentionList.d.ts +3 -0
  285. package/lib/typescript/src/domain/groupChannel/index.d.ts +1 -0
  286. package/lib/typescript/src/domain/groupChannel/module/createGroupChannelModule.d.ts +1 -1
  287. package/lib/typescript/src/domain/groupChannel/types.d.ts +24 -7
  288. package/lib/typescript/src/domain/groupChannelBannedUsers/types.d.ts +3 -3
  289. package/lib/typescript/src/domain/groupChannelList/types.d.ts +2 -2
  290. package/lib/typescript/src/domain/groupChannelModeration/types.d.ts +3 -3
  291. package/lib/typescript/src/domain/groupChannelMutedMembers/types.d.ts +3 -3
  292. package/lib/typescript/src/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.d.ts +3 -0
  293. package/lib/typescript/src/domain/groupChannelNotifications/component/GroupChannelNotificationsView.d.ts +2 -0
  294. package/lib/typescript/src/domain/groupChannelNotifications/index.d.ts +4 -0
  295. package/lib/typescript/src/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.d.ts +3 -0
  296. package/lib/typescript/src/domain/groupChannelNotifications/module/moduleContext.d.ts +3 -0
  297. package/lib/typescript/src/domain/groupChannelNotifications/types.d.ts +33 -0
  298. package/lib/typescript/src/domain/groupChannelOperators/types.d.ts +3 -3
  299. package/lib/typescript/src/domain/groupChannelSettings/component/GroupChannelSettingsMenu.d.ts +1 -1
  300. package/lib/typescript/src/domain/groupChannelSettings/types.d.ts +3 -1
  301. package/lib/typescript/src/domain/groupChannelUserList/types.d.ts +6 -6
  302. package/lib/typescript/src/domain/userList/component/UserListList.d.ts +2 -1
  303. package/lib/typescript/src/domain/userList/module/createUserListModule.d.ts +2 -1
  304. package/lib/typescript/src/fragments/createGroupChannelCreateFragment.d.ts +1 -1
  305. package/lib/typescript/src/fragments/createGroupChannelInviteFragment.d.ts +1 -1
  306. package/lib/typescript/src/fragments/createGroupChannelNotificationsFragment.d.ts +3 -0
  307. package/lib/typescript/src/hooks/useConnection.d.ts +1 -1
  308. package/lib/typescript/src/hooks/useContext.d.ts +4 -0
  309. package/lib/typescript/src/hooks/useKeyboardStatus.d.ts +6 -0
  310. package/lib/typescript/src/hooks/useMentionSuggestion.d.ts +17 -0
  311. package/lib/typescript/src/hooks/useMentionTextInput.d.ts +18 -0
  312. package/lib/typescript/src/index.d.ts +7 -2
  313. package/lib/typescript/src/libs/EmojiManager.d.ts +16 -0
  314. package/lib/typescript/src/libs/MentionConfig.d.ts +24 -0
  315. package/lib/typescript/src/libs/MentionManager.d.ts +61 -0
  316. package/lib/typescript/src/localization/StringSet.type.d.ts +16 -2
  317. package/lib/typescript/src/platform/createMediaService.expo.d.ts +1 -1
  318. package/lib/typescript/src/platform/createMediaService.native.d.ts +1 -1
  319. package/lib/typescript/src/platform/dynamicModule.d.ts +1 -1
  320. package/lib/typescript/src/platform/types.d.ts +5 -5
  321. package/lib/typescript/src/types.d.ts +13 -4
  322. package/lib/typescript/src/utils/common.d.ts +1 -0
  323. package/lib/typescript/src/version.d.ts +1 -1
  324. package/package.json +6 -6
  325. package/src/components/ChatFlatList.tsx +2 -1
  326. package/src/components/MessageRenderer/FileMessage/BaseFileMessage.tsx +17 -12
  327. package/src/components/MessageRenderer/FileMessage/ImageFileMessage.tsx +25 -18
  328. package/src/components/MessageRenderer/FileMessage/VideoFileMessage.tsx +20 -10
  329. package/src/components/MessageRenderer/UserMessage/BaseUserMessage.tsx +82 -14
  330. package/src/components/MessageRenderer/UserMessage/OpenGraphUserMessage.tsx +135 -61
  331. package/src/components/MessageRenderer/UserMessage/index.tsx +8 -1
  332. package/src/components/MessageRenderer/index.tsx +39 -7
  333. package/src/components/ReactionAddons/BottomSheetReactionAddon.tsx +106 -0
  334. package/src/components/ReactionAddons/MessageReactionAddon.tsx +123 -0
  335. package/src/components/ReactionAddons/ReactionRoundedButton.tsx +71 -0
  336. package/src/components/ReactionAddons/index.tsx +7 -0
  337. package/src/components/ReactionBottomSheets/ReactionListBottomSheet.tsx +113 -0
  338. package/src/components/ReactionBottomSheets/ReactionUserListBottomSheet.tsx +249 -0
  339. package/src/components/ReactionBottomSheets/index.tsx +24 -0
  340. package/src/constants.ts +2 -0
  341. package/src/containers/GroupChannelPreviewContainer.tsx +3 -1
  342. package/src/containers/SendbirdUIKitContainer.tsx +141 -83
  343. package/src/contexts/ReactionCtx.tsx +102 -0
  344. package/src/contexts/SendbirdChatCtx.tsx +24 -2
  345. package/src/contexts/UserProfileCtx.tsx +9 -0
  346. package/src/domain/groupChannel/component/GroupChannelInput/EditInput.tsx +56 -30
  347. package/src/domain/groupChannel/component/GroupChannelInput/SendInput.tsx +48 -19
  348. package/src/domain/groupChannel/component/GroupChannelInput/index.tsx +137 -43
  349. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +27 -10
  350. package/src/domain/groupChannel/component/GroupChannelSuggestedMentionList.tsx +173 -0
  351. package/src/domain/groupChannel/index.ts +1 -0
  352. package/src/domain/groupChannel/module/createGroupChannelModule.tsx +12 -1
  353. package/src/domain/groupChannel/module/moduleContext.tsx +4 -4
  354. package/src/domain/groupChannel/types.ts +28 -5
  355. package/src/domain/groupChannelBannedUsers/component/GroupChannelBannedUsersList.tsx +3 -2
  356. package/src/domain/groupChannelList/component/GroupChannelListList.tsx +2 -1
  357. package/src/domain/groupChannelMutedMembers/component/GroupChannelMutedMembersList.tsx +2 -1
  358. package/src/domain/groupChannelNotifications/component/GroupChannelNotificationsHeader.tsx +14 -0
  359. package/src/domain/groupChannelNotifications/component/GroupChannelNotificationsView.tsx +128 -0
  360. package/src/domain/groupChannelNotifications/index.ts +4 -0
  361. package/src/domain/groupChannelNotifications/module/createGroupChannelNotificationsModule.tsx +15 -0
  362. package/src/domain/groupChannelNotifications/module/moduleContext.tsx +31 -0
  363. package/src/domain/groupChannelNotifications/types.ts +38 -0
  364. package/src/domain/groupChannelOperators/component/GroupChannelOperatorsList.tsx +2 -1
  365. package/src/domain/groupChannelSettings/component/GroupChannelSettingsMenu.tsx +42 -3
  366. package/src/domain/groupChannelSettings/module/moduleContext.tsx +9 -12
  367. package/src/domain/groupChannelSettings/types.ts +2 -0
  368. package/src/domain/groupChannelUserList/types.ts +7 -2
  369. package/src/domain/userList/component/UserListList.tsx +5 -1
  370. package/src/domain/userList/module/createUserListModule.tsx +3 -1
  371. package/src/fragments/createGroupChannelCreateFragment.tsx +8 -2
  372. package/src/fragments/createGroupChannelFragment.tsx +19 -6
  373. package/src/fragments/createGroupChannelInviteFragment.tsx +2 -2
  374. package/src/fragments/createGroupChannelNotificationsFragment.tsx +27 -0
  375. package/src/fragments/createGroupChannelSettingsFragment.tsx +2 -0
  376. package/src/hooks/useConnection.ts +3 -1
  377. package/src/hooks/useContext.ts +7 -0
  378. package/src/hooks/useKeyboardStatus.ts +54 -0
  379. package/src/hooks/useMentionSuggestion.ts +106 -0
  380. package/src/hooks/useMentionTextInput.ts +139 -0
  381. package/src/index.ts +13 -2
  382. package/src/libs/EmojiManager.ts +80 -0
  383. package/src/libs/MentionConfig.ts +40 -0
  384. package/src/libs/MentionManager.tsx +240 -0
  385. package/src/localization/StringSet.type.ts +38 -8
  386. package/src/types.ts +12 -0
  387. package/src/utils/common.ts +8 -0
  388. package/src/version.ts +1 -1
@@ -0,0 +1,139 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import type { NativeSyntheticEvent, TextInput, TextInputSelectionChangeEventData } from 'react-native';
3
+ import { Platform } from 'react-native';
4
+
5
+ import { SendbirdFileMessage, SendbirdUserMessage, replace, useFreshCallback } from '@sendbird/uikit-utils';
6
+
7
+ import type { MentionedUser } from '../types';
8
+ import { useSendbirdChat } from './useContext';
9
+
10
+ const useMentionTextInput = (params: { messageToEdit?: SendbirdUserMessage | SendbirdFileMessage }) => {
11
+ const { mentionManager } = useSendbirdChat();
12
+
13
+ const mentionedUsersRef = useRef<MentionedUser[]>([]);
14
+ const textInputRef = useRef<TextInput>();
15
+
16
+ const [text, setText] = useState('');
17
+ const [selection, setSelection] = useState({ start: 0, end: 0 });
18
+
19
+ // TODO: Refactor text edit logic more clearly
20
+ useEffect(() => {
21
+ if (mentionManager.shouldUseMentionedMessageTemplate(params.messageToEdit)) {
22
+ const result = mentionManager.templateToTextAndMentionedUsers(
23
+ params.messageToEdit.mentionedMessageTemplate,
24
+ params.messageToEdit.mentionedUsers,
25
+ );
26
+
27
+ mentionedUsersRef.current = result.mentionedUsers;
28
+ setText(result.mentionedText);
29
+ } else {
30
+ mentionedUsersRef.current = [];
31
+ if (params.messageToEdit?.isUserMessage()) {
32
+ setText(params.messageToEdit.message);
33
+ }
34
+ }
35
+ }, [params.messageToEdit]);
36
+
37
+ const onChangeText = useFreshCallback((_nextText: string, addedMentionedUser?: MentionedUser) => {
38
+ const prevText = text;
39
+ let nextText = _nextText;
40
+ let offset = nextText.length - prevText.length;
41
+
42
+ // Text clear
43
+ if (nextText === '') {
44
+ mentionedUsersRef.current = [];
45
+ }
46
+ // Text add
47
+ else if (offset > 0) {
48
+ /** Add mentioned user **/
49
+ if (addedMentionedUser) mentionedUsersRef.current.push(addedMentionedUser);
50
+
51
+ /** Reconcile mentioned users range on the right side of the selection **/
52
+ mentionedUsersRef.current = mentionManager.reconcileRangeOfMentionedUsers(
53
+ offset,
54
+ selection.end,
55
+ mentionedUsersRef.current,
56
+ );
57
+ }
58
+ // Text remove
59
+ else if (offset < 0) {
60
+ // Ranged remove
61
+ if (selection.start !== selection.end) {
62
+ /** Filter mentioned users in selection range **/
63
+ const { filtered, lastSelection } = mentionManager.removeMentionedUsersInSelection(
64
+ selection,
65
+ mentionedUsersRef.current,
66
+ );
67
+
68
+ /** Reconcile mentioned users range on the right side of the selection **/
69
+ mentionedUsersRef.current = mentionManager.reconcileRangeOfMentionedUsers(
70
+ offset,
71
+ Math.max(selection.end, lastSelection),
72
+ filtered,
73
+ );
74
+ }
75
+ // Single remove
76
+ else {
77
+ /** Find mentioned user who ranges in removed selection **/
78
+ const foundIndex = mentionedUsersRef.current.findIndex((it) =>
79
+ mentionManager.rangeHelpers.overlaps(it.range, selection, 'underMore'),
80
+ );
81
+ /** If found, remove from the mentioned user list and remove remainder text **/
82
+ if (foundIndex > -1) {
83
+ const it = mentionedUsersRef.current[foundIndex];
84
+ const remainderLength = it.range.end - it.range.start + offset;
85
+
86
+ offset = -remainderLength + offset;
87
+ nextText = replace(nextText, it.range.start, it.range.start + remainderLength, '');
88
+
89
+ mentionedUsersRef.current.splice(foundIndex, 1);
90
+ }
91
+
92
+ /** Reconcile mentioned users range on the right side of the selection **/
93
+ mentionedUsersRef.current = mentionManager.reconcileRangeOfMentionedUsers(
94
+ offset,
95
+ selection.end,
96
+ mentionedUsersRef.current,
97
+ );
98
+ }
99
+ }
100
+
101
+ setText(nextText);
102
+ });
103
+
104
+ return {
105
+ textInputRef,
106
+ selection,
107
+ onSelectionChange: useFreshCallback((e: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => {
108
+ const nativeSelection = { ...e.nativeEvent.selection };
109
+
110
+ // NOTE: To synchronize call onSelectionChange after onChangeText called on each platform.
111
+ setTimeout(() => {
112
+ const mentionedUser = mentionedUsersRef.current.find((it) =>
113
+ mentionManager.rangeHelpers.overlaps(it.range, nativeSelection),
114
+ );
115
+
116
+ // Selection should be blocked if changed into mentioned area
117
+ if (mentionedUser) {
118
+ const selectionBlock = { start: mentionedUser.range.start, end: mentionedUser.range.end };
119
+ textInputRef.current?.setNativeProps({ selection: selectionBlock });
120
+ // BUG: setNativeProps called again when invoked onChangeText
121
+ // https://github.com/facebook/react-native/issues/33520
122
+ if (Platform.OS === 'android') {
123
+ setTimeout(() => {
124
+ textInputRef.current?.setNativeProps({ selection: { start: 0 } });
125
+ }, 250);
126
+ }
127
+ setSelection(selectionBlock);
128
+ } else {
129
+ setSelection(nativeSelection);
130
+ }
131
+ }, 10);
132
+ }),
133
+ text,
134
+ onChangeText,
135
+ mentionedUsers: mentionedUsersRef.current,
136
+ };
137
+ };
138
+
139
+ export default useMentionTextInput;
package/src/index.ts CHANGED
@@ -4,6 +4,8 @@ import { Platform } from 'react-native';
4
4
  import { Logger } from '@sendbird/uikit-utils';
5
5
 
6
6
  export { default as MessageRenderer } from './components/MessageRenderer';
7
+ export { ReactionAddons } from './components/ReactionAddons';
8
+ export { ReactionBottomSheets } from './components/ReactionBottomSheets';
7
9
  export { default as ChannelCover } from './components/ChannelCover';
8
10
  export { default as ChatFlatList } from './components/ChatFlatList';
9
11
  export { default as FileViewer } from './components/FileViewer';
@@ -27,6 +29,7 @@ export { default as createGroupChannelOperatorsFragment } from './fragments/crea
27
29
  export { default as createGroupChannelRegisterOperatorFragment } from './fragments/createGroupChannelRegisterOperatorFragment';
28
30
  export { default as createGroupChannelMutedMembersFragment } from './fragments/createGroupChannelMutedMembersFragment';
29
31
  export { default as createGroupChannelBannedUsersFragment } from './fragments/createGroupChannelBannedUsersFragment';
32
+ export { default as createGroupChannelNotificationsFragment } from './fragments/createGroupChannelNotificationsFragment';
30
33
 
31
34
  /** Context **/
32
35
  export { SendbirdChatContext, SendbirdChatProvider } from './contexts/SendbirdChatCtx';
@@ -37,7 +40,7 @@ export { LocalizationContext, LocalizationProvider } from './contexts/Localizati
37
40
  /** Hooks **/
38
41
  export { default as useConnection } from './hooks/useConnection';
39
42
  export { default as usePushTokenRegistration } from './hooks/usePushTokenRegistration';
40
- export { useLocalization, usePlatformService, useSendbirdChat, useUserProfile } from './hooks/useContext';
43
+ export * from './hooks/useContext';
41
44
 
42
45
  /** Localization **/
43
46
  export { default as StringSetEn } from './localization/StringSet.en';
@@ -97,9 +100,17 @@ export type {
97
100
  GroupChannelListContextsType,
98
101
  } from './domain/groupChannelList/types';
99
102
 
103
+ export * from './domain/groupChannelNotifications';
104
+ export {
105
+ GroupChannelNotificationsProps,
106
+ GroupChannelNotificationsContextsType,
107
+ GroupChannelNotificationsFragment,
108
+ GroupChannelNotificationsModule,
109
+ } from './domain/groupChannelNotifications/types';
110
+
111
+ export * from './domain/groupChannelUserList/types';
100
112
  export * from './domain/userList';
101
113
  export type { UserListProps, UserListModule, UserListContextsType } from './domain/userList/types';
102
- export * from './domain/groupChannelUserList/types';
103
114
 
104
115
  /** UIKit **/
105
116
  export { default as SendbirdUIKitContainer, SendbirdUIKit } from './containers/SendbirdUIKitContainer';
@@ -0,0 +1,80 @@
1
+ import type { SendbirdEmoji, SendbirdEmojiCategory, SendbirdEmojiContainer } from '@sendbird/uikit-utils';
2
+
3
+ import type { LocalCacheStorage } from '../types';
4
+ import InternalLocalCacheStorage from './InternalLocalCacheStorage';
5
+
6
+ class MemoryStorage implements LocalCacheStorage {
7
+ _data: Record<string, string> = {};
8
+
9
+ async getAllKeys(): Promise<readonly string[] | string[]> {
10
+ return Object.keys(this._data);
11
+ }
12
+
13
+ async getItem(key: string): Promise<string | null> {
14
+ return this._data[key];
15
+ }
16
+
17
+ async removeItem(key: string): Promise<void> {
18
+ delete this._data[key];
19
+ }
20
+
21
+ async setItem(key: string, value: string): Promise<void> {
22
+ this._data[key] = value;
23
+ }
24
+ }
25
+
26
+ class EmojiManager {
27
+ static key = 'sendbird-uikit@emoji-manager';
28
+
29
+ constructor(
30
+ private internalStorage: InternalLocalCacheStorage = new InternalLocalCacheStorage(new MemoryStorage()),
31
+ ) {}
32
+
33
+ private emojiStorage = {
34
+ data: null as null | SendbirdEmojiContainer,
35
+ get: async () => {
36
+ if (!this.emojiStorage.data) {
37
+ const strItem = await this.internalStorage.getItem(EmojiManager.key);
38
+ if (strItem) this.emojiStorage.data = Object.freeze(JSON.parse(strItem));
39
+ }
40
+ return this.emojiStorage.data;
41
+ },
42
+ set: async (data: SendbirdEmojiContainer) => {
43
+ this.emojiStorage.data = Object.freeze(data);
44
+ await this.internalStorage.setItem(EmojiManager.key, JSON.stringify(data));
45
+ },
46
+ };
47
+
48
+ private _emojiCategoryMap: Record<string, SendbirdEmojiCategory> = {};
49
+ public get emojiCategoryMap() {
50
+ return this._emojiCategoryMap;
51
+ }
52
+
53
+ private _allEmojiMap: Record<string, SendbirdEmoji> = {};
54
+ public get allEmojiMap() {
55
+ return this._allEmojiMap;
56
+ }
57
+
58
+ private _allEmoji: SendbirdEmoji[] = [];
59
+ public get allEmoji() {
60
+ return this._allEmoji;
61
+ }
62
+
63
+ public init = async (emojiContainer?: SendbirdEmojiContainer) => {
64
+ if (emojiContainer) await this.emojiStorage.set(emojiContainer);
65
+
66
+ const container = await this.emojiStorage.get();
67
+
68
+ if (container) {
69
+ for (const category of container.emojiCategories) {
70
+ this._emojiCategoryMap[category.id] = category;
71
+ for (const emoji of category.emojis) {
72
+ this._allEmojiMap[emoji.key] = emoji;
73
+ }
74
+ }
75
+ this._allEmoji = Object.values(this._allEmojiMap);
76
+ }
77
+ };
78
+ }
79
+
80
+ export default EmojiManager;
@@ -0,0 +1,40 @@
1
+ export interface MentionConfigInterface {
2
+ mentionLimit: number;
3
+ suggestionLimit: number;
4
+ debounceMills: number;
5
+ delimiter: string;
6
+ trigger: string;
7
+ }
8
+
9
+ class MentionConfig {
10
+ static DEFAULT = {
11
+ MENTION_LIMIT: 10,
12
+ SUGGESTION_LIMIT: 15,
13
+ DEBOUNCE_MILLS: 300,
14
+ DELIMITER: ' ',
15
+ TRIGGER: '@',
16
+ };
17
+ constructor(private _config: MentionConfigInterface) {}
18
+
19
+ get mentionLimit() {
20
+ return this._config.mentionLimit;
21
+ }
22
+
23
+ get suggestionLimit() {
24
+ return this._config.suggestionLimit;
25
+ }
26
+
27
+ get delimiter() {
28
+ return this._config.delimiter;
29
+ }
30
+
31
+ get debounceMills() {
32
+ return this._config.debounceMills;
33
+ }
34
+
35
+ get trigger() {
36
+ return this._config.trigger;
37
+ }
38
+ }
39
+
40
+ export default MentionConfig;
@@ -0,0 +1,240 @@
1
+ import React from 'react';
2
+
3
+ import { Text, createStyleSheet } from '@sendbird/uikit-react-native-foundation';
4
+ import type { SendbirdFileMessage, SendbirdUser, SendbirdUserMessage } from '@sendbird/uikit-utils';
5
+ import { createMentionTemplateRegex, replaceWithRegex } from '@sendbird/uikit-utils';
6
+
7
+ import type { MentionedUser, Range } from '../types';
8
+ import type { MentionConfigInterface } from './MentionConfig';
9
+
10
+ class MentionManager {
11
+ private _invalidStartsKeywords: string[];
12
+ private _templateRegex: RegExp;
13
+
14
+ constructor(public config: MentionConfigInterface, public mentionEnabled: boolean) {
15
+ this._invalidStartsKeywords = [this.config.trigger, this.config.delimiter];
16
+ this._templateRegex = createMentionTemplateRegex(this.config.trigger);
17
+ }
18
+
19
+ public rangeHelpers = {
20
+ inRangeUnderOver(start: number, num: number, end: number) {
21
+ return start < num && num < end;
22
+ },
23
+ inRangeUnderMore(start: number, num: number, end: number) {
24
+ return start < num && num <= end;
25
+ },
26
+ inRangeLessOver(start: number, num: number, end: number) {
27
+ return start <= num && num < end;
28
+ },
29
+ inRangeLessMore(start: number, num: number, end: number) {
30
+ return start <= num && num <= end;
31
+ },
32
+ overlaps(a: Range, b: Range, compare: 'underOver' | 'underMore' | 'lessOver' | 'lessMore' = 'underOver') {
33
+ const inRange = {
34
+ underOver: this.inRangeUnderOver,
35
+ underMore: this.inRangeUnderMore,
36
+ lessOver: this.inRangeLessOver,
37
+ lessMore: this.inRangeLessMore,
38
+ }[compare];
39
+
40
+ return inRange(a.start, b.start, a.end) || inRange(a.start, b.end, a.end);
41
+ },
42
+ };
43
+
44
+ public get templateRegex() {
45
+ return this._templateRegex;
46
+ }
47
+
48
+ public getSearchString = (text: string, selectionIndex: number) => {
49
+ const lastSpan = text.slice(0, selectionIndex).split(this.config.delimiter).pop() ?? '';
50
+ const triggerIdx = lastSpan.indexOf(this.config.trigger);
51
+ const mentionSpan = triggerIdx === -1 ? lastSpan : lastSpan.slice(triggerIdx);
52
+ const searchString = mentionSpan.slice(this.config.trigger.length);
53
+
54
+ return {
55
+ searchString,
56
+ isTriggered: () => mentionSpan.startsWith(this.config.trigger),
57
+ isValidSearchString: () => this._invalidStartsKeywords.every((it) => !searchString.startsWith(it)),
58
+ };
59
+ };
60
+
61
+ /**
62
+ * @description Reconcile the range by offset in the mentioned users
63
+ * */
64
+ public reconcileRangeOfMentionedUsers = (offset: number, selectionIndex: number, mentionedUsers: MentionedUser[]) => {
65
+ return mentionedUsers.map((it) => {
66
+ // Changes only on the right text of selection.
67
+ if (selectionIndex <= it.range.start) {
68
+ return {
69
+ ...it,
70
+ range: {
71
+ start: it.range.start + offset,
72
+ end: it.range.end + offset,
73
+ },
74
+ };
75
+ }
76
+
77
+ return it;
78
+ });
79
+ };
80
+
81
+ /**
82
+ * @description Remove users who in a range
83
+ * */
84
+ public removeMentionedUsersInSelection = (selection: Range, mentionedUsers: MentionedUser[]) => {
85
+ let lastSelection = 0;
86
+ let removedOffset = 0;
87
+ const filtered = mentionedUsers.filter((it) => {
88
+ const shouldRemove = this.rangeHelpers.overlaps(selection, it.range, 'lessMore');
89
+ if (shouldRemove) {
90
+ lastSelection = Math.max(lastSelection, it.range.end);
91
+ removedOffset -= it.range.end - it.range.start;
92
+ }
93
+ return !shouldRemove;
94
+ });
95
+
96
+ return { filtered, lastSelection, removedOffset };
97
+ };
98
+
99
+ public getSearchStringRangeInText = (selectionIndex: number, searchString: string): Range => {
100
+ return {
101
+ start: selectionIndex - searchString.length - this.config.trigger.length,
102
+ end: selectionIndex,
103
+ };
104
+ };
105
+
106
+ /**
107
+ * @description User to @{user.id} template format
108
+ * */
109
+ public asMentionedMessageTemplate = (user: SendbirdUser, delimiter = false) => {
110
+ return `${this.config.trigger}{${user.userId}}` + (delimiter ? this.config.delimiter : '');
111
+ };
112
+
113
+ /**
114
+ * @description User to @user.nickname text format
115
+ * */
116
+ public asMentionedMessageText = (user: SendbirdUser, delimiter = false) => {
117
+ return `${this.config.trigger}${user.nickname}` + (delimiter ? this.config.delimiter : '');
118
+ };
119
+
120
+ /**
121
+ * @description Bold @user.nickname
122
+ * */
123
+ public textToMentionedComponents = (text: string, mentionedUsers: MentionedUser[]) => {
124
+ if (!this.mentionEnabled || mentionedUsers.length === 0) return text;
125
+
126
+ const { leftText, components } = mentionedUsers
127
+ .sort((a, b) => b.range.start - a.range.start)
128
+ .reduce(
129
+ ({ leftText, components }, curr, currentIndex) => {
130
+ const leftSpan = leftText.slice(0, curr.range.start);
131
+ const mentionSpan = leftText.slice(curr.range.start, curr.range.end);
132
+ const rightSpan = leftText.slice(curr.range.end);
133
+
134
+ return {
135
+ leftText: leftSpan,
136
+ components: [
137
+ <Text key={mentionSpan + currentIndex} style={styles.mentionedText}>
138
+ {mentionSpan}
139
+ </Text>,
140
+ rightSpan,
141
+ ...components,
142
+ ],
143
+ };
144
+ },
145
+ { leftText: text, components: [] as (string | JSX.Element)[] },
146
+ );
147
+
148
+ return [leftText, ...components];
149
+ };
150
+
151
+ public textToMentionedMessageTemplate = (text: string, mentionedUsers: MentionedUser[]) => {
152
+ if (!this.mentionEnabled) return text;
153
+
154
+ const { leftText, strings } = mentionedUsers
155
+ .sort((a, b) => b.range.start - a.range.start)
156
+ .reduce(
157
+ ({ leftText, strings }, curr) => {
158
+ const leftSpan = leftText.slice(0, curr.range.start);
159
+ const templateSpan = this.asMentionedMessageTemplate(curr.user);
160
+ const rightSpan = leftText.slice(curr.range.end);
161
+
162
+ return {
163
+ leftText: leftSpan,
164
+ strings: [templateSpan, rightSpan, ...strings],
165
+ };
166
+ },
167
+ { leftText: text, strings: [] as string[] },
168
+ );
169
+
170
+ return [leftText, ...strings].join('');
171
+ };
172
+
173
+ /**
174
+ * @description Convert @{user.id} template to @user.nickname text and MentionedUser[] array.
175
+ * */
176
+ public templateToTextAndMentionedUsers = (template: string, mentionedUsers: SendbirdUser[]) => {
177
+ const actualMentionedUsers: MentionedUser[] = [];
178
+
179
+ let offsetToMove = 0;
180
+ const mentionedText = replaceWithRegex(
181
+ template,
182
+ this.templateRegex,
183
+ ({ match, matchIndex, groups }) => {
184
+ const user = mentionedUsers.find((it) => it.userId === groups[2]);
185
+ if (user && typeof matchIndex === 'number') {
186
+ const userIdSpan = match;
187
+ const userNicknameSpan = this.asMentionedMessageText(user);
188
+
189
+ const offsetAfterConverted = userNicknameSpan.length - userIdSpan.length;
190
+
191
+ const originalRange: Range = {
192
+ start: matchIndex,
193
+ end: matchIndex + userIdSpan.length,
194
+ };
195
+
196
+ const convertedRange: Range = {
197
+ start: Math.max(0, originalRange.start + offsetToMove),
198
+ end: originalRange.end + offsetToMove + offsetAfterConverted,
199
+ };
200
+
201
+ offsetToMove += offsetAfterConverted;
202
+
203
+ actualMentionedUsers.push({ range: convertedRange, user });
204
+ return userNicknameSpan;
205
+ }
206
+ return match;
207
+ },
208
+ '',
209
+ ).join('');
210
+
211
+ return {
212
+ mentionedText,
213
+ mentionedUsers: actualMentionedUsers,
214
+ };
215
+ };
216
+
217
+ public shouldUseMentionedMessageTemplate = (
218
+ message?: SendbirdUserMessage | SendbirdFileMessage,
219
+ ): message is RequiredSpecific<
220
+ SendbirdUserMessage | SendbirdFileMessage,
221
+ 'mentionedMessageTemplate' | 'mentionedUsers' | 'mentionedUserIds' | 'mentionType'
222
+ > => {
223
+ return Boolean(
224
+ this.mentionEnabled &&
225
+ message?.mentionedMessageTemplate &&
226
+ message?.mentionedUsers &&
227
+ message?.mentionedUsers.length > 0,
228
+ );
229
+ };
230
+ }
231
+
232
+ type RequiredSpecific<T, K extends keyof T> = T & {
233
+ [P in K]-?: T[P];
234
+ };
235
+
236
+ const styles = createStyleSheet({
237
+ mentionedText: { fontWeight: 'bold' },
238
+ });
239
+
240
+ export default MentionManager;
@@ -9,11 +9,11 @@ import type {
9
9
  SendbirdUser,
10
10
  } from '@sendbird/uikit-utils';
11
11
  import {
12
- dateSeparator,
12
+ getDateSeparatorFormat,
13
13
  getGroupChannelLastMessage,
14
14
  getGroupChannelPreviewTime,
15
15
  getGroupChannelTitle,
16
- messageTime,
16
+ getMessageTimeFormat,
17
17
  } from '@sendbird/uikit-utils';
18
18
 
19
19
  /**
@@ -44,6 +44,9 @@ export interface StringSet {
44
44
  INPUT_EDIT_OK: string;
45
45
  INPUT_EDIT_CANCEL: string;
46
46
 
47
+ /** GroupChannel > Suggested mention list */
48
+ MENTION_LIMITED: (mentionLimit: number) => string;
49
+
47
50
  /** GroupChannel > Dialog > Message */
48
51
  DIALOG_MESSAGE_COPY: string;
49
52
  DIALOG_MESSAGE_EDIT: string;
@@ -69,9 +72,12 @@ export interface StringSet {
69
72
 
70
73
  /** GroupChannelSettings > Menu */
71
74
  MENU_MODERATION: string;
72
- MENU_NOTIFICATION: string;
73
75
  MENU_MEMBERS: string;
74
76
  MENU_LEAVE_CHANNEL: string;
77
+ MENU_NOTIFICATION: string;
78
+ MENU_NOTIFICATION_LABEL_ON: string;
79
+ MENU_NOTIFICATION_LABEL_OFF: string;
80
+ MENU_NOTIFICATION_LABEL_MENTION_ONLY: string;
75
81
 
76
82
  /** GroupChannelSettings > Dialog */
77
83
  DIALOG_CHANGE_NAME: string;
@@ -84,6 +90,16 @@ export interface StringSet {
84
90
  DIALOG_CHANGE_IMAGE_MENU_CAMERA: string;
85
91
  DIALOG_CHANGE_IMAGE_MENU_PHOTO_LIBRARY: string;
86
92
  };
93
+ GROUP_CHANNEL_NOTIFICATIONS: {
94
+ /** GroupChannelNotifications > Header */
95
+ HEADER_TITLE: string;
96
+
97
+ /** GroupChannelNotifications > Menu */
98
+ MENU_NOTIFICATIONS: string;
99
+ MENU_NOTIFICATIONS_DESC: string;
100
+ MENU_NOTIFICATIONS_OPTION_ALL: string;
101
+ MENU_NOTIFICATIONS_OPTION_MENTION_ONLY: string;
102
+ };
87
103
  GROUP_CHANNEL_MODERATION: {
88
104
  /** GroupChannelModeration > Header */
89
105
  HEADER_TITLE: string;
@@ -237,10 +253,10 @@ export const createBaseStringSet = ({ dateLocale, overrides }: StringSetCreateOp
237
253
  HEADER_TITLE: (currentUserId, channel) =>
238
254
  getGroupChannelTitle(currentUserId, channel, USER_NO_NAME, CHANNEL_NO_MEMBERS),
239
255
  LIST_BANNER_FROZEN: 'Channel is frozen',
240
- LIST_DATE_SEPARATOR: (date, locale) => dateSeparator(date, locale ?? dateLocale),
256
+ LIST_DATE_SEPARATOR: (date, locale) => getDateSeparatorFormat(date, locale ?? dateLocale),
241
257
  LIST_BUTTON_NEW_MSG: (newMessages) => `${newMessages.length} new messages`,
242
258
 
243
- MESSAGE_BUBBLE_TIME: (message, locale) => messageTime(new Date(message.createdAt), locale ?? dateLocale),
259
+ MESSAGE_BUBBLE_TIME: (message, locale) => getMessageTimeFormat(new Date(message.createdAt), locale ?? dateLocale),
244
260
  MESSAGE_BUBBLE_FILE_TITLE: (message) => message.name,
245
261
  MESSAGE_BUBBLE_EDITED_POSTFIX: ' (edited)',
246
262
  MESSAGE_BUBBLE_UNKNOWN_TITLE: () => '(Unknown message type)',
@@ -252,6 +268,8 @@ export const createBaseStringSet = ({ dateLocale, overrides }: StringSetCreateOp
252
268
  INPUT_EDIT_OK: 'Save',
253
269
  INPUT_EDIT_CANCEL: 'Cancel',
254
270
 
271
+ MENTION_LIMITED: (mentionLimit) => `You can have up to ${mentionLimit} mentions per message.`,
272
+
255
273
  DIALOG_MESSAGE_COPY: 'Copy',
256
274
  DIALOG_MESSAGE_EDIT: 'Edit',
257
275
  DIALOG_MESSAGE_SAVE: 'Save',
@@ -271,9 +289,12 @@ export const createBaseStringSet = ({ dateLocale, overrides }: StringSetCreateOp
271
289
  HEADER_TITLE: 'Channel information',
272
290
  HEADER_RIGHT: 'Edit',
273
291
  MENU_MODERATION: 'Moderation',
274
- MENU_NOTIFICATION: 'Notifications',
275
292
  MENU_MEMBERS: 'Members',
276
293
  MENU_LEAVE_CHANNEL: 'Leave channel',
294
+ MENU_NOTIFICATION: 'Notifications',
295
+ MENU_NOTIFICATION_LABEL_ON: 'On',
296
+ MENU_NOTIFICATION_LABEL_OFF: 'Off',
297
+ MENU_NOTIFICATION_LABEL_MENTION_ONLY: 'Mentions only',
277
298
  DIALOG_CHANGE_NAME: 'Change channel name',
278
299
  DIALOG_CHANGE_NAME_PROMPT_TITLE: 'Change channel name',
279
300
  DIALOG_CHANGE_NAME_PROMPT_PLACEHOLDER: 'Enter name',
@@ -285,6 +306,15 @@ export const createBaseStringSet = ({ dateLocale, overrides }: StringSetCreateOp
285
306
  DIALOG_CHANGE_IMAGE_MENU_PHOTO_LIBRARY: 'Choose photo',
286
307
  ...overrides?.GROUP_CHANNEL_SETTINGS,
287
308
  },
309
+ GROUP_CHANNEL_NOTIFICATIONS: {
310
+ HEADER_TITLE: 'Notifications',
311
+ MENU_NOTIFICATIONS: 'Notifications',
312
+ MENU_NOTIFICATIONS_DESC:
313
+ 'Turn on push notifications if you wish to be notified when messages are delivered to this channel.',
314
+ MENU_NOTIFICATIONS_OPTION_ALL: 'All new messages',
315
+ MENU_NOTIFICATIONS_OPTION_MENTION_ONLY: 'Mentions only',
316
+ ...overrides?.GROUP_CHANNEL_NOTIFICATIONS,
317
+ },
288
318
  GROUP_CHANNEL_MODERATION: {
289
319
  HEADER_TITLE: 'Moderation',
290
320
  MENU_OPERATORS: 'Operators',
@@ -382,7 +412,7 @@ export const createBaseStringSet = ({ dateLocale, overrides }: StringSetCreateOp
382
412
  },
383
413
  FILE_VIEWER: {
384
414
  TITLE: (message) => message.sender?.nickname || USER_NO_NAME,
385
- SUBTITLE: (message) => messageTime(new Date(message.createdAt), dateLocale),
415
+ SUBTITLE: (message) => getMessageTimeFormat(new Date(message.createdAt), dateLocale),
386
416
  },
387
417
  PLACEHOLDER: {
388
418
  NO_BANNED_USERS: 'No banned users',
@@ -402,7 +432,7 @@ export const createBaseStringSet = ({ dateLocale, overrides }: StringSetCreateOp
402
432
  ALERT_DEFAULT_OK: 'OK',
403
433
  ALERT_PERMISSIONS_TITLE: 'Allow access?',
404
434
  ALERT_PERMISSIONS_MESSAGE: (permission, appName = 'Application') => {
405
- return `${appName} need permission to access your ${permission}. Go to Settings to allow access`;
435
+ return `${appName} need permission to access your ${permission}.`;
406
436
  },
407
437
  ALERT_PERMISSIONS_OK: 'Go to settings',
408
438
  PROMPT_DEFAULT_OK: 'Submit',
package/src/types.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import type { ErrorInfo, ReactNode } from 'react';
2
2
 
3
+ import type { SendbirdUser } from '@sendbird/uikit-utils';
4
+
3
5
  export type KeyValuePairGet = [string, string | null];
4
6
  export type KeyValuePairSet = [string, string];
5
7
  export interface LocalCacheStorage {
@@ -16,3 +18,13 @@ export interface LocalCacheStorage {
16
18
  export type ErrorBoundaryProps = { error: Error; errorInfo: ErrorInfo; reset: () => void };
17
19
 
18
20
  export type CommonComponent<P = {}> = (props: P & { children?: ReactNode }) => null | JSX.Element; //ReactNode;
21
+
22
+ export type MentionedUser = {
23
+ range: Range;
24
+ user: SendbirdUser;
25
+ };
26
+
27
+ export type Range = {
28
+ start: number;
29
+ end: number;
30
+ };