@droppii-org/chat-sdk 0.0.22 → 0.0.24
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/components/chatBubble/ChatBubble.d.ts +1 -5
- package/dist/components/chatBubble/ChatBubble.d.ts.map +1 -1
- package/dist/components/chatBubble/ChatBubble.js +5 -7
- package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
- package/dist/components/conversation/DeskConversationList.js +2 -3
- package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
- package/dist/components/message/footer/ActionBar.js +7 -5
- package/dist/components/message/footer/FilePreview.d.ts.map +1 -1
- package/dist/components/message/footer/FilePreview.js +3 -3
- package/dist/components/message/item/ImageMessage.js +1 -1
- package/dist/components/message/item/VideoMessage.js +1 -1
- package/dist/components/message/item/index.d.ts +1 -1
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +20 -1
- package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
- package/dist/hooks/message/useSendMessage.js +57 -43
- package/dist/screens/chatBubble/index.d.ts +0 -1
- package/dist/screens/chatBubble/index.d.ts.map +1 -1
- package/dist/screens/chatBubble/index.js +17 -2
- package/package.json +1 -1
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { SessionType } from "@openim/wasm-client-sdk";
|
|
2
1
|
interface ChatBubbleProps {
|
|
3
|
-
conversationId: string;
|
|
4
|
-
sourceID: string;
|
|
5
|
-
sessionType: SessionType;
|
|
6
2
|
className?: string;
|
|
7
3
|
}
|
|
8
|
-
declare const ChatBubble: ({
|
|
4
|
+
declare const ChatBubble: ({ className }: ChatBubbleProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
5
|
export default ChatBubble;
|
|
10
6
|
//# sourceMappingURL=ChatBubble.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatBubble.d.ts","sourceRoot":"","sources":["../../../src/components/chatBubble/ChatBubble.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChatBubble.d.ts","sourceRoot":"","sources":["../../../src/components/chatBubble/ChatBubble.tsx"],"names":[],"mappings":"AAOA,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,UAAU,GAAI,eAAe,eAAe,4CAsDjD,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -4,12 +4,10 @@ import { useState } from "react";
|
|
|
4
4
|
import { FloatButton, Drawer } from "antd";
|
|
5
5
|
import { MessageOutlined, CloseOutlined } from "@ant-design/icons";
|
|
6
6
|
import MessageList from "../message/MessageList";
|
|
7
|
-
import
|
|
8
|
-
const ChatBubble = ({
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
sessionType,
|
|
12
|
-
});
|
|
7
|
+
import useConversationStore from "../../hooks/conversation/useConversationStore";
|
|
8
|
+
const ChatBubble = ({ className }) => {
|
|
9
|
+
const conversationDetail = useConversationStore((state) => state.conversationData);
|
|
10
|
+
const selectedThreadId = useConversationStore((state) => state.selectedThreadId);
|
|
13
11
|
const [isOpen, setIsOpen] = useState(false);
|
|
14
12
|
const toggleChat = () => {
|
|
15
13
|
setIsOpen(!isOpen);
|
|
@@ -23,6 +21,6 @@ const ChatBubble = ({ conversationId, sourceID, sessionType, className, }) => {
|
|
|
23
21
|
body: { padding: 0 },
|
|
24
22
|
}, classNames: {
|
|
25
23
|
wrapper: "!z-[9999]",
|
|
26
|
-
}, children: _jsx(MessageList, { conversationId:
|
|
24
|
+
}, children: _jsx(MessageList, { conversationId: selectedThreadId, conversationData: conversationDetail, className: "flex-1", onClose: () => setIsOpen(false) }) })] }));
|
|
27
25
|
};
|
|
28
26
|
export default ChatBubble;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeskConversationList.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/DeskConversationList.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DeskConversationList.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/DeskConversationList.tsx"],"names":[],"mappings":"AAqGA,UAAU,yBAAyB;IACjC,oBAAoB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,oBAAoB,GAAI,sCAG3B,yBAAyB,4CAgM3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -64,8 +64,7 @@ const formatTimestamp = (timestamp) => {
|
|
|
64
64
|
};
|
|
65
65
|
// Transform API data to UI-friendly format
|
|
66
66
|
const transformConversationData = (apiData, currentUserId) => {
|
|
67
|
-
return apiData.map((conv) => (Object.assign(Object.assign({}, conv), { id: conv.conversationID, threadId: conv.conversationID, name: conv.showName || "Unknown User", username: conv.userID || conv.groupID || "", avatar: conv.faceURL ||
|
|
68
|
-
"https://i.pinimg.com/736x/55/e5/ed/55e5edbb1a5b5f6e4f3cefc98de629ca.jpg", lastMessage: parseLatestMessage(conv.latestMsg, currentUserId), timestamp: formatTimestamp(conv.latestMsgSendTime), unreadCount: conv.unreadCount, isOnline: true, source: conv.conversationType === 3 ? "group" : "direct" })));
|
|
67
|
+
return apiData.map((conv) => (Object.assign(Object.assign({}, conv), { id: conv.conversationID, threadId: conv.conversationID, name: conv.showName || "Unknown User", username: conv.userID || conv.groupID || "", avatar: conv.faceURL || "", lastMessage: parseLatestMessage(conv.latestMsg, currentUserId), timestamp: formatTimestamp(conv.latestMsgSendTime), unreadCount: conv.unreadCount, isOnline: true, source: conv.conversationType === 3 ? "group" : "direct" })));
|
|
69
68
|
};
|
|
70
69
|
const DeskConversationList = ({ onConversationSelect, className = "", }) => {
|
|
71
70
|
const [searchQuery, setSearchQuery] = useState("");
|
|
@@ -125,7 +124,7 @@ const DeskConversationList = ({ onConversationSelect, className = "", }) => {
|
|
|
125
124
|
}, [selectedThreadId, onSetSelectedSourceId]);
|
|
126
125
|
return (_jsxs("div", { className: `flex flex-col h-full bg-white border-r border-gray-200 w-[320px] ${className}`, children: [_jsx("div", { className: "p-3 border-b border-gray-200", children: _jsx(Input, { placeholder: "T\u00ECm ki\u1EBFm", prefix: _jsx(Icon, { icon: "search-o", size: 18, className: "text-gray-400" }), value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "rounded-lg" }) }), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [filteredConversations.map((conversation) => (_jsxs("div", { onClick: () => handleConversationClick(conversation), className: `relative p-3 border-b border-gray-100 hover:bg-gray-50 cursor-pointer transition-colors ${selectedThreadId === conversation.threadId
|
|
127
126
|
? "bg-blue-50"
|
|
128
|
-
: "bg-white"}`, children: [selectedThreadId === conversation.threadId && (_jsx("div", { className: "absolute left-0 top-0 bottom-0 w-1 bg-blue-500" })), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "relative flex-shrink-0", children: _jsx(Badge, { dot: conversation.isOnline, status: conversation.isOnline ? "success" : "default", offset: [-2, 36], children: _jsx(Avatar, { size: 48, src: conversation.avatar, alt: conversation.name }) }) }), _jsx("div", { className: "flex-1 min-w-0", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-semibold text-gray-900 text-sm truncate", children: conversation.name }), _jsx("p", { className: "text-xs text-gray-500 truncate mt-0.5", children: conversation.lastMessage })] }), _jsxs("div", { className: "flex flex-col items-end gap-1 ml-2", children: [_jsx("span", { className: "text-xs text-gray-400", children: conversation.timestamp }), _jsx("div", { className: "flex items-center gap-1", children: conversation.unreadCount > 0 && (_jsx(Badge, { count: conversation.unreadCount })) })] })] }) })] })] }, conversation.id))), filteredConversations.length === 0 && (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Empty, { image: _jsx(Icon, { icon: "chat-square-b", size: 48, className: "text-gray-300" }), description: _jsxs("div", { children: [_jsx("p", { className: "text-lg font-medium mb-2 text-gray-500", children: "Kh\u00F4ng t\u00ECm th\u1EA5y cu\u1ED9c tr\u00F2 chuy\u1EC7n" }), _jsx("p", { className: "text-sm text-gray-400", children: searchQuery
|
|
127
|
+
: "bg-white"}`, children: [selectedThreadId === conversation.threadId && (_jsx("div", { className: "absolute left-0 top-0 bottom-0 w-1 bg-blue-500" })), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "relative flex-shrink-0", children: _jsx(Badge, { dot: conversation.isOnline, status: conversation.isOnline ? "success" : "default", offset: [-2, 36], children: _jsx(Avatar, { size: 48, src: conversation.avatar, alt: conversation.name, children: conversation.name.charAt(0).toUpperCase() }) }) }), _jsx("div", { className: "flex-1 min-w-0", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-semibold text-gray-900 text-sm truncate", children: conversation.name }), _jsx("p", { className: "text-xs text-gray-500 truncate mt-0.5", children: conversation.lastMessage })] }), _jsxs("div", { className: "flex flex-col items-end gap-1 ml-2", children: [_jsx("span", { className: "text-xs text-gray-400", children: conversation.timestamp }), _jsx("div", { className: "flex items-center gap-1", children: conversation.unreadCount > 0 && (_jsx(Badge, { count: conversation.unreadCount })) })] })] }) })] })] }, conversation.id))), filteredConversations.length === 0 && (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Empty, { image: _jsx(Icon, { icon: "chat-square-b", size: 48, className: "text-gray-300" }), description: _jsxs("div", { children: [_jsx("p", { className: "text-lg font-medium mb-2 text-gray-500", children: "Kh\u00F4ng t\u00ECm th\u1EA5y cu\u1ED9c tr\u00F2 chuy\u1EC7n" }), _jsx("p", { className: "text-sm text-gray-400", children: searchQuery
|
|
129
128
|
? "Thử tìm kiếm với từ khóa khác"
|
|
130
129
|
: "Chưa có cuộc trò chuyện nào" })] }) }) }))] })] }));
|
|
131
130
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionBar.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/ActionBar.tsx"],"names":[],"mappings":"AAgEA,QAAA,MAAM,SAAS,+
|
|
1
|
+
{"version":3,"file":"ActionBar.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/ActionBar.tsx"],"names":[],"mappings":"AAgEA,QAAA,MAAM,SAAS,+CAiOd,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -109,22 +109,24 @@ const ActionBar = () => {
|
|
|
109
109
|
return Upload.LIST_IGNORE;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
return
|
|
112
|
+
return false;
|
|
113
113
|
};
|
|
114
114
|
const beforeUploadFile = (file) => {
|
|
115
115
|
const isAllowed = documentTypes.includes(file.type);
|
|
116
116
|
if (!isAllowed) {
|
|
117
117
|
message.error(`${file.name} không đúng định dạng (chỉ hỗ trợ PDF, DOC, DOCX)`);
|
|
118
|
+
return Upload.LIST_IGNORE;
|
|
118
119
|
}
|
|
119
|
-
return
|
|
120
|
+
return false;
|
|
120
121
|
};
|
|
121
122
|
const handleChange = (info) => {
|
|
123
|
+
var _a;
|
|
122
124
|
let newList = [...info.fileList];
|
|
123
|
-
// Nếu file mới là tài liệu -> chỉ giữ 1 cái (file cuối)
|
|
124
125
|
const lastFile = info.file;
|
|
125
126
|
if (documentTypes.includes(lastFile.type || "")) {
|
|
126
|
-
newList = newList.filter((f) => documentTypes.includes(f.type || "")
|
|
127
|
-
|
|
127
|
+
newList = newList.filter((f) => !documentTypes.includes(f.type || ""));
|
|
128
|
+
const originFile = ((_a = lastFile.originFileObj) !== null && _a !== void 0 ? _a : lastFile);
|
|
129
|
+
newList.push(Object.assign(Object.assign({}, lastFile), { originFileObj: originFile }));
|
|
128
130
|
}
|
|
129
131
|
setListUploadFiles(newList);
|
|
130
132
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePreview.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/FilePreview.tsx"],"names":[],"mappings":"AAYA,eAAO,MAAM,YAAY,yCAoCxB,CAAC;AAEF,UAAU,cAAc;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,UAAS,cAAmB,WAkBzE,CAAC;AAEF,QAAA,MAAM,WAAW,+
|
|
1
|
+
{"version":3,"file":"FilePreview.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/FilePreview.tsx"],"names":[],"mappings":"AAYA,eAAO,MAAM,YAAY,yCAoCxB,CAAC;AAEF,UAAU,cAAc;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,UAAS,cAAmB,WAkBzE,CAAC;AAEF,QAAA,MAAM,WAAW,+CAkFhB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -31,9 +31,9 @@ const FilePreview = () => {
|
|
|
31
31
|
setListUploadFiles(listUploadFiles.filter((f) => f.uid !== file.uid));
|
|
32
32
|
};
|
|
33
33
|
const renderFilePreview = useCallback((file) => {
|
|
34
|
-
var _a;
|
|
35
|
-
const isDocument = documentTypes.includes(file.type || "");
|
|
36
|
-
const isVideo = (
|
|
34
|
+
var _a, _b;
|
|
35
|
+
const isDocument = documentTypes.includes(((_a = file === null || file === void 0 ? void 0 : file.originFileObj) === null || _a === void 0 ? void 0 : _a.type) || "");
|
|
36
|
+
const isVideo = (_b = file.type) === null || _b === void 0 ? void 0 : _b.startsWith("video/");
|
|
37
37
|
let src = file.url;
|
|
38
38
|
if (!src && file.originFileObj) {
|
|
39
39
|
src = URL.createObjectURL(file.originFileObj);
|
|
@@ -18,6 +18,6 @@ const ImageMessageItem = (props) => {
|
|
|
18
18
|
minHeight: `${adaptedHight}px`,
|
|
19
19
|
minWidth: `${adaptedWidth}px`,
|
|
20
20
|
};
|
|
21
|
-
return (_jsx(Spin, { spinning: isSending, children: _jsx("div", { className: "relative max-w-[200px]", style: minStyle, children: _jsx(Image, { rootClassName: "message-image cursor-pointer", className: "
|
|
21
|
+
return (_jsx(Spin, { spinning: isSending, children: _jsx("div", { className: "relative max-w-[200px]", style: minStyle, children: _jsx(Image, { rootClassName: "message-image cursor-pointer", className: "rounded-md", src: sourceUrl, preview: true, placeholder: _jsx("div", { style: minStyle, className: "flex items-center justify-center", children: _jsx(Spin, {}) }) }) }) }));
|
|
22
22
|
};
|
|
23
23
|
export default ImageMessageItem;
|
|
@@ -15,6 +15,6 @@ const VideoMessageItem = (props) => {
|
|
|
15
15
|
minHeight: `${adaptedHight}px`,
|
|
16
16
|
minWidth: `${adaptedWidth}px`,
|
|
17
17
|
};
|
|
18
|
-
return (_jsx(Spin, { spinning: isSending, children: _jsx("div", { className: "relative max-w-[200px]", style: minStyle, children: _jsx("video", { className: "
|
|
18
|
+
return (_jsx(Spin, { spinning: isSending, children: _jsx("div", { className: "relative max-w-[200px]", style: minStyle, children: _jsx("video", { className: "rounded-md", src: sourceUrl, controls: true }) }) }));
|
|
19
19
|
};
|
|
20
20
|
export default VideoMessageItem;
|
|
@@ -2,6 +2,6 @@ import { GroupMessageItem } from "../../../types/chat";
|
|
|
2
2
|
interface MessageItemProps {
|
|
3
3
|
groupMessage: GroupMessageItem;
|
|
4
4
|
}
|
|
5
|
-
declare const MessageItem: ({ groupMessage }: MessageItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare const MessageItem: ({ groupMessage }: MessageItemProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
6
6
|
export default MessageItem;
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAkBvD,UAAU,gBAAgB;IACxB,YAAY,EAAE,gBAAgB,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAkBvD,UAAU,gBAAgB;IACxB,YAAY,EAAE,gBAAgB,CAAC;CAChC;AAiBD,QAAA,MAAM,WAAW,GAAI,kBAAkB,gBAAgB,mDA2GtD,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -10,10 +10,25 @@ import ImageMessageItem from "./ImageMessage";
|
|
|
10
10
|
import FileMessageItem from "./FileMessage";
|
|
11
11
|
import VideoMessageItem from "./VideoMessage";
|
|
12
12
|
dayjs.extend(isToday);
|
|
13
|
+
const visibleTypeMessage = [
|
|
14
|
+
MessageType.TextMessage,
|
|
15
|
+
MessageType.PictureMessage,
|
|
16
|
+
MessageType.VoiceMessage,
|
|
17
|
+
MessageType.VideoMessage,
|
|
18
|
+
MessageType.FileMessage,
|
|
19
|
+
MessageType.AtTextMessage,
|
|
20
|
+
MessageType.MergeMessage,
|
|
21
|
+
MessageType.CardMessage,
|
|
22
|
+
MessageType.LocationMessage,
|
|
23
|
+
MessageType.CustomMessage,
|
|
24
|
+
MessageType.QuoteMessage,
|
|
25
|
+
MessageType.FaceMessage,
|
|
26
|
+
];
|
|
13
27
|
const MessageItem = ({ groupMessage }) => {
|
|
14
28
|
const { user } = useChatContext();
|
|
15
29
|
const messagesInGroup = (groupMessage === null || groupMessage === void 0 ? void 0 : groupMessage.messages) || [];
|
|
16
30
|
const isToday = dayjs(groupMessage === null || groupMessage === void 0 ? void 0 : groupMessage.sendTime).isToday();
|
|
31
|
+
const isVisibleGroup = messagesInGroup === null || messagesInGroup === void 0 ? void 0 : messagesInGroup.some((message) => visibleTypeMessage.includes(message === null || message === void 0 ? void 0 : message.contentType));
|
|
17
32
|
const renderMessageByType = (message) => {
|
|
18
33
|
switch (message === null || message === void 0 ? void 0 : message.contentType) {
|
|
19
34
|
case MessageType.TextMessage:
|
|
@@ -28,12 +43,16 @@ const MessageItem = ({ groupMessage }) => {
|
|
|
28
43
|
return _jsx(TextMessageItem, { message: message });
|
|
29
44
|
}
|
|
30
45
|
};
|
|
46
|
+
if (!isVisibleGroup)
|
|
47
|
+
return null;
|
|
31
48
|
return (_jsxs("div", { className: "flex flex-col gap-2 my-4 mx-3 sm:mx-4", children: [_jsx("div", { className: "flex justify-center", children: _jsx("span", { className: "text-xs text-gray-600 text-center bg-neutral-100 px-2 py-1 rounded-full", children: dayjs(groupMessage === null || groupMessage === void 0 ? void 0 : groupMessage.sendTime).format(isToday ? "HH:mm" : "HH:mm, DD MMMM") }) }), messagesInGroup === null || messagesInGroup === void 0 ? void 0 : messagesInGroup.map((message, messageIndex) => {
|
|
32
49
|
var _a, _b, _c, _d;
|
|
50
|
+
if (!visibleTypeMessage.includes(message === null || message === void 0 ? void 0 : message.contentType))
|
|
51
|
+
return null;
|
|
33
52
|
const isMine = (message === null || message === void 0 ? void 0 : message.sendID) === (user === null || user === void 0 ? void 0 : user.userID);
|
|
34
53
|
const showAvatar = messageIndex === messagesInGroup.length - 1;
|
|
35
54
|
const showSenderName = messageIndex === 0 && (message === null || message === void 0 ? void 0 : message.sessionType) === SessionType.Group;
|
|
36
|
-
return (_jsx("div", { className: clsx("flex", isMine ? "justify-end" : "justify-start"), children: _jsxs("div", { className: clsx("flex flex-1 items-end gap-2", isMine ? "justify-end" : "justify-start"), children: [!isMine && (_jsx("div", { className: "flex items-center justify-center w-[32px] h-[32px]", children: showAvatar && (_jsx(Avatar, { children: ((_b = (_a = message === null || message === void 0 ? void 0 : message.senderNickname) === null || _a === void 0 ? void 0 : _a.charAt) === null || _b === void 0 ? void 0 : _b.call(_a, 0)) || "A" })) })), _jsxs("div", { className: "flex flex-col
|
|
55
|
+
return (_jsx("div", { className: clsx("flex", isMine ? "justify-end" : "justify-start"), children: _jsxs("div", { className: clsx("flex flex-1 items-end gap-2", isMine ? "justify-end" : "justify-start"), children: [!isMine && (_jsx("div", { className: "flex items-center justify-center w-[32px] h-[32px]", children: showAvatar && (_jsx(Avatar, { children: ((_b = (_a = message === null || message === void 0 ? void 0 : message.senderNickname) === null || _a === void 0 ? void 0 : _a.charAt) === null || _b === void 0 ? void 0 : _b.call(_a, 0)) || "A" })) })), _jsxs("div", { className: clsx("flex flex-col flex-[0.8]", isMine ? "items-end" : "items-start"), children: [!isMine && showSenderName && (_jsx("span", { className: "text-xs text-gray-500 mb-1 px-3", children: message === null || message === void 0 ? void 0 : message.senderNickname })), _jsxs("div", { className: clsx("px-3 py-2 rounded-2xl max-w-full break-words flex flex-col flex-1 text-gray-900 gap-1", isMine ? "bg-blue-100" : "bg-gray-100"), children: [(message === null || message === void 0 ? void 0 : message.contentType) === MessageType.MergeMessage ? (_jsxs("div", { children: [(_d = (_c = message === null || message === void 0 ? void 0 : message.mergeElem) === null || _c === void 0 ? void 0 : _c.multiMessage) === null || _d === void 0 ? void 0 : _d.map((item) => {
|
|
37
56
|
return renderMessageByType(item);
|
|
38
57
|
}), (message === null || message === void 0 ? void 0 : message.textElem) && (_jsx(TextMessageItem, { message: message }))] })) : (renderMessageByType(message)), _jsx("span", { className: clsx("text-xs text-gray-500 text-right text-gray-500"), children: dayjs(message === null || message === void 0 ? void 0 : message.sendTime).format("HH:mm") })] })] })] }) }, message === null || message === void 0 ? void 0 : message.clientMsgID));
|
|
39
58
|
})] }, groupMessage === null || groupMessage === void 0 ? void 0 : groupMessage.groupMessageID));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSendMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useSendMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,WAAW,EAGZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGlC,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,gCAanD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,oBAAoB,gCAaxE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,iBAAiB,eAAe,gCAazE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,oBAAoB,gCAaxE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,MAAM,mBAAmB,gCAatE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,cAAc,WAAW;gDAiCjD;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB;wDAwBE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,UAAU,EAAE,CAAC;KACrB;
|
|
1
|
+
{"version":3,"file":"useSendMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useSendMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,WAAW,EAGZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGlC,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,gCAanD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,oBAAoB,gCAaxE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,iBAAiB,eAAe,gCAazE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,oBAAoB,gCAaxE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,MAAM,mBAAmB,gCAatE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,cAAc,WAAW;gDAiCjD;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB;wDAwBE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,UAAU,EAAE,CAAC;KACrB;CAwIJ,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,2CAIvC;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,KAmBM,iBACN,CAAC"}
|
|
@@ -109,17 +109,31 @@ export const useSendMessage = (lastMessage) => {
|
|
|
109
109
|
try {
|
|
110
110
|
if (isImage) {
|
|
111
111
|
const picInfo = await createPicBaseInfoFromFile(file);
|
|
112
|
+
const baseInfo = {
|
|
113
|
+
uuid: uuidv4(),
|
|
114
|
+
type: file.type,
|
|
115
|
+
size: file.size,
|
|
116
|
+
width: picInfo.width,
|
|
117
|
+
height: picInfo.height,
|
|
118
|
+
url: URL.createObjectURL(file),
|
|
119
|
+
};
|
|
112
120
|
const parsedImage = {
|
|
113
|
-
sourcePicture:
|
|
114
|
-
bigPicture:
|
|
115
|
-
snapshotPicture:
|
|
121
|
+
sourcePicture: baseInfo,
|
|
122
|
+
bigPicture: baseInfo,
|
|
123
|
+
snapshotPicture: baseInfo,
|
|
116
124
|
sourcePath: "",
|
|
117
125
|
file: file,
|
|
118
126
|
};
|
|
119
127
|
const imageMessage = await createImageMessageByFile(parsedImage);
|
|
120
128
|
if (!imageMessage)
|
|
121
129
|
continue;
|
|
122
|
-
|
|
130
|
+
const extendMessageInfo = generateExtendMessageInfo({
|
|
131
|
+
currentUserID: (user === null || user === void 0 ? void 0 : user.userID) || "",
|
|
132
|
+
lastMessage: messageList.length > 0
|
|
133
|
+
? messageList[messageList.length - 1]
|
|
134
|
+
: lastMessage,
|
|
135
|
+
});
|
|
136
|
+
messageList.push(Object.assign(Object.assign({}, imageMessage), { ex: JSON.stringify(extendMessageInfo) || "{}" }));
|
|
123
137
|
}
|
|
124
138
|
else if (isVideo) {
|
|
125
139
|
const videoBaseInfo = await createVideoBaseInfoFromFile(file);
|
|
@@ -142,7 +156,13 @@ export const useSendMessage = (lastMessage) => {
|
|
|
142
156
|
});
|
|
143
157
|
if (!videoMessage)
|
|
144
158
|
continue;
|
|
145
|
-
|
|
159
|
+
const extendMessageInfo = generateExtendMessageInfo({
|
|
160
|
+
currentUserID: (user === null || user === void 0 ? void 0 : user.userID) || "",
|
|
161
|
+
lastMessage: messageList.length > 0
|
|
162
|
+
? messageList[messageList.length - 1]
|
|
163
|
+
: lastMessage,
|
|
164
|
+
});
|
|
165
|
+
messageList.push(Object.assign(Object.assign({}, videoMessage), { ex: JSON.stringify(extendMessageInfo) || "{}" }));
|
|
146
166
|
}
|
|
147
167
|
else if (isDocument) {
|
|
148
168
|
const fileMessage = await createFileMessageByFile({
|
|
@@ -156,28 +176,36 @@ export const useSendMessage = (lastMessage) => {
|
|
|
156
176
|
});
|
|
157
177
|
if (!fileMessage)
|
|
158
178
|
continue;
|
|
159
|
-
|
|
179
|
+
const extendMessageInfo = generateExtendMessageInfo({
|
|
180
|
+
currentUserID: (user === null || user === void 0 ? void 0 : user.userID) || "",
|
|
181
|
+
lastMessage: messageList.length > 0
|
|
182
|
+
? messageList[messageList.length - 1]
|
|
183
|
+
: lastMessage,
|
|
184
|
+
});
|
|
185
|
+
messageList.push(Object.assign(Object.assign({}, fileMessage), { ex: JSON.stringify(extendMessageInfo) || "{}" }));
|
|
160
186
|
}
|
|
161
187
|
}
|
|
162
188
|
catch (err) {
|
|
163
189
|
console.error("Lỗi xử lý tin nhắn:", err);
|
|
164
190
|
}
|
|
165
191
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
192
|
+
if (!!plainText && plainText.trim() !== "") {
|
|
193
|
+
const extendMessageInfo = generateExtendMessageInfo({
|
|
194
|
+
richText,
|
|
195
|
+
currentUserID: (user === null || user === void 0 ? void 0 : user.userID) || "",
|
|
196
|
+
lastMessage: messageList.length > 0
|
|
197
|
+
? messageList[messageList.length - 1]
|
|
198
|
+
: lastMessage,
|
|
199
|
+
});
|
|
200
|
+
const textMessage = await createTextMessage(plainText);
|
|
201
|
+
if (!textMessage)
|
|
202
|
+
return;
|
|
203
|
+
const messageItem = Object.assign(Object.assign({}, textMessage), { ex: JSON.stringify(extendMessageInfo) || "{}" });
|
|
204
|
+
messageList.push(messageItem);
|
|
205
|
+
}
|
|
206
|
+
for (const message of messageList) {
|
|
207
|
+
await sendMessage(message);
|
|
208
|
+
}
|
|
181
209
|
}, [recvID, groupID, lastMessage, sendMessage]);
|
|
182
210
|
return {
|
|
183
211
|
sendTextMessage,
|
|
@@ -201,28 +229,14 @@ export const generateExtendMessageInfo = ({ richText, currentUserID, lastMessage
|
|
|
201
229
|
},
|
|
202
230
|
};
|
|
203
231
|
};
|
|
204
|
-
const createPicBaseInfoFromFile = (file
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
img
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
type: file.type,
|
|
213
|
-
size: file.size,
|
|
214
|
-
width: img.width,
|
|
215
|
-
height: img.height,
|
|
216
|
-
url: url, // để trống nếu không cần dùng
|
|
217
|
-
});
|
|
218
|
-
};
|
|
219
|
-
img.onerror = (err) => {
|
|
220
|
-
URL.revokeObjectURL(objectUrl);
|
|
221
|
-
reject(err);
|
|
222
|
-
};
|
|
223
|
-
img.src = objectUrl;
|
|
224
|
-
});
|
|
225
|
-
};
|
|
232
|
+
const createPicBaseInfoFromFile = (file) => new Promise((resolve, reject) => {
|
|
233
|
+
const _URL = window.URL || window.webkitURL;
|
|
234
|
+
const img = new Image();
|
|
235
|
+
img.onload = function () {
|
|
236
|
+
resolve(img);
|
|
237
|
+
};
|
|
238
|
+
img.src = _URL.createObjectURL(file);
|
|
239
|
+
});
|
|
226
240
|
function createVideoBaseInfoFromFile(file) {
|
|
227
241
|
return new Promise((resolve, reject) => {
|
|
228
242
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screens/chatBubble/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screens/chatBubble/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAQtD,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,mDAsB3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -2,11 +2,26 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import ChatBubble from "../../components/chatBubble/ChatBubble";
|
|
3
3
|
import { useChatContext } from "../../context/ChatContext";
|
|
4
4
|
import { ConnectStatus } from "../../types/chat";
|
|
5
|
+
import { useConversationDetail } from "../../hooks/conversation/useConversation";
|
|
6
|
+
import useConversationStore from "../../hooks/conversation/useConversationStore";
|
|
7
|
+
import { useEffect } from "react";
|
|
5
8
|
const DChatBubble = (props) => {
|
|
6
|
-
const {
|
|
9
|
+
const { sourceID, sessionType, className } = props;
|
|
7
10
|
const { connectStatus } = useChatContext();
|
|
11
|
+
const { conversationDetail } = useConversationDetail({
|
|
12
|
+
sourceID,
|
|
13
|
+
sessionType,
|
|
14
|
+
});
|
|
15
|
+
const setSelectedThreadId = useConversationStore((state) => state.setSelectedThreadId);
|
|
16
|
+
const setConversationData = useConversationStore((state) => state.setConversationData);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!conversationDetail)
|
|
19
|
+
return;
|
|
20
|
+
setSelectedThreadId(conversationDetail.conversationID);
|
|
21
|
+
setConversationData(conversationDetail);
|
|
22
|
+
}, [conversationDetail]);
|
|
8
23
|
if (connectStatus !== ConnectStatus.Connected)
|
|
9
24
|
return null;
|
|
10
|
-
return
|
|
25
|
+
return _jsx(ChatBubble, { className: className });
|
|
11
26
|
};
|
|
12
27
|
export default DChatBubble;
|