@droppii-org/chat-sdk 0.1.50 → 0.1.51
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/assets/svg/index.d.ts +0 -1
- package/dist/assets/svg/index.d.ts.map +1 -1
- package/dist/assets/svg/index.js +0 -1
- package/dist/assets/svg/index.ts +1 -2
- package/dist/components/biz-inbox/BizThreadCard.d.ts.map +1 -1
- package/dist/components/biz-inbox/BizThreadCard.js +3 -11
- package/dist/components/biz-thread-detail/BizMessageList.js +2 -2
- package/dist/components/biz-thread-detail/BizThreadDetailInput.d.ts.map +1 -1
- package/dist/components/biz-thread-detail/BizThreadDetailInput.js +10 -19
- package/dist/components/biz-thread-detail/index.d.ts +0 -4
- package/dist/components/biz-thread-detail/index.d.ts.map +1 -1
- package/dist/components/biz-thread-detail/index.js +0 -2
- package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
- package/dist/components/conversation/ConversationBySessionItem.js +6 -5
- package/dist/components/conversation/ThreadCard.d.ts +14 -0
- package/dist/components/conversation/ThreadCard.d.ts.map +1 -0
- package/dist/components/conversation/ThreadCard.js +16 -0
- package/dist/components/media-collection/ImageCollection.d.ts.map +1 -1
- package/dist/components/media-collection/ImageCollection.js +3 -17
- package/dist/components/message/MessageList.d.ts.map +1 -1
- package/dist/components/message/MessageList.js +1 -7
- package/dist/components/message/footer/ComposerTextSyncPlugin.d.ts +6 -0
- package/dist/components/message/footer/ComposerTextSyncPlugin.d.ts.map +1 -0
- package/dist/components/message/footer/ComposerTextSyncPlugin.js +16 -0
- package/dist/components/message/footer/FilePreview.d.ts +3 -2
- package/dist/components/message/footer/FilePreview.d.ts.map +1 -1
- package/dist/components/message/footer/FilePreview.js +61 -21
- package/dist/components/message/footer/LinkInputPreview.d.ts +7 -0
- package/dist/components/message/footer/LinkInputPreview.d.ts.map +1 -0
- package/dist/components/message/footer/LinkInputPreview.js +16 -0
- package/dist/components/message/footer/MediaActions.d.ts.map +1 -1
- package/dist/components/message/footer/MediaActions.js +8 -5
- package/dist/components/message/footer/index.d.ts.map +1 -1
- package/dist/components/message/footer/index.js +48 -35
- package/dist/components/message/item/FileMessage.d.ts +2 -2
- package/dist/components/message/item/FileMessage.d.ts.map +1 -1
- package/dist/components/message/item/FileMessage.js +20 -12
- package/dist/components/message/item/ImageMessage.d.ts.map +1 -1
- package/dist/components/message/item/ImageMessage.js +11 -15
- package/dist/components/message/item/LinkCard.d.ts +7 -0
- package/dist/components/message/item/LinkCard.d.ts.map +1 -0
- package/dist/components/message/item/LinkCard.js +17 -0
- package/dist/components/message/item/LinkText.d.ts +6 -0
- package/dist/components/message/item/LinkText.d.ts.map +1 -0
- package/dist/components/message/item/LinkText.js +13 -0
- package/dist/components/message/item/MergeImageMessage.d.ts +7 -0
- package/dist/components/message/item/MergeImageMessage.d.ts.map +1 -0
- package/dist/components/message/item/MergeImageMessage.js +30 -0
- package/dist/components/message/item/MessageBubble.d.ts +13 -0
- package/dist/components/message/item/MessageBubble.d.ts.map +1 -0
- package/dist/components/message/item/MessageBubble.js +19 -0
- package/dist/components/message/item/RevokeMessage.js +1 -1
- package/dist/components/message/item/TextMessage.d.ts.map +1 -1
- package/dist/components/message/item/TextMessage.js +20 -9
- package/dist/components/message/item/UrlTextMessage.d.ts.map +1 -1
- package/dist/components/message/item/UrlTextMessage.js +19 -17
- package/dist/components/message/item/VideoMessage.d.ts.map +1 -1
- package/dist/components/message/item/VideoMessage.js +4 -12
- package/dist/components/message/item/imagePreviewToolbar.d.ts +5 -0
- package/dist/components/message/item/imagePreviewToolbar.d.ts.map +1 -0
- package/dist/components/message/item/imagePreviewToolbar.js +14 -0
- package/dist/components/message/item/index.d.ts +2 -1
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +38 -41
- package/dist/components/message/item/textStyle.d.ts +2 -0
- package/dist/components/message/item/textStyle.d.ts.map +1 -0
- package/dist/components/message/item/textStyle.js +1 -0
- package/dist/hooks/message/useSendMessage.d.ts +3 -10
- package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
- package/dist/hooks/message/useSendMessage.js +27 -44
- package/dist/styles/global.css +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/bizMessage.d.ts +1 -14
- package/dist/utils/bizMessage.d.ts.map +1 -1
- package/dist/utils/bizMessage.js +0 -26
- package/dist/utils/common.d.ts +2 -1
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/common.js +9 -3
- package/dist/utils/fileValidation.d.ts +1 -0
- package/dist/utils/fileValidation.d.ts.map +1 -1
- package/dist/utils/fileValidation.js +10 -17
- package/dist/utils/link.d.ts +13 -0
- package/dist/utils/link.d.ts.map +1 -0
- package/dist/utils/link.js +77 -0
- package/dist/utils/openLink.d.ts +3 -0
- package/dist/utils/openLink.d.ts.map +1 -0
- package/dist/utils/openLink.js +19 -0
- package/package.json +126 -127
|
@@ -8,7 +8,7 @@ import clsx from "clsx";
|
|
|
8
8
|
import { useTranslation } from "react-i18next";
|
|
9
9
|
import EmojiPicker from "./EmojiPicker";
|
|
10
10
|
import { Icon } from "../../../components/icon";
|
|
11
|
-
import { validateFile, validateVideoLimit, } from "../../../utils/fileValidation";
|
|
11
|
+
import { createUploadFile, validateFile, validateVideoLimit, } from "../../../utils/fileValidation";
|
|
12
12
|
import { DOCUMENT_TYPES } from "./editorConfig";
|
|
13
13
|
import CannedResponseIcon from "../../../assets/svg/canned-response";
|
|
14
14
|
import { useMessageFooterContext } from ".";
|
|
@@ -58,15 +58,18 @@ export default function MediaActions({ listUploadFiles, onFilesChange, buttonCla
|
|
|
58
58
|
return false;
|
|
59
59
|
};
|
|
60
60
|
const handleChange = (info) => {
|
|
61
|
-
var _a;
|
|
62
61
|
let newList = [...info.fileList];
|
|
63
62
|
const lastFile = info.file;
|
|
64
63
|
if (DOCUMENT_TYPES.includes(lastFile.type || "")) {
|
|
65
64
|
newList = newList.filter((f) => !DOCUMENT_TYPES.includes(f.type || ""));
|
|
66
|
-
|
|
67
|
-
newList.push(Object.assign(Object.assign({}, lastFile), { originFileObj: originFile }));
|
|
65
|
+
newList.push(lastFile);
|
|
68
66
|
}
|
|
69
|
-
|
|
67
|
+
const normalizedList = newList.map((file) => {
|
|
68
|
+
var _a;
|
|
69
|
+
const originFile = ((_a = file.originFileObj) !== null && _a !== void 0 ? _a : file);
|
|
70
|
+
return Object.assign(Object.assign({}, createUploadFile(originFile)), { uid: file.uid });
|
|
71
|
+
});
|
|
72
|
+
onFilesChange(normalizedList);
|
|
70
73
|
};
|
|
71
74
|
const onPressCanned = useCallback(async () => {
|
|
72
75
|
if (!isOpenCanned) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAEL,wBAAwB,EAEzB,MAAM,cAAc,CAAC;AAStB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAkB/C,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AASD,eAAO,MAAM,oBAAoB,mDAY/B,CAAC;AAEH,eAAO,MAAM,uBAAuB,gCAAyC,CAAC;AAE9E,QAAA,MAAM,qBAAqB,GAAI,4CAG5B,kBAAkB,4CAuSpB,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -5,13 +5,17 @@ import { ToolbarPlugin } from "./ToolbarPlugin";
|
|
|
5
5
|
import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
|
|
6
6
|
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
|
|
7
7
|
import { editorTheme, editorNodes, editorOnError } from "./editorConfig";
|
|
8
|
-
import { createContext, useCallback, useContext, useEffect, useRef, useState, } from "react";
|
|
8
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
9
9
|
import EnterHandler from "./EnterHandler";
|
|
10
10
|
import ActionBar from "./ActionBar";
|
|
11
|
-
import { AccountType } from "../../../types/chat";
|
|
11
|
+
import { AccountType, } from "../../../types/chat";
|
|
12
12
|
import { useSendMessage } from "../../../hooks/message/useSendMessage";
|
|
13
13
|
import { Modal, Popover } from "antd";
|
|
14
14
|
import FilePreview from "./FilePreview";
|
|
15
|
+
import LinkInputPreview from "./LinkInputPreview";
|
|
16
|
+
import ComposerTextSyncPlugin from "./ComposerTextSyncPlugin";
|
|
17
|
+
import { extractLinkUrls } from "../../../utils/link";
|
|
18
|
+
import { useFetchUrlMetadata } from "../../../hooks/common/useFetchUrlMetadata";
|
|
15
19
|
import { useTranslation } from "react-i18next";
|
|
16
20
|
import PasteAndDropPlugin from "./PasteAndDropPlugin";
|
|
17
21
|
import { QuotedMessageFooter } from "./QuotedMessage";
|
|
@@ -48,9 +52,11 @@ export const MessageFooterContext = createContext({
|
|
|
48
52
|
export const useMessageFooterContext = () => useContext(MessageFooterContext);
|
|
49
53
|
const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
50
54
|
const { t } = useTranslation();
|
|
51
|
-
const {
|
|
55
|
+
const { sendMergeMessage } = useSendMessage();
|
|
52
56
|
const accountType = useCurrentUserAccountType();
|
|
53
57
|
const [listUploadFiles, setListUploadFiles] = useState([]);
|
|
58
|
+
const [composerText, setComposerText] = useState("");
|
|
59
|
+
const [isLinkPreviewDismissed, setIsLinkPreviewDismissed] = useState(false);
|
|
54
60
|
const [isOpenCanned, { setTrue: openCanned, setFalse: closeCanned }] = useBoolean(false);
|
|
55
61
|
const isCrm = useAuthStore((state) => state.isCrm);
|
|
56
62
|
const [cannedQuery, setCannedQuery] = useState("");
|
|
@@ -61,6 +67,25 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
61
67
|
const quotedMessage = useConversationStore((state) => state.quotedMessage);
|
|
62
68
|
const conversationData = useConversationStore((state) => state.conversationData);
|
|
63
69
|
const lockToInternal = Boolean((quotedMessage === null || quotedMessage === void 0 ? void 0 : quotedMessage.clientMsgID) && (quotedMessage === null || quotedMessage === void 0 ? void 0 : quotedMessage.isInternal));
|
|
70
|
+
const previewUrl = useMemo(() => {
|
|
71
|
+
const urls = extractLinkUrls(composerText);
|
|
72
|
+
return urls.length === 1 ? urls[0] : null;
|
|
73
|
+
}, [composerText]);
|
|
74
|
+
const showLinkPreview = !!previewUrl && !isLinkPreviewDismissed && !isInternal;
|
|
75
|
+
const { data: previewMetadata } = useFetchUrlMetadata(previewUrl !== null && previewUrl !== void 0 ? previewUrl : "", showLinkPreview);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
setIsLinkPreviewDismissed(false);
|
|
78
|
+
}, [previewUrl]);
|
|
79
|
+
const resolveUrlMetadata = useCallback(() => {
|
|
80
|
+
if (!showLinkPreview || !previewUrl || !previewMetadata)
|
|
81
|
+
return undefined;
|
|
82
|
+
return {
|
|
83
|
+
url: previewUrl,
|
|
84
|
+
title: previewMetadata.title,
|
|
85
|
+
description: previewMetadata.description,
|
|
86
|
+
image: previewMetadata.image,
|
|
87
|
+
};
|
|
88
|
+
}, [showLinkPreview, previewUrl, previewMetadata]);
|
|
64
89
|
const [isSessionClosedModalOpen, { setTrue: openSessionClosedModal, setFalse: closeSessionClosedModal },] = useBoolean(false);
|
|
65
90
|
const pendingMessageRef = useRef(null);
|
|
66
91
|
const { mutateAsync: createSession, isPending: isCreatingSession } = useCreateSession();
|
|
@@ -90,57 +115,45 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
90
115
|
type,
|
|
91
116
|
isInternal,
|
|
92
117
|
files: [...listUploadFiles],
|
|
118
|
+
urlMetadata: resolveUrlMetadata(),
|
|
93
119
|
};
|
|
94
120
|
openSessionClosedModal();
|
|
95
121
|
return false;
|
|
96
122
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
currentSession,
|
|
106
|
-
isInternal,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
123
|
+
sendMergeMessage({
|
|
124
|
+
plainText,
|
|
125
|
+
richText,
|
|
126
|
+
files: listUploadFiles,
|
|
127
|
+
currentSession,
|
|
128
|
+
isInternal,
|
|
129
|
+
urlMetadata: resolveUrlMetadata(),
|
|
130
|
+
});
|
|
109
131
|
setListUploadFiles([]);
|
|
110
132
|
return true;
|
|
111
133
|
}, [
|
|
112
134
|
sendMergeMessage,
|
|
113
|
-
sendTextMessage,
|
|
114
135
|
listUploadFiles,
|
|
115
136
|
currentSession,
|
|
116
137
|
openSessionClosedModal,
|
|
138
|
+
resolveUrlMetadata,
|
|
117
139
|
]);
|
|
118
140
|
const executePendingSend = useCallback((newSession) => {
|
|
119
141
|
const pending = pendingMessageRef.current;
|
|
120
142
|
if (!pending)
|
|
121
143
|
return;
|
|
122
144
|
const sessionToUse = newSession || currentSession;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
sendMergeMessage({
|
|
133
|
-
plainText: pending.plainText,
|
|
134
|
-
richText: pending.richText,
|
|
135
|
-
files: pending.files,
|
|
136
|
-
currentSession: sessionToUse,
|
|
137
|
-
isInternal: pending.isInternal,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
145
|
+
sendMergeMessage({
|
|
146
|
+
plainText: pending.plainText,
|
|
147
|
+
richText: pending.richText,
|
|
148
|
+
files: pending.files,
|
|
149
|
+
currentSession: sessionToUse,
|
|
150
|
+
isInternal: pending.isInternal,
|
|
151
|
+
urlMetadata: pending.urlMetadata,
|
|
152
|
+
});
|
|
140
153
|
setListUploadFiles([]);
|
|
141
154
|
pendingMessageRef.current = null;
|
|
142
155
|
emit("CLEAR_COMPOSER");
|
|
143
|
-
}, [
|
|
156
|
+
}, [sendMergeMessage, currentSession]);
|
|
144
157
|
const handleSessionAction = useCallback(async (action) => {
|
|
145
158
|
const conversationId = conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID;
|
|
146
159
|
if (!conversationId)
|
|
@@ -202,6 +215,6 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
202
215
|
setMaxActiveCannedIndex,
|
|
203
216
|
}, children: [_jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Popover, { open: isOpenCanned, content: _jsx(CannedResponse, { onClose: closeCanned, openCreateCannedModal: onOpenCreateCannedModal, cannedQuery: cannedQuery }), placement: "topLeft", trigger: "click", arrow: false, classNames: {
|
|
204
217
|
body: "mx-1 !p-0",
|
|
205
|
-
}, destroyOnHidden: true, children: _jsxs("div", { className: "border-t pb-2 flex flex-col gap-1 bg-white", children: [_jsx(QuotedMessageFooter, {}), listUploadFiles.length > 0 && _jsx(FilePreview, {}), _jsx(ToolbarPlugin, {}), _jsxs("div", { children: [_jsx(ComposerTabs, { canUseInternal: canUseInternal, hintText: t("canned_response_hint"), isInternal: isInternal, lockToInternal: lockToInternal, setIsInternal: setIsInternal }), _jsx(ComposerEditor, { isInternal: isInternal, placeholderText: placeholderText })] }), _jsx(ActionBar, {})] }) }), _jsx(LinkPlugin, {}), _jsx(ListPlugin, {}), _jsx(EnterHandler, {}), _jsx(PasteAndDropPlugin, {}), isCrm && (_jsx(CannedResponseTriggerPlugin, { onClose: closeCanned, onOpen: onOpenCanned }))] }), _jsx(SessionClosedModal, { open: isSessionClosedModalOpen, loading: isSessionActionLoading, onReopen: handleReopenSession, onCreateNew: handleCreateNewSession, onClose: handleCloseSessionModal })] }));
|
|
218
|
+
}, destroyOnHidden: true, children: _jsxs("div", { className: "border-t pb-2 flex flex-col gap-1 bg-white", children: [_jsx(QuotedMessageFooter, {}), listUploadFiles.length > 0 && _jsx(FilePreview, {}), showLinkPreview && previewUrl && (_jsx(LinkInputPreview, { url: previewUrl, onRemove: () => setIsLinkPreviewDismissed(true) })), _jsx(ToolbarPlugin, {}), _jsxs("div", { children: [_jsx(ComposerTabs, { canUseInternal: canUseInternal, hintText: t("canned_response_hint"), isInternal: isInternal, lockToInternal: lockToInternal, setIsInternal: setIsInternal }), _jsx(ComposerEditor, { isInternal: isInternal, placeholderText: placeholderText })] }), _jsx(ActionBar, {})] }) }), _jsx(LinkPlugin, {}), _jsx(ListPlugin, {}), _jsx(ComposerTextSyncPlugin, { onChange: setComposerText }), _jsx(EnterHandler, {}), _jsx(PasteAndDropPlugin, {}), isCrm && (_jsx(CannedResponseTriggerPlugin, { onClose: closeCanned, onOpen: onOpenCanned }))] }), _jsx(SessionClosedModal, { open: isSessionClosedModalOpen, loading: isSessionActionLoading, onReopen: handleReopenSession, onCreateNew: handleCreateNewSession, onClose: handleCloseSessionModal })] }));
|
|
206
219
|
};
|
|
207
220
|
export default MessageFooterProvider;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MessageItem } from "@openim/wasm-client-sdk";
|
|
2
|
-
interface
|
|
2
|
+
interface FileMessageItemProps {
|
|
3
3
|
message: MessageItem;
|
|
4
4
|
}
|
|
5
|
-
declare const FileMessageItem: (props:
|
|
5
|
+
declare const FileMessageItem: (props: FileMessageItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export default FileMessageItem;
|
|
7
7
|
//# sourceMappingURL=FileMessage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/FileMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"FileMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/FileMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,yBAAyB,CAAC;AAOrE,UAAU,oBAAoB;IAC5B,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,eAAe,GAAI,OAAO,oBAAoB,4CAiEnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { MessageStatus } from "@openim/wasm-client-sdk";
|
|
3
|
+
import { Spin } from "antd";
|
|
4
|
+
import { Icon } from "../../../components/icon";
|
|
3
5
|
import { documentIcon } from "../../../assets/svg";
|
|
6
|
+
import { shortenFileName } from "../../../components/message/footer/FilePreview";
|
|
7
|
+
import { renderFileSize } from "../../../utils/common";
|
|
4
8
|
const FileMessageItem = (props) => {
|
|
5
9
|
var _a;
|
|
6
10
|
const { message } = props;
|
|
11
|
+
const fileElem = message.fileElem;
|
|
12
|
+
const fileName = (fileElem === null || fileElem === void 0 ? void 0 : fileElem.fileName) || "";
|
|
13
|
+
const fileSize = (_a = fileElem === null || fileElem === void 0 ? void 0 : fileElem.fileSize) !== null && _a !== void 0 ? _a : 0;
|
|
14
|
+
const sourceUrl = (fileElem === null || fileElem === void 0 ? void 0 : fileElem.sourceUrl) || "";
|
|
15
|
+
const isSending = message.status === MessageStatus.Sending;
|
|
16
|
+
const hasUrl = !!sourceUrl;
|
|
17
|
+
const handleView = () => {
|
|
18
|
+
if (!hasUrl)
|
|
19
|
+
return;
|
|
20
|
+
window.open(sourceUrl, "_blank", "noopener,noreferrer");
|
|
21
|
+
};
|
|
7
22
|
const handleDownload = () => {
|
|
8
|
-
|
|
9
|
-
const url = ((_a = message.fileElem) === null || _a === void 0 ? void 0 : _a.sourceUrl) || "";
|
|
10
|
-
const fileName = ((_b = message.fileElem) === null || _b === void 0 ? void 0 : _b.fileName) || "";
|
|
11
|
-
if (!url) {
|
|
12
|
-
console.warn("Không có link file để tải");
|
|
23
|
+
if (!hasUrl)
|
|
13
24
|
return;
|
|
14
|
-
}
|
|
15
25
|
const link = document.createElement("a");
|
|
16
|
-
link.href =
|
|
17
|
-
|
|
18
|
-
link.setAttribute("download", fileName);
|
|
19
|
-
}
|
|
26
|
+
link.href = sourceUrl;
|
|
27
|
+
link.setAttribute("download", fileName);
|
|
20
28
|
link.setAttribute("target", "_blank");
|
|
21
29
|
link.setAttribute("rel", "noopener noreferrer");
|
|
22
30
|
document.body.appendChild(link);
|
|
23
31
|
link.click();
|
|
24
32
|
link.remove();
|
|
25
33
|
};
|
|
26
|
-
return (_jsxs("div", { className: "
|
|
34
|
+
return (_jsx(Spin, { spinning: isSending, children: _jsxs("div", { className: "flex h-[51px] w-[292px] items-center gap-3 rounded-xl border border-[rgba(168,173,175,0.2)] bg-white px-3 py-1", children: [_jsx("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden [&>svg]:h-6 [&>svg]:w-6", children: documentIcon }), _jsxs("div", { className: "flex min-w-0 w-[168px] flex-col justify-center", children: [_jsx("span", { className: "truncate text-[14px] font-medium leading-[160%] text-[#393E40]", children: shortenFileName(fileName) }), _jsx("span", { className: "truncate text-[13px] leading-[160%] text-[#5C6366]", children: renderFileSize(fileSize) })] }), _jsxs("div", { className: "flex w-[52px] shrink-0 items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: handleView, disabled: !hasUrl, "aria-label": "Xem file", className: !hasUrl ? "opacity-30" : undefined, children: _jsx(Icon, { icon: "eye-o", size: 20, className: "text-[#393E40]" }) }), _jsx("button", { type: "button", onClick: handleDownload, disabled: !hasUrl, "aria-label": "T\u1EA3i xu\u1ED1ng", className: !hasUrl ? "opacity-30" : undefined, children: _jsx(Icon, { icon: "download-o", size: 20, className: "text-[#393E40]" }) })] })] }) }));
|
|
27
35
|
};
|
|
28
36
|
export default FileMessageItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/ImageMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/ImageMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,yBAAyB,CAAC;AAKrE,UAAU,qBAAqB;IAC7B,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,4CA+BrD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { MessageStatus } from "@openim/wasm-client-sdk";
|
|
3
3
|
import { Image, Spin } from "antd";
|
|
4
|
-
|
|
4
|
+
import { useTranslation } from "react-i18next";
|
|
5
|
+
import { renderImagePreviewToolbar } from "./imagePreviewToolbar";
|
|
5
6
|
const ImageMessageItem = (props) => {
|
|
6
|
-
var _a, _b, _c
|
|
7
|
+
var _a, _b, _c;
|
|
7
8
|
const { message } = props;
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const adaptedHight = min(minHeight, snapshotMaxHeight) + 10;
|
|
13
|
-
const adaptedWidth = min(imageWidth, 200) + 10;
|
|
14
|
-
const sourceUrl = ((_c = message.pictureElem.sourcePicture) === null || _c === void 0 ? void 0 : _c.url) ||
|
|
15
|
-
((_d = message.pictureElem.snapshotPicture) === null || _d === void 0 ? void 0 : _d.url);
|
|
9
|
+
const { t } = useTranslation();
|
|
10
|
+
const pictureElem = message.pictureElem;
|
|
11
|
+
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) || "";
|
|
12
|
+
const bigUrl = ((_c = pictureElem === null || pictureElem === void 0 ? void 0 : pictureElem.bigPicture) === null || _c === void 0 ? void 0 : _c.url) || sourceUrl;
|
|
16
13
|
const isSending = message.status === MessageStatus.Sending;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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: "rounded-md", src: sourceUrl, preview: true, placeholder: _jsx("div", { style: minStyle, className: "flex items-center justify-center", children: _jsx(Spin, {}) }) }) }) }));
|
|
14
|
+
return (_jsx("div", { className: "-mx-1", children: _jsx(Spin, { spinning: isSending, children: _jsx(Image, { src: sourceUrl, width: 205, height: 205, className: "cursor-pointer rounded-xl object-cover", preview: {
|
|
15
|
+
src: bigUrl,
|
|
16
|
+
toolbarRender: (originalNode, info) => { var _a; return renderImagePreviewToolbar(originalNode, (_a = info === null || info === void 0 ? void 0 : info.image) === null || _a === void 0 ? void 0 : _a.url, t); },
|
|
17
|
+
}, placeholder: _jsx("div", { className: "flex h-[205px] w-[205px] items-center justify-center rounded-xl bg-black/10", children: _jsx(Spin, {}) }) }) }) }));
|
|
22
18
|
};
|
|
23
19
|
export default ImageMessageItem;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UrlMetadataInfo } from "../../../types/chat";
|
|
2
|
+
export interface LinkCardProps {
|
|
3
|
+
metadata: UrlMetadataInfo;
|
|
4
|
+
}
|
|
5
|
+
declare const LinkCard: ({ metadata }: LinkCardProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
export default LinkCard;
|
|
7
|
+
//# sourceMappingURL=LinkCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkCard.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/LinkCard.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAED,QAAA,MAAM,QAAQ,GAAI,cAAc,aAAa,mDA0C5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
import { getHostLabel } from "../../../utils/link";
|
|
5
|
+
import { openLink } from "../../../utils/openLink";
|
|
6
|
+
const LinkCard = ({ metadata }) => {
|
|
7
|
+
const { t } = useTranslation("biz-inbox");
|
|
8
|
+
const { url, title, description, image } = metadata;
|
|
9
|
+
if (!title && !description && !image) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const handleOpen = () => {
|
|
13
|
+
openLink(url, t);
|
|
14
|
+
};
|
|
15
|
+
return (_jsxs("button", { type: "button", onClick: handleOpen, "data-testid": "link-message-card", className: "flex w-full max-w-[292px] flex-col overflow-hidden rounded-[12px] border border-[rgba(57,62,64,0.1)] bg-white text-left", children: [image && (_jsx("div", { className: "aspect-[16/9] w-full overflow-hidden", children: _jsx("img", { src: image, alt: "", className: "h-full w-full object-cover" }) })), _jsxs("div", { className: "flex flex-col px-3 py-2", children: [title && (_jsx("p", { className: "truncate text-[14px] font-medium leading-[1.6] text-[#393E40]", children: title })), _jsx("p", { className: "truncate text-[12px] font-medium leading-[1.6] tracking-[0.12px] text-[#1B3FE4]", children: getHostLabel(url) }), description && (_jsx("p", { className: "line-clamp-2 text-[12px] leading-[1.6] text-[#5C6366]", children: description }))] })] }));
|
|
16
|
+
};
|
|
17
|
+
export default LinkCard;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkText.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/LinkText.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,QAAA,MAAM,QAAQ,GAAI,UAAU,aAAa,4CA2BxC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { useTranslation } from "react-i18next";
|
|
5
|
+
import { parseTextWithLinks } from "../../../utils/link";
|
|
6
|
+
import { openLink } from "../../../utils/openLink";
|
|
7
|
+
import { MESSAGE_TEXT_CLASS } from "./textStyle";
|
|
8
|
+
const LinkText = ({ text }) => {
|
|
9
|
+
const { t } = useTranslation("biz-inbox");
|
|
10
|
+
const segments = parseTextWithLinks(text);
|
|
11
|
+
return (_jsx("span", { className: clsx("min-w-0 whitespace-pre-wrap text-left [overflow-wrap:anywhere]", MESSAGE_TEXT_CLASS), children: segments.map((segment, index) => segment.type === "link" ? (_jsx("button", { type: "button", onClick: () => openLink(segment.url, t), className: "inline text-left font-medium text-[#1B3FE4] underline-offset-2 hover:underline", children: segment.value }, `${segment.url}-${index}`)) : (_jsx("span", { children: segment.value }, `text-${index}`))) }));
|
|
12
|
+
};
|
|
13
|
+
export default LinkText;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MessageItem } from "@openim/wasm-client-sdk";
|
|
2
|
+
interface MergeImageMessageItemProps {
|
|
3
|
+
message: MessageItem;
|
|
4
|
+
}
|
|
5
|
+
declare const MergeImageMessageItem: (props: MergeImageMessageItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default MergeImageMessageItem;
|
|
7
|
+
//# sourceMappingURL=MergeImageMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MergeImageMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/MergeImageMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,yBAAyB,CAAC;AAMrE,UAAU,0BAA0B;IAClC,OAAO,EAAE,WAAW,CAAC;CACtB;AAQD,QAAA,MAAM,qBAAqB,GAAI,OAAO,0BAA0B,4CA4C/D,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MessageStatus } from "@openim/wasm-client-sdk";
|
|
3
|
+
import { Image, Spin } from "antd";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
import { useTranslation } from "react-i18next";
|
|
6
|
+
import { renderImagePreviewToolbar } from "./imagePreviewToolbar";
|
|
7
|
+
const MERGE_IMAGE_GRID_COLS_CLASS = {
|
|
8
|
+
1: "grid-cols-[repeat(1,100px)]",
|
|
9
|
+
2: "grid-cols-[repeat(2,100px)]",
|
|
10
|
+
3: "grid-cols-[repeat(3,100px)]",
|
|
11
|
+
};
|
|
12
|
+
const MergeImageMessageItem = (props) => {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
const { message } = props;
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
const subMessages = (_b = (_a = message.mergeElem) === null || _a === void 0 ? void 0 : _a.multiMessage) !== null && _b !== void 0 ? _b : [];
|
|
17
|
+
const isSending = message.status === MessageStatus.Sending;
|
|
18
|
+
const cols = Math.min(subMessages.length, 3);
|
|
19
|
+
return (_jsx("div", { className: "-mx-1", children: _jsx(Spin, { spinning: isSending, children: _jsx(Image.PreviewGroup, { preview: {
|
|
20
|
+
toolbarRender: (originalNode, info) => { var _a; return renderImagePreviewToolbar(originalNode, (_a = info === null || info === void 0 ? void 0 : info.image) === null || _a === void 0 ? void 0 : _a.url, t); },
|
|
21
|
+
}, children: _jsx("div", { className: clsx("grid gap-1", MERGE_IMAGE_GRID_COLS_CLASS[cols]), children: subMessages.map((item) => {
|
|
22
|
+
var _a, _b, _c, _d, _e, _f;
|
|
23
|
+
const sourceUrl = ((_b = (_a = item.pictureElem) === null || _a === void 0 ? void 0 : _a.sourcePicture) === null || _b === void 0 ? void 0 : _b.url) ||
|
|
24
|
+
((_d = (_c = item.pictureElem) === null || _c === void 0 ? void 0 : _c.snapshotPicture) === null || _d === void 0 ? void 0 : _d.url) ||
|
|
25
|
+
"";
|
|
26
|
+
const bigUrl = ((_f = (_e = item.pictureElem) === null || _e === void 0 ? void 0 : _e.bigPicture) === null || _f === void 0 ? void 0 : _f.url) || sourceUrl;
|
|
27
|
+
return (_jsx(Image, { src: sourceUrl, width: 100, height: 100, className: "cursor-pointer rounded-xl object-cover", preview: { src: bigUrl }, placeholder: _jsx("div", { className: "flex h-[100px] w-[100px] items-center justify-center rounded-xl bg-black/10", children: _jsx(Spin, {}) }) }, item.clientMsgID));
|
|
28
|
+
}) }) }) }) }));
|
|
29
|
+
};
|
|
30
|
+
export default MergeImageMessageItem;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface MessageBubbleProps {
|
|
3
|
+
isMine: boolean;
|
|
4
|
+
content: ReactNode;
|
|
5
|
+
senderName?: string;
|
|
6
|
+
showSenderName?: boolean;
|
|
7
|
+
showTip?: boolean;
|
|
8
|
+
isInternal?: boolean;
|
|
9
|
+
id?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const MessageBubble: ({ isMine, content, senderName, showSenderName, showTip, isInternal, id, }: MessageBubbleProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default MessageBubble;
|
|
13
|
+
//# sourceMappingURL=MessageBubble.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/MessageBubble.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAmCD,QAAA,MAAM,aAAa,GAAI,2EAQpB,kBAAkB,4CAsCpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
const INCOMING_TAIL_PATH = "M1.3798 18H4V0C3.51762 4.5 3.34269 10.5 0.966518 14C-0.568384 16.2608 -0.159364 18 1.3798 18Z";
|
|
5
|
+
const OUTGOING_TAIL_PATH = "M2.6202 18H0V0C0.482375 4.5 0.657308 10.5 3.03348 14C4.56838 16.2608 4.15936 18 2.6202 18Z";
|
|
6
|
+
const MessageBubbleTail = ({ isMine, isInternal, }) => (_jsx("div", { className: "flex shrink-0 items-center justify-center", children: _jsx("div", { className: "flex-none", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "4", height: "18", viewBox: "0 0 4 18", fill: "none", "aria-hidden": true, children: _jsx("path", { d: isMine ? OUTGOING_TAIL_PATH : INCOMING_TAIL_PATH, fill: isInternal ? "#FF9500" : isMine ? "#0051FF" : "#83899D", fillOpacity: "0.1" }) }) }) }));
|
|
7
|
+
const MessageBubble = ({ isMine, content, senderName, showSenderName, showTip = true, isInternal = false, id, }) => {
|
|
8
|
+
const bubbleClass = clsx("relative max-w-full p-2", showTip
|
|
9
|
+
? isMine
|
|
10
|
+
? "rounded-[20px] rounded-br-none"
|
|
11
|
+
: "rounded-[20px] rounded-bl-none"
|
|
12
|
+
: "rounded-[20px]", isInternal
|
|
13
|
+
? "bg-[rgba(255,149,0,0.1)]"
|
|
14
|
+
: isMine
|
|
15
|
+
? "bg-[rgba(0,81,255,0.1)]"
|
|
16
|
+
: "bg-[rgba(131,137,157,0.1)]");
|
|
17
|
+
return (_jsxs("div", { className: "relative flex items-end", "data-testid": "message-bubble", children: [!isMine && showTip && (_jsx(MessageBubbleTail, { isMine: isMine, isInternal: isInternal })), _jsx("div", { className: bubbleClass, id: id, children: _jsxs("div", { className: "flex flex-col gap-1 px-1", children: [showSenderName && senderName && (_jsx("span", { className: "text-[12px] font-medium leading-[160%] tracking-[0.12px] text-[#747B7E]", children: senderName })), _jsx("div", { className: "flex flex-col gap-2", children: content })] }) }), isMine && showTip && (_jsx(MessageBubbleTail, { isMine: isMine, isInternal: isInternal }))] }));
|
|
18
|
+
};
|
|
19
|
+
export default MessageBubble;
|
|
@@ -3,6 +3,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useTranslation } from "react-i18next";
|
|
4
4
|
const RevokeMessageItem = (_) => {
|
|
5
5
|
const { t } = useTranslation();
|
|
6
|
-
return (_jsx("span", { className: "
|
|
6
|
+
return (_jsx("span", { className: "whitespace-pre-wrap text-[16px] leading-[160%] italic text-gray-500", children: t("revoked") }));
|
|
7
7
|
};
|
|
8
8
|
export default RevokeMessageItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/TextMessage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/TextMessage.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AAQnE,UAAU,oBAAoB;IAC5B,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,eAAe,GAAI,OAAO,oBAAoB,mDAiDnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
3
4
|
import { MessageType } from "@openim/wasm-client-sdk";
|
|
4
5
|
import useAuthStore from "../../../store/auth";
|
|
5
|
-
import { sanitizeHtml } from "../../../utils/common";
|
|
6
|
+
import { htmlHasFormatting, sanitizeHtml, stripHtml } from "../../../utils/common";
|
|
7
|
+
import { extractLinkUrls } from "../../../utils/link";
|
|
8
|
+
import LinkText from "./LinkText";
|
|
9
|
+
import { MESSAGE_TEXT_CLASS } from "./textStyle";
|
|
6
10
|
const TextMessageItem = (props) => {
|
|
7
|
-
var _a, _b, _c;
|
|
11
|
+
var _a, _b, _c, _d;
|
|
8
12
|
const { message } = props;
|
|
9
13
|
const isCrm = useAuthStore((state) => state.isCrm);
|
|
10
14
|
let extendMessageInfo = null;
|
|
@@ -18,13 +22,20 @@ const TextMessageItem = (props) => {
|
|
|
18
22
|
if ((message === null || message === void 0 ? void 0 : message.contentType) === MessageType.CustomMessage && !isCrm) {
|
|
19
23
|
return null;
|
|
20
24
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const sanitizedContent = sanitizeHtml(htmlContent);
|
|
26
|
-
return (_jsx("div", { className: "!text-sm sm:text-base break-normal whitespace-pre-line flex-1", style: { overflowWrap: "anywhere" }, dangerouslySetInnerHTML: { __html: sanitizedContent } }));
|
|
25
|
+
const richHtmlContent = ((_b = (_a = extendMessageInfo === null || extendMessageInfo === void 0 ? void 0 : extendMessageInfo.messageInfo) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.content) || "";
|
|
26
|
+
if (richHtmlContent && htmlHasFormatting(richHtmlContent)) {
|
|
27
|
+
const sanitizedContent = sanitizeHtml(richHtmlContent);
|
|
28
|
+
return (_jsx("div", { className: clsx("break-normal whitespace-pre-line flex-1", MESSAGE_TEXT_CLASS), style: { overflowWrap: "anywhere" }, dangerouslySetInnerHTML: { __html: sanitizedContent } }));
|
|
27
29
|
}
|
|
28
|
-
|
|
30
|
+
const text = ((_c = message === null || message === void 0 ? void 0 : message.textElem) === null || _c === void 0 ? void 0 : _c.content) ||
|
|
31
|
+
((_d = message === null || message === void 0 ? void 0 : message.quoteElem) === null || _d === void 0 ? void 0 : _d.text) ||
|
|
32
|
+
stripHtml(richHtmlContent) ||
|
|
33
|
+
"";
|
|
34
|
+
if (!text)
|
|
35
|
+
return null;
|
|
36
|
+
if (extractLinkUrls(text).length > 0) {
|
|
37
|
+
return _jsx(LinkText, { text: text });
|
|
38
|
+
}
|
|
39
|
+
return (_jsx("p", { className: clsx("whitespace-pre-wrap break-words", MESSAGE_TEXT_CLASS), children: text }));
|
|
29
40
|
};
|
|
30
41
|
export default TextMessageItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UrlTextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/UrlTextMessage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"UrlTextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/UrlTextMessage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAatD,UAAU,uBAAuB;IAC/B,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,kBAAkB,GAAI,OAAO,uBAAuB,4CA6DzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
3
|
+
import { wrapLinksInHtml, sanitizeHtml, htmlHasFormatting, stripHtml, } from "../../../utils/common";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
import LinkText from "./LinkText";
|
|
6
|
+
import LinkCard from "./LinkCard";
|
|
7
|
+
import { MESSAGE_TEXT_CLASS } from "./textStyle";
|
|
6
8
|
const UrlTextMessageItem = (props) => {
|
|
7
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
9
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
8
10
|
const { message } = props;
|
|
9
|
-
const { data: externalLinkData } = useFetchExternalLink(((_b = (_a = message === null || message === void 0 ? void 0 : message.urlTextElem) === null || _a === void 0 ? void 0 : _a.urls) === null || _b === void 0 ? void 0 : _b[0]) || "");
|
|
10
11
|
let extendMessageInfo = null;
|
|
11
|
-
const onPressExternalLink = (url) => {
|
|
12
|
-
if (!url)
|
|
13
|
-
return;
|
|
14
|
-
window.open(url, "_blank", "noopener,noreferrer");
|
|
15
|
-
};
|
|
16
12
|
try {
|
|
17
13
|
extendMessageInfo = JSON.parse((message === null || message === void 0 ? void 0 : message.ex) || "{}");
|
|
18
14
|
}
|
|
@@ -20,13 +16,19 @@ const UrlTextMessageItem = (props) => {
|
|
|
20
16
|
extendMessageInfo = {};
|
|
21
17
|
console.error("Failed to parse extendMessageInfo", error);
|
|
22
18
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
const sanitizedContent = sanitizeHtml(wrapLinksInHtml(htmlContent));
|
|
28
|
-
return (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("div", { className: "!text-sm sm:text-base break-normal whitespace-pre-line flex-1", style: { overflowWrap: "anywhere" }, dangerouslySetInnerHTML: { __html: sanitizedContent } }), !!externalLinkData && (_jsxs("div", { className: "flex items-center rounded-md px-3 py-2 border-l-4 border-l-blue-500 bg-blue-50 gap-2 cursor-pointer overflow-hidden", style: { wordBreak: "break-word", overflowWrap: "anywhere" }, onClick: () => onPressExternalLink((externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.url) || ""), children: [_jsxs("div", { className: "flex flex-1 flex-col gap-1", children: [(externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.title) && (_jsx("span", { className: "!text-sm font-semibold truncate break-normal", children: externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.title })), (externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.description) && (_jsx("span", { className: "!text-sm text-gray-500 line-clamp-2", children: externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.description })), (externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.url) && (_jsx("span", { className: "!text-sm font-medium text-blue-500", children: getHostFromUrl(externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.url) }))] }), ((_e = externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.logo) === null || _e === void 0 ? void 0 : _e.url) && (_jsx(Image, { src: (_f = externalLinkData === null || externalLinkData === void 0 ? void 0 : externalLinkData.logo) === null || _f === void 0 ? void 0 : _f.url, width: 48, height: 48 }))] }))] }));
|
|
19
|
+
const richHtmlContent = ((_b = (_a = extendMessageInfo === null || extendMessageInfo === void 0 ? void 0 : extendMessageInfo.messageInfo) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.content) || "";
|
|
20
|
+
if (richHtmlContent && htmlHasFormatting(richHtmlContent)) {
|
|
21
|
+
const sanitizedContent = sanitizeHtml(wrapLinksInHtml(richHtmlContent));
|
|
22
|
+
return (_jsx("div", { className: clsx("break-normal whitespace-pre-line flex-1", MESSAGE_TEXT_CLASS), style: { overflowWrap: "anywhere" }, dangerouslySetInnerHTML: { __html: sanitizedContent } }));
|
|
29
23
|
}
|
|
30
|
-
|
|
24
|
+
const text = (_h = (_g = (_f = (_d = (_c = message === null || message === void 0 ? void 0 : message.textElem) === null || _c === void 0 ? void 0 : _c.content) !== null && _d !== void 0 ? _d : (_e = message === null || message === void 0 ? void 0 : message.urlTextElem) === null || _e === void 0 ? void 0 : _e.content) !== null && _f !== void 0 ? _f : message === null || message === void 0 ? void 0 : message.content) !== null && _g !== void 0 ? _g : stripHtml(richHtmlContent)) !== null && _h !== void 0 ? _h : "";
|
|
25
|
+
const urlMetadata = extendMessageInfo === null || extendMessageInfo === void 0 ? void 0 : extendMessageInfo.urlMetadata;
|
|
26
|
+
if (urlMetadata === null || urlMetadata === void 0 ? void 0 : urlMetadata.url) {
|
|
27
|
+
return (_jsxs("div", { className: "flex max-w-[292px] flex-col gap-2", children: [text && _jsx(LinkText, { text: text }), _jsx(LinkCard, { metadata: urlMetadata })] }));
|
|
28
|
+
}
|
|
29
|
+
if (text) {
|
|
30
|
+
return _jsx(LinkText, { text: text });
|
|
31
|
+
}
|
|
32
|
+
return (_jsx("span", { className: clsx("break-normal whitespace-pre-line flex-1", MESSAGE_TEXT_CLASS), style: { overflowWrap: "anywhere" }, children: ((_k = (_j = message === null || message === void 0 ? void 0 : message.urlTextElem) === null || _j === void 0 ? void 0 : _j.urls) === null || _k === void 0 ? void 0 : _k[0]) || "" }));
|
|
31
33
|
};
|
|
32
34
|
export default UrlTextMessageItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/VideoMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,yBAAyB,CAAC;AAGrE,UAAU,qBAAqB;IAC7B,OAAO,EAAE,WAAW,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"VideoMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/VideoMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,yBAAyB,CAAC;AAGrE,UAAU,qBAAqB;IAC7B,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,4CAmBrD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { MessageStatus } from "@openim/wasm-client-sdk";
|
|
3
3
|
import { Spin } from "antd";
|
|
4
|
-
const min = (a, b) => (a > b ? b : a);
|
|
5
4
|
const VideoMessageItem = (props) => {
|
|
6
5
|
const { message } = props;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const adaptedHight = min(minHeight, imageHeight) + 10;
|
|
11
|
-
const adaptedWidth = min(imageWidth, 200) + 10;
|
|
12
|
-
const sourceUrl = message.videoElem.videoUrl;
|
|
6
|
+
const videoElem = message.videoElem;
|
|
7
|
+
const videoUrl = (videoElem === null || videoElem === void 0 ? void 0 : videoElem.videoUrl) || "";
|
|
8
|
+
const posterUrl = (videoElem === null || videoElem === void 0 ? void 0 : videoElem.snapshotUrl) || "";
|
|
13
9
|
const isSending = message.status === MessageStatus.Sending;
|
|
14
|
-
|
|
15
|
-
minHeight: `${adaptedHight}px`,
|
|
16
|
-
minWidth: `${adaptedWidth}px`,
|
|
17
|
-
};
|
|
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 }) }) }));
|
|
10
|
+
return (_jsx("div", { className: "-mx-1", children: _jsx(Spin, { spinning: isSending, children: _jsx("video", { src: videoUrl, poster: posterUrl, controls: true, className: "h-[150px] w-[215px] rounded-xl object-cover" }) }) }));
|
|
19
11
|
};
|
|
20
12
|
export default VideoMessageItem;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { TFunction } from "i18next";
|
|
3
|
+
export declare const downloadImage: (imageUrl?: string) => void;
|
|
4
|
+
export declare const renderImagePreviewToolbar: (originalNode: ReactNode, imageUrl: string | undefined, t: TFunction) => ReactNode;
|
|
5
|
+
//# sourceMappingURL=imagePreviewToolbar.d.ts.map
|