@webinex/chatify 2.0.0-build2 → 2.0.0-build202511241945

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