@droppii-org/chat-sdk 0.1.2 → 0.1.4
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/cannedResponse.d.ts +7 -0
- package/dist/assets/svg/cannedResponse.d.ts.map +1 -0
- package/dist/assets/svg/cannedResponse.js +3 -0
- package/dist/assets/svg/cannedResponse.tsx +48 -0
- package/dist/assets/svg/index.d.ts +1 -0
- package/dist/assets/svg/index.d.ts.map +1 -1
- package/dist/assets/svg/index.js +1 -0
- package/dist/assets/svg/index.ts +1 -0
- package/dist/components/cannedResponse/CannedResponseBody.d.ts +8 -0
- package/dist/components/cannedResponse/CannedResponseBody.d.ts.map +1 -0
- package/dist/components/cannedResponse/CannedResponseBody.js +58 -0
- package/dist/components/cannedResponse/CannedResponseFooter.d.ts +6 -0
- package/dist/components/cannedResponse/CannedResponseFooter.d.ts.map +1 -0
- package/dist/components/cannedResponse/CannedResponseFooter.js +8 -0
- package/dist/components/cannedResponse/CannedResponseHeader.d.ts +8 -0
- package/dist/components/cannedResponse/CannedResponseHeader.d.ts.map +1 -0
- package/dist/components/cannedResponse/CannedResponseHeader.js +11 -0
- package/dist/components/cannedResponse/index.d.ts +8 -0
- package/dist/components/cannedResponse/index.d.ts.map +1 -0
- package/dist/components/cannedResponse/index.js +34 -0
- package/dist/components/cannedResponse/team/TeamItem.d.ts +11 -0
- package/dist/components/cannedResponse/team/TeamItem.d.ts.map +1 -0
- package/dist/components/cannedResponse/team/TeamItem.js +31 -0
- package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
- package/dist/components/conversation/ConversationBySessionItem.js +6 -2
- package/dist/components/mediaCollection/LinkCollection.js +1 -1
- package/dist/components/message/MediaPreviewIcon.d.ts +7 -0
- package/dist/components/message/MediaPreviewIcon.d.ts.map +1 -0
- package/dist/components/message/MediaPreviewIcon.js +24 -0
- package/dist/components/message/MessageHeader.js +1 -1
- package/dist/components/message/MessageList.d.ts +1 -0
- package/dist/components/message/MessageList.d.ts.map +1 -1
- package/dist/components/message/MessageList.js +49 -6
- package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
- package/dist/components/message/footer/ActionBar.js +15 -86
- package/dist/components/message/footer/CannedResponsePlugin.d.ts +7 -0
- package/dist/components/message/footer/CannedResponsePlugin.d.ts.map +1 -0
- package/dist/components/message/footer/CannedResponsePlugin.js +31 -0
- package/dist/components/message/footer/EmojiPicker.d.ts.map +1 -1
- package/dist/components/message/footer/EmojiPicker.js +9 -5
- package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
- package/dist/components/message/footer/EnterHandler.js +16 -5
- package/dist/components/message/footer/FilePreview.d.ts +5 -0
- package/dist/components/message/footer/FilePreview.d.ts.map +1 -1
- package/dist/components/message/footer/FilePreview.js +15 -12
- package/dist/components/message/footer/MediaActions.d.ts +10 -0
- package/dist/components/message/footer/MediaActions.d.ts.map +1 -0
- package/dist/components/message/footer/MediaActions.js +98 -0
- package/dist/components/message/footer/QuotedMessage.d.ts +2 -0
- package/dist/components/message/footer/QuotedMessage.d.ts.map +1 -0
- package/dist/components/message/footer/QuotedMessage.js +24 -0
- package/dist/components/message/footer/editorConfig.d.ts +24 -0
- package/dist/components/message/footer/editorConfig.d.ts.map +1 -0
- package/dist/components/message/footer/editorConfig.js +33 -0
- package/dist/components/message/footer/index.d.ts +2 -1
- package/dist/components/message/footer/index.d.ts.map +1 -1
- package/dist/components/message/footer/index.js +33 -28
- package/dist/components/message/item/QuoteMessage.d.ts +9 -0
- package/dist/components/message/item/QuoteMessage.d.ts.map +1 -0
- package/dist/components/message/item/QuoteMessage.js +41 -0
- package/dist/components/message/item/RevokeMessage.d.ts +5 -0
- package/dist/components/message/item/RevokeMessage.d.ts.map +1 -0
- package/dist/components/message/item/RevokeMessage.js +8 -0
- package/dist/components/message/item/TextMessage.js +1 -1
- package/dist/components/message/item/UrlTextMessage.d.ts.map +1 -1
- package/dist/components/message/item/UrlTextMessage.js +3 -3
- package/dist/components/message/item/index.d.ts +6 -1
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +79 -25
- package/dist/components/richTextEditor/RichTextEditor.d.ts +12 -0
- package/dist/components/richTextEditor/RichTextEditor.d.ts.map +1 -0
- package/dist/components/richTextEditor/RichTextEditor.js +62 -0
- package/dist/components/searchConversation/SearchDrawer.js +1 -1
- package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts +3 -1
- package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts.map +1 -1
- package/dist/components/searchConversation/item/SearchItemAsMessage.js +5 -2
- package/dist/components/thread/AssignConfirmModal.d.ts +12 -0
- package/dist/components/thread/AssignConfirmModal.d.ts.map +1 -0
- package/dist/components/thread/AssignConfirmModal.js +11 -0
- package/dist/components/thread/ManualAssignPopover.d.ts +14 -0
- package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -0
- package/dist/components/thread/ManualAssignPopover.js +83 -0
- package/dist/components/thread/SessionSection.d.ts.map +1 -1
- package/dist/components/thread/SessionSection.js +11 -6
- package/dist/components/thread/UserSection.js +1 -1
- package/dist/hooks/cannedResponse/useFetchCannedCategories.d.ts +3 -0
- package/dist/hooks/cannedResponse/useFetchCannedCategories.d.ts.map +1 -0
- package/dist/hooks/cannedResponse/useFetchCannedCategories.js +13 -0
- package/dist/hooks/cannedResponse/useFetchCannedResponse.d.ts +219 -0
- package/dist/hooks/cannedResponse/useFetchCannedResponse.d.ts.map +1 -0
- package/dist/hooks/cannedResponse/useFetchCannedResponse.js +55 -0
- package/dist/hooks/message/useMessage.d.ts.map +1 -1
- package/dist/hooks/message/useMessage.js +18 -1
- package/dist/hooks/message/useRevokeMessage.d.ts +5 -0
- package/dist/hooks/message/useRevokeMessage.d.ts.map +1 -0
- package/dist/hooks/message/useRevokeMessage.js +16 -0
- package/dist/hooks/message/useSendMessage.d.ts +1 -0
- package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
- package/dist/hooks/message/useSendMessage.js +40 -9
- package/dist/hooks/session/useAssignSession.d.ts +8 -0
- package/dist/hooks/session/useAssignSession.d.ts.map +1 -0
- package/dist/hooks/session/useAssignSession.js +15 -0
- package/dist/hooks/session/useCreateNote.d.ts.map +1 -1
- package/dist/hooks/session/useCreateNote.js +2 -1
- package/dist/hooks/session/useGetTeamSupporters.d.ts +8 -0
- package/dist/hooks/session/useGetTeamSupporters.d.ts.map +1 -0
- package/dist/hooks/session/useGetTeamSupporters.js +20 -0
- package/dist/hooks/team/useFetchMyTeam.d.ts +3 -0
- package/dist/hooks/team/useFetchMyTeam.d.ts.map +1 -0
- package/dist/hooks/team/useFetchMyTeam.js +12 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/locales/vi/common.json +54 -53
- package/dist/screens/deskMessage/index.d.ts +4 -1
- package/dist/screens/deskMessage/index.d.ts.map +1 -1
- package/dist/screens/deskMessage/index.js +2 -2
- package/dist/services/query.d.ts +5 -0
- package/dist/services/query.d.ts.map +1 -1
- package/dist/services/query.js +5 -0
- package/dist/services/routes.d.ts +5 -0
- package/dist/services/routes.d.ts.map +1 -1
- package/dist/services/routes.js +5 -0
- package/dist/store/conversation.d.ts.map +1 -1
- package/dist/store/conversation.js +7 -1
- package/dist/styles/global.css +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/chat.d.ts +7 -1
- package/dist/types/chat.d.ts.map +1 -1
- package/dist/types/chat.js +5 -0
- package/dist/types/dto.d.ts +53 -1
- package/dist/types/dto.d.ts.map +1 -1
- package/dist/utils/common.d.ts +3 -2
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/common.js +43 -19
- package/dist/utils/fileValidation.d.ts.map +1 -1
- package/dist/utils/fileValidation.js +2 -8
- package/dist/utils/queryHelpers.d.ts +3 -0
- package/dist/utils/queryHelpers.d.ts.map +1 -0
- package/dist/utils/queryHelpers.js +11 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cannedResponse.d.ts","sourceRoot":"","sources":["../../../src/assets/svg/cannedResponse.tsx"],"names":[],"mappings":"AAAA,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,kBAAkB,GAAI,OAAO,SAAS,4CAyC3C,CAAC;AACF,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const CannedResponseIcon = (props) => (_jsxs("svg", { width: props.size || 18, height: props.size || 18, viewBox: `${0} ${0} ${props.size || 18} ${props.size || 18}`, fill: "none", xmlns: "http://www.w3.org/2000/svg", className: props === null || props === void 0 ? void 0 : props.className, children: [_jsxs("g", { clipPath: "url(#clip0_4070_70030)", children: [_jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M6.66732 0.833374C7.12755 0.833374 7.50065 1.20647 7.50065 1.66671L5.00065 18.3334C5.00065 18.7936 4.62755 19.1667 4.16732 19.1667C3.70708 19.1667 3.33398 18.7936 3.33398 18.3334L5.83398 1.66671C5.83398 1.20647 6.20708 0.833374 6.66732 0.833374Z", fill: "currentColor" }), _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M14.9993 0.833374C15.4596 0.833374 15.8327 1.20647 15.8327 1.66671L13.3327 18.3334C13.3327 18.7936 12.9596 19.1667 12.4993 19.1667C12.0391 19.1667 11.666 18.7936 11.666 18.3334L14.166 1.66671C14.166 1.20647 14.5391 0.833374 14.9993 0.833374Z", fill: "currentColor" }), _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M19.1673 5.83333C19.1673 6.29357 18.7942 6.66667 18.334 6.66667H1.66732C1.20708 6.66667 0.833984 6.29357 0.833984 5.83333C0.833984 5.37309 1.20708 5 1.66732 5H18.334C18.7942 5 19.1673 5.3731 19.1673 5.83333Z", fill: "currentColor" }), _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M19.1673 14.1667C19.1673 14.627 18.7942 15 18.334 15H1.66732C1.20708 15 0.833984 14.627 0.833984 14.1667C0.833984 13.7065 1.20708 13.3334 1.66732 13.3334H18.334C18.7942 13.3334 19.1673 13.7065 19.1673 14.1667Z", fill: "currentColor" })] }), _jsx("defs", { children: _jsx("clipPath", { id: "clip0_4070_70030", children: _jsx("rect", { width: props.size || 18, height: props.size || 18, fill: "white" }) }) })] }));
|
|
3
|
+
export default CannedResponseIcon;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
interface ISvgProps {
|
|
2
|
+
size?: number;
|
|
3
|
+
className?: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const CannedResponseIcon = (props: ISvgProps) => (
|
|
7
|
+
<svg
|
|
8
|
+
width={props.size || 18}
|
|
9
|
+
height={props.size || 18}
|
|
10
|
+
viewBox={`${0} ${0} ${props.size || 18} ${props.size || 18}`}
|
|
11
|
+
fill="none"
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
className={props?.className}
|
|
14
|
+
>
|
|
15
|
+
<g clipPath="url(#clip0_4070_70030)">
|
|
16
|
+
<path
|
|
17
|
+
fillRule="evenodd"
|
|
18
|
+
clipRule="evenodd"
|
|
19
|
+
d="M6.66732 0.833374C7.12755 0.833374 7.50065 1.20647 7.50065 1.66671L5.00065 18.3334C5.00065 18.7936 4.62755 19.1667 4.16732 19.1667C3.70708 19.1667 3.33398 18.7936 3.33398 18.3334L5.83398 1.66671C5.83398 1.20647 6.20708 0.833374 6.66732 0.833374Z"
|
|
20
|
+
fill="currentColor"
|
|
21
|
+
/>
|
|
22
|
+
<path
|
|
23
|
+
fillRule="evenodd"
|
|
24
|
+
clipRule="evenodd"
|
|
25
|
+
d="M14.9993 0.833374C15.4596 0.833374 15.8327 1.20647 15.8327 1.66671L13.3327 18.3334C13.3327 18.7936 12.9596 19.1667 12.4993 19.1667C12.0391 19.1667 11.666 18.7936 11.666 18.3334L14.166 1.66671C14.166 1.20647 14.5391 0.833374 14.9993 0.833374Z"
|
|
26
|
+
fill="currentColor"
|
|
27
|
+
/>
|
|
28
|
+
<path
|
|
29
|
+
fillRule="evenodd"
|
|
30
|
+
clipRule="evenodd"
|
|
31
|
+
d="M19.1673 5.83333C19.1673 6.29357 18.7942 6.66667 18.334 6.66667H1.66732C1.20708 6.66667 0.833984 6.29357 0.833984 5.83333C0.833984 5.37309 1.20708 5 1.66732 5H18.334C18.7942 5 19.1673 5.3731 19.1673 5.83333Z"
|
|
32
|
+
fill="currentColor"
|
|
33
|
+
/>
|
|
34
|
+
<path
|
|
35
|
+
fillRule="evenodd"
|
|
36
|
+
clipRule="evenodd"
|
|
37
|
+
d="M19.1673 14.1667C19.1673 14.627 18.7942 15 18.334 15H1.66732C1.20708 15 0.833984 14.627 0.833984 14.1667C0.833984 13.7065 1.20708 13.3334 1.66732 13.3334H18.334C18.7942 13.3334 19.1673 13.7065 19.1673 14.1667Z"
|
|
38
|
+
fill="currentColor"
|
|
39
|
+
/>
|
|
40
|
+
</g>
|
|
41
|
+
<defs>
|
|
42
|
+
<clipPath id="clip0_4070_70030">
|
|
43
|
+
<rect width={props.size || 18} height={props.size || 18} fill="white" />
|
|
44
|
+
</clipPath>
|
|
45
|
+
</defs>
|
|
46
|
+
</svg>
|
|
47
|
+
);
|
|
48
|
+
export default CannedResponseIcon;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/assets/svg/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/assets/svg/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
|
package/dist/assets/svg/index.js
CHANGED
package/dist/assets/svg/index.ts
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface ICannedResponseBodyProps {
|
|
2
|
+
search?: string;
|
|
3
|
+
onSelectCannedResponse?: (content: string) => void;
|
|
4
|
+
cannedQuery?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const CannedResponseBody: (props: ICannedResponseBodyProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default CannedResponseBody;
|
|
8
|
+
//# sourceMappingURL=CannedResponseBody.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CannedResponseBody.d.ts","sourceRoot":"","sources":["../../../src/components/cannedResponse/CannedResponseBody.tsx"],"names":[],"mappings":"AAaA,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,QAAA,MAAM,kBAAkB,GAAI,OAAO,wBAAwB,4CA6J1D,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Empty, Segmented, Spin } from "antd";
|
|
3
|
+
import { useFetchMyTeams } from "../../hooks/team/useFetchMyTeam";
|
|
4
|
+
import { useTranslation } from "react-i18next";
|
|
5
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
6
|
+
import { CannedResponseVisibleScope } from "../../types/chat";
|
|
7
|
+
import TeamItem from "./team/TeamItem";
|
|
8
|
+
import { useFetchCannedResponse } from "../../hooks/cannedResponse/useFetchCannedResponse";
|
|
9
|
+
import InfiniteScroll from "react-infinite-scroll-component";
|
|
10
|
+
import { Icon } from "../icon";
|
|
11
|
+
import { sanitizeHtml } from "../../utils/common";
|
|
12
|
+
import { useDebounce } from "ahooks";
|
|
13
|
+
const CannedResponseBody = (props) => {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
const { search, onSelectCannedResponse, cannedQuery } = props;
|
|
16
|
+
const { t } = useTranslation();
|
|
17
|
+
const { data: myTeams, isLoading: isLoadingTeams } = useFetchMyTeams();
|
|
18
|
+
const [scope, setScope] = useState(CannedResponseVisibleScope.TEAM);
|
|
19
|
+
const [selectedTeamId, setSelectedTeamId] = useState(undefined);
|
|
20
|
+
const [selectedCategoryId, setSelectedCategoryId] = useState(undefined);
|
|
21
|
+
const cannedQueryDebounced = useDebounce(cannedQuery, { wait: 300 });
|
|
22
|
+
const { dataFlatten: cannedResponses, fetchNextPage, hasNextPage, } = useFetchCannedResponse({
|
|
23
|
+
visibilityScope: scope,
|
|
24
|
+
teamId: selectedTeamId,
|
|
25
|
+
categoryId: selectedCategoryId,
|
|
26
|
+
shortcut: search || cannedQueryDebounced || "",
|
|
27
|
+
});
|
|
28
|
+
const options = useMemo(() => {
|
|
29
|
+
return [
|
|
30
|
+
{ label: t("team"), value: CannedResponseVisibleScope.TEAM },
|
|
31
|
+
{ label: t("personal"), value: CannedResponseVisibleScope.PRIVATE },
|
|
32
|
+
];
|
|
33
|
+
}, [t]);
|
|
34
|
+
const onSelectCategory = useCallback((teamId, categoryId) => {
|
|
35
|
+
setSelectedTeamId(teamId);
|
|
36
|
+
setSelectedCategoryId(categoryId);
|
|
37
|
+
}, []);
|
|
38
|
+
const renderTeamItem = useCallback((team, index) => {
|
|
39
|
+
return (_jsx(TeamItem, { team: team, onSelectCategory: onSelectCategory, selectedTeamId: selectedTeamId, selectedCategoryId: selectedCategoryId, defaultOpen: index === 0 }, team === null || team === void 0 ? void 0 : team.teamId));
|
|
40
|
+
}, [onSelectCategory, selectedTeamId, selectedCategoryId]);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (!isLoadingTeams && myTeams && myTeams.length > 0) {
|
|
43
|
+
setSelectedTeamId(myTeams[0].teamId);
|
|
44
|
+
}
|
|
45
|
+
}, [isLoadingTeams, myTeams]);
|
|
46
|
+
return (_jsxs("div", { className: "flex flex-1 flex-row h-[400px]", children: [_jsxs("div", { className: "w-[170px] p-2 border-r border-gray-200", children: [_jsx(Segmented, { options: options, block: true, size: "small", value: scope, onChange: setScope }), _jsx("div", { className: "overflow-y-auto h-full", children: scope === CannedResponseVisibleScope.TEAM && (_jsx("div", { className: "mt-1 flex flex-col", children: (_a = myTeams === null || myTeams === void 0 ? void 0 : myTeams.map) === null || _a === void 0 ? void 0 : _a.call(myTeams, (team, index) => renderTeamItem(team, index)) })) })] }), _jsxs("div", { id: "scrollableCannedDiv", className: "flex flex-col flex-1 h-full overflow-y-auto", children: [!!cannedQuery && !search && (_jsx("div", { className: "px-3 py-2 border-b border-gray-200", children: _jsxs("span", { className: "text-sm text-gray-500", children: [t("canned_response_quick_search_placeholder"), _jsx("span", { className: "text-blue-600", children: ` #${cannedQuery}` })] }) })), _jsx(InfiniteScroll, { dataLength: (cannedResponses === null || cannedResponses === void 0 ? void 0 : cannedResponses.length) || 0, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableCannedDiv", children: (cannedResponses === null || cannedResponses === void 0 ? void 0 : cannedResponses.length) === 0 ? (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Empty, { image: _jsx(Icon, { icon: "chat-square-b", size: 80, className: "text-gray-300" }), description: t("no_canned_response") }) })) : ((_b = cannedResponses === null || cannedResponses === void 0 ? void 0 : cannedResponses.map) === null || _b === void 0 ? void 0 : _b.call(cannedResponses, (canned) => {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
const htmlContent = (canned === null || canned === void 0 ? void 0 : canned.content) || "";
|
|
49
|
+
// 🔒 Sanitize HTML to prevent XSS attacks
|
|
50
|
+
const sanitizedContent = sanitizeHtml(htmlContent);
|
|
51
|
+
return (_jsxs("div", { className: "flex flex-col flex-1 px-3 py-2 cursor-pointer hover:bg-blue-100 w-full border-b border-gray-200", onClick: () => onSelectCannedResponse === null || onSelectCannedResponse === void 0 ? void 0 : onSelectCannedResponse(sanitizedContent), children: [_jsxs("span", { className: "text-xs truncate text-gray-500", children: [`${((_a = canned === null || canned === void 0 ? void 0 : canned.category) === null || _a === void 0 ? void 0 : _a.name)
|
|
52
|
+
? `${(_b = canned === null || canned === void 0 ? void 0 : canned.category) === null || _b === void 0 ? void 0 : _b.name} / `
|
|
53
|
+
: ""}`, _jsx("span", { className: "text-black", children: `${(canned === null || canned === void 0 ? void 0 : canned.name) || ""} ` }), _jsx("span", { children: "/" }), _jsx("span", { className: "text-blue-500", children: ` #${(canned === null || canned === void 0 ? void 0 : canned.shortcut) || ""}` })] }), _jsx("div", { dangerouslySetInnerHTML: {
|
|
54
|
+
__html: sanitizedContent,
|
|
55
|
+
}, className: "text-sm mt-1" })] }, canned === null || canned === void 0 ? void 0 : canned.id));
|
|
56
|
+
})) })] })] }));
|
|
57
|
+
};
|
|
58
|
+
export default CannedResponseBody;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface ICannedResponseFooterProps {
|
|
2
|
+
openCreateCannedModal?: () => void;
|
|
3
|
+
}
|
|
4
|
+
declare const CannedResponseFooter: ({ openCreateCannedModal, }: ICannedResponseFooterProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export default CannedResponseFooter;
|
|
6
|
+
//# sourceMappingURL=CannedResponseFooter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CannedResponseFooter.d.ts","sourceRoot":"","sources":["../../../src/components/cannedResponse/CannedResponseFooter.tsx"],"names":[],"mappings":"AAGA,UAAU,0BAA0B;IAClC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAED,QAAA,MAAM,oBAAoB,GAAI,4BAE3B,0BAA0B,4CAgB5B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation } from "react-i18next";
|
|
3
|
+
import { Icon } from "../icon";
|
|
4
|
+
const CannedResponseFooter = ({ openCreateCannedModal, }) => {
|
|
5
|
+
const { t } = useTranslation();
|
|
6
|
+
return (_jsx("div", { className: "flex items-center justify-end border-t border-gray-200 p-2", children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1", onClick: openCreateCannedModal, children: [_jsx(Icon, { icon: "plus-circle-o", size: 16, className: "text-blue-500" }), _jsx("span", { className: "text-sm text-blue-500", children: t("add_canned_response") })] }) }));
|
|
7
|
+
};
|
|
8
|
+
export default CannedResponseFooter;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface ICannedResponseHeaderProps {
|
|
2
|
+
onClose?: () => void;
|
|
3
|
+
search?: string;
|
|
4
|
+
setSearch?: (search: string) => void;
|
|
5
|
+
}
|
|
6
|
+
declare const CannedResponseHeader: (props: ICannedResponseHeaderProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default CannedResponseHeader;
|
|
8
|
+
//# sourceMappingURL=CannedResponseHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CannedResponseHeader.d.ts","sourceRoot":"","sources":["../../../src/components/cannedResponse/CannedResponseHeader.tsx"],"names":[],"mappings":"AAKA,UAAU,0BAA0B;IAClC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,QAAA,MAAM,oBAAoB,GAAI,OAAO,0BAA0B,4CA+B9D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation } from "react-i18next";
|
|
3
|
+
import CannedResponseIcon from "../../assets/svg/cannedResponse";
|
|
4
|
+
import { Button, Input } from "antd";
|
|
5
|
+
import { Icon } from "../icon";
|
|
6
|
+
const CannedResponseHeader = (props) => {
|
|
7
|
+
const { onClose, search, setSearch } = props;
|
|
8
|
+
const { t } = useTranslation();
|
|
9
|
+
return (_jsxs("div", { className: "px-3 py-2 flex flex-row items-center gap-2 border-b border-gray-200", children: [_jsxs("div", { className: "flex flex-row items-center gap-2", children: [_jsx(CannedResponseIcon, { size: 20, className: "text-blue-500" }), _jsx("span", { className: "text-base font-medium", children: t("canned_responses") })] }), _jsxs("div", { className: "flex flex-1 flex-row items-center justify-end gap-2", children: [_jsx(Input, { size: "large", placeholder: t("search"), prefix: _jsx(Icon, { icon: "search-o", size: 20, className: "text-gray-500" }), style: { width: 260 }, className: "text-sm", value: search, onChange: (e) => setSearch === null || setSearch === void 0 ? void 0 : setSearch(e.target.value) }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-o", size: 16 }) })] })] }));
|
|
10
|
+
};
|
|
11
|
+
export default CannedResponseHeader;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface ICannedResponseProps {
|
|
2
|
+
onClose?: () => void;
|
|
3
|
+
openCreateCannedModal?: () => void;
|
|
4
|
+
cannedQuery?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const CannedResponse: ({ onClose, openCreateCannedModal, cannedQuery, }: ICannedResponseProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default CannedResponse;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/cannedResponse/index.tsx"],"names":[],"mappings":"AASA,UAAU,oBAAoB;IAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,QAAA,MAAM,cAAc,GAAI,kDAIrB,oBAAoB,4CAgDtB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useDebounce } from "ahooks";
|
|
3
|
+
import CannedResponseBody from "./CannedResponseBody";
|
|
4
|
+
import CannedResponseHeader from "./CannedResponseHeader";
|
|
5
|
+
import { useCallback, useState } from "react";
|
|
6
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
7
|
+
import { $getRoot } from "lexical";
|
|
8
|
+
import { $generateNodesFromDOM } from "@lexical/html";
|
|
9
|
+
import CannedResponseFooter from "./CannedResponseFooter";
|
|
10
|
+
const CannedResponse = ({ onClose, openCreateCannedModal, cannedQuery = "", }) => {
|
|
11
|
+
const [editor] = useLexicalComposerContext();
|
|
12
|
+
const [search, setSearch] = useState("");
|
|
13
|
+
const debouncedSearch = useDebounce(search, {
|
|
14
|
+
wait: 300,
|
|
15
|
+
});
|
|
16
|
+
const onSelectCannedResponse = useCallback((content) => {
|
|
17
|
+
editor.update(() => {
|
|
18
|
+
const root = $getRoot();
|
|
19
|
+
// 1. Clear content cũ
|
|
20
|
+
root.clear();
|
|
21
|
+
// 2. Parse HTML -> DOM
|
|
22
|
+
const parser = new DOMParser();
|
|
23
|
+
const dom = parser.parseFromString(content, "text/html");
|
|
24
|
+
// 3. Convert DOM -> Lexical nodes
|
|
25
|
+
const nodes = $generateNodesFromDOM(editor, dom);
|
|
26
|
+
// 4. Append vào editor
|
|
27
|
+
root.append(...nodes);
|
|
28
|
+
// 5. Move cursor về cuối (optional nhưng nên có)
|
|
29
|
+
root.selectEnd();
|
|
30
|
+
});
|
|
31
|
+
}, [editor]);
|
|
32
|
+
return (_jsxs("div", { className: "w-[600px]", children: [_jsx(CannedResponseHeader, { onClose: onClose, search: search, setSearch: setSearch }), _jsx(CannedResponseBody, { search: debouncedSearch, onSelectCannedResponse: onSelectCannedResponse, cannedQuery: cannedQuery }), _jsx(CannedResponseFooter, { openCreateCannedModal: openCreateCannedModal })] }));
|
|
33
|
+
};
|
|
34
|
+
export default CannedResponse;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IMyTeamResponse } from "../../../types/dto";
|
|
2
|
+
interface TeamItemProps {
|
|
3
|
+
team: IMyTeamResponse;
|
|
4
|
+
onSelectCategory?: (teamId: string, categoryId?: string) => void;
|
|
5
|
+
selectedTeamId?: string;
|
|
6
|
+
selectedCategoryId?: string;
|
|
7
|
+
defaultOpen?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare const TeamItem: ({ team, onSelectCategory, selectedTeamId, selectedCategoryId, defaultOpen, }: TeamItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export default TeamItem;
|
|
11
|
+
//# sourceMappingURL=TeamItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TeamItem.d.ts","sourceRoot":"","sources":["../../../../src/components/cannedResponse/team/TeamItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAQrD,UAAU,aAAa;IACrB,IAAI,EAAE,eAAe,CAAC;IACtB,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,QAAA,MAAM,QAAQ,GAAI,8EAMf,aAAa,4CAiFf,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFetchCannedCategories } from "../../../hooks/cannedResponse/useFetchCannedCategories";
|
|
3
|
+
import { useBoolean } from "ahooks";
|
|
4
|
+
import { Icon } from "../../icon";
|
|
5
|
+
import clsx from "clsx";
|
|
6
|
+
import { useTranslation } from "react-i18next";
|
|
7
|
+
import { useCallback } from "react";
|
|
8
|
+
const TeamItem = ({ team, onSelectCategory, selectedTeamId, selectedCategoryId, defaultOpen = false, }) => {
|
|
9
|
+
const { t } = useTranslation();
|
|
10
|
+
const [isOpen, { toggle }] = useBoolean(defaultOpen);
|
|
11
|
+
const { data: categories } = useFetchCannedCategories(team.teamId, isOpen);
|
|
12
|
+
const onToggle = useCallback(() => {
|
|
13
|
+
if (!isOpen && !selectedTeamId && !!(team === null || team === void 0 ? void 0 : team.teamId)) {
|
|
14
|
+
onSelectCategory === null || onSelectCategory === void 0 ? void 0 : onSelectCategory(team === null || team === void 0 ? void 0 : team.teamId, undefined);
|
|
15
|
+
}
|
|
16
|
+
toggle();
|
|
17
|
+
}, [toggle, isOpen, onSelectCategory, team === null || team === void 0 ? void 0 : team.teamId, selectedTeamId]);
|
|
18
|
+
return (_jsxs("div", { className: "border-b border-gray-200", children: [_jsxs("div", { className: "flex items-center justify-between py-2 cursor-pointer", onClick: onToggle, children: [_jsx("span", { className: "text-sm font-medium truncate flex-1", children: (team === null || team === void 0 ? void 0 : team.name) || "" }), _jsx(Icon, { icon: isOpen ? "angle-up-b" : "angle-down-b", size: 16, className: clsx(!isOpen && "text-gray-500") })] }), isOpen && (_jsxs("div", { className: "mb-2", children: [_jsx("div", { className: clsx("px-3 py-1 cursor-pointer hover:bg-gray-100 rounded-md", selectedTeamId &&
|
|
19
|
+
selectedTeamId === (team === null || team === void 0 ? void 0 : team.teamId) &&
|
|
20
|
+
!selectedCategoryId &&
|
|
21
|
+
"bg-gray-100"), onClick: () => onSelectCategory === null || onSelectCategory === void 0 ? void 0 : onSelectCategory(team === null || team === void 0 ? void 0 : team.teamId, undefined), children: _jsx("span", { className: clsx("text-sm truncate", selectedTeamId === (team === null || team === void 0 ? void 0 : team.teamId) && !selectedCategoryId
|
|
22
|
+
? "font-medium text-blue-500"
|
|
23
|
+
: "text-gray-500"), children: t("all") }) }, `${team.teamId}-all`), categories === null || categories === void 0 ? void 0 : categories.map((category) => {
|
|
24
|
+
const isSelected = selectedTeamId &&
|
|
25
|
+
selectedCategoryId &&
|
|
26
|
+
selectedTeamId === (category === null || category === void 0 ? void 0 : category.teamId) &&
|
|
27
|
+
selectedCategoryId === (category === null || category === void 0 ? void 0 : category.id);
|
|
28
|
+
return (_jsx("div", { className: clsx("px-3 py-1 cursor-pointer hover:bg-gray-100 rounded-md", isSelected && "bg-gray-100"), onClick: () => onSelectCategory === null || onSelectCategory === void 0 ? void 0 : onSelectCategory(team === null || team === void 0 ? void 0 : team.teamId, category === null || category === void 0 ? void 0 : category.id), children: _jsx("span", { className: clsx("text-sm truncate", isSelected ? "font-medium text-blue-500" : "text-gray-500"), children: category === null || category === void 0 ? void 0 : category.name }) }, `${team.teamId}-${category.id}`));
|
|
29
|
+
})] }))] }));
|
|
30
|
+
};
|
|
31
|
+
export default TeamItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationBySessionItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/ConversationBySessionItem.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAQpD,UAAU,8BAA8B;IACtC,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAED,QAAA,MAAM,yBAAyB,GAAI,kBAEhC,8BAA8B,
|
|
1
|
+
{"version":3,"file":"ConversationBySessionItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/ConversationBySessionItem.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAQpD,UAAU,8BAA8B;IACtC,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAED,QAAA,MAAM,yBAAyB,GAAI,kBAEhC,8BAA8B,mDA2FhC,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
|
|
@@ -10,8 +10,12 @@ import { formatTimestamp, parseLatestMessage } from "../../utils/common";
|
|
|
10
10
|
const ConversationBySessionItem = ({ sessionItem, }) => {
|
|
11
11
|
var _a;
|
|
12
12
|
const { t } = useTranslation();
|
|
13
|
-
const
|
|
14
|
-
const isSelected = useConversationStore((state) => {
|
|
13
|
+
const user = useChatContext().user;
|
|
14
|
+
const isSelected = useConversationStore((state) => {
|
|
15
|
+
var _a;
|
|
16
|
+
return state.selectedConversationId ===
|
|
17
|
+
((_a = sessionItem === null || sessionItem === void 0 ? void 0 : sessionItem.conversation) === null || _a === void 0 ? void 0 : _a.conversationID);
|
|
18
|
+
});
|
|
15
19
|
const conversation = sessionItem === null || sessionItem === void 0 ? void 0 : sessionItem.conversation;
|
|
16
20
|
const router = useRouter();
|
|
17
21
|
const pathname = usePathname();
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MessageItem } from "@openim/wasm-client-sdk";
|
|
2
|
+
interface MediaPreviewIconProps {
|
|
3
|
+
message?: MessageItem;
|
|
4
|
+
}
|
|
5
|
+
declare const MediaPreviewIcon: ({ message }: MediaPreviewIconProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
export default MediaPreviewIcon;
|
|
7
|
+
//# sourceMappingURL=MediaPreviewIcon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaPreviewIcon.d.ts","sourceRoot":"","sources":["../../../src/components/message/MediaPreviewIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AAInE,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,QAAA,MAAM,gBAAgB,GAAI,aAAa,qBAAqB,mDA8B3D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MessageType } from "@openim/wasm-client-sdk";
|
|
3
|
+
import { Image } from "antd";
|
|
4
|
+
import { documentIcon } from "../../assets/svg";
|
|
5
|
+
const MediaPreviewIcon = ({ message }) => {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
if (!message) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
if (message.contentType === MessageType.FileMessage) {
|
|
11
|
+
return _jsx("div", { children: documentIcon });
|
|
12
|
+
}
|
|
13
|
+
if (message.contentType === MessageType.PictureMessage) {
|
|
14
|
+
const imageUrl = ((_a = message.pictureElem.sourcePicture) === null || _a === void 0 ? void 0 : _a.url) ||
|
|
15
|
+
((_b = message.pictureElem.snapshotPicture) === null || _b === void 0 ? void 0 : _b.url);
|
|
16
|
+
return (_jsx("div", { className: "w-10 h-10", children: _jsx(Image, { rootClassName: "message-image cursor-pointer", className: "rounded-md", src: imageUrl }) }));
|
|
17
|
+
}
|
|
18
|
+
if (message.contentType === MessageType.VideoMessage) {
|
|
19
|
+
const videoUrl = message.videoElem.videoUrl;
|
|
20
|
+
return (_jsx("div", { className: "flex flex-col justify-center items-center w-10 h-10 bg-black rounded-md", children: _jsx("video", { src: videoUrl, controls: false, autoPlay: false, muted: true }) }));
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
export default MediaPreviewIcon;
|
|
@@ -122,6 +122,6 @@ const MessageHeader = ({ onClose, currentSession }) => {
|
|
|
122
122
|
setCurrentSessionStatus(currentSession.status);
|
|
123
123
|
}
|
|
124
124
|
}, [currentSession]);
|
|
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: "
|
|
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: t("member_count", { count: 2 }) })] }), _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 }) }))] })] }));
|
|
126
126
|
};
|
|
127
127
|
export default MessageHeader;
|
|
@@ -3,6 +3,7 @@ interface MessageListProps {
|
|
|
3
3
|
searchClientMsgID?: string;
|
|
4
4
|
className?: string;
|
|
5
5
|
onClose?: () => void;
|
|
6
|
+
openCreateCannedModal?: () => void;
|
|
6
7
|
}
|
|
7
8
|
declare const MessageList: (props: MessageListProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
9
|
export default MessageList;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AAyBA,UAAU,gBAAgB;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CAiT3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useMessage } from "../../hooks/message/useMessage";
|
|
4
|
-
import { Empty, Spin } from "antd";
|
|
5
|
-
import { useEffect, useMemo, useRef } from "react";
|
|
4
|
+
import { Empty, Modal, Spin } from "antd";
|
|
5
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
import dayjs from "dayjs";
|
|
7
7
|
import isToday from "dayjs/plugin/isToday";
|
|
8
8
|
import emitter from "../../utils/events";
|
|
@@ -14,26 +14,50 @@ import { images } from "../../constants/images";
|
|
|
14
14
|
import { useTranslation } from "react-i18next";
|
|
15
15
|
import useConversationStore from "../../store/conversation";
|
|
16
16
|
import { isNumber } from "lodash";
|
|
17
|
-
import { useDebounceFn } from "ahooks";
|
|
17
|
+
import { useBoolean, useDebounceFn } from "ahooks";
|
|
18
18
|
import { MSG_ITEM_CONTENT_PREFIX, MSG_ITEM_PREFIX } from "../../constants";
|
|
19
19
|
import { markConversationMessageAsRead } from "../../hooks/conversation/useConversation";
|
|
20
20
|
import { useChatContext } from "../../context/ChatContext";
|
|
21
21
|
import { useGetSession } from "../../hooks/session/useGetSession";
|
|
22
|
+
import { useRevokeMessage } from "../../hooks/message/useRevokeMessage";
|
|
22
23
|
dayjs.extend(isToday);
|
|
23
24
|
const BOTTOM_THRESHOLD = -5;
|
|
24
25
|
const MessageList = (props) => {
|
|
25
26
|
var _a;
|
|
26
27
|
const { t } = useTranslation();
|
|
27
28
|
const { user } = useChatContext();
|
|
28
|
-
const { onClose, conversationId, searchClientMsgID } = props;
|
|
29
|
+
const { onClose, conversationId, searchClientMsgID, openCreateCannedModal } = props;
|
|
29
30
|
const scrollRef = useRef(null);
|
|
30
31
|
const { getMoreOldMessages, moreOldLoading, loadState, getMoreNewMessages, moreNewLoading, latestLoadState, } = useMessage(conversationId, searchClientMsgID);
|
|
31
32
|
const conversationData = useConversationStore((state) => state.conversationData);
|
|
33
|
+
const setQuotedMessage = useConversationStore((state) => state.setQuotedMessage);
|
|
34
|
+
const setSearchClientMsgID = useConversationStore((state) => state.setSearchClientMsgID);
|
|
32
35
|
const { dataFlatten: sessions, refetch: refetchSession } = useGetSession({
|
|
33
36
|
filter: {
|
|
34
37
|
conversationIds: !!conversationId ? [conversationId] : [],
|
|
35
38
|
},
|
|
36
39
|
});
|
|
40
|
+
const [openMenuId, setOpenMenuId] = useState(null);
|
|
41
|
+
const [selectedItem, setSelectedItem] = useState(null);
|
|
42
|
+
const [showConfirmRevoke, { setTrue: openConfirmRevoke, setFalse: closeConfirmRevoke },] = useBoolean(false);
|
|
43
|
+
const { revokeMessage, loading: isRevoking } = useRevokeMessage();
|
|
44
|
+
const handleOpenRevoke = useCallback((clientMsgID) => {
|
|
45
|
+
setSelectedItem(clientMsgID);
|
|
46
|
+
openConfirmRevoke();
|
|
47
|
+
}, [openConfirmRevoke]);
|
|
48
|
+
const handleCloseRevoke = useCallback(() => {
|
|
49
|
+
setSelectedItem(null);
|
|
50
|
+
closeConfirmRevoke();
|
|
51
|
+
}, [closeConfirmRevoke]);
|
|
52
|
+
const onRevokeMessage = useCallback(async () => {
|
|
53
|
+
await revokeMessage((conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID) || "", selectedItem || "");
|
|
54
|
+
handleCloseRevoke();
|
|
55
|
+
}, [
|
|
56
|
+
conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID,
|
|
57
|
+
selectedItem,
|
|
58
|
+
revokeMessage,
|
|
59
|
+
handleCloseRevoke,
|
|
60
|
+
]);
|
|
37
61
|
const currentSession = useMemo(() => {
|
|
38
62
|
return sessions === null || sessions === void 0 ? void 0 : sessions.find((session) => session.conversationId === conversationId);
|
|
39
63
|
}, [sessions, conversationId]);
|
|
@@ -84,6 +108,15 @@ const MessageList = (props) => {
|
|
|
84
108
|
}, 500);
|
|
85
109
|
}, 200);
|
|
86
110
|
};
|
|
111
|
+
const onPressQuoteMessage = useCallback((clientMsgID) => {
|
|
112
|
+
const hasMessage = loadState.messageList.some((msg) => msg.clientMsgID === clientMsgID);
|
|
113
|
+
if (hasMessage) {
|
|
114
|
+
scrollToMessage(clientMsgID);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
setSearchClientMsgID(clientMsgID);
|
|
118
|
+
}
|
|
119
|
+
}, [scrollToMessage, loadState.messageList, setSearchClientMsgID]);
|
|
87
120
|
const loadMoreOldMessage = () => {
|
|
88
121
|
if (!loadState.hasMoreOld || moreOldLoading)
|
|
89
122
|
return;
|
|
@@ -123,6 +156,16 @@ const MessageList = (props) => {
|
|
|
123
156
|
loadState.initLoading,
|
|
124
157
|
handleMarkConversationMessageAsRead,
|
|
125
158
|
]);
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
if (!openMenuId)
|
|
161
|
+
return;
|
|
162
|
+
const scrollContainer = scrollRef.current;
|
|
163
|
+
if (!scrollContainer)
|
|
164
|
+
return;
|
|
165
|
+
const close = () => setOpenMenuId(null);
|
|
166
|
+
scrollContainer.addEventListener("scroll", close);
|
|
167
|
+
return () => scrollContainer.removeEventListener("scroll", close);
|
|
168
|
+
}, [openMenuId]);
|
|
126
169
|
if (!conversationData) {
|
|
127
170
|
return (_jsx("div", { className: "flex flex-1 items-center justify-center h-full", children: _jsx(Empty, { description: t("no_conversation_data") }) }));
|
|
128
171
|
}
|
|
@@ -142,13 +185,13 @@ const MessageList = (props) => {
|
|
|
142
185
|
display: "flex",
|
|
143
186
|
flexDirection: "column-reverse",
|
|
144
187
|
minWidth: 0,
|
|
145
|
-
width: "100%"
|
|
188
|
+
width: "100%",
|
|
146
189
|
}, inverse: true, hasMore: loadState.hasMoreOld, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableMessagesDiv", onScroll: (e) => {
|
|
147
190
|
const target = e.target;
|
|
148
191
|
if (target.scrollTop > BOTTOM_THRESHOLD) {
|
|
149
192
|
handleMarkConversationMessageAsRead();
|
|
150
193
|
loadMoreNewMessage();
|
|
151
194
|
}
|
|
152
|
-
}, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array }, message.clientMsgID))) }) }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), _jsx(MessageFooter, { currentSession: currentSession })] }));
|
|
195
|
+
}, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array, contextMenuOpen: openMenuId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenMenuId(open ? message.clientMsgID : null), onRevokeMessage: handleOpenRevoke, onQuoteMessage: setQuotedMessage, onPressQuoteMessage: onPressQuoteMessage }, message.clientMsgID))) }) }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), _jsx(MessageFooter, { currentSession: currentSession, openCreateCannedModal: openCreateCannedModal }), _jsx(Modal, { centered: true, open: showConfirmRevoke, onOk: onRevokeMessage, onCancel: handleCloseRevoke, title: t("revoke_message_confirm_title"), okText: t("revoke"), cancelText: t("cancel"), okType: "danger", confirmLoading: isRevoking, getContainer: false, forceRender: true, children: _jsx("p", { children: t("revoke_message_confirm_message") }) })] }));
|
|
153
196
|
};
|
|
154
197
|
export default MessageList;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionBar.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/ActionBar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ActionBar.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/ActionBar.tsx"],"names":[],"mappings":"AAsBA,QAAA,MAAM,SAAS,+CA0Gd,CAAC;AAEF,eAAe,SAAS,CAAC"}
|