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