@droppii-org/chat-sdk 0.0.51 → 0.0.53
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/message/MessageHeader.d.ts.map +1 -1
- package/dist/components/message/MessageHeader.js +2 -1
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +15 -2
- package/dist/components/searchConversation/SearchDrawer.d.ts +3 -0
- package/dist/components/searchConversation/SearchDrawer.d.ts.map +1 -0
- package/dist/components/searchConversation/SearchDrawer.js +24 -0
- package/dist/components/searchConversation/SearchMessageOnCurrentConversation.d.ts +7 -0
- package/dist/components/searchConversation/SearchMessageOnCurrentConversation.d.ts.map +1 -0
- package/dist/components/searchConversation/SearchMessageOnCurrentConversation.js +28 -0
- package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts +1 -0
- package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts.map +1 -1
- package/dist/components/searchConversation/item/SearchItemAsMessage.js +2 -1
- package/dist/locales/vi/common.json +4 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageHeader.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"MessageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageHeader.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIpD,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED,KAAK,sBAAsB,GAAG,aAAa,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,sBAAsB,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,QAAA,MAAM,aAAa,GAAI,6BAA6B,kBAAkB,4CA4LrE,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -11,6 +11,7 @@ import { SessionStatus, SessionTag } from "../../types/chat";
|
|
|
11
11
|
import SelectSession from "./SelectSession";
|
|
12
12
|
import { useUpdateSession } from "../../hooks/session/useUpdateSession";
|
|
13
13
|
import useAuthStore from "../../store/auth";
|
|
14
|
+
import SearchDrawer from "../searchConversation/SearchDrawer";
|
|
14
15
|
const MessageHeader = ({ onClose, currentSession }) => {
|
|
15
16
|
var _a;
|
|
16
17
|
const { t } = useTranslation();
|
|
@@ -121,6 +122,6 @@ const MessageHeader = ({ onClose, currentSession }) => {
|
|
|
121
122
|
setCurrentSessionStatus(currentSession.status);
|
|
122
123
|
}
|
|
123
124
|
}, [currentSession]);
|
|
124
|
-
return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", children: [_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: displayName || "" }), _jsx("p", { className: "text-xs text-gray-500 truncate", children: "2 thành viên" })] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(
|
|
125
|
+
return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", children: [_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: displayName || "" }), _jsx("p", { className: "text-xs text-gray-500 truncate", children: "2 thành viên" })] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
|
|
125
126
|
};
|
|
126
127
|
export default MessageHeader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/index.tsx"],"names":[],"mappings":"AAIA,OAAO,EACL,WAAW,IAAI,eAAe,EAE/B,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/index.tsx"],"names":[],"mappings":"AAIA,OAAO,EACL,WAAW,IAAI,eAAe,EAE/B,MAAM,yBAAyB,CAAC;AAejC,UAAU,gBAAgB;IACxB,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC;AAED,QAAA,MAAM,WAAW,GAAI,0BAA0B,gBAAgB,mDA4H9D,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -11,10 +11,23 @@ import { getVisibleNeighbor, visibleTypeMessage, } from "../../../hooks/message/
|
|
|
11
11
|
import { MSG_ITEM_CONTENT_PREFIX, MSG_ITEM_PREFIX } from "../../../constants";
|
|
12
12
|
import { formatTimestamp } from "../../../utils/common";
|
|
13
13
|
import useAuthStore from "../../../store/auth";
|
|
14
|
+
import useConversationStore from "../../../store/conversation";
|
|
15
|
+
import { useMemo } from "react";
|
|
14
16
|
const MessageItem = ({ message, allMessages }) => {
|
|
15
17
|
var _a, _b, _c, _d;
|
|
16
|
-
const isCx = useAuthStore((state) => state.isCx);
|
|
17
18
|
const userID = useAuthStore((state) => state.userID);
|
|
19
|
+
const isCrm = useAuthStore((state) => state.isCrm);
|
|
20
|
+
const conversationData = useConversationStore((state) => state.conversationData);
|
|
21
|
+
const showSenderInfo = useMemo(() => {
|
|
22
|
+
var _a, _b, _c;
|
|
23
|
+
try {
|
|
24
|
+
const isChatSupport = (_c = (_b = (_a = JSON.parse((conversationData === null || conversationData === void 0 ? void 0 : conversationData.ex) || "{}")) === null || _a === void 0 ? void 0 : _a.sessionInfo) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.botId;
|
|
25
|
+
return isChatSupport && isCrm;
|
|
26
|
+
}
|
|
27
|
+
catch (_d) {
|
|
28
|
+
console.log("Failed to parse conversationData.ex");
|
|
29
|
+
}
|
|
30
|
+
}, [conversationData === null || conversationData === void 0 ? void 0 : conversationData.ex, isCrm]);
|
|
18
31
|
const isVisibleGroup = visibleTypeMessage.includes(message === null || message === void 0 ? void 0 : message.contentType);
|
|
19
32
|
const renderMessageByType = (message) => {
|
|
20
33
|
switch (message === null || message === void 0 ? void 0 : message.contentType) {
|
|
@@ -46,7 +59,7 @@ const MessageItem = ({ message, allMessages }) => {
|
|
|
46
59
|
const showSenderName = !prevSameUser && !isMine;
|
|
47
60
|
return (_jsxs("div", { className: "flex flex-col gap-2 py-1 px-3 sm:p x-4", id: `${MSG_ITEM_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, children: [showTimeBreak && (_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: formatTimestamp(message.sendTime, {
|
|
48
61
|
dateMonthFormat: "DD MMMM",
|
|
49
|
-
}) }) })), _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: showSenderAvatar && (_jsx(Avatar, { src: message === null || message === void 0 ? void 0 : message.senderFaceUrl, 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: [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-white"), id: `${MSG_ITEM_CONTENT_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, 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) => {
|
|
62
|
+
}) }) })), _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 && showSenderInfo && (_jsx("div", { className: "flex items-center justify-center w-[32px] h-[32px]", children: showSenderAvatar && (_jsx(Avatar, { src: message === null || message === void 0 ? void 0 : message.senderFaceUrl, 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: [showSenderName && showSenderInfo && (_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-white"), id: `${MSG_ITEM_CONTENT_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, 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) => {
|
|
50
63
|
return renderMessageByType(item);
|
|
51
64
|
}), (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"), children: dayjs(message === null || message === void 0 ? void 0 : message.sendTime).format("HH:mm") })] })] })] }) }, message === null || message === void 0 ? void 0 : message.clientMsgID)] }, message === null || message === void 0 ? void 0 : message.clientMsgID));
|
|
52
65
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchDrawer.tsx"],"names":[],"mappings":"AAQA,QAAA,MAAM,YAAY,+CAsEjB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Drawer, Input } from "antd";
|
|
3
|
+
import { Icon } from "../icon";
|
|
4
|
+
import { useIsMobile } from "../../hooks/common/useIsMobile";
|
|
5
|
+
import useBoolean from "ahooks/lib/useBoolean";
|
|
6
|
+
import { useTranslation } from "react-i18next";
|
|
7
|
+
import { useRef, useState } from "react";
|
|
8
|
+
import SearchMessageOnCurrentConversation from "./SearchMessageOnCurrentConversation";
|
|
9
|
+
const SearchDrawer = () => {
|
|
10
|
+
const { t } = useTranslation();
|
|
11
|
+
const searchInputRef = useRef(null);
|
|
12
|
+
const [isOpen, { toggle }] = useBoolean(false);
|
|
13
|
+
const [search, setSearch] = useState("");
|
|
14
|
+
const isMobile = useIsMobile();
|
|
15
|
+
return (_jsxs("div", { children: [_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: toggle, children: _jsx(Icon, { icon: "search-o", size: 22 }) }), _jsx(Drawer, { open: isOpen, onClose: toggle, mask: false, closeIcon: false, styles: {
|
|
16
|
+
body: {
|
|
17
|
+
padding: 0,
|
|
18
|
+
height: "100%",
|
|
19
|
+
},
|
|
20
|
+
}, getContainer: false, width: isMobile ? "100%" : 360, children: _jsxs("div", { className: "flex flex-col h-full", children: [_jsxs("div", { className: "flex items-center justify-between p-3", children: [_jsx("span", { className: "text-lg font-medium", children: "T\u00ECm ki\u1EBFm tin nh\u1EAFn" }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: toggle, children: _jsx(Icon, { icon: "close-b", size: 22 }) })] }), _jsx("div", { className: "px-3", children: _jsx(Input, { ref: searchInputRef, placeholder: t("search"), prefix: _jsx(Icon, { icon: "search-o", size: 18, className: "text-gray-400" }), onChange: (e) => {
|
|
21
|
+
setSearch(e.target.value);
|
|
22
|
+
}, className: "rounded-lg text-sm", size: "large", allowClear: true, value: search, autoFocus: false }) }), _jsx("div", { className: "py-3", children: _jsx(SearchMessageOnCurrentConversation, { searchTerm: search, onClose: toggle }) })] }) })] }));
|
|
23
|
+
};
|
|
24
|
+
export default SearchDrawer;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface SearchMessageOnCurrentConversationProps {
|
|
2
|
+
searchTerm: string;
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
}
|
|
5
|
+
declare const SearchMessageOnCurrentConversation: (props: SearchMessageOnCurrentConversationProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default SearchMessageOnCurrentConversation;
|
|
7
|
+
//# sourceMappingURL=SearchMessageOnCurrentConversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchMessageOnCurrentConversation.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchMessageOnCurrentConversation.tsx"],"names":[],"mappings":"AAQA,UAAU,uCAAuC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AACD,QAAA,MAAM,kCAAkC,GACtC,OAAO,uCAAuC,4CAmD/C,CAAC;AAEF,eAAe,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Empty, Spin } from "antd";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
import { useSearchMessage } from "../../hooks/search/useSearchMessage";
|
|
5
|
+
import { MessageType } from "@openim/wasm-client-sdk";
|
|
6
|
+
import InfiniteScroll from "react-infinite-scroll-component";
|
|
7
|
+
import SearchItemAsMessage from "./item/SearchItemAsMessage";
|
|
8
|
+
import useConversationStore from "../../store/conversation";
|
|
9
|
+
const SearchMessageOnCurrentConversation = (props) => {
|
|
10
|
+
const { searchTerm = "" } = props;
|
|
11
|
+
const { t } = useTranslation();
|
|
12
|
+
const conversationData = useConversationStore((state) => state.conversationData);
|
|
13
|
+
const { dataFlatten, hasNextPage, fetchNextPage, isLoading } = useSearchMessage({
|
|
14
|
+
payload: {
|
|
15
|
+
searchTerm: searchTerm.trim(),
|
|
16
|
+
contentType: MessageType.TextMessage,
|
|
17
|
+
recvID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
if (searchTerm.trim() === "")
|
|
21
|
+
return _jsx(Empty, { description: t("no_search_text") });
|
|
22
|
+
if (dataFlatten.length === 0 && !isLoading)
|
|
23
|
+
return _jsx(Empty, { description: t("no_result") });
|
|
24
|
+
if (isLoading)
|
|
25
|
+
return (_jsx("div", { className: "flex items-center justify-center", children: _jsx(Spin, {}) }));
|
|
26
|
+
return (_jsx("div", { id: "scrollableVideoDiv", className: "h-full overflow-auto", children: _jsx(InfiniteScroll, { dataLength: dataFlatten.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableVideoDiv", children: dataFlatten.map((item) => (_jsx(SearchItemAsMessage, { message: item.chatLog, searchTerm: searchTerm, onClick: props === null || props === void 0 ? void 0 : props.onClose }))) }) }));
|
|
27
|
+
};
|
|
28
|
+
export default SearchMessageOnCurrentConversation;
|
|
@@ -2,6 +2,7 @@ import { MessageItem } from "@openim/wasm-client-sdk";
|
|
|
2
2
|
interface SearchItemAsMessageProps {
|
|
3
3
|
message: MessageItem;
|
|
4
4
|
searchTerm: string;
|
|
5
|
+
onClick?: () => void;
|
|
5
6
|
}
|
|
6
7
|
declare const SearchItemAsMessage: (props: SearchItemAsMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export default SearchItemAsMessage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/searchConversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AASnE,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/searchConversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AASnE,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CA0E3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -11,7 +11,7 @@ import useConversationStore from "../../../store/conversation";
|
|
|
11
11
|
const SearchItemAsMessage = (props) => {
|
|
12
12
|
var _a;
|
|
13
13
|
const { t } = useTranslation();
|
|
14
|
-
const { message, searchTerm = "" } = props;
|
|
14
|
+
const { message, searchTerm = "", onClick } = props;
|
|
15
15
|
const { user } = useChatContext();
|
|
16
16
|
const onPressItem = async () => {
|
|
17
17
|
const { data } = await DChatSDK.getOneConversation({
|
|
@@ -31,6 +31,7 @@ const SearchItemAsMessage = (props) => {
|
|
|
31
31
|
useConversationStore
|
|
32
32
|
.getState()
|
|
33
33
|
.setSelectedConversationId(data.conversationID);
|
|
34
|
+
onClick === null || onClick === void 0 ? void 0 : onClick();
|
|
34
35
|
};
|
|
35
36
|
let msgContent = "";
|
|
36
37
|
try {
|
|
@@ -32,5 +32,8 @@
|
|
|
32
32
|
"update_session_tag_failed": "Cập nhật tag không thành công",
|
|
33
33
|
"customer": "Khách hàng",
|
|
34
34
|
"you": "Bạn",
|
|
35
|
-
"select_tag": "Chọn tag"
|
|
35
|
+
"select_tag": "Chọn tag",
|
|
36
|
+
"search_message": "Tìm kiếm tin nhắn",
|
|
37
|
+
"no_result": "Không có kết quả",
|
|
38
|
+
"no_search_text": "Nhập từ khoá tìm kiếm"
|
|
36
39
|
}
|