@webinex/chatify 2.0.0-alpha1 → 2.0.0-alpha10

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/dist/Chatify-DGRV4QKP.js +2203 -0
  2. package/dist/Chatify-DGRV4QKP.js.map +1 -0
  3. package/dist/Chatify.css +670 -0
  4. package/dist/audit.css +60 -0
  5. package/dist/audit.js +242 -0
  6. package/dist/audit.js.map +1 -0
  7. package/dist/index.js +97 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/types/audit/AuditChatList.d.ts +9 -0
  10. package/dist/types/audit/AuditConversationPanel.d.ts +10 -0
  11. package/dist/types/audit/AuditPanel.d.ts +14 -0
  12. package/dist/types/audit/AuditPanelCustomizeValue.d.ts +9 -0
  13. package/dist/types/audit/AuditSearch.d.ts +5 -0
  14. package/dist/types/audit/AuditSearchValue.d.ts +14 -0
  15. package/dist/types/audit/auditApi.d.ts +97 -0
  16. package/dist/types/audit/index.d.ts +17 -0
  17. package/dist/types/core/api/api.d.ts +17295 -0
  18. package/dist/{esm/types → types}/core/api/baseApi.d.ts +1 -1
  19. package/dist/{esm/types → types}/core/client.d.ts +8 -6
  20. package/dist/{esm/types → types}/core/types.d.ts +28 -6
  21. package/dist/types/ui/Chat/ChatEditableHeaderName.d.ts +1 -0
  22. package/dist/types/ui/Chat/ChatHeaderActions.d.ts +1 -0
  23. package/dist/{esm/types → types}/ui/Chat/ChatView.d.ts +1 -2
  24. package/dist/types/ui/Chat/Members/ChatMembersButton.d.ts +1 -0
  25. package/dist/types/ui/Chat/Members/ChatMembersPanel.d.ts +1 -0
  26. package/dist/types/ui/Chat/Members/ChatMembersPreview.d.ts +1 -0
  27. package/dist/{esm/types → types}/ui/ChatGroup/ChatGroupPanel.d.ts +2 -2
  28. package/dist/types/ui/ChatGroup/Create/CreateChatButton.d.ts +1 -0
  29. package/{src → dist}/types/ui/ChatGroup/Create/CreateChatForm.d.ts +1 -2
  30. package/dist/types/ui/ChatGroup/Create/CreateChatMemberInput.d.ts +4 -0
  31. package/dist/types/ui/ChatGroup/Create/CreateChatNameInput.d.ts +4 -0
  32. package/dist/types/ui/ChatGroup/Create/CreateChatPanel.d.ts +1 -0
  33. package/dist/types/ui/ChatGroup/Layout/ChatGroupAside.d.ts +1 -0
  34. package/dist/types/ui/ChatGroup/Layout/ChatGroupBody.d.ts +1 -0
  35. package/dist/types/ui/ChatGroup/Layout/ChatGroupFooter.d.ts +1 -0
  36. package/dist/types/ui/ChatGroup/Layout/ChatGroupHeader.d.ts +1 -0
  37. package/dist/types/ui/ChatGroup/Layout/ChatGroupMain.d.ts +1 -0
  38. package/dist/types/ui/ChatGroup/List/ChatListPanel.d.ts +1 -0
  39. package/dist/types/ui/ChatGroup/List/index.d.ts +6 -0
  40. package/dist/types/ui/Chatify.d.ts +9 -0
  41. package/dist/{esm/types → types}/ui/Conversation/Conversation.d.ts +3 -2
  42. package/dist/types/ui/Conversation/ConversationActions.d.ts +1 -0
  43. package/dist/types/ui/Conversation/ConversationBody.d.ts +1 -0
  44. package/dist/{esm/types → types}/ui/Conversation/ConversationContext.d.ts +7 -4
  45. package/dist/types/ui/Conversation/ConversationHeader.d.ts +1 -0
  46. package/dist/types/ui/Conversation/ConversationName.d.ts +1 -0
  47. package/dist/types/ui/Conversation/InputBox/InputBox.d.ts +1 -0
  48. package/dist/types/ui/Conversation/InputBox/InputBoxFile.d.ts +7 -0
  49. package/dist/types/ui/Conversation/InputBox/InputBoxFileList.d.ts +7 -0
  50. package/dist/types/ui/Conversation/InputBox/InputFilesBox.d.ts +11 -0
  51. package/dist/types/ui/Conversation/InputBox/InputSubmitButtonBox.d.ts +6 -0
  52. package/dist/{esm/types → types}/ui/Conversation/InputBox/InputTextBox.d.ts +2 -1
  53. package/{src → dist}/types/ui/Conversation/InputBox/index.d.ts +8 -1
  54. package/dist/types/ui/Conversation/Message/MessageAuthor.d.ts +2 -0
  55. package/dist/types/ui/Conversation/Message/MessageBox.d.ts +5 -0
  56. package/dist/types/ui/Conversation/Message/MessageContent.d.ts +2 -0
  57. package/dist/types/ui/Conversation/Message/MessageFile.d.ts +5 -0
  58. package/dist/types/ui/Conversation/Message/MessageFileList.d.ts +2 -0
  59. package/dist/types/ui/Conversation/Message/MessageInfoBox.d.ts +2 -0
  60. package/dist/{esm/types → types}/ui/Conversation/Message/MessageRow.d.ts +1 -1
  61. package/dist/types/ui/Conversation/Message/MessageText.d.ts +2 -0
  62. package/{src → dist}/types/ui/Conversation/Message/index.d.ts +6 -0
  63. package/dist/types/ui/Conversation/SendingMessage/SendingMessageBox.d.ts +6 -0
  64. package/dist/types/ui/Conversation/SendingMessage/SendingMessageContent.d.ts +2 -0
  65. package/dist/types/ui/Conversation/SendingMessage/SendingMessageInfoBox.d.ts +2 -0
  66. package/dist/types/ui/Conversation/SendingMessage/SendingMessageText.d.ts +2 -0
  67. package/dist/types/ui/Conversation/SystemMessage/SystemMessageBox.d.ts +5 -0
  68. package/{src → dist}/types/ui/Conversation/SystemMessage/SystemMessageRow.d.ts +1 -1
  69. package/dist/types/ui/Thread/ThreadActions.d.ts +1 -0
  70. package/dist/{esm/types → types}/ui/Thread/ThreadContext.d.ts +1 -1
  71. package/dist/types/ui/common/Avatar.d.ts +5 -0
  72. package/dist/types/ui/common/ChatList/ChatList.d.ts +16 -0
  73. package/dist/types/ui/common/ChatList/ChatListItemAvatar.d.ts +2 -0
  74. package/dist/types/ui/common/ChatList/ChatListItemBox.d.ts +9 -0
  75. package/dist/types/ui/common/ChatList/ChatListItemLastMessage.d.ts +2 -0
  76. package/dist/types/ui/common/ChatList/ChatListItemLastMessageAuthor.d.ts +2 -0
  77. package/dist/types/ui/common/ChatList/ChatListItemLastMessageContent.d.ts +2 -0
  78. package/dist/types/ui/common/ChatList/ChatListItemLastMessageSentAt.d.ts +2 -0
  79. package/dist/types/ui/common/ChatList/ChatListItemName.d.ts +2 -0
  80. package/dist/types/ui/common/ChatList/ChatListItemUnreadCount.d.ts +2 -0
  81. package/dist/types/ui/common/ChatList/ChatListValue.d.ts +8 -0
  82. package/{src/types/ui/ChatGroup/List → dist/types/ui/common/ChatList}/index.d.ts +1 -0
  83. package/dist/types/ui/common/Icon.d.ts +21 -0
  84. package/dist/types/ui/common/MessageSkeleton.d.ts +4 -0
  85. package/dist/{esm/types → types}/ui/common/index.d.ts +1 -0
  86. package/{src → dist}/types/ui/customize.d.ts +3 -3
  87. package/dist/{esm/types → types}/ui/index.d.ts +1 -3
  88. package/dist/{esm/types → types}/ui/localizer.d.ts +12 -2
  89. package/dist/types/ui/useFormatter.d.ts +3 -0
  90. package/package.json +81 -93
  91. package/src/audit/AuditChatList.tsx +25 -0
  92. package/src/audit/AuditConversationPanel.tsx +48 -0
  93. package/src/audit/AuditPanel.tsx +76 -0
  94. package/src/audit/AuditPanelCustomizeValue.ts +11 -0
  95. package/src/audit/AuditSearch.tsx +89 -0
  96. package/src/audit/AuditSearchValue.tsx +42 -0
  97. package/src/audit/auditApi.tsx +113 -0
  98. package/src/audit/index.d.ts +18 -0
  99. package/src/audit/index.tsx +28 -0
  100. package/src/audit/styles.scss +72 -0
  101. package/src/core/api/api.ts +655 -642
  102. package/src/core/api/baseApi.ts +38 -38
  103. package/src/core/api/index.ts +1 -1
  104. package/src/core/client.ts +287 -280
  105. package/src/core/constants.ts +1 -1
  106. package/src/core/debounce.ts +90 -90
  107. package/src/core/index.ts +4 -4
  108. package/src/core/types.tsx +182 -152
  109. package/src/index.ts +2 -2
  110. package/src/styles/aside.scss +26 -161
  111. package/src/styles/chat-list.scss +138 -0
  112. package/src/styles/chat.scss +11 -208
  113. package/src/styles/conversation.scss +200 -0
  114. package/src/styles/index.scss +161 -110
  115. package/src/styles/input.scss +148 -74
  116. package/src/styles/keyframes.scss +14 -14
  117. package/src/styles/members.scss +13 -13
  118. package/src/styles/mixins.scss +25 -20
  119. package/src/styles/variables.scss +13 -10
  120. package/src/ui/Chat/ChatContext.tsx +30 -30
  121. package/src/ui/Chat/ChatEditableHeaderName.tsx +63 -63
  122. package/src/ui/Chat/ChatHeaderActions.tsx +19 -19
  123. package/src/ui/Chat/ChatPanel.tsx +30 -30
  124. package/src/ui/Chat/ChatView.tsx +115 -115
  125. package/src/ui/Chat/Members/ChatMembersButton.tsx +9 -9
  126. package/src/ui/Chat/Members/ChatMembersPanel.tsx +112 -112
  127. package/src/ui/Chat/Members/ChatMembersPreview.tsx +25 -25
  128. package/src/ui/Chat/Members/index.ts +13 -13
  129. package/src/ui/Chat/index.ts +6 -6
  130. package/src/ui/ChatGroup/ChatGroupContext.tsx +50 -50
  131. package/src/ui/ChatGroup/ChatGroupPanel.tsx +73 -73
  132. package/src/ui/ChatGroup/Create/CreateChatButton.tsx +15 -15
  133. package/src/ui/ChatGroup/Create/CreateChatForm.tsx +36 -36
  134. package/src/ui/ChatGroup/Create/CreateChatMemberInput.tsx +65 -65
  135. package/src/ui/ChatGroup/Create/CreateChatNameInput.tsx +25 -25
  136. package/src/ui/ChatGroup/Create/CreateChatPanel.tsx +45 -45
  137. package/src/ui/ChatGroup/Create/index.ts +19 -19
  138. package/src/ui/ChatGroup/Layout/ChatGroupAside.tsx +12 -12
  139. package/src/ui/ChatGroup/Layout/ChatGroupBody.tsx +10 -10
  140. package/src/ui/ChatGroup/Layout/ChatGroupFooter.tsx +3 -3
  141. package/src/ui/ChatGroup/Layout/ChatGroupHeader.tsx +5 -5
  142. package/src/ui/ChatGroup/Layout/ChatGroupMain.tsx +17 -17
  143. package/src/ui/ChatGroup/Layout/index.ts +19 -19
  144. package/src/ui/ChatGroup/List/ChatListPanel.tsx +28 -0
  145. package/src/ui/ChatGroup/List/index.ts +8 -31
  146. package/src/ui/ChatGroup/index.ts +5 -5
  147. package/src/ui/Chatify.tsx +15 -9
  148. package/src/ui/Conversation/Conversation.tsx +92 -76
  149. package/src/ui/Conversation/ConversationActions.tsx +12 -5
  150. package/src/ui/Conversation/ConversationBody.tsx +28 -28
  151. package/src/ui/Conversation/ConversationContext.ts +30 -27
  152. package/src/ui/Conversation/ConversationHeader.tsx +19 -23
  153. package/src/ui/Conversation/ConversationName.tsx +7 -7
  154. package/src/ui/Conversation/InputBox/InputBox.tsx +126 -40
  155. package/src/ui/Conversation/InputBox/InputBoxFile.tsx +38 -0
  156. package/src/ui/Conversation/InputBox/InputBoxFileList.tsx +21 -0
  157. package/src/ui/Conversation/InputBox/InputFilesBox.tsx +78 -9
  158. package/src/ui/Conversation/InputBox/InputSubmitButtonBox.tsx +26 -17
  159. package/src/ui/Conversation/InputBox/InputTextBox.tsx +61 -53
  160. package/src/ui/Conversation/InputBox/index.ts +23 -16
  161. package/src/ui/Conversation/Message/MessageAuthor.tsx +13 -13
  162. package/src/ui/Conversation/Message/MessageBox.tsx +20 -20
  163. package/src/ui/Conversation/Message/MessageContent.tsx +15 -11
  164. package/src/ui/Conversation/Message/MessageFile.tsx +54 -0
  165. package/src/ui/Conversation/Message/MessageFileList.tsx +14 -0
  166. package/src/ui/Conversation/Message/MessageInfoBox.tsx +28 -28
  167. package/src/ui/Conversation/Message/MessageRow.tsx +28 -28
  168. package/src/ui/Conversation/Message/MessageText.tsx +7 -7
  169. package/src/ui/Conversation/Message/index.ts +28 -22
  170. package/src/ui/Conversation/NextObserver/NextMessagesObserver.tsx +47 -47
  171. package/src/ui/Conversation/NextObserver/index.ts +1 -1
  172. package/src/ui/Conversation/ReadObserver/MessageReadObserver.tsx +49 -49
  173. package/src/ui/Conversation/ReadObserver/index.ts +1 -1
  174. package/src/ui/Conversation/SendingMessage/SendingMessageBox.tsx +16 -16
  175. package/src/ui/Conversation/SendingMessage/SendingMessageContent.tsx +13 -13
  176. package/src/ui/Conversation/SendingMessage/SendingMessageInfoBox.tsx +13 -13
  177. package/src/ui/Conversation/SendingMessage/SendingMessageText.tsx +7 -7
  178. package/src/ui/Conversation/SendingMessage/index.ts +16 -16
  179. package/src/ui/Conversation/SystemMessage/SystemMessageBox.tsx +20 -20
  180. package/src/ui/Conversation/SystemMessage/SystemMessageRow.tsx +28 -28
  181. package/src/ui/Conversation/SystemMessage/index.ts +10 -10
  182. package/src/ui/Conversation/index.ts +13 -13
  183. package/src/ui/Thread/ThreadActions.tsx +22 -22
  184. package/src/ui/Thread/ThreadContext.ts +13 -13
  185. package/src/ui/Thread/ThreadPanel.tsx +127 -127
  186. package/src/ui/Thread/index.tsx +3 -3
  187. package/src/ui/color.ts +20 -20
  188. package/src/ui/common/Avatar.tsx +20 -20
  189. package/src/ui/common/ChatList/ChatList.tsx +84 -0
  190. package/src/ui/{ChatGroup/List → common/ChatList}/ChatListItemAvatar.tsx +22 -22
  191. package/src/ui/{ChatGroup/List → common/ChatList}/ChatListItemBox.tsx +32 -26
  192. package/src/ui/{ChatGroup/List → common/ChatList}/ChatListItemLastMessage.tsx +15 -15
  193. package/src/ui/{ChatGroup/List → common/ChatList}/ChatListItemLastMessageAuthor.tsx +15 -15
  194. package/src/ui/{ChatGroup/List → common/ChatList}/ChatListItemLastMessageContent.tsx +21 -21
  195. package/src/ui/{ChatGroup/List → common/ChatList}/ChatListItemLastMessageSentAt.tsx +22 -22
  196. package/src/ui/{ChatGroup/List → common/ChatList}/ChatListItemName.tsx +8 -8
  197. package/src/ui/{ChatGroup/List → common/ChatList}/ChatListItemUnreadCount.tsx +12 -12
  198. package/src/ui/common/ChatList/ChatListValue.ts +9 -0
  199. package/{dist/esm/types/ui/ChatGroup/List/index.d.ts → src/ui/common/ChatList/index.ts} +12 -9
  200. package/src/ui/common/Icon.tsx +46 -40
  201. package/src/ui/common/MessageSkeleton.tsx +20 -20
  202. package/src/ui/common/index.ts +14 -13
  203. package/src/ui/customize.tsx +51 -53
  204. package/src/ui/index.ts +11 -11
  205. package/src/ui/localizer.tsx +108 -81
  206. package/src/ui/useFormatter.tsx +17 -0
  207. package/dist/css/chatify.css +0 -560
  208. package/dist/esm/index.js +0 -11
  209. package/dist/esm/index.js.map +0 -1
  210. package/dist/esm/types/core/api/accountApi.d.ts +0 -5
  211. package/dist/esm/types/core/api/api.d.ts +0 -2380
  212. package/dist/esm/types/core/api/chatApi.d.ts +0 -16
  213. package/dist/esm/types/core/api/chatListApi.d.ts +0 -5
  214. package/dist/esm/types/core/api/chatMemberApi.d.ts +0 -6
  215. package/dist/esm/types/core/api/chatMessageApi.d.ts +0 -3
  216. package/dist/esm/types/core/api/threadApi.d.ts +0 -1
  217. package/dist/esm/types/core/api/threadMessageApi.d.ts +0 -6
  218. package/dist/esm/types/ui/Chat/ChatEditableHeaderName.d.ts +0 -2
  219. package/dist/esm/types/ui/Chat/ChatHeaderActions.d.ts +0 -2
  220. package/dist/esm/types/ui/Chat/Members/ChatMembersButton.d.ts +0 -2
  221. package/dist/esm/types/ui/Chat/Members/ChatMembersPanel.d.ts +0 -2
  222. package/dist/esm/types/ui/Chat/Members/ChatMembersPreview.d.ts +0 -2
  223. package/dist/esm/types/ui/ChatGroup/Create/CreateChatButton.d.ts +0 -2
  224. package/dist/esm/types/ui/ChatGroup/Create/CreateChatForm.d.ts +0 -11
  225. package/dist/esm/types/ui/ChatGroup/Create/CreateChatMemberInput.d.ts +0 -5
  226. package/dist/esm/types/ui/ChatGroup/Create/CreateChatNameInput.d.ts +0 -5
  227. package/dist/esm/types/ui/ChatGroup/Create/CreateChatPanel.d.ts +0 -2
  228. package/dist/esm/types/ui/ChatGroup/Layout/ChatGroupAside.d.ts +0 -2
  229. package/dist/esm/types/ui/ChatGroup/Layout/ChatGroupBody.d.ts +0 -2
  230. package/dist/esm/types/ui/ChatGroup/Layout/ChatGroupFooter.d.ts +0 -2
  231. package/dist/esm/types/ui/ChatGroup/Layout/ChatGroupHeader.d.ts +0 -2
  232. package/dist/esm/types/ui/ChatGroup/Layout/ChatGroupMain.d.ts +0 -2
  233. package/dist/esm/types/ui/ChatGroup/List/ChatList.d.ts +0 -2
  234. package/dist/esm/types/ui/ChatGroup/List/ChatListItemAvatar.d.ts +0 -3
  235. package/dist/esm/types/ui/ChatGroup/List/ChatListItemBox.d.ts +0 -6
  236. package/dist/esm/types/ui/ChatGroup/List/ChatListItemLastMessage.d.ts +0 -3
  237. package/dist/esm/types/ui/ChatGroup/List/ChatListItemLastMessageAuthor.d.ts +0 -3
  238. package/dist/esm/types/ui/ChatGroup/List/ChatListItemLastMessageContent.d.ts +0 -3
  239. package/dist/esm/types/ui/ChatGroup/List/ChatListItemLastMessageSentAt.d.ts +0 -3
  240. package/dist/esm/types/ui/ChatGroup/List/ChatListItemName.d.ts +0 -3
  241. package/dist/esm/types/ui/ChatGroup/List/ChatListItemUnreadCount.d.ts +0 -3
  242. package/dist/esm/types/ui/Chatify.d.ts +0 -8
  243. package/dist/esm/types/ui/Conversation/ConversationActions.d.ts +0 -2
  244. package/dist/esm/types/ui/Conversation/ConversationBody.d.ts +0 -2
  245. package/dist/esm/types/ui/Conversation/ConversationHeader.d.ts +0 -2
  246. package/dist/esm/types/ui/Conversation/ConversationName.d.ts +0 -2
  247. package/dist/esm/types/ui/Conversation/InputBox/InputBox.d.ts +0 -2
  248. package/dist/esm/types/ui/Conversation/InputBox/InputFilesBox.d.ts +0 -2
  249. package/dist/esm/types/ui/Conversation/InputBox/InputSubmitButtonBox.d.ts +0 -5
  250. package/dist/esm/types/ui/Conversation/InputBox/index.d.ts +0 -14
  251. package/dist/esm/types/ui/Conversation/Message/MessageAuthor.d.ts +0 -3
  252. package/dist/esm/types/ui/Conversation/Message/MessageBox.d.ts +0 -6
  253. package/dist/esm/types/ui/Conversation/Message/MessageContent.d.ts +0 -3
  254. package/dist/esm/types/ui/Conversation/Message/MessageInfoBox.d.ts +0 -3
  255. package/dist/esm/types/ui/Conversation/Message/MessageText.d.ts +0 -3
  256. package/dist/esm/types/ui/Conversation/Message/index.d.ts +0 -20
  257. package/dist/esm/types/ui/Conversation/SendingMessage/SendingMessageBox.d.ts +0 -7
  258. package/dist/esm/types/ui/Conversation/SendingMessage/SendingMessageContent.d.ts +0 -3
  259. package/dist/esm/types/ui/Conversation/SendingMessage/SendingMessageInfoBox.d.ts +0 -3
  260. package/dist/esm/types/ui/Conversation/SendingMessage/SendingMessageText.d.ts +0 -3
  261. package/dist/esm/types/ui/Conversation/SystemMessage/SystemMessageBox.d.ts +0 -6
  262. package/dist/esm/types/ui/Conversation/SystemMessage/SystemMessageRow.d.ts +0 -9
  263. package/dist/esm/types/ui/Thread/ThreadActions.d.ts +0 -2
  264. package/dist/esm/types/ui/common/Avatar.d.ts +0 -6
  265. package/dist/esm/types/ui/common/Icon.d.ts +0 -20
  266. package/dist/esm/types/ui/common/MessageSkeleton.d.ts +0 -5
  267. package/dist/esm/types/ui/customize.d.ts +0 -9
  268. package/dist/index.d.ts +0 -3005
  269. package/src/core/api/accountApi.ts +0 -11
  270. package/src/core/api/chatApi.ts +0 -87
  271. package/src/core/api/chatListApi.ts +0 -134
  272. package/src/core/api/chatMemberApi.ts +0 -20
  273. package/src/core/api/chatMessageApi.ts +0 -12
  274. package/src/core/api/threadApi.ts +0 -8
  275. package/src/core/api/threadMessageApi.ts +0 -20
  276. package/src/types/core/api/accountApi.d.ts +0 -5
  277. package/src/types/core/api/api.d.ts +0 -2380
  278. package/src/types/core/api/baseApi.d.ts +0 -15
  279. package/src/types/core/api/chatApi.d.ts +0 -16
  280. package/src/types/core/api/chatListApi.d.ts +0 -5
  281. package/src/types/core/api/chatMemberApi.d.ts +0 -6
  282. package/src/types/core/api/chatMessageApi.d.ts +0 -3
  283. package/src/types/core/api/index.d.ts +0 -1
  284. package/src/types/core/api/threadApi.d.ts +0 -1
  285. package/src/types/core/api/threadMessageApi.d.ts +0 -6
  286. package/src/types/core/client.d.ts +0 -83
  287. package/src/types/core/constants.d.ts +0 -1
  288. package/src/types/core/debounce.d.ts +0 -27
  289. package/src/types/core/index.d.ts +0 -4
  290. package/src/types/core/types.d.ts +0 -105
  291. package/src/types/index.d.ts +0 -2
  292. package/src/types/ui/Chat/ChatContext.d.ts +0 -10
  293. package/src/types/ui/Chat/ChatEditableHeaderName.d.ts +0 -2
  294. package/src/types/ui/Chat/ChatHeaderActions.d.ts +0 -2
  295. package/src/types/ui/Chat/ChatPanel.d.ts +0 -13
  296. package/src/types/ui/Chat/ChatView.d.ts +0 -17
  297. package/src/types/ui/Chat/Members/ChatMembersButton.d.ts +0 -2
  298. package/src/types/ui/Chat/Members/ChatMembersPanel.d.ts +0 -2
  299. package/src/types/ui/Chat/Members/ChatMembersPreview.d.ts +0 -2
  300. package/src/types/ui/Chat/Members/index.d.ts +0 -11
  301. package/src/types/ui/Chat/index.d.ts +0 -6
  302. package/src/types/ui/ChatGroup/ChatGroupContext.d.ts +0 -12
  303. package/src/types/ui/ChatGroup/ChatGroupPanel.d.ts +0 -15
  304. package/src/types/ui/ChatGroup/Create/CreateChatButton.d.ts +0 -2
  305. package/src/types/ui/ChatGroup/Create/CreateChatMemberInput.d.ts +0 -5
  306. package/src/types/ui/ChatGroup/Create/CreateChatNameInput.d.ts +0 -5
  307. package/src/types/ui/ChatGroup/Create/CreateChatPanel.d.ts +0 -2
  308. package/src/types/ui/ChatGroup/Create/index.d.ts +0 -17
  309. package/src/types/ui/ChatGroup/Layout/ChatGroupAside.d.ts +0 -2
  310. package/src/types/ui/ChatGroup/Layout/ChatGroupBody.d.ts +0 -2
  311. package/src/types/ui/ChatGroup/Layout/ChatGroupFooter.d.ts +0 -2
  312. package/src/types/ui/ChatGroup/Layout/ChatGroupHeader.d.ts +0 -2
  313. package/src/types/ui/ChatGroup/Layout/ChatGroupMain.d.ts +0 -2
  314. package/src/types/ui/ChatGroup/Layout/index.d.ts +0 -17
  315. package/src/types/ui/ChatGroup/List/ChatList.d.ts +0 -2
  316. package/src/types/ui/ChatGroup/List/ChatListItemAvatar.d.ts +0 -3
  317. package/src/types/ui/ChatGroup/List/ChatListItemBox.d.ts +0 -6
  318. package/src/types/ui/ChatGroup/List/ChatListItemLastMessage.d.ts +0 -3
  319. package/src/types/ui/ChatGroup/List/ChatListItemLastMessageAuthor.d.ts +0 -3
  320. package/src/types/ui/ChatGroup/List/ChatListItemLastMessageContent.d.ts +0 -3
  321. package/src/types/ui/ChatGroup/List/ChatListItemLastMessageSentAt.d.ts +0 -3
  322. package/src/types/ui/ChatGroup/List/ChatListItemName.d.ts +0 -3
  323. package/src/types/ui/ChatGroup/List/ChatListItemUnreadCount.d.ts +0 -3
  324. package/src/types/ui/ChatGroup/index.d.ts +0 -5
  325. package/src/types/ui/Chatify.d.ts +0 -8
  326. package/src/types/ui/Conversation/Conversation.d.ts +0 -21
  327. package/src/types/ui/Conversation/ConversationActions.d.ts +0 -2
  328. package/src/types/ui/Conversation/ConversationBody.d.ts +0 -2
  329. package/src/types/ui/Conversation/ConversationContext.d.ts +0 -20
  330. package/src/types/ui/Conversation/ConversationHeader.d.ts +0 -2
  331. package/src/types/ui/Conversation/ConversationName.d.ts +0 -2
  332. package/src/types/ui/Conversation/InputBox/InputBox.d.ts +0 -2
  333. package/src/types/ui/Conversation/InputBox/InputFilesBox.d.ts +0 -2
  334. package/src/types/ui/Conversation/InputBox/InputSubmitButtonBox.d.ts +0 -5
  335. package/src/types/ui/Conversation/InputBox/InputTextBox.d.ts +0 -8
  336. package/src/types/ui/Conversation/Message/MessageAuthor.d.ts +0 -3
  337. package/src/types/ui/Conversation/Message/MessageBox.d.ts +0 -6
  338. package/src/types/ui/Conversation/Message/MessageContent.d.ts +0 -3
  339. package/src/types/ui/Conversation/Message/MessageInfoBox.d.ts +0 -3
  340. package/src/types/ui/Conversation/Message/MessageRow.d.ts +0 -6
  341. package/src/types/ui/Conversation/Message/MessageText.d.ts +0 -3
  342. package/src/types/ui/Conversation/NextObserver/NextMessagesObserver.d.ts +0 -5
  343. package/src/types/ui/Conversation/NextObserver/index.d.ts +0 -1
  344. package/src/types/ui/Conversation/ReadObserver/MessageReadObserver.d.ts +0 -6
  345. package/src/types/ui/Conversation/ReadObserver/index.d.ts +0 -1
  346. package/src/types/ui/Conversation/SendingMessage/SendingMessageBox.d.ts +0 -7
  347. package/src/types/ui/Conversation/SendingMessage/SendingMessageContent.d.ts +0 -3
  348. package/src/types/ui/Conversation/SendingMessage/SendingMessageInfoBox.d.ts +0 -3
  349. package/src/types/ui/Conversation/SendingMessage/SendingMessageText.d.ts +0 -3
  350. package/src/types/ui/Conversation/SendingMessage/index.d.ts +0 -14
  351. package/src/types/ui/Conversation/SystemMessage/SystemMessageBox.d.ts +0 -6
  352. package/src/types/ui/Conversation/SystemMessage/index.d.ts +0 -8
  353. package/src/types/ui/Conversation/index.d.ts +0 -12
  354. package/src/types/ui/Thread/ThreadActions.d.ts +0 -2
  355. package/src/types/ui/Thread/ThreadContext.d.ts +0 -8
  356. package/src/types/ui/Thread/ThreadPanel.d.ts +0 -14
  357. package/src/types/ui/Thread/index.d.ts +0 -3
  358. package/src/types/ui/color.d.ts +0 -6
  359. package/src/types/ui/common/Avatar.d.ts +0 -6
  360. package/src/types/ui/common/Icon.d.ts +0 -20
  361. package/src/types/ui/common/MessageSkeleton.d.ts +0 -5
  362. package/src/types/ui/common/index.d.ts +0 -11
  363. package/src/types/ui/index.d.ts +0 -11
  364. package/src/types/ui/localizer.d.ts +0 -35
  365. package/src/ui/ChatGroup/List/ChatList.tsx +0 -42
  366. /package/dist/{esm/types → types}/core/api/index.d.ts +0 -0
  367. /package/dist/{esm/types → types}/core/constants.d.ts +0 -0
  368. /package/dist/{esm/types → types}/core/debounce.d.ts +0 -0
  369. /package/dist/{esm/types → types}/core/index.d.ts +0 -0
  370. /package/dist/{esm/types → types}/index.d.ts +0 -0
  371. /package/dist/{esm/types → types}/ui/Chat/ChatContext.d.ts +0 -0
  372. /package/dist/{esm/types → types}/ui/Chat/ChatPanel.d.ts +0 -0
  373. /package/dist/{esm/types → types}/ui/Chat/Members/index.d.ts +0 -0
  374. /package/dist/{esm/types → types}/ui/Chat/index.d.ts +0 -0
  375. /package/dist/{esm/types → types}/ui/ChatGroup/ChatGroupContext.d.ts +0 -0
  376. /package/dist/{esm/types → types}/ui/ChatGroup/Create/index.d.ts +0 -0
  377. /package/dist/{esm/types → types}/ui/ChatGroup/Layout/index.d.ts +0 -0
  378. /package/dist/{esm/types → types}/ui/ChatGroup/index.d.ts +0 -0
  379. /package/dist/{esm/types → types}/ui/Conversation/NextObserver/NextMessagesObserver.d.ts +0 -0
  380. /package/dist/{esm/types → types}/ui/Conversation/NextObserver/index.d.ts +0 -0
  381. /package/dist/{esm/types → types}/ui/Conversation/ReadObserver/MessageReadObserver.d.ts +0 -0
  382. /package/dist/{esm/types → types}/ui/Conversation/ReadObserver/index.d.ts +0 -0
  383. /package/dist/{esm/types → types}/ui/Conversation/SendingMessage/index.d.ts +0 -0
  384. /package/dist/{esm/types → types}/ui/Conversation/SystemMessage/index.d.ts +0 -0
  385. /package/dist/{esm/types → types}/ui/Conversation/index.d.ts +0 -0
  386. /package/dist/{esm/types → types}/ui/Thread/ThreadPanel.d.ts +0 -0
  387. /package/dist/{esm/types → types}/ui/Thread/index.d.ts +0 -0
  388. /package/dist/{esm/types → types}/ui/color.d.ts +0 -0
@@ -0,0 +1,2203 @@
1
+ import './Chatify.css';var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
+ import { Button, Avatar as Avatar$1, List, Space, Tooltip, Input, Skeleton, Menu, Row, Col, Form, Checkbox } from "antd";
6
+ import React, { useContext, useState, useMemo, forwardRef, useCallback, useRef, useEffect, memo, useLayoutEffect } from "react";
7
+ import { DownloadOutlined, DeleteOutlined, EyeInvisibleOutlined, EyeOutlined, TeamOutlined, CloseOutlined, EditOutlined, UsergroupAddOutlined, UserAddOutlined, UsergroupDeleteOutlined, UserDeleteOutlined, SendOutlined, PaperClipOutlined } from "@ant-design/icons";
8
+ import { createApi, fakeBaseQuery } from "@reduxjs/toolkit/query/react";
9
+ import { useSelector } from "react-redux";
10
+ import * as SignalR from "@microsoft/signalr";
11
+ import { isHotkey } from "is-hotkey";
12
+ import dayjs from "dayjs";
13
+ const DEFAULT_COLOR_OPTIONS = {
14
+ saturation: 100,
15
+ lightness: 75
16
+ };
17
+ function color(value, options = {}) {
18
+ options = Object.assign({}, DEFAULT_COLOR_OPTIONS, options);
19
+ let hash = 0;
20
+ for (let i = 0; i < value.length; i++) {
21
+ hash = value.charCodeAt(i) + ((hash << 5) - hash);
22
+ hash = hash & hash;
23
+ }
24
+ return `hsl(${hash % 360}, ${options.saturation}%, ${options.lightness}%)`;
25
+ }
26
+ const CustomizeContext = React.createContext(null);
27
+ function useCustomizeContext() {
28
+ return useContext(CustomizeContext);
29
+ }
30
+ function useCustom(key) {
31
+ const value = useContext(CustomizeContext);
32
+ return value ? value[key] : void 0;
33
+ }
34
+ function useCustomize(custom) {
35
+ const Custom = useCustom(custom.key);
36
+ if (Custom == null) {
37
+ return null;
38
+ }
39
+ return Custom ?? custom.Component;
40
+ }
41
+ function customize(key, Component) {
42
+ const Result = React.forwardRef((props, forwardRef2) => {
43
+ const Custom = useCustom(key);
44
+ if (Custom === null) {
45
+ return null;
46
+ }
47
+ if (Custom) {
48
+ return /* @__PURE__ */ jsx(Custom, { ...props, ref: forwardRef2 });
49
+ }
50
+ return /* @__PURE__ */ jsx(Component, { ...props, ref: forwardRef2 });
51
+ });
52
+ Component.displayName = Component.displayName || key;
53
+ Result.displayName = "Customizable." + Component.displayName;
54
+ return Object.assign(Result, { key, Component });
55
+ }
56
+ const ICONS = {
57
+ attach: PaperClipOutlined,
58
+ send: SendOutlined,
59
+ "remove-member": UserDeleteOutlined,
60
+ "remove-member-delete-history": UsergroupDeleteOutlined,
61
+ "add-member": UserAddOutlined,
62
+ "add-member-with-history": UsergroupAddOutlined,
63
+ members: TeamOutlined,
64
+ edit: EditOutlined,
65
+ close: CloseOutlined,
66
+ chat: TeamOutlined,
67
+ watch: EyeOutlined,
68
+ unwatch: EyeInvisibleOutlined,
69
+ "delete-file": DeleteOutlined,
70
+ "open-file": DownloadOutlined
71
+ };
72
+ const Icon = customize("Icon", (props) => {
73
+ const { type } = props;
74
+ const IconComponent = ICONS[type];
75
+ return IconComponent ? /* @__PURE__ */ jsx(IconComponent, {}) : null;
76
+ });
77
+ const ChatReactContext = React.createContext(null);
78
+ function useChatContext() {
79
+ return useContext(ChatReactContext);
80
+ }
81
+ function ChatContext(props) {
82
+ const { id, children } = props;
83
+ const [showMembers, onShowMembers] = useState(false);
84
+ const value = useMemo(
85
+ () => ({
86
+ id,
87
+ showMembers,
88
+ onShowMembers
89
+ }),
90
+ [id, showMembers]
91
+ );
92
+ return /* @__PURE__ */ jsx(ChatReactContext.Provider, { value, children });
93
+ }
94
+ const ChatMembersButton = customize("ChatMembersButton", () => {
95
+ const { showMembers, onShowMembers } = useChatContext();
96
+ return /* @__PURE__ */ jsx(Button, { onClick: () => onShowMembers(!showMembers), type: "link", icon: /* @__PURE__ */ jsx(Icon, { type: "members" }) });
97
+ });
98
+ const SYSTEM_ID = "chatify::system";
99
+ function chatId(messageId) {
100
+ return messageId.slice(0, 36);
101
+ }
102
+ function messageSequencePart(id) {
103
+ return id.slice(37);
104
+ }
105
+ function parseThreadMessageId(messageId) {
106
+ const [threadId, index] = messageId.split("::", 2);
107
+ return [threadId, parseInt(index, 10)];
108
+ }
109
+ function calcThreadUnreadCount(thread) {
110
+ var _a, _b;
111
+ const lastReadMessageIndex = thread.lastReadMessageId != null ? parseThreadMessageId(thread.lastReadMessageId)[1] : -1;
112
+ const lastThreadMessageIndex = ((_a = thread.lastMessage) == null ? void 0 : _a.id) != null ? parseThreadMessageId((_b = thread.lastMessage) == null ? void 0 : _b.id)[1] : -1;
113
+ return lastThreadMessageIndex - lastReadMessageIndex;
114
+ }
115
+ function calcThreadListUnreadCount(threads) {
116
+ return threads.reduce((prev, thread) => {
117
+ return prev + calcThreadUnreadCount(thread);
118
+ }, 0);
119
+ }
120
+ class Debounce {
121
+ constructor(config) {
122
+ __publicField(this, "_enqueued", []);
123
+ __publicField(this, "_processing", []);
124
+ __publicField(this, "_timeoutByGroup", {});
125
+ __publicField(this, "_subscribers", []);
126
+ __publicField(this, "subscribe", (callback) => {
127
+ this._subscribers.push(callback);
128
+ return () => {
129
+ this._subscribers = this._subscribers.filter((x) => x !== callback);
130
+ };
131
+ });
132
+ __publicField(this, "notify", () => {
133
+ this._subscribers.forEach((subscriber) => subscriber(this));
134
+ });
135
+ this.config = config;
136
+ }
137
+ get units() {
138
+ return [
139
+ ...this._enqueued.map((x) => ({ ...x, state: "enqueued" })),
140
+ ...this._processing.map((x) => ({ ...x, state: "processing" }))
141
+ ];
142
+ }
143
+ push(value) {
144
+ const group = this.config.groupBy(value);
145
+ const unit = this._enqueued.find((unit2) => this.config.groupBy(unit2.value) === group);
146
+ if (!unit) {
147
+ this._enqueued.push({ value, enqueueTime: Date.now() });
148
+ } else if (this.config.compare(unit.value, value) >= 0) {
149
+ unit.value = value;
150
+ unit.enqueueTime = Date.now();
151
+ }
152
+ this._process(group);
153
+ }
154
+ _process(group) {
155
+ if (!this._enqueued.some((unit) => this.config.groupBy(unit.value) === group)) {
156
+ return;
157
+ }
158
+ let timeout = this._timeoutByGroup[group];
159
+ timeout && clearTimeout(timeout);
160
+ if (this._processing.some((unit) => this.config.groupBy(unit.value) === group)) {
161
+ return;
162
+ }
163
+ timeout = setTimeout(() => {
164
+ const processing = this._enqueued.find((unit) => this.config.groupBy(unit.value) === group);
165
+ this._processing.push(processing);
166
+ this._enqueued.splice(this._enqueued.indexOf(processing), 1);
167
+ this.notify();
168
+ this.config.callback(processing.value).then(() => {
169
+ this._processing.splice(this._processing.indexOf(processing), 1);
170
+ this.notify();
171
+ this._process(group);
172
+ }).catch(() => {
173
+ this._processing.splice(this._processing.indexOf(processing), 1);
174
+ this.push(processing.value);
175
+ });
176
+ }, this.config.timeout);
177
+ this._timeoutByGroup[group] = timeout;
178
+ }
179
+ }
180
+ const DEFAULT_MESSAGE_LIST_TAKE = 20;
181
+ const __settings = {
182
+ me: null,
183
+ client: null
184
+ };
185
+ const TAG_TYPES = ["chat", "account", "message", "thread", "thread-message"];
186
+ const baseApi = createApi({
187
+ baseQuery: fakeBaseQuery(),
188
+ reducerPath: "chatify",
189
+ tagTypes: TAG_TYPES,
190
+ endpoints: (_) => ({})
191
+ });
192
+ const __baseApi = baseApi;
193
+ const DEFAULT_SIGNALR_CONFIG = {
194
+ hubUri: "/api/chatify/hub",
195
+ headersFactory: () => Promise.resolve({})
196
+ };
197
+ const CHATIFY_SIGNALR_METHODS = [
198
+ "chatify://chat-new-message",
199
+ "chatify://chat-created",
200
+ "chatify://chat-message-read",
201
+ "chatify://chat-member-added",
202
+ "chatify://chat-member-removed",
203
+ "chatify://chat-name-changed",
204
+ "chatify://thread-created",
205
+ "chatify://thread-message-new",
206
+ "chatify://thread-message-read",
207
+ "chatify://thread-watch-added",
208
+ "chatify://thread-watch-removed",
209
+ "chatify://thread-updated"
210
+ ];
211
+ class ChatifyClient {
212
+ constructor(config) {
213
+ __publicField(this, "_config");
214
+ __publicField(this, "_connection", null);
215
+ __publicField(this, "_connectionPromise", null);
216
+ __publicField(this, "_subscribers", {});
217
+ __publicField(this, "_reconnectSubscribers", []);
218
+ __publicField(this, "_threadConnectionByThreadId", /* @__PURE__ */ new Map());
219
+ __publicField(this, "connect", async () => {
220
+ if (this._connection) {
221
+ return;
222
+ }
223
+ if (this._connectionPromise) {
224
+ return await this._connectionPromise;
225
+ }
226
+ this._connectionPromise = this.createAndStartConnection();
227
+ this._connection = await this._connectionPromise;
228
+ });
229
+ __publicField(this, "createAndStartConnection", async () => {
230
+ const headers = await this._config.signalR.headersFactory();
231
+ const connection = new SignalR.HubConnectionBuilder().withUrl(this._config.signalR.hubUri, {
232
+ accessTokenFactory: this._config.signalR.accessTokenFactory ? this._config.signalR.accessTokenFactory : void 0,
233
+ headers
234
+ }).withAutomaticReconnect().build();
235
+ CHATIFY_SIGNALR_METHODS.forEach((x) => {
236
+ connection.on(x, (...args) => {
237
+ var _a;
238
+ (_a = this._subscribers[x]) == null ? void 0 : _a.forEach((s) => {
239
+ try {
240
+ s(args);
241
+ } catch (ex) {
242
+ console.error(`Failed to notify subscriber`, ex);
243
+ }
244
+ });
245
+ });
246
+ });
247
+ connection.onreconnected(() => this._reconnectSubscribers.forEach((subscriber) => subscriber()));
248
+ await connection.start();
249
+ return connection;
250
+ });
251
+ __publicField(this, "subscribe", (method, subscriber) => {
252
+ this.connect().then(() => {
253
+ this._subscribers[method] = this._subscribers[method] ?? [];
254
+ this._subscribers[method].push(subscriber);
255
+ });
256
+ return () => this._subscribers[method].filter((x) => x !== subscriber);
257
+ });
258
+ __publicField(this, "subscribeReconnect", (subscriber) => {
259
+ this._reconnectSubscribers.push(subscriber);
260
+ return () => this._reconnectSubscribers.filter((x) => x !== subscriber);
261
+ });
262
+ __publicField(this, "accounts", async () => {
263
+ const { data } = await this.axios.get("account");
264
+ return data;
265
+ });
266
+ __publicField(this, "updateAccount", async (request) => {
267
+ await this.axios.put(`account/${encodeURIComponent(request.id)}`, request);
268
+ });
269
+ __publicField(this, "chats", async () => {
270
+ const { data } = await this.axios.get("chat");
271
+ return data;
272
+ });
273
+ __publicField(this, "chat", async (id) => {
274
+ const { data } = await this.axios.get(`chat/${encodeURIComponent(id)}`);
275
+ return data;
276
+ });
277
+ __publicField(this, "addChat", async (args) => {
278
+ const { data } = await this.axios.post(`chat`, args);
279
+ return data;
280
+ });
281
+ __publicField(this, "chatMessages", async (args) => {
282
+ const { chatId: chatId2, skip = 0, take = 20 } = args;
283
+ const pagingRule = encodeURIComponent(JSON.stringify({ skip, take }));
284
+ const { data } = await this.axios.get(
285
+ `chat/${encodeURIComponent(chatId2)}/message?pagingRule=${pagingRule}`
286
+ );
287
+ return data;
288
+ });
289
+ __publicField(this, "sendChatMessage", async (request) => {
290
+ const { chatId: chatId2, ...rest } = request;
291
+ await this.axios.post(`chat/${encodeURIComponent(chatId2)}/message`, rest);
292
+ });
293
+ __publicField(this, "readChatMessage", async (request) => {
294
+ await this.axios.put(`chat/message/read`, request);
295
+ });
296
+ __publicField(this, "removeChatMember", async (request) => {
297
+ await this.axios.delete(`chat/${encodeURIComponent(request.chatId)}/member`, { data: request });
298
+ });
299
+ __publicField(this, "updateChatName", async (request) => {
300
+ await this.axios.put(`chat/${encodeURIComponent(request.id)}/name`, request);
301
+ });
302
+ __publicField(this, "addChatMember", async (request) => {
303
+ await this.axios.post(`chat/${encodeURIComponent(request.chatId)}/member`, request);
304
+ });
305
+ __publicField(this, "sendThreadMessage", async ({ body, threadId }) => {
306
+ const { data: id } = await this.axios.post(`thread/${encodeURIComponent(threadId)}/message`, {
307
+ body
308
+ });
309
+ return id;
310
+ });
311
+ __publicField(this, "readThreadMessage", async (id) => {
312
+ await this.axios.put(`thread/message/${encodeURIComponent(id)}/read`);
313
+ });
314
+ __publicField(this, "watchThreads", async () => {
315
+ const { data } = await this.axios.get(`thread/watch`);
316
+ return data;
317
+ });
318
+ __publicField(this, "thread", async (id) => {
319
+ const { data } = await this.axios.get(`thread/${encodeURIComponent(id)}`);
320
+ return data;
321
+ });
322
+ __publicField(this, "threadMessages", async ({
323
+ threadId,
324
+ skip,
325
+ take
326
+ }) => {
327
+ const searchParams = new URLSearchParams();
328
+ searchParams.append("skip", skip.toString());
329
+ searchParams.append("take", take.toString());
330
+ const { data } = await this.axios.get(
331
+ `thread/${encodeURIComponent(threadId)}/message?${searchParams.toString()}`
332
+ );
333
+ return data;
334
+ });
335
+ __publicField(this, "watchThread", async (id, watch) => {
336
+ await this.axios.put(`thread/${encodeURIComponent(id)}/watch`, { watch });
337
+ });
338
+ __publicField(this, "connectToThread", async (id) => {
339
+ const connectionCount = this._threadConnectionByThreadId.get(id) ?? 0;
340
+ this._threadConnectionByThreadId.set(id, connectionCount + 1);
341
+ if (connectionCount === 0) {
342
+ this.connect().then(() => this._connection.invoke("ConnectToThread", id));
343
+ }
344
+ });
345
+ __publicField(this, "disconnectFromThread", async (id) => {
346
+ const connectionCount = this._threadConnectionByThreadId.get(id) ?? 0;
347
+ this._threadConnectionByThreadId.set(id, Math.max(0, connectionCount - 1));
348
+ if (connectionCount === 1) {
349
+ this.connect().then(() => this._connection.invoke("DisconnectFromThread", id));
350
+ }
351
+ });
352
+ this._config = {
353
+ ...config,
354
+ signalR: {
355
+ ...DEFAULT_SIGNALR_CONFIG,
356
+ ...config.signalR
357
+ }
358
+ };
359
+ }
360
+ get axios() {
361
+ return this._config.axios;
362
+ }
363
+ }
364
+ function unsubscribe(...subscribers) {
365
+ const result = () => subscribers.forEach((x) => x());
366
+ result.when = (promise) => promise.then(result);
367
+ return result;
368
+ }
369
+ const THREAD_MESSAGE_READ_QUEUE = new Debounce({
370
+ callback: (id) => __settings.client.readThreadMessage(id),
371
+ compare: (a, b) => -a.localeCompare(b),
372
+ groupBy: (id) => parseThreadMessageId(id)[0],
373
+ timeout: 500
374
+ });
375
+ const CHAT_MESSAGE_READ_QUEUE = new Debounce({
376
+ callback: (id) => __settings.client.readChatMessage({ id }),
377
+ compare: (a, b) => -a.localeCompare(b),
378
+ groupBy: (id) => chatId(id),
379
+ timeout: 500
380
+ });
381
+ const __chatifyApi = __baseApi.injectEndpoints({
382
+ endpoints: (builder) => ({
383
+ // ====================================================
384
+ // ============== ACCOUNT ======================
385
+ // ====================================================
386
+ getAccountList: builder.query({
387
+ queryFn: async () => ({ data: await __settings.client.accounts() }),
388
+ providesTags: ["account"]
389
+ }),
390
+ // ====================================================
391
+ // ================ CHAT =======================
392
+ // ====================================================
393
+ getChat: builder.query({
394
+ queryFn: async ({ id }) => ({ data: await __settings.client.chat(id) }),
395
+ providesTags: ["chat", "account"],
396
+ onCacheEntryAdded: async ({ id }, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {
397
+ await cacheDataLoaded;
398
+ unsubscribe(
399
+ __settings.client.subscribe(
400
+ "chatify://chat-member-added",
401
+ ([chatId2, _, account, message, , read]) => chatId2 === id && updateCachedData((chat) => {
402
+ chat.members.push(account);
403
+ chat.lastReadMessageId = read ? message.id : chat.lastReadMessageId;
404
+ })
405
+ ),
406
+ __settings.client.subscribe(
407
+ "chatify://chat-member-removed",
408
+ ([chatId2, accountId, , message, read]) => id === chatId2 && updateCachedData((chat) => {
409
+ chat.members = chat.members.filter((x) => x.id !== accountId);
410
+ chat.lastReadMessageId = read ? message.id : chat.lastReadMessageId;
411
+ })
412
+ ),
413
+ __settings.client.subscribe(
414
+ "chatify://chat-name-changed",
415
+ ([chatId2, newName, message, read]) => id === chatId2 && updateCachedData((chat) => {
416
+ chat.name = newName;
417
+ chat.lastReadMessageId = read ? message.id : chat.lastReadMessageId;
418
+ })
419
+ ),
420
+ __settings.client.subscribe(
421
+ "chatify://chat-new-message",
422
+ ([message]) => id === message.chatId && updateCachedData((chat) => {
423
+ chat.lastReadMessageId = message.sentBy.id === __settings.me() ? message.id : chat.lastReadMessageId;
424
+ })
425
+ ),
426
+ __settings.client.subscribe(
427
+ "chatify://chat-message-read",
428
+ ([events]) => events.find((x) => x.chatId === id) && updateCachedData((chat) => {
429
+ const event = events.find((x) => x.chatId === id);
430
+ chat.lastReadMessageId = event.newLastReadMessageId;
431
+ })
432
+ )
433
+ ).when(cacheEntryRemoved);
434
+ }
435
+ }),
436
+ addChat: builder.mutation({
437
+ queryFn: async ({ name, members }) => {
438
+ const chatId2 = await __settings.client.addChat({
439
+ name,
440
+ members
441
+ });
442
+ return { data: chatId2 };
443
+ }
444
+ }),
445
+ updateChatName: builder.mutation({
446
+ queryFn: async ({ id, name }) => {
447
+ await __settings.client.updateChatName({ id, name });
448
+ return { data: null };
449
+ }
450
+ }),
451
+ // ====================================================
452
+ // ============= CHAT LIST =====================
453
+ // ====================================================
454
+ getChatList: builder.query({
455
+ queryFn: async () => ({ data: await __settings.client.chats() }),
456
+ providesTags: ["chat", "account"],
457
+ onCacheEntryAdded: async (_, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {
458
+ await cacheDataLoaded;
459
+ unsubscribe(
460
+ __settings.client.subscribe(
461
+ "chatify://chat-created",
462
+ ([chat]) => updateCachedData((chatList) => {
463
+ chatList.push(chat);
464
+ })
465
+ ),
466
+ __settings.client.subscribe(
467
+ "chatify://chat-new-message",
468
+ ([message]) => updateCachedData((chatList) => {
469
+ const chat = chatList.find((x) => x.id === message.chatId);
470
+ if (!chat) {
471
+ return;
472
+ }
473
+ chat.message = message;
474
+ if (message.sentBy.id === __settings.me()) {
475
+ chat.lastReadMessageId = message.id;
476
+ chat.totalUnreadCount = 0;
477
+ }
478
+ if (message.sentBy.id !== __settings.me()) {
479
+ chat.totalUnreadCount++;
480
+ }
481
+ })
482
+ ),
483
+ __settings.client.subscribe(
484
+ "chatify://chat-message-read",
485
+ ([events]) => updateCachedData((chatList) => {
486
+ for (const event of events) {
487
+ const chat = chatList.find((x) => x.id === event.chatId);
488
+ if (!chat) {
489
+ return;
490
+ }
491
+ chat.lastReadMessageId = event.newLastReadMessageId;
492
+ chat.totalUnreadCount = chat.totalUnreadCount - event.readCount;
493
+ }
494
+ })
495
+ ),
496
+ __settings.client.subscribe(
497
+ "chatify://chat-member-added",
498
+ ([chatId2, chatName, account, message, , read]) => updateCachedData((chatList) => {
499
+ const chat = chatList.find((x) => x.id === chatId2);
500
+ if (account.id === __settings.me() && !chat) {
501
+ chatList.push({
502
+ id: chatId2,
503
+ name: chatName,
504
+ message,
505
+ totalUnreadCount: read ? 0 : 1,
506
+ active: true,
507
+ lastReadMessageId: read ? message.id : null
508
+ });
509
+ }
510
+ if (!chat) {
511
+ return;
512
+ }
513
+ chat.message = message;
514
+ chat.active = true;
515
+ if (read) {
516
+ chat.totalUnreadCount = 0;
517
+ chat.lastReadMessageId = message.id;
518
+ } else {
519
+ chat.totalUnreadCount++;
520
+ }
521
+ })
522
+ ),
523
+ __settings.client.subscribe(
524
+ "chatify://chat-member-removed",
525
+ ([chatId2, accountId, deleteHistory, message, read]) => updateCachedData((chatList) => {
526
+ if (accountId === __settings.me() && deleteHistory) {
527
+ return chatList.filter((x) => x.id !== chatId2);
528
+ }
529
+ const chat = chatList.find((x) => x.id === chatId2);
530
+ if (!chat) {
531
+ return;
532
+ }
533
+ chat.message = message;
534
+ if (accountId === __settings.me()) {
535
+ chat.active = false;
536
+ }
537
+ if (!read) {
538
+ chat.totalUnreadCount++;
539
+ } else {
540
+ chat.totalUnreadCount = 0;
541
+ chat.lastReadMessageId = message.id;
542
+ }
543
+ })
544
+ ),
545
+ __settings.client.subscribe(
546
+ "chatify://chat-name-changed",
547
+ ([chatId2, newName, message, read]) => updateCachedData((chatList) => {
548
+ const chat = chatList.find((x) => x.id === chatId2);
549
+ if (!chat) return;
550
+ chat.name = newName;
551
+ chat.message = message;
552
+ if (!read) {
553
+ chat.totalUnreadCount++;
554
+ } else {
555
+ chat.totalUnreadCount = 0;
556
+ chat.lastReadMessageId = message.id;
557
+ }
558
+ })
559
+ )
560
+ ).when(cacheEntryRemoved);
561
+ }
562
+ }),
563
+ // ====================================================
564
+ // ============ CHAT MEMBER ====================
565
+ // ====================================================
566
+ removeChatMember: builder.mutation({
567
+ queryFn: async (args) => {
568
+ await __settings.client.removeChatMember(args);
569
+ return { data: null };
570
+ }
571
+ }),
572
+ addChatMember: builder.mutation({
573
+ queryFn: async (args) => {
574
+ await __settings.client.addChatMember(args);
575
+ return { data: null };
576
+ }
577
+ }),
578
+ // ====================================================
579
+ // ============ CHAT MESSAGE ===================
580
+ // ====================================================
581
+ getChatMessageList: builder.query({
582
+ queryFn: async ({ chatId: chatId2 }) => {
583
+ const messages = await __settings.client.chatMessages({
584
+ chatId: chatId2,
585
+ skip: 0,
586
+ take: DEFAULT_MESSAGE_LIST_TAKE + 1
587
+ });
588
+ return {
589
+ data: {
590
+ messages: messages.slice(0, DEFAULT_MESSAGE_LIST_TAKE),
591
+ hasMore: messages.length === DEFAULT_MESSAGE_LIST_TAKE + 1
592
+ }
593
+ };
594
+ },
595
+ providesTags: ["message", "chat", "account"],
596
+ onCacheEntryAdded: async ({ chatId: chatId2 }, { dispatch, cacheEntryRemoved, cacheDataLoaded }) => {
597
+ await cacheDataLoaded;
598
+ unsubscribe(
599
+ __settings.client.subscribe("chatify://chat-new-message", ([message]) => {
600
+ message.chatId === chatId2 && dispatch(
601
+ chatifyApi.util.updateQueryData("getChatMessageList", { chatId: chatId2 }, (draft) => {
602
+ draft.messages.unshift(message);
603
+ })
604
+ );
605
+ }),
606
+ __settings.client.subscribe("chatify://chat-member-added", ([eventChatId, , , message]) => {
607
+ eventChatId === chatId2 && dispatch(
608
+ chatifyApi.util.updateQueryData("getChatMessageList", { chatId: chatId2 }, (draft) => {
609
+ draft.messages.unshift(message);
610
+ })
611
+ );
612
+ }),
613
+ __settings.client.subscribe("chatify://chat-member-removed", ([eventChatId, , , message]) => {
614
+ eventChatId === chatId2 && dispatch(
615
+ chatifyApi.util.updateQueryData("getChatMessageList", { chatId: chatId2 }, (draft) => {
616
+ draft.messages.unshift(message);
617
+ })
618
+ );
619
+ }),
620
+ __settings.client.subscribe("chatify://chat-name-changed", ([eventChatId, , message]) => {
621
+ eventChatId === chatId2 && dispatch(
622
+ chatifyApi.util.updateQueryData("getChatMessageList", { chatId: chatId2 }, (draft) => {
623
+ draft.messages.unshift(message);
624
+ })
625
+ );
626
+ })
627
+ ).when(cacheEntryRemoved);
628
+ }
629
+ }),
630
+ fetchNextChatMessageList: builder.mutation({
631
+ queryFn: async ({ chatId: chatId2 }, { getState }) => {
632
+ const current = chatifyApi.endpoints.getChatMessageList.select({ chatId: chatId2 })(getState());
633
+ const messages = await __settings.client.chatMessages({
634
+ chatId: chatId2,
635
+ skip: current.data.messages.length,
636
+ take: DEFAULT_MESSAGE_LIST_TAKE + 1
637
+ });
638
+ return {
639
+ data: null,
640
+ meta: {
641
+ messages: messages.slice(0, DEFAULT_MESSAGE_LIST_TAKE),
642
+ hasMore: messages.length === DEFAULT_MESSAGE_LIST_TAKE + 1
643
+ }
644
+ };
645
+ },
646
+ onQueryStarted: async ({ chatId: chatId2 }, { dispatch, queryFulfilled }) => {
647
+ const result = await queryFulfilled;
648
+ const meta = result.meta;
649
+ dispatch(
650
+ chatifyApi.util.updateQueryData("getChatMessageList", { chatId: chatId2 }, (draft) => {
651
+ draft.hasMore = meta.hasMore;
652
+ draft.messages.push(...meta.messages);
653
+ })
654
+ );
655
+ }
656
+ }),
657
+ sendChatMessage: builder.mutation({
658
+ queryFn: async ({ chatId: chatId2, text, files }) => {
659
+ await __settings.client.sendChatMessage({
660
+ chatId: chatId2,
661
+ text,
662
+ files
663
+ });
664
+ return { data: null };
665
+ }
666
+ }),
667
+ readChatMessage: builder.mutation({
668
+ queryFn: async () => {
669
+ return { data: null };
670
+ },
671
+ onQueryStarted: async ({ id }, { dispatch }) => {
672
+ CHAT_MESSAGE_READ_QUEUE.push(id);
673
+ dispatch(chatifyApi.endpoints.getChatMessageReadQueue.initiate(void 0, { forceRefetch: true }));
674
+ }
675
+ }),
676
+ getChatMessageReadQueue: builder.query({
677
+ queryFn: async () => ({ data: CHAT_MESSAGE_READ_QUEUE.units }),
678
+ onCacheEntryAdded: async (_, { dispatch, cacheEntryRemoved }) => {
679
+ unsubscribe(
680
+ CHAT_MESSAGE_READ_QUEUE.subscribe((value) => {
681
+ dispatch(
682
+ chatifyApi.util.updateQueryData("getChatMessageReadQueue", void 0, () => value.units)
683
+ );
684
+ })
685
+ ).when(cacheEntryRemoved);
686
+ }
687
+ }),
688
+ // ====================================================
689
+ // =============== THREAD ======================s
690
+ // ====================================================
691
+ getWatchThreadList: builder.query({
692
+ queryFn: async () => {
693
+ const threads = await __settings.client.watchThreads();
694
+ return { data: threads };
695
+ },
696
+ providesTags: ["account", "thread"],
697
+ onCacheEntryAdded: async (_, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {
698
+ await cacheDataLoaded;
699
+ unsubscribe(
700
+ __settings.client.subscribe(
701
+ "chatify://thread-created",
702
+ ([thread, watch]) => watch && updateCachedData((threads) => {
703
+ threads.push(thread);
704
+ })
705
+ ),
706
+ __settings.client.subscribe(
707
+ "chatify://thread-message-new",
708
+ ([threadId, message, readForId]) => updateCachedData((threads) => {
709
+ const thread = threads.find((x) => x.id === threadId);
710
+ if (!thread) return;
711
+ thread.lastMessage = message;
712
+ if (readForId === __settings.me()) {
713
+ thread.lastReadMessageId = message.id;
714
+ }
715
+ })
716
+ ),
717
+ __settings.client.subscribe(
718
+ "chatify://thread-message-read",
719
+ ([threadId, messageId]) => updateCachedData((threads) => {
720
+ const thread = threads.find((x) => x.id === threadId);
721
+ if (!thread) return;
722
+ thread.lastReadMessageId = messageId;
723
+ })
724
+ ),
725
+ __settings.client.subscribe(
726
+ "chatify://thread-watch-added",
727
+ ([thread]) => updateCachedData((threads) => {
728
+ threads.push(thread);
729
+ })
730
+ ),
731
+ __settings.client.subscribe(
732
+ "chatify://thread-watch-removed",
733
+ ([id]) => updateCachedData((threads) => {
734
+ const index = threads.findIndex((x) => x.id === id);
735
+ if (index !== -1) threads.splice(index, 1);
736
+ })
737
+ ),
738
+ __settings.client.subscribe(
739
+ "chatify://thread-updated",
740
+ ([threadId, threadName]) => updateCachedData((threads) => {
741
+ const thread = threads.find((x) => x.id === threadId);
742
+ if (!thread) return;
743
+ thread.name = threadName;
744
+ })
745
+ )
746
+ ).when(cacheEntryRemoved);
747
+ }
748
+ }),
749
+ getThread: builder.query({
750
+ queryFn: async ({ id }) => {
751
+ const threads = await __settings.client.thread(id);
752
+ return { data: threads };
753
+ },
754
+ providesTags: ["account", "thread"],
755
+ onCacheEntryAdded: async ({ id }, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {
756
+ await cacheDataLoaded;
757
+ unsubscribe(
758
+ __settings.client.subscribe(
759
+ "chatify://thread-message-read",
760
+ ([threadId, messageId]) => id === threadId && updateCachedData((t) => {
761
+ t.lastReadMessageId = messageId;
762
+ })
763
+ ),
764
+ __settings.client.subscribe(
765
+ "chatify://thread-message-new",
766
+ ([threadId, message, readForId]) => id === threadId && updateCachedData((thread) => {
767
+ thread.lastMessageId = message.id;
768
+ thread.lastReadMessageId = readForId === __settings.me() ? message.id : thread.lastReadMessageId;
769
+ })
770
+ ),
771
+ __settings.client.subscribe(
772
+ "chatify://thread-watch-added",
773
+ ([threadListItem]) => id === threadListItem.id && updateCachedData((thread) => {
774
+ var _a;
775
+ thread.watch = true;
776
+ thread.lastMessageId = ((_a = threadListItem.lastMessage) == null ? void 0 : _a.id) ?? null;
777
+ thread.lastReadMessageId = threadListItem.lastReadMessageId ?? null;
778
+ })
779
+ ),
780
+ __settings.client.subscribe(
781
+ "chatify://thread-watch-removed",
782
+ ([threadId]) => id === threadId && updateCachedData((thread) => {
783
+ thread.watch = false;
784
+ })
785
+ ),
786
+ __settings.client.subscribe(
787
+ "chatify://thread-updated",
788
+ ([threadId, threadName]) => id === threadId && updateCachedData((thread) => {
789
+ thread.name = threadName;
790
+ })
791
+ )
792
+ ).when(cacheEntryRemoved);
793
+ }
794
+ }),
795
+ watchThread: builder.mutation({
796
+ queryFn: async ({ id, watch }) => {
797
+ await __settings.client.watchThread(id, watch);
798
+ return { data: null };
799
+ }
800
+ }),
801
+ // ====================================================
802
+ // ============ THREAD MESSAGE =================
803
+ // ====================================================
804
+ getThreadMessageList: builder.query({
805
+ queryFn: async (args) => {
806
+ const requestArgs = {
807
+ skip: 0,
808
+ take: DEFAULT_MESSAGE_LIST_TAKE + 1,
809
+ ...args
810
+ };
811
+ const messages = await __settings.client.threadMessages(requestArgs);
812
+ return {
813
+ data: {
814
+ messages: messages.slice(0, DEFAULT_MESSAGE_LIST_TAKE),
815
+ hasMore: messages.length === DEFAULT_MESSAGE_LIST_TAKE + 1
816
+ }
817
+ };
818
+ },
819
+ providesTags: ["account", "thread", "thread-message"],
820
+ onCacheEntryAdded: async ({ threadId }, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {
821
+ await cacheDataLoaded;
822
+ unsubscribe(
823
+ __settings.client.subscribe("chatify://thread-message-new", ([_threadId, message]) => {
824
+ threadId === _threadId && updateCachedData((messageList) => {
825
+ !messageList.messages.some((x) => x.id === message.id) && messageList.messages.unshift(message);
826
+ });
827
+ })
828
+ ).when(cacheEntryRemoved);
829
+ }
830
+ }),
831
+ fetchNextThreadMessageList: builder.mutation({
832
+ queryFn: async ({ threadId }, { getState }) => {
833
+ const current = chatifyApi.endpoints.getThreadMessageList.select({ threadId })(getState());
834
+ const messages = await __settings.client.threadMessages({
835
+ threadId,
836
+ skip: current.data.messages.length,
837
+ take: DEFAULT_MESSAGE_LIST_TAKE + 1
838
+ });
839
+ return {
840
+ data: null,
841
+ meta: {
842
+ messages: messages.slice(0, DEFAULT_MESSAGE_LIST_TAKE),
843
+ hasMore: messages.length === DEFAULT_MESSAGE_LIST_TAKE + 1
844
+ }
845
+ };
846
+ },
847
+ onQueryStarted: async ({ threadId }, { dispatch, queryFulfilled }) => {
848
+ const result = await queryFulfilled;
849
+ const meta = result.meta;
850
+ dispatch(
851
+ chatifyApi.util.updateQueryData("getThreadMessageList", { threadId }, (draft) => {
852
+ draft.hasMore = meta.hasMore;
853
+ draft.messages.push(...meta.messages);
854
+ })
855
+ );
856
+ }
857
+ }),
858
+ sendThreadMessage: builder.mutation({
859
+ queryFn: async (args) => {
860
+ const id = await __settings.client.sendThreadMessage(args);
861
+ return { data: id };
862
+ }
863
+ }),
864
+ readThreadMessage: builder.mutation({
865
+ queryFn: async () => {
866
+ return { data: null };
867
+ },
868
+ onQueryStarted: async ({ id }, { dispatch }) => {
869
+ THREAD_MESSAGE_READ_QUEUE.push(id);
870
+ dispatch(chatifyApi.endpoints.getThreadMessageReadQueue.initiate(void 0, { forceRefetch: true }));
871
+ }
872
+ }),
873
+ getThreadMessageReadQueue: builder.query({
874
+ queryFn: async () => ({ data: THREAD_MESSAGE_READ_QUEUE.units }),
875
+ onCacheEntryAdded: async (_, { dispatch, cacheEntryRemoved }) => {
876
+ unsubscribe(
877
+ THREAD_MESSAGE_READ_QUEUE.subscribe((value) => {
878
+ dispatch(
879
+ chatifyApi.util.updateQueryData("getThreadMessageReadQueue", void 0, () => value.units)
880
+ );
881
+ })
882
+ ).when(cacheEntryRemoved);
883
+ }
884
+ })
885
+ })
886
+ });
887
+ function useChatListItem(id) {
888
+ return useSelector(
889
+ (state) => {
890
+ var _a;
891
+ return id != null ? (_a = __chatifyApi.endpoints.getChatList.select()(state).data) == null ? void 0 : _a.find((x) => x.id === id) : null;
892
+ }
893
+ );
894
+ }
895
+ function useUnreadThreadMessageCount() {
896
+ const { data: threads, ...state } = chatifyApi.useGetWatchThreadListQuery();
897
+ const count = useMemo(() => threads != null ? calcThreadListUnreadCount(threads) : null, [threads]);
898
+ return [count, state];
899
+ }
900
+ const chatifyApi = Object.assign(__chatifyApi, {
901
+ settings: __settings,
902
+ useChatListItem,
903
+ useUnreadThreadMessageCount
904
+ });
905
+ const _Avatar = forwardRef(
906
+ (props, forwardRef2) => {
907
+ const { account } = props;
908
+ return /* @__PURE__ */ jsx(Avatar$1, { ref: forwardRef2, src: account.avatar });
909
+ }
910
+ );
911
+ _Avatar.displayName = "Avatar";
912
+ const Avatar = customize("Avatar", _Avatar);
913
+ function useAdd(chatId2, accountId, withHistory) {
914
+ const [add, state] = chatifyApi.useAddChatMemberMutation();
915
+ const onAdd = useCallback(
916
+ () => add({ chatId: chatId2, accountId, withHistory }),
917
+ [add, chatId2, accountId, withHistory]
918
+ );
919
+ return [onAdd, state];
920
+ }
921
+ function useRemove(chatId2, accountId, deleteHistory) {
922
+ const [remove, state] = chatifyApi.useRemoveChatMemberMutation();
923
+ const onRemove = useCallback(
924
+ () => remove({ chatId: chatId2, accountId, deleteHistory }),
925
+ [remove, chatId2, accountId, deleteHistory]
926
+ );
927
+ return [onRemove, state];
928
+ }
929
+ const ChatMemberListItem = customize("ChatMemberListItem", (props) => {
930
+ const { chatId: chatId2 } = props;
931
+ const { data: chat } = chatifyApi.useGetChatQuery({ id: chatId2 });
932
+ const { data: accounts } = chatifyApi.useGetAccountListQuery();
933
+ const account = accounts.find((x) => x.id === props.id);
934
+ const isMember = chat.members.some((x) => x.id === account.id);
935
+ const [onAddWithoutHistory] = useAdd(chatId2, account.id, false);
936
+ const [onAddWithHistory] = useAdd(chatId2, account.id, true);
937
+ const [onRemoveKeepHistory] = useRemove(chatId2, account.id, false);
938
+ const [onRemoveDeleteHistory] = useRemove(chatId2, account.id, true);
939
+ return /* @__PURE__ */ jsx(
940
+ List.Item,
941
+ {
942
+ className: "wxchtf-chat-members-list-item",
943
+ actions: isMember ? [
944
+ /* @__PURE__ */ jsx(Tooltip, { title: "Remove (keep history)", children: /* @__PURE__ */ jsx(Button, { onClick: onRemoveKeepHistory, type: "link", icon: /* @__PURE__ */ jsx(Icon, { type: "remove-member" }) }) }, "remove"),
945
+ /* @__PURE__ */ jsx(Tooltip, { title: "Remove (delete history)", children: /* @__PURE__ */ jsx(
946
+ Button,
947
+ {
948
+ onClick: onRemoveDeleteHistory,
949
+ type: "link",
950
+ icon: /* @__PURE__ */ jsx(Icon, { type: "remove-member-delete-history" })
951
+ }
952
+ ) }, "remove_delete_history")
953
+ ] : [
954
+ /* @__PURE__ */ jsx(Tooltip, { title: "Add (no history)", children: /* @__PURE__ */ jsx(Button, { onClick: onAddWithoutHistory, type: "link", icon: /* @__PURE__ */ jsx(Icon, { type: "add-member" }) }) }, "add_no_history"),
955
+ /* @__PURE__ */ jsx(Tooltip, { title: "Add (share history)", children: /* @__PURE__ */ jsx(
956
+ Button,
957
+ {
958
+ onClick: onAddWithHistory,
959
+ type: "link",
960
+ icon: /* @__PURE__ */ jsx(Icon, { type: "add-member-with-history" })
961
+ }
962
+ ) }, "add")
963
+ ],
964
+ children: /* @__PURE__ */ jsxs(Space, { children: [
965
+ /* @__PURE__ */ jsx(Avatar, { account }),
966
+ /* @__PURE__ */ jsx("span", { children: account.name })
967
+ ] })
968
+ }
969
+ );
970
+ });
971
+ const ChatMembersPanel = customize("ChatMembersPanel", () => {
972
+ const { id } = useChatContext();
973
+ const { data: chat } = chatifyApi.useGetChatQuery({ id });
974
+ const { data: accounts } = chatifyApi.useGetAccountListQuery();
975
+ const ordered = useMemo(
976
+ () => accounts == null ? void 0 : accounts.slice().sort(
977
+ (a, b) => ((chat == null ? void 0 : chat.members.some((m) => m.id === a.id)) ? -100 : 0) - ((chat == null ? void 0 : chat.members.some((m) => m.id === b.id)) ? -100 : 0) + a.name.localeCompare(b.name)
978
+ ),
979
+ [accounts, chat]
980
+ );
981
+ if (!(chat == null ? void 0 : chat.members) || !accounts) {
982
+ return null;
983
+ }
984
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-chat-members-panel", children: /* @__PURE__ */ jsx(
985
+ List,
986
+ {
987
+ className: "wxchtf-chat-members-list",
988
+ dataSource: ordered,
989
+ renderItem: (item) => /* @__PURE__ */ jsx(ChatMemberListItem, { id: item.id, chatId: id })
990
+ }
991
+ ) });
992
+ });
993
+ const ChatMembersPreview = customize("ChatMembersPreview", () => {
994
+ const { id } = useChatContext();
995
+ const { data: chat } = chatifyApi.useGetChatQuery({ id });
996
+ if (!(chat == null ? void 0 : chat.members)) {
997
+ return null;
998
+ }
999
+ return /* @__PURE__ */ jsx(Avatar$1.Group, { max: { count: 5 }, children: chat.members.map((x) => /* @__PURE__ */ jsx(Tooltip, { title: x.name, children: /* @__PURE__ */ jsx(Avatar, { account: x }) }, x.id)) });
1000
+ });
1001
+ const InputFileButton = customize("InputFileButton", (props) => {
1002
+ const { onUpload, onAddedClick, accept, loading, value, disabled } = props;
1003
+ const inputRef = useRef(null);
1004
+ const onClick = useCallback(() => {
1005
+ var _a;
1006
+ return (_a = inputRef.current) == null ? void 0 : _a.click();
1007
+ }, []);
1008
+ const countButtonRef = useRef(null);
1009
+ useEffect(() => {
1010
+ var _a;
1011
+ (_a = countButtonRef.current) == null ? void 0 : _a.classList.add("active");
1012
+ }, [value]);
1013
+ const onCountButtonAnimationEnd = useCallback(() => {
1014
+ var _a;
1015
+ (_a = countButtonRef.current) == null ? void 0 : _a.classList.remove("active");
1016
+ }, []);
1017
+ const onInputChange = useCallback(
1018
+ (e) => {
1019
+ const files = e.target.files;
1020
+ files && files.length > 0 && onUpload(Array.from(files));
1021
+ },
1022
+ [onUpload]
1023
+ );
1024
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1025
+ /* @__PURE__ */ jsx(
1026
+ Button,
1027
+ {
1028
+ loading,
1029
+ onClick,
1030
+ type: "link",
1031
+ disabled,
1032
+ icon: /* @__PURE__ */ jsx(Icon, { type: "attach" }),
1033
+ className: "wxchtf-add-files-btn"
1034
+ }
1035
+ ),
1036
+ value.length > 0 && /* @__PURE__ */ jsx(
1037
+ Button,
1038
+ {
1039
+ ref: countButtonRef,
1040
+ className: "wxchtf-add-files-added-btn",
1041
+ onAnimationIteration: onCountButtonAnimationEnd,
1042
+ onClick: onAddedClick,
1043
+ type: "link",
1044
+ disabled,
1045
+ icon: /* @__PURE__ */ jsxs(Fragment, { children: [
1046
+ "+",
1047
+ value.length
1048
+ ] })
1049
+ }
1050
+ ),
1051
+ /* @__PURE__ */ jsx(
1052
+ "input",
1053
+ {
1054
+ value: "",
1055
+ accept,
1056
+ onChange: onInputChange,
1057
+ ref: inputRef,
1058
+ type: "file",
1059
+ multiple: true,
1060
+ style: { display: "none" }
1061
+ }
1062
+ )
1063
+ ] });
1064
+ });
1065
+ const InputFilesBox = customize("InputFilesBox", (props) => {
1066
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-add-files-box", children: /* @__PURE__ */ jsx(InputFileButton, { ...props }) });
1067
+ });
1068
+ const LocalizerContext = React.createContext(null);
1069
+ function useLocalizer() {
1070
+ return useContext(LocalizerContext);
1071
+ }
1072
+ const base = {
1073
+ isToday: (value) => dayjs(value).isSame(dayjs(), "day"),
1074
+ timestamp: (value) => dayjs(value).format("HH:mm"),
1075
+ dateTime: (value) => dayjs(value).format("DD/MM/YYYY HH:mm"),
1076
+ message: {
1077
+ read: () => "Read",
1078
+ reading: () => "Reading...",
1079
+ sending: () => "Sending..."
1080
+ },
1081
+ addChat: {
1082
+ title: () => "Add chat",
1083
+ name: {
1084
+ label: () => "Name",
1085
+ required: () => `Name is required`,
1086
+ max250: () => "Max 250 characters allowed"
1087
+ },
1088
+ members: {
1089
+ label: () => "Members",
1090
+ required: () => "Members is required"
1091
+ },
1092
+ submitBtn: () => "Submit"
1093
+ },
1094
+ system: {
1095
+ "chatify://chat-created": () => "Chat created",
1096
+ "chatify://member-added": () => "New member added",
1097
+ "chatify://member-removed": () => "Member removed",
1098
+ "chatify://chat-name-changed": (_, { newName }) => `Chat name changed to '${newName}'`
1099
+ },
1100
+ input: {
1101
+ placeholder: () => "Start typing... (Press Enter to send, and Shift+Enter to start a new line)"
1102
+ },
1103
+ settings: {
1104
+ members: () => "Members"
1105
+ },
1106
+ size: {
1107
+ bytes: (value) => `${value.toLocaleString(void 0, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} bytes`,
1108
+ kb: (value) => `${value.toLocaleString(void 0, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} KB`,
1109
+ mb: (value) => `${value.toLocaleString(void 0, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} MB`
1110
+ },
1111
+ chatList: {
1112
+ topShown: (count) => `Latest active ${count} chat${count !== 1 ? "s" : ""} shown`
1113
+ }
1114
+ };
1115
+ const defaultLocalizer = base;
1116
+ const isEnter$1 = isHotkey("enter");
1117
+ const isCtrlEnter = isHotkey("ctrl+enter");
1118
+ const AUTO_SIZE = { maxRows: 5, minRows: 1 };
1119
+ const InputTextBox = customize(
1120
+ "InputTextBox",
1121
+ memo((props) => {
1122
+ const { value, onChange, onSend, disabled, inputRef } = props;
1123
+ const localizer = useLocalizer();
1124
+ const onInputChange = useCallback(
1125
+ (e) => onChange(e.target.value),
1126
+ [onChange]
1127
+ );
1128
+ const onKeyDown = useCallback(
1129
+ (e) => {
1130
+ if (disabled) {
1131
+ e.preventDefault();
1132
+ return;
1133
+ }
1134
+ if (isEnter$1(e) || isCtrlEnter(e)) {
1135
+ e.preventDefault();
1136
+ onSend(value);
1137
+ }
1138
+ },
1139
+ [onSend, value, disabled]
1140
+ );
1141
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-text-input-box", children: /* @__PURE__ */ jsx(
1142
+ Input.TextArea,
1143
+ {
1144
+ ref: inputRef,
1145
+ value,
1146
+ onChange: onInputChange,
1147
+ autoSize: AUTO_SIZE,
1148
+ className: "wxchtf-text-input-textarea",
1149
+ placeholder: localizer.input.placeholder(),
1150
+ onKeyDown
1151
+ }
1152
+ ) });
1153
+ })
1154
+ );
1155
+ const InputSubmitButtonBox = customize("InputSubmitButtonBox", (props) => {
1156
+ const { onSubmit, disabled, loading } = props;
1157
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-submit-btn-box", children: /* @__PURE__ */ jsx(
1158
+ Button,
1159
+ {
1160
+ onClick: onSubmit,
1161
+ type: "link",
1162
+ icon: /* @__PURE__ */ jsx(Icon, { type: "send" }),
1163
+ className: "wxchtf-submit-btn",
1164
+ disabled,
1165
+ loading
1166
+ }
1167
+ ) });
1168
+ });
1169
+ const ConversationContext = React.createContext(void 0);
1170
+ function useConversation$1() {
1171
+ return React.useContext(ConversationContext);
1172
+ }
1173
+ const MessageSkeleton = customize("MessageSkeleton", (props) => {
1174
+ const { count = 1 } = props;
1175
+ return /* @__PURE__ */ jsx(Fragment, { children: Array.from(Array(count)).map((_, index) => /* @__PURE__ */ jsxs("div", { className: "wxchtf-message-skeleton", children: [
1176
+ /* @__PURE__ */ jsx(Skeleton.Avatar, { className: "wxchtf-avatar", active: true }),
1177
+ /* @__PURE__ */ jsx(Skeleton.Button, { active: true, className: "wxchtf-content" })
1178
+ ] }, index)) });
1179
+ });
1180
+ const ChatListItemName = customize("ChatListItemName", (props) => {
1181
+ const { chat } = props;
1182
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-chat-name", children: chat.name });
1183
+ });
1184
+ const ChatListItemUnreadCount = customize("ChatListItemUnreadCount", (props) => {
1185
+ const { totalUnreadCount: unreadCount } = props.chat;
1186
+ if (unreadCount == null || unreadCount <= 0) {
1187
+ return null;
1188
+ }
1189
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-unread-count", children: unreadCount });
1190
+ });
1191
+ function formatSystemMessage(localizer, text) {
1192
+ const [key, payload] = text.split("::", 2);
1193
+ const data = payload ? JSON.parse(payload) : null;
1194
+ return localizer.system[key](key, data);
1195
+ }
1196
+ const SystemMessageRow = customize("SystemMessageRow", (props) => {
1197
+ const { message, containerRef } = props;
1198
+ const { text, sentAt } = message;
1199
+ const localizer = useLocalizer();
1200
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "wxchtf-system-message", children: [
1201
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-text", children: text && formatSystemMessage(localizer, text) }),
1202
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-timestamp", children: localizer.timestamp(sentAt) })
1203
+ ] });
1204
+ });
1205
+ const Observer = (props) => {
1206
+ const { message, messageRef } = props;
1207
+ const { onRead, lastReadMessageId } = useConversation$1();
1208
+ const isRead = lastReadMessageId != null && message.id.localeCompare(lastReadMessageId) <= 0;
1209
+ const readRef = useRef(isRead);
1210
+ useEffect(() => {
1211
+ readRef.current = readRef.current || isRead;
1212
+ }, [isRead]);
1213
+ const observer = useMemo(
1214
+ () => new IntersectionObserver(([entry]) => {
1215
+ if (entry.isIntersecting && !readRef.current) {
1216
+ readRef.current = true;
1217
+ onRead == null ? void 0 : onRead(message.id);
1218
+ }
1219
+ }),
1220
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1221
+ []
1222
+ );
1223
+ useEffect(() => {
1224
+ observer.observe(messageRef.current);
1225
+ return () => observer.disconnect();
1226
+ }, [observer]);
1227
+ return /* @__PURE__ */ jsx(Fragment, {});
1228
+ };
1229
+ function MessageReadObserver(props) {
1230
+ const { noReadTracking } = useConversation$1();
1231
+ if (noReadTracking === true) {
1232
+ return null;
1233
+ }
1234
+ return /* @__PURE__ */ jsx(Observer, { ...props });
1235
+ }
1236
+ const SystemMessageBox = customize("SystemMessageBox", (props) => {
1237
+ const ref = useRef(null);
1238
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1239
+ /* @__PURE__ */ jsx(MessageReadObserver, { messageRef: ref, ...props }),
1240
+ /* @__PURE__ */ jsx(SystemMessageRow, { containerRef: ref, ...props })
1241
+ ] });
1242
+ });
1243
+ const ChatListItemLastMessageContent = customize(
1244
+ "ChatListItemLastMessageContent",
1245
+ (props) => {
1246
+ const { lastMessage } = props.chat;
1247
+ const localizer = useLocalizer();
1248
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-chat-last-message", children: lastMessage.sentBy.id === "chatify::system" ? lastMessage.text && formatSystemMessage(localizer, lastMessage.text) : lastMessage.text });
1249
+ }
1250
+ );
1251
+ const ChatListItemLastMessageAuthor = customize(
1252
+ "ChatListItemLastMessageAuthor",
1253
+ (props) => {
1254
+ const { lastMessage } = props.chat;
1255
+ if (lastMessage.sentBy.id === "chatify::system") {
1256
+ return null;
1257
+ }
1258
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-chat-last-author", children: lastMessage.sentBy.name });
1259
+ }
1260
+ );
1261
+ const ChatListItemLastMessageSentAt = customize(
1262
+ "ChatListItemLastMessageSentAt",
1263
+ (props) => {
1264
+ const {
1265
+ chat: {
1266
+ lastMessage: { sentAt }
1267
+ }
1268
+ } = props;
1269
+ const localizer = useLocalizer();
1270
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-chat-last-sent-at", children: localizer.isToday(sentAt) ? localizer.timestamp(sentAt) : localizer.dateTime(sentAt) });
1271
+ }
1272
+ );
1273
+ const ChatListItemLastMessage = customize("ChatListItemLastMessage", (props) => {
1274
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-chat-last", children: [
1275
+ /* @__PURE__ */ jsx(ChatListItemLastMessageAuthor, { ...props }),
1276
+ /* @__PURE__ */ jsx(ChatListItemLastMessageContent, { ...props }),
1277
+ /* @__PURE__ */ jsx(ChatListItemLastMessageSentAt, { ...props })
1278
+ ] });
1279
+ });
1280
+ const ChatListItemAvatar = customize("ChatListItemAvatar", (props) => {
1281
+ const { id } = props.chat;
1282
+ return /* @__PURE__ */ jsx(
1283
+ "div",
1284
+ {
1285
+ className: "wxchtf-chat-avatar",
1286
+ style: {
1287
+ "--background-color": color(id, { lightness: 90 }),
1288
+ "--color": color(id, { saturation: 60, lightness: 65 })
1289
+ },
1290
+ children: /* @__PURE__ */ jsx(Icon, { type: "chat" })
1291
+ }
1292
+ );
1293
+ });
1294
+ const ChatListItemBox = customize("ChatListItemBox", (props) => {
1295
+ const { noRead = false } = props;
1296
+ const { lastMessage, lastReadMessageId } = props.chat;
1297
+ const read = lastReadMessageId != null && lastReadMessageId.localeCompare(lastMessage.id) >= 0;
1298
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-chat" + (!read && !noRead ? " --unread" : ""), children: [
1299
+ /* @__PURE__ */ jsx(ChatListItemAvatar, { ...props }),
1300
+ /* @__PURE__ */ jsxs("span", { className: "wxchtf-chat-info", children: [
1301
+ /* @__PURE__ */ jsx(ChatListItemName, { ...props }),
1302
+ /* @__PURE__ */ jsx(ChatListItemUnreadCount, { ...props }),
1303
+ /* @__PURE__ */ jsx(ChatListItemLastMessage, { ...props })
1304
+ ] })
1305
+ ] });
1306
+ });
1307
+ function useOnSelect(props) {
1308
+ const { onSelect } = props;
1309
+ return useMemo(
1310
+ () => onSelect ? (info) => onSelect(info.key) : void 0,
1311
+ [onSelect]
1312
+ );
1313
+ }
1314
+ function useMenuItems(props) {
1315
+ const { items, noRead, top } = props;
1316
+ const localizer = useLocalizer();
1317
+ return useMemo(() => {
1318
+ const result = items == null ? void 0 : items.slice().sort(
1319
+ (a, b) => -messageSequencePart(a.lastMessage.id).localeCompare(messageSequencePart(b.lastMessage.id))
1320
+ ).map((x) => ({ key: x.id, label: /* @__PURE__ */ jsx(ChatListItemBox, { chat: x, noRead }) }));
1321
+ if (top != null) {
1322
+ return [
1323
+ ...result,
1324
+ {
1325
+ type: "item",
1326
+ key: "top",
1327
+ disabled: true,
1328
+ label: /* @__PURE__ */ jsx("div", { style: { textAlign: "center", cursor: "text", fontStyle: "italic" }, children: localizer.chatList.topShown(top) })
1329
+ }
1330
+ ];
1331
+ }
1332
+ return result;
1333
+ }, [items, noRead, top, localizer]);
1334
+ }
1335
+ const ChatList = customize("ChatList", (props) => {
1336
+ const { selected: selectedChatId } = props;
1337
+ const selected = useMemo(() => selectedChatId ? [selectedChatId] : [], [selectedChatId]);
1338
+ const onSelect = useOnSelect(props);
1339
+ const items = useMenuItems(props);
1340
+ return /* @__PURE__ */ jsx(Fragment, { children: items && /* @__PURE__ */ jsx(Menu, { className: "wxchtf-chat-list", selectedKeys: selected, onSelect, items }) });
1341
+ });
1342
+ function useFormatter() {
1343
+ const localizer = useLocalizer();
1344
+ return {
1345
+ size: (value) => {
1346
+ if (value < 1024) {
1347
+ return localizer.size.bytes(value);
1348
+ } else if (value < 1024 * 1024) {
1349
+ return localizer.size.kb(value / 1024);
1350
+ } else {
1351
+ return localizer.size.mb(value / 1024 / 1024);
1352
+ }
1353
+ }
1354
+ };
1355
+ }
1356
+ const InputBoxFile = customize("InputBoxFile", (props) => {
1357
+ const { file, disabled, onDelete } = props;
1358
+ const formatter = useFormatter();
1359
+ const onDeleteClick = useCallback(() => onDelete(file), [file, onDelete]);
1360
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-file", children: [
1361
+ /* @__PURE__ */ jsxs("div", { className: "wxchtf-file-info", children: [
1362
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-file-name", title: file.name, children: file.name }),
1363
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-file-size", children: formatter.size(file.bytes) })
1364
+ ] }),
1365
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-file-actions", children: /* @__PURE__ */ jsx(
1366
+ Button,
1367
+ {
1368
+ disabled,
1369
+ className: "wxchtf-delete",
1370
+ type: "link",
1371
+ icon: /* @__PURE__ */ jsx(Icon, { type: "delete-file" }),
1372
+ onClick: onDeleteClick
1373
+ }
1374
+ ) })
1375
+ ] });
1376
+ });
1377
+ const InputBoxFileList = customize("InputBoxFileList", (props) => {
1378
+ const { files, onDelete, disabled } = props;
1379
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-file-list", children: files.map((file) => /* @__PURE__ */ jsx(InputBoxFile, { file, onDelete, disabled }, file.ref)) });
1380
+ });
1381
+ function useFormState() {
1382
+ const { onSend } = useConversation$1();
1383
+ const [text, setText] = useState("");
1384
+ const [sending, setSending] = useState(false);
1385
+ const { onUpload, files, loading, setFiles, showFileBox, onDeleteFile } = useFlippoInputFileBox();
1386
+ const onSubmit = useCallback(() => {
1387
+ if (!onSend) {
1388
+ return;
1389
+ }
1390
+ const textValue = text.trim().length === 0 ? null : text.trim();
1391
+ if (!textValue && files.length === 0 || loading) {
1392
+ return;
1393
+ }
1394
+ setSending(true);
1395
+ Promise.resolve(onSend({ text: textValue, files })).finally(() => setSending(false)).then(() => {
1396
+ setFiles([]);
1397
+ setText("");
1398
+ });
1399
+ }, [text, onSend, files, setFiles, loading]);
1400
+ return [onSubmit, { text, setText, files, onUpload, loading, showFileBox, onDeleteFile, sending }];
1401
+ }
1402
+ function useFlippoInputFileBox() {
1403
+ const [loading, setLoading] = useState(false);
1404
+ const [files, setFiles] = useState([]);
1405
+ const { flippo } = useCustomizeContext();
1406
+ const onUpload = useCallback(
1407
+ (files2) => {
1408
+ if (!flippo) return;
1409
+ setLoading(true);
1410
+ Promise.all(files2.map((file) => flippo.store(file))).then(
1411
+ (references) => setFiles((prev) => [
1412
+ ...prev,
1413
+ ...references.map((reference, index) => ({
1414
+ name: files2[index].name,
1415
+ ref: reference,
1416
+ bytes: files2[index].size
1417
+ }))
1418
+ ])
1419
+ ).finally(() => setLoading(false));
1420
+ },
1421
+ [flippo]
1422
+ );
1423
+ const onDeleteFile = useCallback((file) => {
1424
+ setFiles((prev) => prev.filter((f) => f !== file));
1425
+ }, []);
1426
+ return { onUpload, files, loading, setFiles, showFileBox: !!flippo, onDeleteFile };
1427
+ }
1428
+ const InputBox = customize("InputBox", () => {
1429
+ const [onSend, { text, setText, files, loading, onUpload, showFileBox, onDeleteFile, sending }] = useFormState();
1430
+ const inputRef = useRef(null);
1431
+ const [showFileList, setShowFileList] = useState(false);
1432
+ const toggleShowFileList = useCallback(() => setShowFileList((prev) => !prev), []);
1433
+ const prevFilesLength = useRef(files.length);
1434
+ useLayoutEffect(() => {
1435
+ var _a;
1436
+ return (_a = inputRef.current) == null ? void 0 : _a.focus();
1437
+ }, []);
1438
+ useEffect(() => {
1439
+ if (prevFilesLength.current === 0 && files.length > 0 && !showFileList) {
1440
+ setShowFileList(true);
1441
+ }
1442
+ prevFilesLength.current = files.length;
1443
+ if (files.length === 0 && showFileList) {
1444
+ setShowFileList(false);
1445
+ }
1446
+ }, [files, showFileList]);
1447
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-input-form", children: /* @__PURE__ */ jsxs("div", { className: "wxchtf-input-box", children: [
1448
+ showFileList && /* @__PURE__ */ jsx("div", { className: "wxchtf-file-list-box", children: /* @__PURE__ */ jsx(InputBoxFileList, { files, onDelete: onDeleteFile, disabled: sending }) }),
1449
+ /* @__PURE__ */ jsxs("div", { className: "wxchtf-input-box-row", children: [
1450
+ showFileBox && /* @__PURE__ */ jsx(
1451
+ InputFilesBox,
1452
+ {
1453
+ onAddedClick: toggleShowFileList,
1454
+ onUpload,
1455
+ value: files,
1456
+ loading,
1457
+ disabled: sending
1458
+ }
1459
+ ),
1460
+ /* @__PURE__ */ jsx(
1461
+ InputTextBox,
1462
+ {
1463
+ value: text,
1464
+ onSend,
1465
+ onChange: setText,
1466
+ disabled: sending,
1467
+ inputRef
1468
+ }
1469
+ ),
1470
+ /* @__PURE__ */ jsx(InputSubmitButtonBox, { onSubmit: onSend, disabled: loading, loading: sending })
1471
+ ] })
1472
+ ] }) });
1473
+ });
1474
+ const MessageAuthor = customize("MessageAuthor", (props) => {
1475
+ const { sentBy } = props.message;
1476
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-message-author", children: /* @__PURE__ */ jsx(Avatar, { account: sentBy }) });
1477
+ });
1478
+ const MessageText = customize("MessageText", (props) => {
1479
+ const { text } = props.message;
1480
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-message-text", children: text });
1481
+ });
1482
+ function open(url) {
1483
+ const w = window.open(url, "_blank");
1484
+ w == null ? void 0 : w.focus();
1485
+ }
1486
+ function useOpen(props) {
1487
+ const { file } = props;
1488
+ const { flippo } = useCustomizeContext();
1489
+ const [isOpenFetching, setIsOpenFetching] = useState(false);
1490
+ const onOpen = useCallback(
1491
+ () => flippo && Promise.resolve(setIsOpenFetching(true)).then(() => flippo.getSasUrl(file.ref)).then(open).finally(() => setIsOpenFetching(false)),
1492
+ [flippo, file.ref]
1493
+ );
1494
+ return [onOpen, { isOpenFetching }];
1495
+ }
1496
+ const MessageFile = customize("MessageFile", (props) => {
1497
+ const { file } = props;
1498
+ const formatter = useFormatter();
1499
+ const [onOpen, { isOpenFetching }] = useOpen(props);
1500
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-file", children: [
1501
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-icon", children: /* @__PURE__ */ jsx(Button, { loading: isOpenFetching, onClick: onOpen, type: "link", icon: /* @__PURE__ */ jsx(Icon, { type: "open-file" }) }) }),
1502
+ /* @__PURE__ */ jsxs("div", { className: "wxchtf-file-info", children: [
1503
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-name", title: file.name, children: file.name }),
1504
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-size", children: formatter.size(file.bytes) })
1505
+ ] })
1506
+ ] });
1507
+ });
1508
+ const MessageFileList = customize("MessageFileList", (props) => {
1509
+ const { files } = props.message;
1510
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-file-list", children: files.map((file) => /* @__PURE__ */ jsx(MessageFile, { file }, file.ref)) });
1511
+ });
1512
+ const MessageContent = customize("MessageContent", (props) => {
1513
+ const { files, text } = props.message;
1514
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-message-content", children: [
1515
+ text && /* @__PURE__ */ jsx(MessageText, { ...props }),
1516
+ files.length > 0 && /* @__PURE__ */ jsx(MessageFileList, { ...props })
1517
+ ] });
1518
+ });
1519
+ const MessageInfoBox = customize("MessageInfoBox", (props) => {
1520
+ const { message } = props;
1521
+ const { id, sentBy, sentAt } = message;
1522
+ const { lastReadMessageId, isReading, noReadTracking } = useConversation$1();
1523
+ const me = chatifyApi.settings.me();
1524
+ const my = sentBy.id === me;
1525
+ const localizer = useLocalizer();
1526
+ const isRead = lastReadMessageId != null && id.localeCompare(lastReadMessageId) <= 0;
1527
+ const reading = !isRead && (isReading == null ? void 0 : isReading(id));
1528
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-message-info-box", children: [
1529
+ !my && /* @__PURE__ */ jsxs("div", { className: "wxchtf-message-author-name", children: [
1530
+ sentBy.name,
1531
+ ","
1532
+ ] }),
1533
+ /* @__PURE__ */ jsx("div", { className: "wxchtf-message-sent-at", children: localizer.timestamp(sentAt) }),
1534
+ !my && !noReadTracking && /* @__PURE__ */ jsx("div", { className: "wxchtf-message-read-box", children: reading ? localizer.message.reading() : localizer.message.read() })
1535
+ ] });
1536
+ });
1537
+ const MessageRow = customize("MessageRow", (props) => {
1538
+ const { message, containerRef } = props;
1539
+ const { sentBy } = message;
1540
+ const me = chatifyApi.settings.me();
1541
+ const my = sentBy.id === me;
1542
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "wxchtf-message" + (my ? " --my" : ""), children: [
1543
+ /* @__PURE__ */ jsx(MessageAuthor, { ...props }),
1544
+ /* @__PURE__ */ jsxs("div", { children: [
1545
+ /* @__PURE__ */ jsx(MessageInfoBox, { ...props }),
1546
+ /* @__PURE__ */ jsx(MessageContent, { ...props })
1547
+ ] })
1548
+ ] });
1549
+ });
1550
+ const MessageBox = customize("MessageBox", (props) => {
1551
+ const ref = useRef(null);
1552
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1553
+ /* @__PURE__ */ jsx(MessageReadObserver, { messageRef: ref, ...props }),
1554
+ /* @__PURE__ */ jsx(MessageRow, { containerRef: ref, ...props })
1555
+ ] });
1556
+ });
1557
+ function NextMessagesObserver(props) {
1558
+ const { onLoad, loading } = props;
1559
+ const [intersecting, setIntersecting] = useState(false);
1560
+ const ref = useRef(null);
1561
+ const timerRef = useRef();
1562
+ const observer = useMemo(
1563
+ () => new IntersectionObserver(([entry]) => {
1564
+ if (entry.isIntersecting) {
1565
+ timerRef.current = window.setTimeout(() => setIntersecting(true), 200);
1566
+ } else {
1567
+ clearTimeout(timerRef.current);
1568
+ }
1569
+ }),
1570
+ []
1571
+ );
1572
+ useEffect(() => {
1573
+ observer.observe(ref.current);
1574
+ return () => observer.disconnect();
1575
+ }, [observer]);
1576
+ useEffect(() => {
1577
+ if (!intersecting) {
1578
+ return;
1579
+ }
1580
+ onLoad();
1581
+ }, [intersecting]);
1582
+ if (loading || intersecting) {
1583
+ return /* @__PURE__ */ jsx(MessageSkeleton, { count: 4 });
1584
+ }
1585
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-next", ref });
1586
+ }
1587
+ const SendingMessageText = customize("SendingMessageText", (props) => {
1588
+ const { text } = props;
1589
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-sending-message-text", children: text });
1590
+ });
1591
+ const SendingMessageInfoBox = customize("SendingMessageInfoBox", (_) => {
1592
+ const localizer = useLocalizer();
1593
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-sending-message-info-box", children: /* @__PURE__ */ jsx("div", { className: "wxchtf-sending-message-sending-box", children: localizer.message.sending() }) });
1594
+ });
1595
+ const SendingMessageContent = customize("SendingMessageContent", (props) => {
1596
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-sending-message-content", children: [
1597
+ /* @__PURE__ */ jsx(SendingMessageText, { ...props }),
1598
+ /* @__PURE__ */ jsx(SendingMessageInfoBox, { ...props })
1599
+ ] });
1600
+ });
1601
+ const SendingMessageBox = customize("SendingMessageBox", (props) => {
1602
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-sending-message", children: /* @__PURE__ */ jsx(SendingMessageContent, { ...props }) });
1603
+ });
1604
+ const ConversationActions = customize("ConversationActions", () => {
1605
+ const { onClose } = useConversation$1();
1606
+ if (!onClose) return null;
1607
+ return /* @__PURE__ */ jsx(Button, { onClick: onClose, type: "link", icon: /* @__PURE__ */ jsx(Icon, { type: "close" }) });
1608
+ });
1609
+ const ConversationBody = customize("ConversationBody", () => {
1610
+ const { id, messages = [], hasMore, onNext, nextLoading } = useConversation$1();
1611
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-conversation-body", children: [
1612
+ !messages && /* @__PURE__ */ jsx(MessageSkeleton, { count: 5 }),
1613
+ messages == null ? void 0 : messages.map((x) => {
1614
+ if (x.sentBy.id === SYSTEM_ID) {
1615
+ return /* @__PURE__ */ jsx(SystemMessageBox, { message: x }, x.id);
1616
+ }
1617
+ return /* @__PURE__ */ jsx(MessageBox, { message: x }, x.id);
1618
+ }),
1619
+ hasMore && /* @__PURE__ */ jsx(NextMessagesObserver, { onLoad: onNext, loading: nextLoading }, messages.length + id)
1620
+ ] });
1621
+ });
1622
+ const ConversationName = customize("ConversationName", () => {
1623
+ const { name } = useConversation$1();
1624
+ return /* @__PURE__ */ jsx("span", { className: "wxchtf-conversation-name", children: name });
1625
+ });
1626
+ const ConversationHeader = customize("ConversationHeader", () => {
1627
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-conversation-header", children: /* @__PURE__ */ jsxs(Row, { justify: "space-between", align: "middle", children: [
1628
+ /* @__PURE__ */ jsx(Col, { children: /* @__PURE__ */ jsx(ConversationName, {}) }),
1629
+ /* @__PURE__ */ jsx(Col, { className: "wxchtf-conversation-actions", children: /* @__PURE__ */ jsx(ConversationActions, {}) })
1630
+ ] }) });
1631
+ });
1632
+ const Conversation = customize("Conversation", (props) => {
1633
+ const {
1634
+ value,
1635
+ hasMore,
1636
+ messages,
1637
+ nextLoading,
1638
+ onNext,
1639
+ onRead,
1640
+ onSend,
1641
+ isReading,
1642
+ noReadTracking,
1643
+ onClose
1644
+ } = props;
1645
+ const { id, active, name, lastReadMessageId } = value;
1646
+ const context = useMemo(
1647
+ () => ({
1648
+ id,
1649
+ name,
1650
+ active,
1651
+ lastReadMessageId,
1652
+ hasMore,
1653
+ messages,
1654
+ nextLoading,
1655
+ onNext,
1656
+ onRead,
1657
+ onSend,
1658
+ isReading,
1659
+ noReadTracking,
1660
+ onClose
1661
+ }),
1662
+ [
1663
+ id,
1664
+ name,
1665
+ active,
1666
+ onNext,
1667
+ onRead,
1668
+ onSend,
1669
+ hasMore,
1670
+ messages,
1671
+ nextLoading,
1672
+ lastReadMessageId,
1673
+ isReading,
1674
+ noReadTracking,
1675
+ onClose
1676
+ ]
1677
+ );
1678
+ return /* @__PURE__ */ jsx(ConversationContext.Provider, { value: context, children: /* @__PURE__ */ jsx("div", { className: "wxchtf-conversation", children: /* @__PURE__ */ jsxs("div", { className: "wxchtf-conversation-main", children: [
1679
+ /* @__PURE__ */ jsx(ConversationHeader, {}),
1680
+ /* @__PURE__ */ jsx(ConversationBody, {}),
1681
+ active && /* @__PURE__ */ jsx(InputBox, {})
1682
+ ] }) }) });
1683
+ });
1684
+ const isEscape = isHotkey("escape");
1685
+ const isEnter = isHotkey("enter");
1686
+ function useUpdateChatName(id, value) {
1687
+ const [updateChatName] = chatifyApi.useUpdateChatNameMutation();
1688
+ return () => updateChatName({ id, name: value });
1689
+ }
1690
+ const ChatEditableHeaderName = customize("ChatEditableHeaderName", () => {
1691
+ const { id, name, active } = useConversation$1();
1692
+ const [editNameValue, setEditNameValue] = useState("");
1693
+ const [edit, setEdit] = useState(false);
1694
+ const updateChatName = useUpdateChatName(id, editNameValue);
1695
+ useEffect(() => {
1696
+ if (edit) {
1697
+ setEditNameValue(name ?? "");
1698
+ }
1699
+ }, [edit, name]);
1700
+ if (!active) {
1701
+ return /* @__PURE__ */ jsx("span", { className: "wxchtf-conversation-name", children: name });
1702
+ }
1703
+ if (edit) {
1704
+ return /* @__PURE__ */ jsx(Tooltip, { defaultOpen: true, title: "Press Enter to save new chat name or Escape to cancel editing", children: /* @__PURE__ */ jsx(
1705
+ Input,
1706
+ {
1707
+ value: editNameValue,
1708
+ onChange: (e) => setEditNameValue(e.target.value),
1709
+ onBlur: () => setEdit(false),
1710
+ onKeyDown: (e) => {
1711
+ if (isEscape(e)) {
1712
+ setEdit(false);
1713
+ } else if (isEnter(e)) {
1714
+ setEdit(false);
1715
+ if (editNameValue !== name && editNameValue.trim() !== "") {
1716
+ updateChatName();
1717
+ }
1718
+ }
1719
+ },
1720
+ autoFocus: true
1721
+ }
1722
+ ) });
1723
+ }
1724
+ return /* @__PURE__ */ jsx(Tooltip, { title: "Click to edit name...", children: /* @__PURE__ */ jsx("span", { className: "wxchtf-conversation-name --editable", onClick: () => setEdit(true), children: name }) });
1725
+ });
1726
+ const ChatHeaderActions = customize("ChatHeaderActions", () => {
1727
+ const { active } = useConversation$1();
1728
+ if (!active) {
1729
+ return null;
1730
+ }
1731
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-chat-members", children: [
1732
+ /* @__PURE__ */ jsx(ChatMembersPreview, {}),
1733
+ /* @__PURE__ */ jsx(ChatMembersButton, {})
1734
+ ] });
1735
+ });
1736
+ const DEFAULT_CHAT_VIEW_CUSTOMIZE_VALUE = {
1737
+ ConversationName: () => /* @__PURE__ */ jsx(ChatEditableHeaderName, {}),
1738
+ ConversationActions: () => /* @__PURE__ */ jsx(ChatHeaderActions, {})
1739
+ };
1740
+ function useConversation(props) {
1741
+ const { value: chat } = props;
1742
+ const { id, name, active, lastReadMessageId } = chat;
1743
+ const { data: messageList } = chatifyApi.useGetChatMessageListQuery({ chatId: id });
1744
+ const { messages, hasMore } = messageList ?? {};
1745
+ const [fetchNext, { isLoading: isFetchNextLoading }] = chatifyApi.useFetchNextChatMessageListMutation();
1746
+ const onNext = useCallback(() => fetchNext({ chatId: id }), [fetchNext, id]);
1747
+ const [read] = chatifyApi.useReadChatMessageMutation();
1748
+ const onRead = useCallback((id2) => read({ id: id2 }), [read]);
1749
+ const [send] = chatifyApi.useSendChatMessageMutation();
1750
+ const onSend = useCallback((message) => send({ ...message, chatId: id }).unwrap(), [id, send]);
1751
+ const { data: readQueue } = chatifyApi.useGetChatMessageReadQueueQuery();
1752
+ const conversation = useMemo(() => {
1753
+ if (!id) {
1754
+ return null;
1755
+ }
1756
+ const result = {
1757
+ value: { id, name, active, lastReadMessageId },
1758
+ messages,
1759
+ hasMore,
1760
+ onNext,
1761
+ nextLoading: isFetchNextLoading,
1762
+ onRead,
1763
+ onSend,
1764
+ isReading: (id2) => readQueue.some((x) => chatId(x.value) === chatId(id2) && id2 <= x.value)
1765
+ };
1766
+ return result;
1767
+ }, [
1768
+ onNext,
1769
+ onRead,
1770
+ onSend,
1771
+ isFetchNextLoading,
1772
+ id,
1773
+ name,
1774
+ active,
1775
+ messages,
1776
+ hasMore,
1777
+ lastReadMessageId,
1778
+ readQueue
1779
+ ]);
1780
+ return conversation;
1781
+ }
1782
+ function Content$1(props) {
1783
+ const conversation = useConversation(props);
1784
+ const { showMembers } = useChatContext();
1785
+ if (!conversation) {
1786
+ return null;
1787
+ }
1788
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-chat", children: [
1789
+ /* @__PURE__ */ jsx(Conversation, { ...conversation }),
1790
+ showMembers && /* @__PURE__ */ jsx(ChatMembersPanel, {})
1791
+ ] });
1792
+ }
1793
+ const ChatView = customize("ChatView", (props) => {
1794
+ const { value } = props;
1795
+ const customized = useCustomizeContext();
1796
+ const customize2 = useMemo(
1797
+ () => ({ ...customized ?? {}, ...DEFAULT_CHAT_VIEW_CUSTOMIZE_VALUE }),
1798
+ [customized]
1799
+ );
1800
+ return /* @__PURE__ */ jsx(CustomizeContext.Provider, { value: customize2, children: /* @__PURE__ */ jsx(ChatContext, { id: value.id, children: /* @__PURE__ */ jsx(Content$1, { value }) }) });
1801
+ });
1802
+ function ChatPanel(props) {
1803
+ const { id, className = "", customize: customize2, localizer = defaultLocalizer, style } = props;
1804
+ const { data: chat } = chatifyApi.useGetChatQuery({ id });
1805
+ return /* @__PURE__ */ jsx("div", { className: `wxchtf-chatify wxchtf-chat-panel ${className}`, style, children: /* @__PURE__ */ jsx(LocalizerContext.Provider, { value: localizer, children: /* @__PURE__ */ jsx(CustomizeContext.Provider, { value: customize2, children: chat && /* @__PURE__ */ jsx(ChatView, { value: chat }, id) }) }) });
1806
+ }
1807
+ const CreateChatNameInput = customize("CreateChatNameInput", (props) => {
1808
+ const { name } = props;
1809
+ const localizer = useLocalizer();
1810
+ return /* @__PURE__ */ jsx(
1811
+ Form.Item,
1812
+ {
1813
+ name,
1814
+ label: localizer.addChat.name.label(),
1815
+ rules: [
1816
+ { required: true, message: localizer.addChat.name.required() },
1817
+ { max: 250, message: localizer.addChat.name.max250() }
1818
+ ],
1819
+ children: /* @__PURE__ */ jsx(Input, {})
1820
+ }
1821
+ );
1822
+ });
1823
+ function CheckboxList(props) {
1824
+ const { value, onChange } = props;
1825
+ const { data: accounts, isFetching } = chatifyApi.useGetAccountListQuery();
1826
+ const me = chatifyApi.settings.me();
1827
+ const dataSource = useMemo(() => (accounts == null ? void 0 : accounts.filter((x) => x.id !== me)) ?? [], [accounts, me]);
1828
+ return /* @__PURE__ */ jsx(
1829
+ List,
1830
+ {
1831
+ rowKey: "id",
1832
+ className: "wxchtf-create-chat-member-input-list",
1833
+ loading: isFetching,
1834
+ dataSource,
1835
+ renderItem: (x) => {
1836
+ const checked = value.includes(x.id);
1837
+ return /* @__PURE__ */ jsx(List.Item, { className: checked ? "--selected" : "", children: /* @__PURE__ */ jsx(
1838
+ Checkbox,
1839
+ {
1840
+ checked,
1841
+ onChange: () => onChange(value.includes(x.id) ? value.filter((y) => y !== x.id) : [...value, x.id]),
1842
+ children: /* @__PURE__ */ jsx(List.Item.Meta, { avatar: /* @__PURE__ */ jsx(Avatar, { account: x }), title: x.name })
1843
+ }
1844
+ ) });
1845
+ }
1846
+ }
1847
+ );
1848
+ }
1849
+ const CreateChatMemberInput = customize(
1850
+ "CreateChatMemberInput",
1851
+ (props) => {
1852
+ const { name } = props;
1853
+ const localizer = useLocalizer();
1854
+ return /* @__PURE__ */ jsx(
1855
+ Form.Item,
1856
+ {
1857
+ label: localizer.addChat.members.label(),
1858
+ rules: [{ required: true, message: localizer.addChat.members.required() }],
1859
+ name,
1860
+ children: /* @__PURE__ */ jsx(CheckboxList, {})
1861
+ }
1862
+ );
1863
+ }
1864
+ );
1865
+ const INITIAL_VALUE = {
1866
+ name: "",
1867
+ members: []
1868
+ };
1869
+ const CreateChatForm = customize("CreateChatForm", (props) => {
1870
+ const { value = INITIAL_VALUE, onSubmit, busy = false } = props;
1871
+ const localizer = useLocalizer();
1872
+ return /* @__PURE__ */ jsxs(Form, { onFinish: onSubmit, layout: "vertical", disabled: busy, initialValues: value, children: [
1873
+ /* @__PURE__ */ jsx(CreateChatNameInput, { name: "name" }),
1874
+ /* @__PURE__ */ jsx(CreateChatMemberInput, { name: "members" }),
1875
+ /* @__PURE__ */ jsx(Button, { loading: busy, type: "primary", block: true, htmlType: "submit", children: localizer.addChat.submitBtn() })
1876
+ ] });
1877
+ });
1878
+ const ChatGroupReactContext = React.createContext(null);
1879
+ function useChatGroupContext() {
1880
+ return useContext(ChatGroupReactContext);
1881
+ }
1882
+ function ChatGroupContext(props) {
1883
+ const { children } = props;
1884
+ const [state, setState] = useState({
1885
+ chatId: null,
1886
+ view: null,
1887
+ showMembers: false
1888
+ });
1889
+ const value = useMemo(
1890
+ () => ({
1891
+ ...state,
1892
+ openChat: (chatId2) => setState((prev) => ({ ...prev, view: "chat", chatId: chatId2 })),
1893
+ none: () => setState((prev) => ({ ...prev, view: null, chatId: null })),
1894
+ toggleMembers: () => setState((prev) => ({ ...prev, showMembers: !prev.showMembers })),
1895
+ toggleNewChat: () => setState((prev) => {
1896
+ if (prev.view === "new-chat" && !prev.chatId) {
1897
+ return { ...prev, view: null };
1898
+ } else if (prev.view === "new-chat" && prev.chatId) {
1899
+ return { ...prev, view: "chat" };
1900
+ } else {
1901
+ return { ...prev, view: "new-chat" };
1902
+ }
1903
+ })
1904
+ }),
1905
+ [state]
1906
+ );
1907
+ return /* @__PURE__ */ jsx(ChatGroupReactContext.Provider, { value, children });
1908
+ }
1909
+ function useSubmit() {
1910
+ const [add, { isLoading }] = chatifyApi.useAddChatMutation();
1911
+ const { openChat } = useChatGroupContext();
1912
+ const onSubmit = useCallback(
1913
+ (value) => add({
1914
+ name: value.name,
1915
+ members: value.members
1916
+ }).unwrap().then((id) => openChat(id)),
1917
+ [add, openChat]
1918
+ );
1919
+ return [onSubmit, isLoading];
1920
+ }
1921
+ const CreateChatPanel = customize("CreateChatPanel", () => {
1922
+ const localizer = useLocalizer();
1923
+ const [onSubmit, submitting] = useSubmit();
1924
+ const { toggleNewChat } = useChatGroupContext();
1925
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-create-chat-panel", children: [
1926
+ /* @__PURE__ */ jsx(
1927
+ Button,
1928
+ {
1929
+ onClick: () => toggleNewChat(),
1930
+ className: "wxchtf-create-chat-panel-close",
1931
+ type: "link",
1932
+ icon: /* @__PURE__ */ jsx(Icon, { type: "close" })
1933
+ }
1934
+ ),
1935
+ /* @__PURE__ */ jsx("h3", { children: localizer.addChat.title() }),
1936
+ /* @__PURE__ */ jsx(CreateChatForm, { busy: submitting ?? false, onSubmit })
1937
+ ] });
1938
+ });
1939
+ const CreateChatButton = customize("CreateChatButton", () => {
1940
+ const { toggleNewChat } = useChatGroupContext();
1941
+ return /* @__PURE__ */ jsx("span", { className: "wxchtf-add-btn-wrapper", children: /* @__PURE__ */ jsx(Button, { className: "wxchtf-add-btn", onClick: toggleNewChat, icon: "+", children: "Add chat" }) });
1942
+ });
1943
+ function useData() {
1944
+ const { data: chats } = chatifyApi.useGetChatListQuery();
1945
+ return useMemo(
1946
+ () => (chats == null ? void 0 : chats.map(
1947
+ (x) => ({
1948
+ id: x.id,
1949
+ name: x.name,
1950
+ lastMessage: x.message,
1951
+ lastReadMessageId: x.lastReadMessageId
1952
+ })
1953
+ )) ?? [],
1954
+ [chats]
1955
+ );
1956
+ }
1957
+ const ChatListPanel = customize("ChatListPanel", () => {
1958
+ const { chatId: chatId2, openChat } = useChatGroupContext();
1959
+ const data = useData();
1960
+ return /* @__PURE__ */ jsx(ChatList, { items: data, selected: chatId2, onSelect: openChat });
1961
+ });
1962
+ const ChatGroupAside = customize("ChatGroupAside", () => {
1963
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-aside", children: [
1964
+ /* @__PURE__ */ jsx(CreateChatButton, {}),
1965
+ /* @__PURE__ */ jsx(ChatListPanel, {})
1966
+ ] });
1967
+ });
1968
+ const ChatGroupHeader = customize("ChatGroupHeader", () => {
1969
+ return /* @__PURE__ */ jsx("div", { className: "wxchtf-header" });
1970
+ });
1971
+ const ChatGroupFooter = customize("ChatGroupFooter", () => /* @__PURE__ */ jsx("div", { className: "wxchtf-footer" }));
1972
+ const ChatGroupMain = customize("ChatGroupMain", () => {
1973
+ const { chatId: chatId2, view } = useChatGroupContext();
1974
+ const chat = chatifyApi.useChatListItem(chatId2);
1975
+ return /* @__PURE__ */ jsxs("div", { className: "wxchtf-main", children: [
1976
+ view === "chat" && chat && /* @__PURE__ */ jsx(ChatView, { value: chat }, chatId2),
1977
+ view === "new-chat" && /* @__PURE__ */ jsx(CreateChatPanel, {})
1978
+ ] });
1979
+ });
1980
+ const ChatGroupBody = customize("ChatGroupBody", () => /* @__PURE__ */ jsxs("div", { className: "wxchtf-body", children: [
1981
+ /* @__PURE__ */ jsx(ChatGroupAside, {}),
1982
+ /* @__PURE__ */ jsx(ChatGroupMain, {})
1983
+ ] }));
1984
+ function Content(props) {
1985
+ const { className = "", style } = props;
1986
+ const { data: chats } = chatifyApi.useGetChatListQuery();
1987
+ const { openChat, none, chatId: chatId2 } = useChatGroupContext();
1988
+ const openFirstChatRef = useRef(false);
1989
+ useEffect(() => {
1990
+ if (chats && !chats.some((x) => x.id === chatId2)) {
1991
+ chats.length ? openChat(chats[0].id) : none();
1992
+ }
1993
+ }, [chats, chatId2]);
1994
+ useEffect(() => {
1995
+ if (chats && !openFirstChatRef.current) {
1996
+ openFirstChatRef.current = true;
1997
+ chats.length && openChat(chats[0].id);
1998
+ }
1999
+ }, [chats]);
2000
+ return /* @__PURE__ */ jsxs("div", { className: className + " wxchtf-chatify wxchtf-chat-group", style, children: [
2001
+ /* @__PURE__ */ jsx(ChatGroupHeader, {}),
2002
+ /* @__PURE__ */ jsx(ChatGroupBody, {}),
2003
+ /* @__PURE__ */ jsx(ChatGroupFooter, {})
2004
+ ] });
2005
+ }
2006
+ const DEFAULT_CUSTOMIZE$1 = {
2007
+ ChatGroupHeader: null,
2008
+ ChatGroupFooter: null
2009
+ };
2010
+ const ChatGroupPanel = (props) => {
2011
+ const { localizer = defaultLocalizer, customize: customize2 = DEFAULT_CUSTOMIZE$1 } = props;
2012
+ const customizeValue = useMemo(() => Object.assign({}, DEFAULT_CUSTOMIZE$1, customize2), [customize2]);
2013
+ return /* @__PURE__ */ jsx(LocalizerContext.Provider, { value: localizer, children: /* @__PURE__ */ jsx(CustomizeContext.Provider, { value: customizeValue, children: /* @__PURE__ */ jsx(ChatGroupContext, { children: /* @__PURE__ */ jsx(Content, { ...props }) }) }) });
2014
+ };
2015
+ const ThreadContext = React.createContext(null);
2016
+ function useThreadContext() {
2017
+ return React.useContext(ThreadContext);
2018
+ }
2019
+ const ThreadActions = customize("ThreadActions", () => {
2020
+ const { watch, onWatch } = useThreadContext();
2021
+ if (!watch) {
2022
+ return /* @__PURE__ */ jsx(Tooltip, { title: "Watch thread", children: /* @__PURE__ */ jsx(Button, { type: "link", icon: /* @__PURE__ */ jsx(Icon, { type: "watch" }), onClick: () => onWatch(true) }) });
2023
+ }
2024
+ return /* @__PURE__ */ jsx(Tooltip, { title: "Unwatch thread", children: /* @__PURE__ */ jsx(Button, { type: "link", icon: /* @__PURE__ */ jsx(Icon, { type: "unwatch" }), onClick: () => onWatch(false) }) });
2025
+ });
2026
+ function usePanelState(props) {
2027
+ const { threadId } = props;
2028
+ const { data: thread } = chatifyApi.useGetThreadQuery({ id: threadId });
2029
+ const { data: messageList } = chatifyApi.useGetThreadMessageListQuery({ threadId });
2030
+ const { id, name, archive, lastReadMessageId, watch } = thread ?? {};
2031
+ const { messages, hasMore } = messageList ?? {};
2032
+ const [read] = chatifyApi.useReadThreadMessageMutation();
2033
+ const onRead = useCallback((id2) => read({ id: id2 }), [read]);
2034
+ const [fetchNext, { isLoading: isFetchNextLoading }] = chatifyApi.useFetchNextThreadMessageListMutation();
2035
+ const onNext = useCallback(() => fetchNext({ threadId }), [fetchNext, threadId]);
2036
+ const [send] = chatifyApi.useSendThreadMessageMutation();
2037
+ const onSend = useCallback(
2038
+ (message) => send({ body: message, threadId }).unwrap(),
2039
+ [threadId, send]
2040
+ );
2041
+ const { data: readQueue } = chatifyApi.useGetThreadMessageReadQueueQuery();
2042
+ const conversation = useMemo(() => {
2043
+ if (!id) {
2044
+ return null;
2045
+ }
2046
+ const result = {
2047
+ value: { id, name, active: !archive, lastReadMessageId: lastReadMessageId ?? null },
2048
+ messages,
2049
+ hasMore,
2050
+ onNext,
2051
+ nextLoading: isFetchNextLoading,
2052
+ onRead,
2053
+ onSend,
2054
+ noReadTracking: !watch,
2055
+ isReading: (id2) => readQueue.some(
2056
+ (unit) => parseThreadMessageId(unit.value)[0] === parseThreadMessageId(id2)[0] && id2 <= unit.value
2057
+ )
2058
+ };
2059
+ return result;
2060
+ }, [
2061
+ onNext,
2062
+ onRead,
2063
+ onSend,
2064
+ isFetchNextLoading,
2065
+ id,
2066
+ name,
2067
+ archive,
2068
+ messages,
2069
+ hasMore,
2070
+ lastReadMessageId,
2071
+ readQueue,
2072
+ watch
2073
+ ]);
2074
+ const [watchThread] = chatifyApi.useWatchThreadMutation();
2075
+ const threadContext = useMemo(
2076
+ () => thread ? {
2077
+ id: thread.id,
2078
+ watch: thread.watch,
2079
+ onWatch: (value) => watchThread({ id: thread.id, watch: value }).unwrap()
2080
+ } : null,
2081
+ [thread, watchThread]
2082
+ );
2083
+ return [conversation, threadContext];
2084
+ }
2085
+ const DEFAULT_CUSTOMIZE = {
2086
+ ConversationActions: () => /* @__PURE__ */ jsx(ThreadActions, {})
2087
+ };
2088
+ function ThreadPanel(props) {
2089
+ const { threadId, customize: customize2, localizer = defaultLocalizer, className = "" } = props;
2090
+ const [conversation, threadContext] = usePanelState(props);
2091
+ const customizeMergeValue = useMemo(() => ({ ...DEFAULT_CUSTOMIZE, ...customize2 }), [customize2]);
2092
+ useEffect(() => {
2093
+ chatifyApi.settings.client.connectToThread(threadId);
2094
+ return () => {
2095
+ chatifyApi.settings.client.disconnectFromThread(threadId);
2096
+ };
2097
+ }, [threadId]);
2098
+ if (!conversation || !threadContext) {
2099
+ return null;
2100
+ }
2101
+ return /* @__PURE__ */ jsx(LocalizerContext.Provider, { value: localizer, children: /* @__PURE__ */ jsx(ThreadContext.Provider, { value: threadContext, children: /* @__PURE__ */ jsx(CustomizeContext.Provider, { value: customizeMergeValue, children: /* @__PURE__ */ jsx("div", { className: `wxchtf-chatify wxchtf-thread ${className}`, children: conversation && /* @__PURE__ */ jsx(Conversation, { ...conversation }) }) }) }) });
2102
+ }
2103
+ const Chatify = {
2104
+ Thread: ThreadPanel,
2105
+ ChatGroup: ChatGroupPanel,
2106
+ Chat: ChatPanel
2107
+ };
2108
+ export {
2109
+ SendingMessageText as $,
2110
+ ChatListPanel as A,
2111
+ useChatGroupContext as B,
2112
+ CustomizeContext as C,
2113
+ DEFAULT_CHAT_VIEW_CUSTOMIZE_VALUE as D,
2114
+ ChatGroupContext as E,
2115
+ ChatGroupPanel as F,
2116
+ InputFileButton as G,
2117
+ InputFilesBox as H,
2118
+ InputBox as I,
2119
+ InputSubmitButtonBox as J,
2120
+ InputTextBox as K,
2121
+ LocalizerContext as L,
2122
+ InputBoxFileList as M,
2123
+ InputBoxFile as N,
2124
+ MessageAuthor as O,
2125
+ MessageBox as P,
2126
+ MessageContent as Q,
2127
+ MessageInfoBox as R,
2128
+ MessageRow as S,
2129
+ MessageText as T,
2130
+ MessageFileList as U,
2131
+ MessageFile as V,
2132
+ NextMessagesObserver as W,
2133
+ MessageReadObserver as X,
2134
+ SendingMessageBox as Y,
2135
+ SendingMessageContent as Z,
2136
+ SendingMessageInfoBox as _,
2137
+ useCustomize as a,
2138
+ SystemMessageBox as a0,
2139
+ formatSystemMessage as a1,
2140
+ SystemMessageRow as a2,
2141
+ ConversationActions as a3,
2142
+ ConversationBody as a4,
2143
+ ConversationHeader as a5,
2144
+ ConversationName as a6,
2145
+ ConversationContext as a7,
2146
+ useConversation$1 as a8,
2147
+ Conversation as a9,
2148
+ CHATIFY_SIGNALR_METHODS as aA,
2149
+ ChatifyClient as aB,
2150
+ unsubscribe as aC,
2151
+ ThreadActions as aa,
2152
+ ThreadPanel as ab,
2153
+ ThreadContext as ac,
2154
+ useThreadContext as ad,
2155
+ Avatar as ae,
2156
+ ICONS as af,
2157
+ Icon as ag,
2158
+ MessageSkeleton as ah,
2159
+ ChatList as ai,
2160
+ ChatListItemAvatar as aj,
2161
+ ChatListItemBox as ak,
2162
+ ChatListItemLastMessage as al,
2163
+ ChatListItemLastMessageAuthor as am,
2164
+ ChatListItemLastMessageContent as an,
2165
+ ChatListItemLastMessageSentAt as ao,
2166
+ ChatListItemName as ap,
2167
+ ChatListItemUnreadCount as aq,
2168
+ SYSTEM_ID as ar,
2169
+ chatId as as,
2170
+ messageSequencePart as at,
2171
+ parseThreadMessageId as au,
2172
+ calcThreadUnreadCount as av,
2173
+ calcThreadListUnreadCount as aw,
2174
+ useChatListItem as ax,
2175
+ useUnreadThreadMessageCount as ay,
2176
+ chatifyApi as az,
2177
+ customize as b,
2178
+ color as c,
2179
+ Chatify as d,
2180
+ useLocalizer as e,
2181
+ defaultLocalizer as f,
2182
+ ChatMembersButton as g,
2183
+ ChatMembersPanel as h,
2184
+ ChatMembersPreview as i,
2185
+ ChatView as j,
2186
+ useChatContext as k,
2187
+ ChatContext as l,
2188
+ ChatEditableHeaderName as m,
2189
+ ChatHeaderActions as n,
2190
+ ChatPanel as o,
2191
+ CreateChatForm as p,
2192
+ CreateChatMemberInput as q,
2193
+ CreateChatNameInput as r,
2194
+ CreateChatPanel as s,
2195
+ CreateChatButton as t,
2196
+ useCustomizeContext as u,
2197
+ ChatGroupAside as v,
2198
+ ChatGroupHeader as w,
2199
+ ChatGroupFooter as x,
2200
+ ChatGroupMain as y,
2201
+ ChatGroupBody as z
2202
+ };
2203
+ //# sourceMappingURL=Chatify-DGRV4QKP.js.map