@droppii-org/chat-sdk 0.1.47 → 0.1.49
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/biz-thread-detail/BizAttachmentPreview.d.ts +9 -0
- package/dist/components/biz-thread-detail/BizAttachmentPreview.d.ts.map +1 -0
- package/dist/components/biz-thread-detail/BizAttachmentPreview.js +74 -0
- package/dist/components/biz-thread-detail/BizImageViewer.d.ts +8 -0
- package/dist/components/biz-thread-detail/BizImageViewer.d.ts.map +1 -0
- package/dist/components/biz-thread-detail/BizImageViewer.js +35 -0
- package/dist/components/biz-thread-detail/BizMessageContent.d.ts.map +1 -1
- package/dist/components/biz-thread-detail/BizMessageContent.js +46 -1
- package/dist/components/biz-thread-detail/BizMoreOptionPanel.d.ts +2 -1
- package/dist/components/biz-thread-detail/BizMoreOptionPanel.d.ts.map +1 -1
- package/dist/components/biz-thread-detail/BizMoreOptionPanel.js +6 -2
- package/dist/components/biz-thread-detail/BizThreadDetailInput.d.ts.map +1 -1
- package/dist/components/biz-thread-detail/BizThreadDetailInput.js +32 -7
- package/dist/components/biz-thread-detail/index.d.ts +2 -2
- package/dist/components/biz-thread-detail/index.d.ts.map +1 -1
- package/dist/components/biz-thread-detail/index.js +1 -1
- package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
- package/dist/hooks/message/useSendMessage.js +57 -32
- package/dist/screens/biz-thread-detail/index.js +1 -1
- package/dist/styles/global.css +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/fileValidation.d.ts +2 -0
- package/dist/utils/fileValidation.d.ts.map +1 -1
- package/dist/utils/fileValidation.js +30 -0
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { UploadFile } from "antd";
|
|
2
|
+
export interface BizAttachmentPreviewProps {
|
|
3
|
+
files: UploadFile[];
|
|
4
|
+
onRemove: (uid: string) => void;
|
|
5
|
+
onVideoReady?: () => void;
|
|
6
|
+
}
|
|
7
|
+
declare const BizAttachmentPreview: ({ files, onRemove, onVideoReady, }: BizAttachmentPreviewProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export default BizAttachmentPreview;
|
|
9
|
+
//# sourceMappingURL=BizAttachmentPreview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizAttachmentPreview.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/BizAttachmentPreview.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAmJlC,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,QAAA,MAAM,oBAAoB,GAAI,oCAI3B,yBAAyB,mDAuB3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Icon } from "../../components/icon";
|
|
5
|
+
import { documentIcon } from "../../assets/svg";
|
|
6
|
+
import { shortenFileName } from "../../components/message/footer/FilePreview";
|
|
7
|
+
import { DOCUMENT_MIME_TYPES } from "../../utils/fileValidation";
|
|
8
|
+
const formatDuration = (seconds) => {
|
|
9
|
+
const minutes = Math.floor(seconds / 60);
|
|
10
|
+
const secs = Math.floor(seconds % 60);
|
|
11
|
+
return `${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
|
|
12
|
+
};
|
|
13
|
+
const formatFileSize = (bytes) => {
|
|
14
|
+
if (bytes === 0)
|
|
15
|
+
return "0 B";
|
|
16
|
+
if (bytes < 1024)
|
|
17
|
+
return `${bytes} B`;
|
|
18
|
+
const kb = bytes / 1024;
|
|
19
|
+
if (kb < 1024)
|
|
20
|
+
return `${Math.round(kb)} KB`;
|
|
21
|
+
return `${(kb / 1024).toFixed(1)} MB`;
|
|
22
|
+
};
|
|
23
|
+
const getFileType = (file) => {
|
|
24
|
+
var _a, _b, _c;
|
|
25
|
+
const mimeType = (_c = (_b = (_a = file.originFileObj) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : file.type) !== null && _c !== void 0 ? _c : "";
|
|
26
|
+
if (DOCUMENT_MIME_TYPES.includes(mimeType))
|
|
27
|
+
return "document";
|
|
28
|
+
if (mimeType.startsWith("video/"))
|
|
29
|
+
return "video";
|
|
30
|
+
return "image";
|
|
31
|
+
};
|
|
32
|
+
const RemoveButton = ({ uid, onRemove }) => (_jsx("button", { type: "button", onClick: () => onRemove(uid), className: "absolute -right-1 -top-1 flex h-5 w-5 items-center justify-center rounded-full bg-[#393E40]", "aria-label": "X\u00F3a", children: _jsx(Icon, { icon: "close-o", size: 12, className: "text-white" }) }));
|
|
33
|
+
const MediaThumb = ({ file, onRemove, onVideoReady }) => {
|
|
34
|
+
var _a;
|
|
35
|
+
const [src, setSrc] = useState("");
|
|
36
|
+
const [duration, setDuration] = useState(null);
|
|
37
|
+
const isVideo = getFileType(file) === "video";
|
|
38
|
+
const isLoading = file.status === "uploading";
|
|
39
|
+
const percent = Math.round((_a = file.percent) !== null && _a !== void 0 ? _a : 0);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
var _a;
|
|
42
|
+
const originFile = file.originFileObj;
|
|
43
|
+
if (!originFile) {
|
|
44
|
+
setSrc((_a = file.url) !== null && _a !== void 0 ? _a : "");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const url = URL.createObjectURL(originFile);
|
|
48
|
+
setSrc(url);
|
|
49
|
+
return () => URL.revokeObjectURL(url);
|
|
50
|
+
}, [file.originFileObj, file.url]);
|
|
51
|
+
const handleLoadedMetadata = (event) => {
|
|
52
|
+
setDuration(event.currentTarget.duration);
|
|
53
|
+
onVideoReady === null || onVideoReady === void 0 ? void 0 : onVideoReady();
|
|
54
|
+
};
|
|
55
|
+
return (_jsxs("div", { className: "relative h-12 w-12 shrink-0", children: [isVideo ? (_jsx("video", { src: src, className: "h-12 w-12 rounded-lg object-cover", preload: "metadata", muted: true, onLoadedMetadata: handleLoadedMetadata })) : (_jsx("img", { src: src, alt: file.name, className: "h-12 w-12 rounded-lg object-cover" })), isLoading && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center rounded-lg bg-black/60", children: _jsxs("span", { className: "text-xs font-semibold text-white", children: [percent, "%"] }) })), isVideo && duration !== null && (_jsx("div", { className: "absolute bottom-1 left-1/2 flex w-9 -translate-x-1/2 items-center justify-center rounded-xl bg-black/70 px-1 text-center text-[10px] font-normal leading-4 text-white", children: formatDuration(duration) })), _jsx(RemoveButton, { uid: file.uid, onRemove: onRemove })] }));
|
|
56
|
+
};
|
|
57
|
+
const DocumentCard = ({ file, onRemove }) => {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
const isLoading = file.status === "uploading";
|
|
60
|
+
const percent = Math.round((_a = file.percent) !== null && _a !== void 0 ? _a : 0);
|
|
61
|
+
return (_jsxs("div", { className: "relative flex h-12 w-40 shrink-0 items-center gap-[7px] rounded-lg bg-[rgba(131,137,157,0.08)] py-[4px] pl-2 pr-5", children: [_jsx("div", { className: "flex h-full w-8 shrink-0 items-center justify-center overflow-hidden [&>svg]:h-8 [&>svg]:w-8", children: documentIcon }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "truncate text-[11px] font-normal leading-[160%] text-[#393E40]", children: shortenFileName(file.name) }), isLoading ? (_jsxs("span", { className: "text-[10px] leading-[160%] tracking-[0.1px] text-[#747B7E]", children: [percent, "%"] })) : (_jsx("span", { className: "text-[10px] leading-[160%] tracking-[0.1px] text-[#747B7E]", children: formatFileSize((_b = file.size) !== null && _b !== void 0 ? _b : 0) }))] }), _jsx(RemoveButton, { uid: file.uid, onRemove: onRemove })] }));
|
|
62
|
+
};
|
|
63
|
+
const BizAttachmentPreview = ({ files, onRemove, onVideoReady, }) => {
|
|
64
|
+
if (files.length === 0)
|
|
65
|
+
return null;
|
|
66
|
+
return (_jsx("div", { className: "flex items-center gap-3 self-stretch overflow-x-auto px-2 pb-2 pt-3", children: files.map((file) => {
|
|
67
|
+
const fileType = getFileType(file);
|
|
68
|
+
if (fileType === "document") {
|
|
69
|
+
return (_jsx(DocumentCard, { file: file, onRemove: onRemove }, file.uid));
|
|
70
|
+
}
|
|
71
|
+
return (_jsx(MediaThumb, { file: file, onRemove: onRemove, onVideoReady: onVideoReady }, file.uid));
|
|
72
|
+
}) }));
|
|
73
|
+
};
|
|
74
|
+
export default BizAttachmentPreview;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface BizImageViewerProps {
|
|
2
|
+
images: string[];
|
|
3
|
+
initialIndex?: number;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
}
|
|
6
|
+
declare const BizImageViewer: ({ images, initialIndex, onClose, }: BizImageViewerProps) => import("react").ReactPortal;
|
|
7
|
+
export default BizImageViewer;
|
|
8
|
+
//# sourceMappingURL=BizImageViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizImageViewer.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/BizImageViewer.tsx"],"names":[],"mappings":"AAOA,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,cAAc,GAAI,oCAIrB,mBAAmB,gCA2ErB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect } from "react";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
5
|
+
import clsx from "clsx";
|
|
6
|
+
import { Icon } from "../../components/icon";
|
|
7
|
+
const BizImageViewer = ({ images, initialIndex = 0, onClose, }) => {
|
|
8
|
+
var _a;
|
|
9
|
+
const [currentIndex, setCurrentIndex] = useState(initialIndex);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const handleKeyDown = (e) => {
|
|
12
|
+
if (e.key === "Escape")
|
|
13
|
+
onClose();
|
|
14
|
+
if (e.key === "ArrowLeft")
|
|
15
|
+
setCurrentIndex((i) => Math.max(0, i - 1));
|
|
16
|
+
if (e.key === "ArrowRight")
|
|
17
|
+
setCurrentIndex((i) => Math.min(images.length - 1, i + 1));
|
|
18
|
+
};
|
|
19
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
20
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
21
|
+
}, [images.length, onClose]);
|
|
22
|
+
const handleDownload = () => {
|
|
23
|
+
const url = images[currentIndex];
|
|
24
|
+
const filename = url.substring(url.lastIndexOf("/") + 1) || "image";
|
|
25
|
+
const link = document.createElement("a");
|
|
26
|
+
link.href = url;
|
|
27
|
+
link.download = filename;
|
|
28
|
+
document.body.appendChild(link);
|
|
29
|
+
link.click();
|
|
30
|
+
document.body.removeChild(link);
|
|
31
|
+
};
|
|
32
|
+
const container = (_a = document.querySelector('[data-testid="biz-thread-detail-root"]')) !== null && _a !== void 0 ? _a : document.body;
|
|
33
|
+
return createPortal(_jsxs("div", { className: "absolute inset-0 z-[999] flex flex-col bg-black", children: [_jsxs("div", { className: "flex items-center justify-between px-4 pt-12 pb-4", children: [_jsx("button", { className: "flex h-10 w-10 items-center justify-center text-white text-xl", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 24 }) }), _jsx("button", { className: "flex h-10 w-10 items-center justify-center text-white text-xl", onClick: handleDownload, children: _jsx(Icon, { icon: "download-o", size: 24 }) })] }), _jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center overflow-hidden px-4", children: _jsx("img", { src: images[currentIndex], alt: "", className: "max-h-full max-w-full rounded-[24px] object-contain" }) }), _jsxs("div", { className: "flex flex-col items-center gap-2 pb-8 pt-4", children: [_jsxs("span", { className: "text-sm text-white", children: [currentIndex + 1, "/", images.length] }), _jsx("div", { className: "flex gap-1.5", children: images.map((_, i) => (_jsx("button", { className: clsx("h-1.5 w-1.5 rounded-full transition-colors", i === currentIndex ? "bg-white" : "bg-white/30"), onClick: () => setCurrentIndex(i) }, i))) })] })] }), container);
|
|
34
|
+
};
|
|
35
|
+
export default BizImageViewer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BizMessageContent.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/BizMessageContent.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BizMessageContent.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/BizMessageContent.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAA8B,MAAM,yBAAyB,CAAC;AAOlF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,WAAW,CAAC;CACtB;AAuGD,QAAA,MAAM,iBAAiB,GAAI,aAAa,sBAAsB,mDA4C7D,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -1,11 +1,56 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
import { MessageStatus, MessageType } from "@openim/wasm-client-sdk";
|
|
6
|
+
import { Image, Spin } from "antd";
|
|
4
7
|
import BizLinkMessageCard from "./BizLinkMessageCard";
|
|
5
8
|
import BizLinkTextContent from "./BizLinkTextContent";
|
|
9
|
+
import BizImageViewer from "./BizImageViewer";
|
|
6
10
|
import { extractBizLinkUrls } from "../../utils/bizLink";
|
|
11
|
+
const MERGE_IMAGE_GRID_COLS_CLASS = {
|
|
12
|
+
1: "grid-cols-[repeat(1,100px)]",
|
|
13
|
+
2: "grid-cols-[repeat(2,100px)]",
|
|
14
|
+
3: "grid-cols-[repeat(3,100px)]",
|
|
15
|
+
};
|
|
16
|
+
const BizPictureMessage = ({ message }) => {
|
|
17
|
+
var _a, _b, _c;
|
|
18
|
+
const [viewerVisible, setViewerVisible] = useState(false);
|
|
19
|
+
const pictureElem = message.pictureElem;
|
|
20
|
+
const sourceUrl = ((_a = pictureElem === null || pictureElem === void 0 ? void 0 : pictureElem.sourcePicture) === null || _a === void 0 ? void 0 : _a.url) || ((_b = pictureElem === null || pictureElem === void 0 ? void 0 : pictureElem.snapshotPicture) === null || _b === void 0 ? void 0 : _b.url) || "";
|
|
21
|
+
const bigUrl = ((_c = pictureElem === null || pictureElem === void 0 ? void 0 : pictureElem.bigPicture) === null || _c === void 0 ? void 0 : _c.url) || sourceUrl;
|
|
22
|
+
const isSending = message.status === MessageStatus.Sending;
|
|
23
|
+
return (_jsxs("div", { className: "-mx-1", children: [_jsx(Spin, { spinning: isSending, children: _jsx("div", { className: "cursor-pointer", onClick: () => setViewerVisible(true), children: _jsx(Image, { src: sourceUrl, width: 205, height: 205, className: "rounded-xl object-cover", preview: false, placeholder: _jsx("div", { className: "flex h-[205px] w-[205px] items-center justify-center rounded-xl bg-black/10", children: _jsx(Spin, {}) }) }) }) }), viewerVisible && (_jsx(BizImageViewer, { images: [bigUrl], onClose: () => setViewerVisible(false) }))] }));
|
|
24
|
+
};
|
|
25
|
+
const BizMergeImageMessage = ({ message }) => {
|
|
26
|
+
var _a, _b;
|
|
27
|
+
const [viewerIndex, setViewerIndex] = useState(null);
|
|
28
|
+
const subMessages = (_b = (_a = message.mergeElem) === null || _a === void 0 ? void 0 : _a.multiMessage) !== null && _b !== void 0 ? _b : [];
|
|
29
|
+
const isSending = message.status === MessageStatus.Sending;
|
|
30
|
+
const cols = Math.min(subMessages.length, 3);
|
|
31
|
+
const imageUrls = subMessages.map((item) => {
|
|
32
|
+
var _a, _b, _c, _d, _e, _f;
|
|
33
|
+
const sourceUrl = ((_b = (_a = item.pictureElem) === null || _a === void 0 ? void 0 : _a.sourcePicture) === null || _b === void 0 ? void 0 : _b.url) ||
|
|
34
|
+
((_d = (_c = item.pictureElem) === null || _c === void 0 ? void 0 : _c.snapshotPicture) === null || _d === void 0 ? void 0 : _d.url) ||
|
|
35
|
+
"";
|
|
36
|
+
return ((_f = (_e = item.pictureElem) === null || _e === void 0 ? void 0 : _e.bigPicture) === null || _f === void 0 ? void 0 : _f.url) || sourceUrl;
|
|
37
|
+
});
|
|
38
|
+
return (_jsxs("div", { className: "-mx-1", children: [_jsx(Spin, { spinning: isSending, children: _jsx("div", { className: clsx("grid gap-1", MERGE_IMAGE_GRID_COLS_CLASS[cols]), children: subMessages.map((item, index) => {
|
|
39
|
+
var _a, _b, _c, _d;
|
|
40
|
+
const sourceUrl = ((_b = (_a = item.pictureElem) === null || _a === void 0 ? void 0 : _a.sourcePicture) === null || _b === void 0 ? void 0 : _b.url) ||
|
|
41
|
+
((_d = (_c = item.pictureElem) === null || _c === void 0 ? void 0 : _c.snapshotPicture) === null || _d === void 0 ? void 0 : _d.url) ||
|
|
42
|
+
"";
|
|
43
|
+
return (_jsx("div", { className: "cursor-pointer", onClick: () => setViewerIndex(index), children: _jsx(Image, { src: sourceUrl, width: 100, height: 100, className: "rounded-xl object-cover", preview: false, placeholder: _jsx("div", { className: "flex h-[100px] w-[100px] items-center justify-center rounded-xl bg-black/10", children: _jsx(Spin, {}) }) }) }, item.clientMsgID));
|
|
44
|
+
}) }) }), viewerIndex !== null && (_jsx(BizImageViewer, { images: imageUrls, initialIndex: viewerIndex, onClose: () => setViewerIndex(null) }))] }));
|
|
45
|
+
};
|
|
7
46
|
const BizMessageContent = ({ message }) => {
|
|
8
47
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
48
|
+
if (message.contentType === MessageType.PictureMessage) {
|
|
49
|
+
return _jsx(BizPictureMessage, { message: message });
|
|
50
|
+
}
|
|
51
|
+
if (message.contentType === MessageType.MergeMessage) {
|
|
52
|
+
return _jsx(BizMergeImageMessage, { message: message });
|
|
53
|
+
}
|
|
9
54
|
const text = (_e = (_d = (_b = (_a = message.textElem) === null || _a === void 0 ? void 0 : _a.content) !== null && _b !== void 0 ? _b : (_c = message.urlTextElem) === null || _c === void 0 ? void 0 : _c.content) !== null && _d !== void 0 ? _d : message.content) !== null && _e !== void 0 ? _e : "";
|
|
10
55
|
const hasLinks = text ? extractBizLinkUrls(text).length > 0 : false;
|
|
11
56
|
if (message.contentType === MessageType.UrlTextMessage) {
|
|
@@ -3,7 +3,8 @@ export interface BizMoreOptionPanelProps {
|
|
|
3
3
|
disabled?: boolean;
|
|
4
4
|
onSelectOption?: (option: BizMoreOptionConfig) => void;
|
|
5
5
|
onTriggerMediaInput?: () => void;
|
|
6
|
+
onTriggerDocumentInput?: () => void;
|
|
6
7
|
}
|
|
7
|
-
declare const BizMoreOptionPanel: ({ disabled, onSelectOption, onTriggerMediaInput, }: BizMoreOptionPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
declare const BizMoreOptionPanel: ({ disabled, onSelectOption, onTriggerMediaInput, onTriggerDocumentInput, }: BizMoreOptionPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
9
|
export default BizMoreOptionPanel;
|
|
9
10
|
//# sourceMappingURL=BizMoreOptionPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BizMoreOptionPanel.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/BizMoreOptionPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,mBAAmB,EACpB,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACvD,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"BizMoreOptionPanel.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/BizMoreOptionPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,mBAAmB,EACpB,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACvD,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;CACrC;AAED,QAAA,MAAM,kBAAkB,GAAI,4EAKzB,uBAAuB,4CA8BzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -3,14 +3,18 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useCallback } from "react";
|
|
4
4
|
import { BIZ_MORE_OPTIONS, } from "../../constants/bizMoreOption";
|
|
5
5
|
import BizMoreOptionItem from "./BizMoreOptionItem";
|
|
6
|
-
const BizMoreOptionPanel = ({ disabled = false, onSelectOption, onTriggerMediaInput, }) => {
|
|
6
|
+
const BizMoreOptionPanel = ({ disabled = false, onSelectOption, onTriggerMediaInput, onTriggerDocumentInput, }) => {
|
|
7
7
|
const handleSelectOption = useCallback((option) => {
|
|
8
8
|
if (option.labelKey === "thread_detail.more_option.media") {
|
|
9
9
|
onTriggerMediaInput === null || onTriggerMediaInput === void 0 ? void 0 : onTriggerMediaInput();
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
+
if (option.labelKey === "thread_detail.more_option.document") {
|
|
13
|
+
onTriggerDocumentInput === null || onTriggerDocumentInput === void 0 ? void 0 : onTriggerDocumentInput();
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
12
16
|
onSelectOption === null || onSelectOption === void 0 ? void 0 : onSelectOption(option);
|
|
13
|
-
}, [onSelectOption, onTriggerMediaInput]);
|
|
17
|
+
}, [onSelectOption, onTriggerMediaInput, onTriggerDocumentInput]);
|
|
14
18
|
return (_jsx("div", { "data-testid": "biz-more-option-panel", className: "grid grid-cols-4 gap-y-5 bg-white py-5", children: BIZ_MORE_OPTIONS.map((option) => (_jsx(BizMoreOptionItem, { option: Object.assign(Object.assign({}, option), { enabled: option.enabled && !disabled }), onSelect: handleSelectOption }, option.labelKey))) }));
|
|
15
19
|
};
|
|
16
20
|
export default BizMoreOptionPanel;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BizThreadDetailInput.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/BizThreadDetailInput.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BizThreadDetailInput.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/BizThreadDetailInput.tsx"],"names":[],"mappings":"AA8BA,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,QAAA,MAAM,oBAAoB,GAAI,gDAI3B,yBAAyB,4CAkY3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -13,8 +13,8 @@ import useBizMessageDraftStore from "../../store/bizMessageDraft";
|
|
|
13
13
|
import { resolveBizAvatarUrl, resolveBizDisplayName, } from "../../utils/bizConversation";
|
|
14
14
|
import { emit } from "../../utils/events";
|
|
15
15
|
import { extractBizLinkUrls } from "../../utils/bizLink";
|
|
16
|
-
import { processAndValidateFiles } from "../../utils/fileValidation";
|
|
17
|
-
import
|
|
16
|
+
import { processAndValidateDocuments, processAndValidateFiles, } from "../../utils/fileValidation";
|
|
17
|
+
import BizAttachmentPreview from "./BizAttachmentPreview";
|
|
18
18
|
import BizLinkInputPreview from "./BizLinkInputPreview";
|
|
19
19
|
import BizMoreOptionPanel from "./BizMoreOptionPanel";
|
|
20
20
|
const MAX_LINES = 5;
|
|
@@ -42,13 +42,14 @@ const BizThreadDetailInput = ({ placeholder, onSendMessage, onInputChange, }) =>
|
|
|
42
42
|
"",
|
|
43
43
|
}),
|
|
44
44
|
}), [bizConversation, conversationData, t]);
|
|
45
|
-
const { sendTextMessage } = useSendMessage(sendMessageOptions);
|
|
45
|
+
const { sendTextMessage, sendMergeMessage } = useSendMessage(sendMessageOptions);
|
|
46
46
|
const userID = useAuthStore((state) => state.userID);
|
|
47
47
|
const setDraft = useBizMessageDraftStore((state) => state.setDraft);
|
|
48
48
|
const clearDraft = useBizMessageDraftStore((state) => state.clearDraft);
|
|
49
49
|
const containerRef = useRef(null);
|
|
50
50
|
const textareaRef = useRef(null);
|
|
51
51
|
const mediaInputRef = useRef(null);
|
|
52
|
+
const documentInputRef = useRef(null);
|
|
52
53
|
const [value, setValue] = useState("");
|
|
53
54
|
const [listUploadFiles, setListUploadFiles] = useState([]);
|
|
54
55
|
const [isVideoLoading, setIsVideoLoading] = useState(false);
|
|
@@ -64,7 +65,11 @@ const BizThreadDetailInput = ({ placeholder, onSendMessage, onInputChange, }) =>
|
|
|
64
65
|
useEffect(() => {
|
|
65
66
|
setPreviewDismissed(false);
|
|
66
67
|
}, [previewUrl]);
|
|
67
|
-
const
|
|
68
|
+
const hasFiles = listUploadFiles.length > 0;
|
|
69
|
+
const canSend = (value.trim().length > 0 || hasFiles) &&
|
|
70
|
+
!isSending &&
|
|
71
|
+
isConversationReady &&
|
|
72
|
+
!isVideoLoading;
|
|
68
73
|
const getTextareaHeights = useCallback(() => {
|
|
69
74
|
const textarea = textareaRef.current;
|
|
70
75
|
if (!textarea)
|
|
@@ -146,6 +151,17 @@ const BizThreadDetailInput = ({ placeholder, onSendMessage, onInputChange, }) =>
|
|
|
146
151
|
}
|
|
147
152
|
event.target.value = "";
|
|
148
153
|
}, [tCommon, listUploadFiles]);
|
|
154
|
+
const handleDocumentInputChange = useCallback((event) => {
|
|
155
|
+
var _a;
|
|
156
|
+
const files = Array.from((_a = event.target.files) !== null && _a !== void 0 ? _a : []);
|
|
157
|
+
if (files.length === 0)
|
|
158
|
+
return;
|
|
159
|
+
const validFiles = processAndValidateDocuments(files, tCommon);
|
|
160
|
+
if (validFiles.length > 0) {
|
|
161
|
+
setListUploadFiles((prev) => [...prev, ...validFiles]);
|
|
162
|
+
}
|
|
163
|
+
event.target.value = "";
|
|
164
|
+
}, [tCommon]);
|
|
149
165
|
const handleRemoveFile = useCallback((uid) => {
|
|
150
166
|
setListUploadFiles((prev) => prev.filter((f) => f.uid !== uid));
|
|
151
167
|
setIsVideoLoading(false);
|
|
@@ -159,13 +175,22 @@ const BizThreadDetailInput = ({ placeholder, onSendMessage, onInputChange, }) =>
|
|
|
159
175
|
};
|
|
160
176
|
const handleSend = async () => {
|
|
161
177
|
const text = value.trim();
|
|
162
|
-
if (!text || isSending)
|
|
178
|
+
if ((!text && !hasFiles) || isSending)
|
|
163
179
|
return;
|
|
164
180
|
setIsSending(true);
|
|
165
181
|
try {
|
|
166
182
|
if (onSendMessage) {
|
|
167
183
|
onSendMessage(text);
|
|
168
184
|
}
|
|
185
|
+
else if (hasFiles) {
|
|
186
|
+
await sendMergeMessage({
|
|
187
|
+
plainText: text,
|
|
188
|
+
richText: "",
|
|
189
|
+
files: listUploadFiles,
|
|
190
|
+
isInternal: false,
|
|
191
|
+
});
|
|
192
|
+
setListUploadFiles([]);
|
|
193
|
+
}
|
|
169
194
|
else {
|
|
170
195
|
const sent = await sendTextMessage({
|
|
171
196
|
plainText: text,
|
|
@@ -221,8 +246,8 @@ const BizThreadDetailInput = ({ placeholder, onSendMessage, onInputChange, }) =>
|
|
|
221
246
|
event.preventDefault();
|
|
222
247
|
void handleSend();
|
|
223
248
|
};
|
|
224
|
-
return (_jsxs("div", { ref: containerRef, "data-testid": "biz-thread-detail-input", className: "flex w-full shrink-0 flex-col bg-[rgba(131,137,157,0.05)]", children: [_jsx("input", { ref: mediaInputRef, type: "file", accept: "image/jpeg,image/png,image/jpg,video/*", multiple: true, className: "hidden", onChange: handleMediaInputChange }), listUploadFiles.length > 0 && (_jsx(
|
|
249
|
+
return (_jsxs("div", { ref: containerRef, "data-testid": "biz-thread-detail-input", className: "flex w-full shrink-0 flex-col bg-[rgba(131,137,157,0.05)]", children: [_jsx("input", { ref: mediaInputRef, type: "file", accept: "image/jpeg,image/png,image/jpg,video/*", multiple: true, className: "hidden", onChange: handleMediaInputChange }), _jsx("input", { ref: documentInputRef, type: "file", accept: ".pdf,.doc,.docx", multiple: true, className: "hidden", onChange: handleDocumentInputChange }), listUploadFiles.length > 0 && (_jsx(BizAttachmentPreview, { files: listUploadFiles, onRemove: handleRemoveFile, onVideoReady: () => setIsVideoLoading(false) })), showLinkPreview && previewUrl && (_jsx(BizLinkInputPreview, { url: previewUrl, onRemove: () => setPreviewDismissed(true) })), _jsxs("div", { className: "flex items-end gap-3 px-3 py-2", children: [_jsx("div", { className: "flex shrink-0 items-center", children: _jsx("button", { type: "button", onClick: handleToggleMoreOption, "aria-label": t("thread_detail.more_option.toggle"), "aria-expanded": isMoreOptionOpen, "data-testid": "biz-thread-detail-more-option-toggle", className: "flex py-3 items-center justify-center rounded-full", children: isMoreOptionOpen ? (_jsx(Icon, { icon: "close-circle-o", size: 24, className: "text-[#1B3FE4]" })) : (_jsx(Icon, { icon: "plus-circle-o", size: 24, className: "text-[#393E40]" })) }) }), _jsx("div", { className: clsx("flex min-w-0 flex-1 overflow-hidden rounded-xl border bg-white transition-shadow", isFocused
|
|
225
250
|
? "border-[#607CFB] shadow-[0px_0px_2px_rgba(27,63,228,0.5)]"
|
|
226
|
-
: "border-[#DDDEDF]"), style: { minHeight: CONTAINER_MIN_HEIGHT }, children: _jsx("div", { className: "flex min-w-0 flex-[1_0_0] items-center gap-2 self-stretch px-3 py-1", children: _jsx("textarea", { ref: textareaRef, value: value, rows: 1, onChange: (event) => handleChange(event.target.value), onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : t("thread_detail.input_placeholder"), "data-testid": "biz-thread-detail-message-input", className: "biz-message-input-scrollbar min-h-0 min-w-0 flex-1 resize-none appearance-none border-0 bg-transparent p-0 text-[16px] leading-[1.6] tracking-[0.16px] text-black outline-none ring-0 placeholder:text-[#747B7E] focus:border-0 focus:outline-none focus:ring-0" }) }) }), _jsx("div", { className: "flex shrink-0 items-center pb-1", children: _jsx("button", { type: "button", onClick: () => void handleSend(), disabled: !canSend, "data-testid": "biz-thread-detail-send", className: clsx("flex h-10 w-10 items-center justify-center rounded-full", canSend ? "bg-[#002BEB]" : "bg-[#002BEB] opacity-25"), children: _jsx(Icon, { icon: "send-b", size: 20, className: "text-white" }) }) })] }), isMoreOptionOpen && (_jsx(BizMoreOptionPanel, { disabled: !isConversationReady, onTriggerMediaInput: () => { var _a; return (_a = mediaInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); } }))] }));
|
|
251
|
+
: "border-[#DDDEDF]"), style: { minHeight: CONTAINER_MIN_HEIGHT }, children: _jsx("div", { className: "flex min-w-0 flex-[1_0_0] items-center gap-2 self-stretch px-3 py-1", children: _jsx("textarea", { ref: textareaRef, value: value, rows: 1, onChange: (event) => handleChange(event.target.value), onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : t("thread_detail.input_placeholder"), "data-testid": "biz-thread-detail-message-input", className: "biz-message-input-scrollbar min-h-0 min-w-0 flex-1 resize-none appearance-none border-0 bg-transparent p-0 text-[16px] leading-[1.6] tracking-[0.16px] text-black outline-none ring-0 placeholder:text-[#747B7E] focus:border-0 focus:outline-none focus:ring-0" }) }) }), _jsx("div", { className: "flex shrink-0 items-center pb-1", children: _jsx("button", { type: "button", onClick: () => void handleSend(), disabled: !canSend, "data-testid": "biz-thread-detail-send", className: clsx("flex h-10 w-10 items-center justify-center rounded-full", canSend ? "bg-[#002BEB]" : "bg-[#002BEB] opacity-25"), children: _jsx(Icon, { icon: "send-b", size: 20, className: "text-white" }) }) })] }), isMoreOptionOpen && (_jsx(BizMoreOptionPanel, { disabled: !isConversationReady, onTriggerMediaInput: () => { var _a; return (_a = mediaInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, onTriggerDocumentInput: () => { var _a; return (_a = documentInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); } }))] }));
|
|
227
252
|
};
|
|
228
253
|
export default BizThreadDetailInput;
|
|
@@ -9,6 +9,6 @@ export { default as BizMoreOptionPanel } from "./BizMoreOptionPanel";
|
|
|
9
9
|
export type { BizMoreOptionPanelProps } from "./BizMoreOptionPanel";
|
|
10
10
|
export { default as BizMoreOptionItem } from "./BizMoreOptionItem";
|
|
11
11
|
export type { BizMoreOptionItemProps } from "./BizMoreOptionItem";
|
|
12
|
-
export { default as
|
|
13
|
-
export type {
|
|
12
|
+
export { default as BizAttachmentPreview } from "./BizAttachmentPreview";
|
|
13
|
+
export type { BizAttachmentPreviewProps } from "./BizAttachmentPreview";
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,YAAY,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACzE,YAAY,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/biz-thread-detail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,YAAY,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACzE,YAAY,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACzE,YAAY,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -4,4 +4,4 @@ export { default as BizMessageList } from "./BizMessageList";
|
|
|
4
4
|
export { default as BizMessageItem } from "./item/BizMessageItem";
|
|
5
5
|
export { default as BizMoreOptionPanel } from "./BizMoreOptionPanel";
|
|
6
6
|
export { default as BizMoreOptionItem } from "./BizMoreOptionItem";
|
|
7
|
-
export { default as
|
|
7
|
+
export { default as BizAttachmentPreview } from "./BizAttachmentPreview";
|
|
@@ -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,cAAc,CAAC;AAWtB,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAUlC,OAAO,EAAgB,gBAAgB,EAAyB,MAAM,aAAa,CAAC;AAkBpF,eAAO,MAAM,iBAAiB,GAAI,SAAS;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,YAE0C,CAAC;AAE5C,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,oBAAoB,GAAU,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,gCActE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,EACZ,eAAe,WAAW,gCAc3B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAC9B,4BAA4B,GAC5B,wCAAwC,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACzC,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,eAAe,CAAC;CACxE;AAED,eAAO,MAAM,cAAc,GAAI,UAAU,qBAAqB;4EA+OvD;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB,KAAG,OAAO,CAAC,OAAO,CAAC;oFA6CjB;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB;mCArKqB,WAAW;
|
|
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,cAAc,CAAC;AAWtB,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAUlC,OAAO,EAAgB,gBAAgB,EAAyB,MAAM,aAAa,CAAC;AAkBpF,eAAO,MAAM,iBAAiB,GAAI,SAAS;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,YAE0C,CAAC;AAE5C,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,oBAAoB,GAAU,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,gCActE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,EACZ,eAAe,WAAW,gCAc3B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAC9B,4BAA4B,GAC5B,wCAAwC,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACzC,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,eAAe,CAAC;CACxE;AAED,eAAO,MAAM,cAAc,GAAI,UAAU,qBAAqB;4EA+OvD;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB,KAAG,OAAO,CAAC,OAAO,CAAC;oFA6CjB;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB;mCArKqB,WAAW;CAwUpC,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,0CAIvC;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC,sBA4BA,CAAC"}
|
|
@@ -311,45 +311,70 @@ export const useSendMessage = (options) => {
|
|
|
311
311
|
if (!recvID && !groupID)
|
|
312
312
|
return;
|
|
313
313
|
const messageList = [];
|
|
314
|
-
|
|
314
|
+
const imageFileWrappers = files.filter((f) => { var _a; return (_a = f.originFileObj) === null || _a === void 0 ? void 0 : _a.type.startsWith("image/"); });
|
|
315
|
+
const nonImageFileWrappers = files.filter((f) => { var _a; return !((_a = f.originFileObj) === null || _a === void 0 ? void 0 : _a.type.startsWith("image/")); });
|
|
316
|
+
const imageMessages = [];
|
|
317
|
+
for (const fileWrapper of imageFileWrappers) {
|
|
318
|
+
const file = fileWrapper.originFileObj;
|
|
319
|
+
if (!file)
|
|
320
|
+
continue;
|
|
321
|
+
try {
|
|
322
|
+
const picInfo = await createPicBaseInfoFromFile(file);
|
|
323
|
+
const baseInfo = {
|
|
324
|
+
uuid: uuidv4(),
|
|
325
|
+
type: file.type,
|
|
326
|
+
size: file.size,
|
|
327
|
+
width: picInfo.width,
|
|
328
|
+
height: picInfo.height,
|
|
329
|
+
url: URL.createObjectURL(file),
|
|
330
|
+
};
|
|
331
|
+
const imageMessage = await createImageMessageByFile({
|
|
332
|
+
sourcePicture: baseInfo,
|
|
333
|
+
bigPicture: baseInfo,
|
|
334
|
+
snapshotPicture: baseInfo,
|
|
335
|
+
sourcePath: "",
|
|
336
|
+
file,
|
|
337
|
+
});
|
|
338
|
+
if (!imageMessage)
|
|
339
|
+
continue;
|
|
340
|
+
imageMessages.push(imageMessage);
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
console.error("Lỗi xử lý ảnh:", err);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (imageMessages.length === 1) {
|
|
347
|
+
messageFileStore.set(imageMessages[0].clientMsgID, {
|
|
348
|
+
type: "image",
|
|
349
|
+
file: imageFileWrappers[0].originFileObj,
|
|
350
|
+
});
|
|
351
|
+
messageList.push(imageMessages[0]);
|
|
352
|
+
}
|
|
353
|
+
else if (imageMessages.length > 1) {
|
|
354
|
+
imageMessages.forEach((imageMsg, index) => {
|
|
355
|
+
messageFileStore.set(imageMsg.clientMsgID, {
|
|
356
|
+
type: "image",
|
|
357
|
+
file: imageFileWrappers[index].originFileObj,
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
const mergeMsg = await createMergerMessage({
|
|
361
|
+
messageList: imageMessages,
|
|
362
|
+
title: "Album ảnh",
|
|
363
|
+
summaryList: imageMessages.map(() => "[Hình ảnh]"),
|
|
364
|
+
});
|
|
365
|
+
if (mergeMsg)
|
|
366
|
+
messageList.push(mergeMsg);
|
|
367
|
+
}
|
|
368
|
+
for (const fileWrapper of nonImageFileWrappers) {
|
|
315
369
|
const file = fileWrapper.originFileObj;
|
|
316
370
|
if (!file)
|
|
317
371
|
continue;
|
|
318
|
-
const isImage = file.type.startsWith("image/");
|
|
319
372
|
const isVideo = file.type.startsWith("video/");
|
|
320
373
|
const isDocument = file.type.startsWith("application/");
|
|
321
374
|
try {
|
|
322
|
-
if (
|
|
323
|
-
const picInfo = await createPicBaseInfoFromFile(file);
|
|
324
|
-
const baseInfo = {
|
|
325
|
-
uuid: uuidv4(),
|
|
326
|
-
type: file.type,
|
|
327
|
-
size: file.size,
|
|
328
|
-
width: picInfo.width,
|
|
329
|
-
height: picInfo.height,
|
|
330
|
-
url: URL.createObjectURL(file),
|
|
331
|
-
};
|
|
332
|
-
const parsedImage = {
|
|
333
|
-
sourcePicture: baseInfo,
|
|
334
|
-
bigPicture: baseInfo,
|
|
335
|
-
snapshotPicture: baseInfo,
|
|
336
|
-
sourcePath: "",
|
|
337
|
-
file: file,
|
|
338
|
-
};
|
|
339
|
-
const imageMessage = await createImageMessageByFile(parsedImage);
|
|
340
|
-
if (!imageMessage)
|
|
341
|
-
continue;
|
|
342
|
-
messageFileStore.set(imageMessage.clientMsgID, {
|
|
343
|
-
type: "image",
|
|
344
|
-
file: file,
|
|
345
|
-
});
|
|
346
|
-
messageList.push(imageMessage);
|
|
347
|
-
}
|
|
348
|
-
else if (isVideo) {
|
|
375
|
+
if (isVideo) {
|
|
349
376
|
const videoBaseInfo = await createVideoInfoWithThumbnail(file);
|
|
350
|
-
const thumbFile = new File([videoBaseInfo.thumbnail], file.name + "-thumb.jpg", {
|
|
351
|
-
type: "image/jpeg",
|
|
352
|
-
});
|
|
377
|
+
const thumbFile = new File([videoBaseInfo.thumbnail], file.name + "-thumb.jpg", { type: "image/jpeg" });
|
|
353
378
|
const videoMessage = await createVideoMessageByFile({
|
|
354
379
|
videoPath: "",
|
|
355
380
|
duration: videoBaseInfo.duration,
|
|
@@ -31,6 +31,6 @@ const DChatBizThreadDetail = (_a) => {
|
|
|
31
31
|
if (!conversation) {
|
|
32
32
|
return null;
|
|
33
33
|
}
|
|
34
|
-
return (_jsxs("div", { "data-testid": "biz-thread-detail-root", className: clsx("flex h-full w-full flex-col bg-white", className), children: [_jsx(BizThreadDetailHeader, { conversation: conversation, onBack: handleBack }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: children !== null && children !== void 0 ? children : _jsx(BizMessageList, {}) }), _jsx(BizThreadDetailInput, Object.assign({}, inputProps))] }));
|
|
34
|
+
return (_jsxs("div", { "data-testid": "biz-thread-detail-root", className: clsx("relative flex h-full w-full flex-col overflow-hidden bg-white", className), children: [_jsx(BizThreadDetailHeader, { conversation: conversation, onBack: handleBack }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: children !== null && children !== void 0 ? children : _jsx(BizMessageList, {}) }), _jsx(BizThreadDetailInput, Object.assign({}, inputProps))] }));
|
|
35
35
|
};
|
|
36
36
|
export default DChatBizThreadDetail;
|