@anker-in/campaign-ui 0.3.2 → 0.3.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/cjs/components/LiveChatWidget/LiveChatWidget.d.ts +21 -1
- package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js +1 -1
- package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/api/chat.d.ts +23 -2
- package/dist/cjs/components/LiveChatWidget/api/chat.js +2 -2
- package/dist/cjs/components/LiveChatWidget/api/chat.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/ChatHeader.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/ChatHeader.js.map +2 -2
- package/dist/cjs/components/LiveChatWidget/components/ChatInput.d.ts +5 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatInput.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/ChatInput.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/ChatMessage.js +2 -2
- package/dist/cjs/components/LiveChatWidget/components/ChatMessage.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/ChatWindow.d.ts +5 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatWindow.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/ChatWindow.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/ComplianceDialog.d.ts +51 -0
- package/dist/cjs/components/LiveChatWidget/components/ComplianceDialog.js +33 -0
- package/dist/cjs/components/LiveChatWidget/components/ComplianceDialog.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/CartCard.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/CartCard.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ErrorBlock.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ErrorBlock.js.map +2 -2
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/FAQList.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/FAQList.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PolicyBlock.js +2 -2
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PolicyBlock.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.d.ts +17 -24
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.js +1 -4
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.d.ts +7 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductList.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductList.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.d.ts +4 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/QuickReplies.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/QuickReplies.js.map +2 -2
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent.js +1 -1
- package/dist/cjs/components/LiveChatWidget/components/MessageContent.js.map +2 -2
- package/dist/cjs/components/LiveChatWidget/components/MessageList.js +2 -2
- package/dist/cjs/components/LiveChatWidget/components/MessageList.js.map +2 -2
- package/dist/cjs/components/LiveChatWidget/constants.d.ts +5 -0
- package/dist/cjs/components/LiveChatWidget/constants.js +1 -1
- package/dist/cjs/components/LiveChatWidget/constants.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.d.ts +9 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.js +1 -1
- package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.d.ts +35 -2
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js +1 -1
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/index.d.ts +1 -1
- package/dist/cjs/components/LiveChatWidget/index.js +1 -1
- package/dist/cjs/components/LiveChatWidget/index.js.map +2 -2
- package/dist/cjs/components/LiveChatWidget/types.d.ts +212 -3
- package/dist/cjs/components/LiveChatWidget/types.js +1 -1
- package/dist/cjs/components/LiveChatWidget/types.js.map +1 -1
- package/dist/cjs/components/LiveChatWidget/utils/fetcher.d.ts +42 -0
- package/dist/cjs/components/LiveChatWidget/utils/fetcher.js +2 -0
- package/dist/cjs/components/LiveChatWidget/utils/fetcher.js.map +7 -0
- package/dist/cjs/components/chat/markdown.js +1 -1
- package/dist/cjs/components/chat/markdown.js.map +2 -2
- package/dist/cjs/components/credits/creditsBanner/index.js +2 -2
- package/dist/cjs/components/credits/creditsBanner/index.js.map +2 -2
- package/dist/cjs/components/index.d.ts +2 -0
- package/dist/cjs/components/index.js +1 -1
- package/dist/cjs/components/index.js.map +3 -3
- package/dist/cjs/stories/LiveChatWidget.stories.d.ts +1 -79
- package/dist/cjs/stories/LiveChatWidget.stories.js +8 -47
- package/dist/cjs/stories/LiveChatWidget.stories.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/LiveChatWidget.d.ts +21 -1
- package/dist/esm/components/LiveChatWidget/LiveChatWidget.js +1 -1
- package/dist/esm/components/LiveChatWidget/LiveChatWidget.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/api/chat.d.ts +23 -2
- package/dist/esm/components/LiveChatWidget/api/chat.js +2 -2
- package/dist/esm/components/LiveChatWidget/api/chat.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/ChatHeader.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/ChatHeader.js.map +2 -2
- package/dist/esm/components/LiveChatWidget/components/ChatInput.d.ts +5 -0
- package/dist/esm/components/LiveChatWidget/components/ChatInput.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/ChatInput.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/ChatMessage.js +2 -2
- package/dist/esm/components/LiveChatWidget/components/ChatMessage.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/ChatWindow.d.ts +5 -0
- package/dist/esm/components/LiveChatWidget/components/ChatWindow.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/ChatWindow.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/ComplianceDialog.d.ts +51 -0
- package/dist/esm/components/LiveChatWidget/components/ComplianceDialog.js +33 -0
- package/dist/esm/components/LiveChatWidget/components/ComplianceDialog.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/CartCard.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/CartCard.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ErrorBlock.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ErrorBlock.js.map +2 -2
- package/dist/esm/components/LiveChatWidget/components/MessageContent/FAQList.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/FAQList.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PolicyBlock.js +2 -2
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PolicyBlock.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.d.ts +17 -24
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.js +1 -4
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.d.ts +7 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductList.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductList.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.d.ts +4 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent/QuickReplies.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/QuickReplies.js.map +2 -2
- package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent.js +1 -1
- package/dist/esm/components/LiveChatWidget/components/MessageContent.js.map +2 -2
- package/dist/esm/components/LiveChatWidget/components/MessageList.js +2 -2
- package/dist/esm/components/LiveChatWidget/components/MessageList.js.map +2 -2
- package/dist/esm/components/LiveChatWidget/constants.d.ts +5 -0
- package/dist/esm/components/LiveChatWidget/constants.js +1 -1
- package/dist/esm/components/LiveChatWidget/constants.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.d.ts +9 -0
- package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.js +1 -1
- package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.d.ts +35 -2
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.js +1 -1
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/index.d.ts +1 -1
- package/dist/esm/components/LiveChatWidget/index.js +1 -1
- package/dist/esm/components/LiveChatWidget/index.js.map +2 -2
- package/dist/esm/components/LiveChatWidget/types.d.ts +212 -3
- package/dist/esm/components/LiveChatWidget/utils/fetcher.d.ts +42 -0
- package/dist/esm/components/LiveChatWidget/utils/fetcher.js +2 -0
- package/dist/esm/components/LiveChatWidget/utils/fetcher.js.map +7 -0
- package/dist/esm/components/chat/markdown.js +1 -1
- package/dist/esm/components/chat/markdown.js.map +2 -2
- package/dist/esm/components/credits/creditsBanner/index.js +2 -2
- package/dist/esm/components/credits/creditsBanner/index.js.map +2 -2
- package/dist/esm/components/index.d.ts +2 -0
- package/dist/esm/components/index.js +1 -1
- package/dist/esm/components/index.js.map +3 -3
- package/dist/esm/stories/LiveChatWidget.stories.d.ts +1 -79
- package/dist/esm/stories/LiveChatWidget.stories.js +8 -47
- package/dist/esm/stories/LiveChatWidget.stories.js.map +3 -3
- package/dist/index.d.mts +1305 -0
- package/dist/index.d.ts +1305 -0
- package/dist/index.js +26656 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +26641 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +8 -1
- package/src/components/LiveChatWidget/LiveChatWidget.tsx +887 -0
- package/src/components/LiveChatWidget/api/chat.ts +175 -0
- package/src/components/LiveChatWidget/components/ChatBubble.tsx +152 -0
- package/src/components/LiveChatWidget/components/ChatHeader.tsx +150 -0
- package/src/components/LiveChatWidget/components/ChatInput.tsx +253 -0
- package/src/components/LiveChatWidget/components/ChatMessage.tsx +190 -0
- package/src/components/LiveChatWidget/components/ChatWindow.tsx +363 -0
- package/src/components/LiveChatWidget/components/ComplianceDialog.tsx +216 -0
- package/src/components/LiveChatWidget/components/MessageContent/CartCard.tsx +202 -0
- package/src/components/LiveChatWidget/components/MessageContent/ErrorBlock.tsx +75 -0
- package/src/components/LiveChatWidget/components/MessageContent/FAQList.tsx +128 -0
- package/src/components/LiveChatWidget/components/MessageContent/PolicyBlock.tsx +152 -0
- package/src/components/LiveChatWidget/components/MessageContent/ProductCard.tsx +227 -0
- package/src/components/LiveChatWidget/components/MessageContent/ProductComparison.tsx +377 -0
- package/src/components/LiveChatWidget/components/MessageContent/ProductList.tsx +293 -0
- package/src/components/LiveChatWidget/components/MessageContent/PromotionList.tsx +170 -0
- package/src/components/LiveChatWidget/components/MessageContent/QuickReplies.tsx +91 -0
- package/src/components/LiveChatWidget/components/MessageContent/TextBlock.tsx +110 -0
- package/src/components/LiveChatWidget/components/MessageContent/ThinkingBlock.tsx +53 -0
- package/src/components/LiveChatWidget/components/MessageContent/index.ts +16 -0
- package/src/components/LiveChatWidget/components/MessageContent.tsx +113 -0
- package/src/components/LiveChatWidget/components/MessageList.tsx +261 -0
- package/src/components/LiveChatWidget/components/ScrollAnchor.tsx +75 -0
- package/src/components/LiveChatWidget/constants.ts +36 -0
- package/src/components/LiveChatWidget/hooks/useChatAPI.ts +146 -0
- package/src/components/LiveChatWidget/hooks/useChatState.ts +1090 -0
- package/src/components/LiveChatWidget/hooks/useSession.ts +123 -0
- package/src/components/LiveChatWidget/index.tsx +63 -0
- package/src/components/LiveChatWidget/types.ts +1011 -0
- package/src/components/LiveChatWidget/utils/cartTransformers.ts +72 -0
- package/src/components/LiveChatWidget/utils/fetcher.ts +131 -0
- package/src/components/LiveChatWidget/utils/messageRenderers.ts +120 -0
- package/src/components/LiveChatWidget/utils/productTransformers.ts +149 -0
- package/src/components/LiveChatWidget/utils/userId.ts +140 -0
- package/src/components/LiveChatWidget/utils/validation.ts +99 -0
- package/src/components/chat/markdown.tsx +1 -1
- package/src/components/credits/creditsBanner/index.tsx +5 -5
- package/src/components/index.ts +23 -0
- package/src/stories/LiveChatWidget.stories.tsx +322 -0
- package/src/styles/livechat.css +317 -0
- package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.d.ts +0 -7
- package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.js +0 -2
- package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.js.map +0 -7
- package/dist/cjs/components/credits/context/utils/atobID.d.ts +0 -1
- package/dist/cjs/components/credits/context/utils/atobID.js +0 -2
- package/dist/cjs/components/credits/context/utils/atobID.js.map +0 -7
- package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.d.ts +0 -5
- package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.js +0 -2
- package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.js.map +0 -7
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.d.ts +0 -8
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.js +0 -2
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.js.map +0 -7
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.d.ts +0 -9
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js +0 -2
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js.map +0 -7
- package/dist/cjs/components/credits/context/utils/variantGetCoupon.d.ts +0 -6
- package/dist/cjs/components/credits/context/utils/variantGetCoupon.js +0 -2
- package/dist/cjs/components/credits/context/utils/variantGetCoupon.js.map +0 -7
- package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.d.ts +0 -7
- package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.js +0 -2
- package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.js.map +0 -7
- package/dist/esm/components/credits/context/utils/atobID.d.ts +0 -1
- package/dist/esm/components/credits/context/utils/atobID.js +0 -2
- package/dist/esm/components/credits/context/utils/atobID.js.map +0 -7
- package/dist/esm/components/credits/context/utils/functionDiscountCalculate.d.ts +0 -5
- package/dist/esm/components/credits/context/utils/functionDiscountCalculate.js +0 -2
- package/dist/esm/components/credits/context/utils/functionDiscountCalculate.js.map +0 -7
- package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.d.ts +0 -8
- package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.js +0 -2
- package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.js.map +0 -7
- package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.d.ts +0 -9
- package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js +0 -2
- package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js.map +0 -7
- package/dist/esm/components/credits/context/utils/variantGetCoupon.d.ts +0 -6
- package/dist/esm/components/credits/context/utils/variantGetCoupon.js +0 -2
- package/dist/esm/components/credits/context/utils/variantGetCoupon.js.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/LiveChatWidget/components/MessageContent/PromotionList.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u7EC4\u4EF6\n * \u663E\u793A\u5F53\u524D\u8FDB\u884C\u4E2D\u7684\u4FC3\u9500\u6D3B\u52A8\u4FE1\u606F\n * \u57FA\u4E8E\u540E\u7AEF\u6570\u636E\u7ED3\u6784\u89C4\u8303\uFF1Apromotion_list\n */\n\nimport React from 'react'\nimport type { MessageRenderer } from '../../types'\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u6570\u636E\u7ED3\u6784\n */\nexport interface PromotionItem {\n id: string // \u6D3B\u52A8 ID\n title: string // \u6D3B\u52A8\u6807\u9898\n subtitle?: string // \u526F\u6807\u9898\uFF08\u5982 \"Up to 30% off\"\uFF09\n description?: string // \u6D3B\u52A8\u63CF\u8FF0\n banner_url?: string // Banner \u56FE\u7247 URL\n url?: string // \u6D3B\u52A8\u8BE6\u60C5\u9875 URL\n time_range: {\n start: string // \u5F00\u59CB\u65F6\u95F4 (ISO 8601)\n end?: string | null // \u7ED3\u675F\u65F6\u95F4\uFF0Cnull \u8868\u793A\u65E0\u7ED3\u675F\u65E5\u671F\n is_active: boolean // \u662F\u5426\u5F53\u524D\u6D3B\u8DC3\n }\n priority?: number // \u4F18\u5148\u7EA7\uFF08\u6570\u5B57\u8D8A\u5927\u8D8A\u9760\u524D\uFF09\n product_count?: number // \u53C2\u4E0E\u5546\u54C1\u6570\u91CF\n metadata?: {\n display_order?: number\n target_audience?: string\n }\n}\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6570\u636E\u7ED3\u6784\n */\nexport interface PromotionListData {\n found: boolean // \u662F\u5426\u627E\u5230\u6D3B\u52A8\n count: number // \u8FD4\u56DE\u7684\u6D3B\u52A8\u6570\u91CF\n total?: number // \u603B\u6D3B\u52A8\u6570\u91CF\uFF08\u53EF\u9009\uFF09\n results: PromotionItem[] // \u6D3B\u52A8\u5217\u8868\n}\n\nexport interface PromotionListProps {\n /**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6570\u636E\n */\n data: PromotionListData\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser?: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem?: boolean\n}\n\n/**\n * \u683C\u5F0F\u5316\u65E5\u671F\u663E\u793A\n */\nconst formatDate = (dateStr: string): string => {\n const date = new Date(dateStr)\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })\n}\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u663E\u793A\u5F53\u524D\u8FDB\u884C\u4E2D\u7684\u4FC3\u9500\u6D3B\u52A8\n * - \u652F\u6301\u6D3B\u52A8 Banner \u56FE\u7247\u5C55\u793A\n * - \u663E\u793A\u6D3B\u52A8\u65F6\u95F4\u8303\u56F4\n * - \u663E\u793A\u53C2\u4E0E\u5546\u54C1\u6570\u91CF\n * - \u652F\u6301\u8DF3\u8F6C\u5230\u6D3B\u52A8\u8BE6\u60C5\u9875\n *\n * @example\n * ```tsx\n * <PromotionList\n * data={{\n * found: true,\n * count: 2,\n * results: [...]\n * }}\n * />\n * ```\n */\nexport const PromotionList: React.FC<PromotionListProps> = ({ data, isUser = false, isSystem = false }) => {\n const { found, results } = data\n\n // \
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mBAAAE,EAAA,0BAAAC,IAAA,eAAAC,EAAAJ,
|
|
6
|
-
"names": ["PromotionList_exports", "__export", "PromotionList", "PromotionListRenderer", "__toCommonJS", "import_jsx_runtime", "formatDate", "dateStr", "data", "isUser", "isSystem", "found", "results", "promotion", "content"]
|
|
4
|
+
"sourcesContent": ["/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u7EC4\u4EF6\n * \u663E\u793A\u5F53\u524D\u8FDB\u884C\u4E2D\u7684\u4FC3\u9500\u6D3B\u52A8\u4FE1\u606F\n * \u57FA\u4E8E\u540E\u7AEF\u6570\u636E\u7ED3\u6784\u89C4\u8303\uFF1Apromotion_list\n */\n\nimport React from 'react'\nimport type { MessageRenderer, CommonText } from '../../types'\nimport { DEFAULT_COMMON_TEXT } from '../../constants'\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u6570\u636E\u7ED3\u6784\n */\nexport interface PromotionItem {\n id: string // \u6D3B\u52A8 ID\n title: string // \u6D3B\u52A8\u6807\u9898\n subtitle?: string // \u526F\u6807\u9898\uFF08\u5982 \"Up to 30% off\"\uFF09\n description?: string // \u6D3B\u52A8\u63CF\u8FF0\n banner_url?: string // Banner \u56FE\u7247 URL\n url?: string // \u6D3B\u52A8\u8BE6\u60C5\u9875 URL\n time_range: {\n start: string // \u5F00\u59CB\u65F6\u95F4 (ISO 8601)\n end?: string | null // \u7ED3\u675F\u65F6\u95F4\uFF0Cnull \u8868\u793A\u65E0\u7ED3\u675F\u65E5\u671F\n is_active: boolean // \u662F\u5426\u5F53\u524D\u6D3B\u8DC3\n }\n priority?: number // \u4F18\u5148\u7EA7\uFF08\u6570\u5B57\u8D8A\u5927\u8D8A\u9760\u524D\uFF09\n product_count?: number // \u53C2\u4E0E\u5546\u54C1\u6570\u91CF\n metadata?: {\n display_order?: number\n target_audience?: string\n highlight_color?: string\n banner_url?:string\n }\n}\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6570\u636E\u7ED3\u6784\n */\nexport interface PromotionListData {\n found: boolean // \u662F\u5426\u627E\u5230\u6D3B\u52A8\n count: number // \u8FD4\u56DE\u7684\u6D3B\u52A8\u6570\u91CF\n total?: number // \u603B\u6D3B\u52A8\u6570\u91CF\uFF08\u53EF\u9009\uFF09\n results: PromotionItem[] // \u6D3B\u52A8\u5217\u8868\n commonText?: CommonText // \u901A\u7528\u6587\u6848\u914D\u7F6E\n}\n\nexport interface PromotionListProps {\n /**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6570\u636E\n */\n data: PromotionListData\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser?: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem?: boolean\n}\n\n/**\n * \u683C\u5F0F\u5316\u65E5\u671F\u663E\u793A\n */\nconst formatDate = (dateStr: string): string => {\n const date = new Date(dateStr)\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })\n}\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u663E\u793A\u5F53\u524D\u8FDB\u884C\u4E2D\u7684\u4FC3\u9500\u6D3B\u52A8\n * - \u652F\u6301\u6D3B\u52A8 Banner \u56FE\u7247\u5C55\u793A\n * - \u663E\u793A\u6D3B\u52A8\u65F6\u95F4\u8303\u56F4\n * - \u663E\u793A\u53C2\u4E0E\u5546\u54C1\u6570\u91CF\n * - \u652F\u6301\u8DF3\u8F6C\u5230\u6D3B\u52A8\u8BE6\u60C5\u9875\n *\n * @example\n * ```tsx\n * <PromotionList\n * data={{\n * found: true,\n * count: 2,\n * results: [...]\n * }}\n * />\n * ```\n */\nexport const PromotionList: React.FC<PromotionListProps> = ({ data, isUser = false, isSystem = false }) => {\n const { found, results, commonText } = data\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText = { ...DEFAULT_COMMON_TEXT, ...commonText }\n\n return (\n <div className=\"space-y-3\">\n {results.map(promotion => {\n const bannerUrl = promotion.banner_url ||promotion?.metadata?.banner_url\n\n // \u6CA1\u6709\u56FE\u7247\u5219\u4E0D\u5C55\u793A\n if (!bannerUrl) {\n return null\n }\n\n return (\n <div key={promotion.id} className=\"relative overflow-hidden rounded-2xl bg-[#F5F6F7]\">\n {/* Banner \u56FE\u7247 */}\n <div className=\"aspect-[16/9] w-full overflow-hidden bg-gray-100\">\n <img\n src={bannerUrl}\n alt={promotion.title}\n className=\"size-full object-cover object-center\"\n loading=\"lazy\"\n />\n </div>\n\n {/* \u6D3B\u52A8\u4FE1\u606F - \u53E0\u52A0\u5728\u56FE\u7247\u4E0A */}\n <div\n className=\"absolute inset-0 flex flex-col justify-end p-4 text-[#080A0F]\"\n style={{ color: promotion?.metadata?.highlight_color }}\n >\n <div className=\"mb-2\">\n <h3 className=\"text-xl font-bold leading-[1.2] tracking-[-0.04em]\">{promotion.title}</h3>\n {promotion.subtitle && (\n <p className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em]\">{promotion.subtitle}</p>\n )}\n </div>\n\n {/* \u67E5\u770B\u8BE6\u60C5\u6309\u94AE */}\n {promotion.url && (\n <a\n href={promotion.url + '?ref=LiveChat'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 text-sm font-bold tracking-[-0.04em]\"\n >\n {mergedText.learnMore}\n <svg className=\"size-[18px]\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </a>\n )}\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n\n/**\n * \u521B\u5EFA\u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6E32\u67D3\u5668\n */\nexport const PromotionListRenderer: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n if (content.type !== 'promotion_list' || !content.data) {\n return null\n }\n\n return <PromotionList data={content.data as PromotionListData} isUser={isUser} isSystem={isSystem} />\n },\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mBAAAE,EAAA,0BAAAC,IAAA,eAAAC,EAAAJ,GAoHc,IAAAK,EAAA,6BA5GdC,EAAoC,2BA0DpC,MAAMC,EAAcC,GACL,IAAI,KAAKA,CAAO,EACjB,mBAAmB,QAAS,CACtC,KAAM,UACN,MAAO,QACP,IAAK,SACP,CAAC,EAwBUN,EAA8C,CAAC,CAAE,KAAAO,EAAM,OAAAC,EAAS,GAAO,SAAAC,EAAW,EAAM,IAAM,CACzG,KAAM,CAAE,MAAAC,EAAO,QAAAC,EAAS,WAAAC,CAAW,EAAIL,EAGjCM,EAAa,CAAE,GAAG,sBAAqB,GAAGD,CAAW,EAE3D,SACE,OAAC,OAAI,UAAU,YACZ,SAAAD,EAAQ,IAAIG,GAAa,CACxB,MAAMC,EAAYD,EAAU,YAAaA,GAAW,UAAU,WAG9D,OAAKC,KAKH,QAAC,OAAuB,UAAU,oDAEhC,oBAAC,OAAI,UAAU,mDACb,mBAAC,OACC,IAAKA,EACL,IAAKD,EAAU,MACf,UAAU,uCACV,QAAQ,OACV,EACF,KAGA,QAAC,OACC,UAAU,gEACV,MAAO,CAAE,MAAOA,GAAW,UAAU,eAAgB,EAErD,qBAAC,OAAI,UAAU,OACb,oBAAC,MAAG,UAAU,qDAAsD,SAAAA,EAAU,MAAM,EACnFA,EAAU,aACT,OAAC,KAAE,UAAU,qDAAsD,SAAAA,EAAU,SAAS,GAE1F,EAGCA,EAAU,QACT,QAAC,KACC,KAAMA,EAAU,IAAM,gBACtB,OAAO,SACP,IAAI,sBACJ,UAAU,sEAET,UAAAD,EAAW,aACZ,OAAC,OAAI,UAAU,cAAc,KAAK,OAAO,OAAO,eAAe,QAAQ,YACrE,mBAAC,QAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,eAAe,EACtF,GACF,GAEJ,IArCQC,EAAU,EAsCpB,EA1CO,IA4CX,CAAC,EACH,CAEJ,EAKab,EAAyC,CACpD,OAAQ,CAACe,EAASR,EAAQC,IACpBO,EAAQ,OAAS,kBAAoB,CAACA,EAAQ,KACzC,QAGF,OAAChB,EAAA,CAAc,KAAMgB,EAAQ,KAA2B,OAAQR,EAAQ,SAAUC,EAAU,CAEvG",
|
|
6
|
+
"names": ["PromotionList_exports", "__export", "PromotionList", "PromotionListRenderer", "__toCommonJS", "import_jsx_runtime", "import_constants", "formatDate", "dateStr", "data", "isUser", "isSystem", "found", "results", "commonText", "mergedText", "promotion", "bannerUrl", "content"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var o=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var R=(t,e)=>{for(var a in e)o(t,a,{get:e[a],enumerable:!0})},m=(t,e,a,l)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of d(e))!k.call(t,n)&&n!==a&&o(t,n,{get:()=>e[n],enumerable:!(l=u(e,n))||l.enumerable});return t};var x=t=>m(o({},"__esModule",{value:!0}),t);var y={};R(y,{QuickReplies:()=>f,createQuickRepliesRenderer:()=>c});module.exports=x(y);var s=require("react/jsx-runtime");const c=t=>({render:(e,a,l)=>{const n=e,{replies:p}=n.data;if(!p||p.length===0)return null;const r=i=>{t?.(i)};return(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:p.map(i=>(0,s.jsxs)("button",{type:"button",onClick:()=>r(i),className:"livechat-quick-reply-button inline-flex font-bold items-center gap-1 rounded-[19px] px-3 py-[6px] text-sm leading-[140%] tracking-[-0.02em] transition-transform",children:[i.icon&&(0,s.jsx)("span",{className:"text-base",children:i.icon}),(0,s.jsx)("span",{className:"text-left",children:i.label})]},i.id))})}}),f=c();
|
|
2
2
|
//# sourceMappingURL=QuickReplies.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/LiveChatWidget/components/MessageContent/QuickReplies.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u5FEB\u6377\u56DE\u590D\u6309\u94AE\u6E32\u67D3\u5668\n * \u663E\u793A\u53EF\u70B9\u51FB\u7684\u5FEB\u6377\u56DE\u590D\u9009\u9879\n * \u57FA\u4E8E specs/livechat-widget/data-model.md \u7684\u5FEB\u6377\u56DE\u590D\u6570\u636E\u6A21\u578B\n */\n\nimport React from 'react'\nimport type { MessageRenderer, QuickRepliesContent, QuickReply } from '../../types'\n\nexport interface QuickRepliesProps {\n /**\n * \u5FEB\u6377\u56DE\u590D\u70B9\u51FB\u56DE\u8C03\n */\n onReplyClick?: (reply: QuickReply) => void\n}\n\n/**\n * \u5FEB\u6377\u56DE\u590D\u6309\u94AE\u6E32\u67D3\u5668\n *\n * \u529F\u80FD\uFF1A\n * - \u663E\u793A\u591A\u4E2A\u5FEB\u6377\u56DE\u590D\u6309\u94AE\n * - \u652F\u6301\u56FE\u6807\uFF08\u53EF\u9009\uFF09\n * - \u70B9\u51FB\u540E\u53D1\u9001\u5BF9\u5E94\u7684\u6D88\u606F\n *\n * \u4F7F\u7528\u573A\u666F\uFF1A\n * - \u6B22\u8FCE\u6D88\u606F\u540E\u7684\u5E38\u89C1\u95EE\u9898\n * - \u5F15\u5BFC\u7528\u6237\u9009\u62E9\n * - \u5FEB\u901F\u64CD\u4F5C\u6309\u94AE\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 \uD83D\uDED2 \u67E5\u4EF7\u683C \u2502 \u2502 \uD83D\uDCE6 \u67E5\u7269\u6D41 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 \uD83D\uDCDE \u8054\u7CFB\u5BA2\u670D\u2502 \u2502 \uD83D\uDCAC \u5176\u4ED6\u95EE\u9898\u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * ```\n *\n * @example\n * ```tsx\n * const content: QuickRepliesContent = {\n * type: 'quick_replies',\n * data: {\n * replies: [\n * { id: '1', label: '\u67E5\u4EF7\u683C', value: '\u6211\u60F3\u67E5\u8BE2\u5546\u54C1\u4EF7\u683C', icon: '\uD83D\uDED2' },\n * { id: '2', label: '\u67E5\u7269\u6D41', value: '\u6211\u60F3\u67E5\u8BE2\u7269\u6D41\u4FE1\u606F', icon: '\uD83D\uDCE6' }\n * ]\n * }\n * }\n * <QuickReplies.render(content, false, false) />\n * ```\n */\nexport const createQuickRepliesRenderer = (onReplyClick?: (reply: QuickReply) => void): MessageRenderer => ({\n render: (content, isUser, isSystem) => {\n const quickRepliesContent = content as QuickRepliesContent\n const { replies } = quickRepliesContent.data\n\n if (!replies || replies.length === 0) {\n return null\n }\n\n const handleClick = (reply: QuickReply) => {\n onReplyClick?.(reply)\n }\n\n return (\n <div className=\"flex flex-wrap gap-2\">\n {replies.map(reply => (\n <button\n key={reply.id}\n type=\"button\"\n onClick={() => handleClick(reply)}\n className=\"livechat-quick-reply-button inline-flex items-center gap-1 rounded-[19px] px-3 py-[6px] text-sm leading-[140%] tracking-[-0.02em] transition-transform
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,EAAA,+BAAAC,IAAA,eAAAC,EAAAJ,GAqEU,IAAAK,EAAA,6BAhBH,MAAMF,EAA8BG,IAAiE,CAC1G,OAAQ,CAACC,EAASC,EAAQC,IAAa,CACrC,MAAMC,EAAsBH,EACtB,CAAE,QAAAI,CAAQ,EAAID,EAAoB,KAExC,GAAI,CAACC,GAAWA,EAAQ,SAAW,EACjC,OAAO,KAGT,MAAMC,EAAeC,GAAsB,CACzCP,IAAeO,CAAK,CACtB,EAEA,SACE,OAAC,OAAI,UAAU,uBACZ,SAAAF,EAAQ,IAAIE,MACX,QAAC,UAEC,KAAK,SACL,QAAS,IAAMD,EAAYC,CAAK,EAChC,UAAU,
|
|
4
|
+
"sourcesContent": ["/**\n * \u5FEB\u6377\u56DE\u590D\u6309\u94AE\u6E32\u67D3\u5668\n * \u663E\u793A\u53EF\u70B9\u51FB\u7684\u5FEB\u6377\u56DE\u590D\u9009\u9879\n * \u57FA\u4E8E specs/livechat-widget/data-model.md \u7684\u5FEB\u6377\u56DE\u590D\u6570\u636E\u6A21\u578B\n */\n\nimport React from 'react'\nimport type { MessageRenderer, QuickRepliesContent, QuickReply } from '../../types'\n\nexport interface QuickRepliesProps {\n /**\n * \u5FEB\u6377\u56DE\u590D\u70B9\u51FB\u56DE\u8C03\n */\n onReplyClick?: (reply: QuickReply) => void\n}\n\n/**\n * \u5FEB\u6377\u56DE\u590D\u6309\u94AE\u6E32\u67D3\u5668\n *\n * \u529F\u80FD\uFF1A\n * - \u663E\u793A\u591A\u4E2A\u5FEB\u6377\u56DE\u590D\u6309\u94AE\n * - \u652F\u6301\u56FE\u6807\uFF08\u53EF\u9009\uFF09\n * - \u70B9\u51FB\u540E\u53D1\u9001\u5BF9\u5E94\u7684\u6D88\u606F\n *\n * \u4F7F\u7528\u573A\u666F\uFF1A\n * - \u6B22\u8FCE\u6D88\u606F\u540E\u7684\u5E38\u89C1\u95EE\u9898\n * - \u5F15\u5BFC\u7528\u6237\u9009\u62E9\n * - \u5FEB\u901F\u64CD\u4F5C\u6309\u94AE\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 \uD83D\uDED2 \u67E5\u4EF7\u683C \u2502 \u2502 \uD83D\uDCE6 \u67E5\u7269\u6D41 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 \uD83D\uDCDE \u8054\u7CFB\u5BA2\u670D\u2502 \u2502 \uD83D\uDCAC \u5176\u4ED6\u95EE\u9898\u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * ```\n *\n * @example\n * ```tsx\n * const content: QuickRepliesContent = {\n * type: 'quick_replies',\n * data: {\n * replies: [\n * { id: '1', label: '\u67E5\u4EF7\u683C', value: '\u6211\u60F3\u67E5\u8BE2\u5546\u54C1\u4EF7\u683C', icon: '\uD83D\uDED2' },\n * { id: '2', label: '\u67E5\u7269\u6D41', value: '\u6211\u60F3\u67E5\u8BE2\u7269\u6D41\u4FE1\u606F', icon: '\uD83D\uDCE6' }\n * ]\n * }\n * }\n * <QuickReplies.render(content, false, false) />\n * ```\n */\nexport const createQuickRepliesRenderer = (onReplyClick?: (reply: QuickReply) => void): MessageRenderer => ({\n render: (content, isUser, isSystem) => {\n const quickRepliesContent = content as QuickRepliesContent\n const { replies } = quickRepliesContent.data\n\n if (!replies || replies.length === 0) {\n return null\n }\n\n const handleClick = (reply: QuickReply) => {\n onReplyClick?.(reply)\n }\n\n return (\n <div className=\"flex flex-wrap gap-2\">\n {replies.map(reply => (\n <button\n key={reply.id}\n type=\"button\"\n onClick={() => handleClick(reply)}\n className=\"livechat-quick-reply-button inline-flex font-bold items-center gap-1 rounded-[19px] px-3 py-[6px] text-sm leading-[140%] tracking-[-0.02em] transition-transform\"\n >\n {/* \u56FE\u6807\uFF08\u53EF\u9009\uFF09 */}\n {reply.icon && <span className=\"text-base\">{reply.icon}</span>}\n\n {/* \u6807\u7B7E */}\n <span className='text-left'>{reply.label}</span>\n </button>\n ))}\n </div>\n )\n },\n})\n\n/**\n * \u9ED8\u8BA4\u5FEB\u6377\u56DE\u590D\u6E32\u67D3\u5668\uFF08\u65E0\u56DE\u8C03\uFF09\n */\nexport const QuickReplies: MessageRenderer = createQuickRepliesRenderer()\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,EAAA,+BAAAC,IAAA,eAAAC,EAAAJ,GAqEU,IAAAK,EAAA,6BAhBH,MAAMF,EAA8BG,IAAiE,CAC1G,OAAQ,CAACC,EAASC,EAAQC,IAAa,CACrC,MAAMC,EAAsBH,EACtB,CAAE,QAAAI,CAAQ,EAAID,EAAoB,KAExC,GAAI,CAACC,GAAWA,EAAQ,SAAW,EACjC,OAAO,KAGT,MAAMC,EAAeC,GAAsB,CACzCP,IAAeO,CAAK,CACtB,EAEA,SACE,OAAC,OAAI,UAAU,uBACZ,SAAAF,EAAQ,IAAIE,MACX,QAAC,UAEC,KAAK,SACL,QAAS,IAAMD,EAAYC,CAAK,EAChC,UAAU,mKAGT,UAAAA,EAAM,SAAQ,OAAC,QAAK,UAAU,YAAa,SAAAA,EAAM,KAAK,KAGvD,OAAC,QAAK,UAAU,YAAa,SAAAA,EAAM,MAAM,IATpCA,EAAM,EAUb,CACD,EACH,CAEJ,CACF,GAKaX,EAAgCC,EAA2B",
|
|
6
6
|
"names": ["QuickReplies_exports", "__export", "QuickReplies", "createQuickRepliesRenderer", "__toCommonJS", "import_jsx_runtime", "onReplyClick", "content", "isUser", "isSystem", "quickRepliesContent", "replies", "handleClick", "reply"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var x=Object.create;var n=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty;var f=(a,r)=>{for(var l in r)n(a,l,{get:r[l],enumerable:!0})},s=(a,r,l,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of g(r))!N.call(a,t)&&t!==l&&n(a,t,{get:()=>r[t],enumerable:!(d=i(r,t))||d.enumerable});return a};var m=(a,r,l)=>(l=a!=null?x(y(a)):{},s(r||!a||!a.__esModule?n(l,"default",{value:a,enumerable:!0}):l,a)),p=a=>s(n({},"__esModule",{value:!0}),a);var u={};f(u,{TextBlock:()=>h});module.exports=p(u);var o=require("react/jsx-runtime"),b=m(require("react-markdown")),c=m(require("remark-gfm"));const h={render:(a,r,l)=>{const d=a;return d.text?(0,o.jsx)("div",{className:"livechat-markdown text-base md:text-sm",children:(0,o.jsx)(b.default,{remarkPlugins:[c.default],components:{a:({node:t,...e})=>(0,o.jsx)("a",{...e,className:`underline ${r?"text-blue-200 hover:text-blue-100":"text-blue-600 hover:text-blue-700"}`,target:"_blank",rel:"noopener noreferrer"}),code:({node:t,...e})=>e.inline?(0,o.jsx)("code",{...e,className:`rounded px-1.5 py-0.5 font-mono text-xs ${r?"bg-[#004A6E] text-white":"bg-gray-200 text-gray-800"}`}):(0,o.jsx)("code",{...e,className:`block overflow-x-auto rounded px-3 py-2 font-mono text-xs ${r?"bg-[#004A6E] text-white":"bg-gray-200 text-gray-800"}`}),p:({node:t,...e})=>(0,o.jsx)("p",{...e,className:"last:mb-0"}),ul:({node:t,...e})=>(0,o.jsx)("ul",{...e,className:"ml-4 list-disc"}),ol:({node:t,...e})=>(0,o.jsx)("ol",{...e,className:"mb-2 ml-4 list-decimal"}),li:({node:t,...e})=>(0,o.jsx)("li",{...e,className:"mb-1"}),h1:({node:t,...e})=>(0,o.jsx)("h1",{...e,className:"mb-2 font-bold"}),h2:({node:t,...e})=>(0,o.jsx)("h2",{...e,className:"mb-2 font-bold"}),h3:({node:t,...e})=>(0,o.jsx)("h3",{...e,className:"mb-1 font-bold"}),strong:({node:t,...e})=>(0,o.jsx)("strong",{...e,className:"font-bold"}),em:({node:t,...e})=>(0,o.jsx)("em",{...e,className:"italic"}),table:({node:t,...e})=>(0,o.jsx)("div",{className:"my-2 overflow-x-auto",children:(0,o.jsx)("table",{...e,className:"min-w-full border-collapse border border-gray-300 text-base md:text-sm"})}),thead:({node:t,...e})=>(0,o.jsx)("thead",{...e,className:"bg-gray-100"}),tbody:({node:t,...e})=>(0,o.jsx)("tbody",{...e}),tr:({node:t,...e})=>(0,o.jsx)("tr",{...e,className:"border-b border-gray-300"}),th:({node:t,...e})=>(0,o.jsx)("th",{...e,className:"border border-gray-300 px-3 py-2 text-left font-semibold"}),td:({node:t,...e})=>(0,o.jsx)("td",{...e,className:"border border-gray-300 px-3 py-2"})},children:d.text})}):null}};
|
|
2
2
|
//# sourceMappingURL=TextBlock.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/LiveChatWidget/components/MessageContent/TextBlock.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u6587\u672C\u6D88\u606F\u5185\u5BB9\u6E32\u67D3\u5668\n * \u652F\u6301 Markdown \u683C\u5F0F\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u6587\u672C\u6D88\u606F\u8BBE\u8BA1\n */\n\nimport React from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport type { MessageRenderer, TextContent } from '../../types'\n\n/**\n * \u6587\u672C\u6D88\u606F\u6E32\u67D3\u5668\n *\n * \u529F\u80FD\uFF1A\n * - \u652F\u6301 Markdown \u8BED\u6CD5\uFF08\u7C97\u4F53\u3001\u659C\u4F53\u3001\u94FE\u63A5\u3001\u5217\u8868\u7B49\uFF09\n * - \u5B89\u5168\u6E32\u67D3\uFF08React Markdown \u81EA\u52A8\u9632\u62A4 XSS\uFF09\n * - \u54CD\u5E94\u5F0F\u6587\u672C\u6837\u5F0F\n *\n * Markdown \u652F\u6301\uFF1A\n * - \u7C97\u4F53\uFF1A**text** \u6216 __text__\n * - \u659C\u4F53\uFF1A*text* \u6216 _text_\n * - \u94FE\u63A5\uFF1A[text](url)\n * - \u5217\u8868\uFF1A- item \u6216 1. item\n * - \u4EE3\u7801\uFF1A`code` \u6216 ```code block```\n *\n * @example\n * ```tsx\n * const content: TextContent = {\n * type: 'text',\n * text: '\u60A8\u597D\uFF01**\u8FD9\u662F\u7C97\u4F53**\uFF0C*\u8FD9\u662F\u659C\u4F53*\u3002'\n * }\n * <TextBlock.render(content, false, false) />\n * ```\n */\nexport const TextBlock: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n const textContent = content as TextContent\n\n if (!textContent.text) {\n return null\n }\n\n return (\n <div className=\"livechat-markdown text-
|
|
5
|
-
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,eAAAE,IAAA,eAAAC,EAAAH,
|
|
6
|
-
"names": ["TextBlock_exports", "__export", "TextBlock", "__toCommonJS", "import_jsx_runtime", "import_react_markdown", "content", "isUser", "isSystem", "textContent", "ReactMarkdown", "node", "props"]
|
|
4
|
+
"sourcesContent": ["/**\n * \u6587\u672C\u6D88\u606F\u5185\u5BB9\u6E32\u67D3\u5668\n * \u652F\u6301 Markdown \u683C\u5F0F\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u6587\u672C\u6D88\u606F\u8BBE\u8BA1\n */\n\nimport React from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport type { MessageRenderer, TextContent } from '../../types'\n\n/**\n * \u6587\u672C\u6D88\u606F\u6E32\u67D3\u5668\n *\n * \u529F\u80FD\uFF1A\n * - \u652F\u6301 Markdown \u8BED\u6CD5\uFF08\u7C97\u4F53\u3001\u659C\u4F53\u3001\u94FE\u63A5\u3001\u5217\u8868\u7B49\uFF09\n * - \u5B89\u5168\u6E32\u67D3\uFF08React Markdown \u81EA\u52A8\u9632\u62A4 XSS\uFF09\n * - \u54CD\u5E94\u5F0F\u6587\u672C\u6837\u5F0F\n *\n * Markdown \u652F\u6301\uFF1A\n * - \u7C97\u4F53\uFF1A**text** \u6216 __text__\n * - \u659C\u4F53\uFF1A*text* \u6216 _text_\n * - \u94FE\u63A5\uFF1A[text](url)\n * - \u5217\u8868\uFF1A- item \u6216 1. item\n * - \u4EE3\u7801\uFF1A`code` \u6216 ```code block```\n *\n * @example\n * ```tsx\n * const content: TextContent = {\n * type: 'text',\n * text: '\u60A8\u597D\uFF01**\u8FD9\u662F\u7C97\u4F53**\uFF0C*\u8FD9\u662F\u659C\u4F53*\u3002'\n * }\n * <TextBlock.render(content, false, false) />\n * ```\n */\nexport const TextBlock: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n const textContent = content as TextContent\n\n if (!textContent.text) {\n return null\n }\n\n return (\n <div className=\"livechat-markdown text-base md:text-sm\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={{\n // \u81EA\u5B9A\u4E49\u94FE\u63A5\u6837\u5F0F\n a: ({ node, ...props }) => (\n <a\n {...props}\n className={`underline ${isUser ? 'text-blue-200 hover:text-blue-100' : 'text-blue-600 hover:text-blue-700'}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n />\n ),\n // \u81EA\u5B9A\u4E49\u4EE3\u7801\u5757\u6837\u5F0F\n code: ({ node, ...props }: any) =>\n props.inline ? (\n <code\n {...props}\n className={`rounded px-1.5 py-0.5 font-mono text-xs ${isUser ? 'bg-[#004A6E] text-white' : 'bg-gray-200 text-gray-800'}`}\n />\n ) : (\n <code\n {...props}\n className={`block overflow-x-auto rounded px-3 py-2 font-mono text-xs ${isUser ? 'bg-[#004A6E] text-white' : 'bg-gray-200 text-gray-800'}`}\n />\n ),\n // \u81EA\u5B9A\u4E49\u6BB5\u843D\u6837\u5F0F\n p: ({ node, ...props }) => <p {...props} className=\"last:mb-0\" />,\n // \u81EA\u5B9A\u4E49\u5217\u8868\u6837\u5F0F\n ul: ({ node, ...props }) => <ul {...props} className=\"ml-4 list-disc\" />,\n ol: ({ node, ...props }) => <ol {...props} className=\"mb-2 ml-4 list-decimal\" />,\n li: ({ node, ...props }) => <li {...props} className=\"mb-1\" />,\n // \u81EA\u5B9A\u4E49\u6807\u9898\u6837\u5F0F\n h1: ({ node, ...props }) => <h1 {...props} className=\"mb-2 font-bold\" />,\n h2: ({ node, ...props }) => <h2 {...props} className=\"mb-2 font-bold\" />,\n h3: ({ node, ...props }) => <h3 {...props} className=\"mb-1 font-bold\" />,\n // \u81EA\u5B9A\u4E49\u5F3A\u8C03\u6837\u5F0F\n strong: ({ node, ...props }) => <strong {...props} className=\"font-bold\" />,\n em: ({ node, ...props }) => <em {...props} className=\"italic\" />,\n // \u8868\u683C\u6837\u5F0F\n table: ({ node, ...props }) => (\n <div className=\"my-2 overflow-x-auto\">\n <table {...props} className=\"min-w-full border-collapse border border-gray-300 text-base md:text-sm\" />\n </div>\n ),\n thead: ({ node, ...props }) => (\n <thead {...props} className=\"bg-gray-100\" />\n ),\n tbody: ({ node, ...props }) => <tbody {...props} />,\n tr: ({ node, ...props }) => (\n <tr {...props} className=\"border-b border-gray-300\" />\n ),\n th: ({ node, ...props }) => (\n <th {...props} className=\"border border-gray-300 px-3 py-2 text-left font-semibold\" />\n ),\n td: ({ node, ...props }) => (\n <td {...props} className=\"border border-gray-300 px-3 py-2\" />\n ),\n }}\n >\n {textContent.text}\n </ReactMarkdown>\n </div>\n )\n },\n}\n"],
|
|
5
|
+
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,eAAAE,IAAA,eAAAC,EAAAH,GAkDc,IAAAI,EAAA,6BA3CdC,EAA0B,6BAC1BC,EAAsB,yBA2Bf,MAAMJ,EAA6B,CACxC,OAAQ,CAACK,EAASC,EAAQC,IAAa,CACrC,MAAMC,EAAcH,EAEpB,OAAKG,EAAY,QAKf,OAAC,OAAI,UAAU,yCACb,mBAAC,EAAAC,QAAA,CACC,cAAe,CAAC,EAAAC,OAAS,EACzB,WAAY,CAEV,EAAG,CAAC,CAAE,KAAAC,EAAM,GAAGC,CAAM,OACnB,OAAC,KACE,GAAGA,EACJ,UAAW,aAAaN,EAAS,oCAAsC,mCAAmC,GAC1G,OAAO,SACP,IAAI,sBACN,EAGF,KAAM,CAAC,CAAE,KAAAK,EAAM,GAAGC,CAAM,IACtBA,EAAM,UACJ,OAAC,QACE,GAAGA,EACJ,UAAW,2CAA2CN,EAAS,0BAA4B,2BAA2B,GACxH,KAEA,OAAC,QACE,GAAGM,EACJ,UAAW,6DAA6DN,EAAS,0BAA4B,2BAA2B,GAC1I,EAGJ,EAAG,CAAC,CAAE,KAAAK,EAAM,GAAGC,CAAM,OAAM,OAAC,KAAG,GAAGA,EAAO,UAAU,YAAY,EAE/D,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,MAAI,GAAGA,EAAO,UAAU,iBAAiB,EACtE,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,MAAI,GAAGA,EAAO,UAAU,yBAAyB,EAC9E,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,MAAI,GAAGA,EAAO,UAAU,OAAO,EAE5D,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,MAAI,GAAGA,EAAO,UAAU,iBAAiB,EACtE,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,MAAI,GAAGA,EAAO,UAAU,iBAAiB,EACtE,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,MAAI,GAAGA,EAAO,UAAU,iBAAiB,EAEtE,OAAQ,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,UAAQ,GAAGA,EAAO,UAAU,YAAY,EACzE,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,MAAI,GAAGA,EAAO,UAAU,SAAS,EAE9D,MAAO,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OACvB,OAAC,OAAI,UAAU,uBACb,mBAAC,SAAO,GAAGA,EAAO,UAAU,yEAAyE,EACvG,EAEF,MAAO,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OACvB,OAAC,SAAO,GAAGA,EAAO,UAAU,cAAc,EAE5C,MAAO,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OAAM,OAAC,SAAO,GAAGA,EAAO,EACjD,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OACpB,OAAC,MAAI,GAAGA,EAAO,UAAU,2BAA2B,EAEtD,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OACpB,OAAC,MAAI,GAAGA,EAAO,UAAU,2DAA2D,EAEtF,GAAI,CAAC,CAAE,KAAAD,EAAM,GAAGC,CAAM,OACpB,OAAC,MAAI,GAAGA,EAAO,UAAU,mCAAmC,CAEhE,EAEC,SAAAJ,EAAY,KACf,EACF,EAlEO,IAoEX,CACF",
|
|
6
|
+
"names": ["TextBlock_exports", "__export", "TextBlock", "__toCommonJS", "import_jsx_runtime", "import_react_markdown", "import_remark_gfm", "content", "isUser", "isSystem", "textContent", "ReactMarkdown", "remarkGfm", "node", "props"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var d=Object.defineProperty;var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var m=(e,r)=>{for(var t in r)d(e,t,{get:r[t],enumerable:!0})},l=(e,r,t,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of y(r))!R.call(e,s)&&s!==t&&d(e,s,{get:()=>r[s],enumerable:!(a=g(r,s))||a.enumerable});return e};var M=e=>l(d({},"__esModule",{value:!0}),e);var f={};m(f,{MessageContent:()=>C});module.exports=M(f);var n=require("react/jsx-runtime");const u={render:e=>(0,n.jsxs)("div",{className:"text-sm italic text-gray-500",children:["\u672A\u77E5\u6D88\u606F\u7C7B\u578B: ",e.type]})},C=({content:e,isUser:r,isSystem:t,rendererRegistry:a,defaultRenderer:s,className:i="",onAddToCart:p})=>{let o=e;(e.type==="product_card"||e.type==="product_list"||e.type==="product_comparison")&&p&&(o={...e,data:{...e.data,onAddToCart:p}});const c=(a?.get(o.type)||s||u).render(o,r,t);return(0,n.jsx)("div",{className:i,children:c})};
|
|
2
2
|
//# sourceMappingURL=MessageContent.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/LiveChatWidget/components/MessageContent.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u6D88\u606F\u5185\u5BB9\u5BB9\u5668\u7EC4\u4EF6\n * \u6839\u636E\u6D88\u606F\u5185\u5BB9\u7C7B\u578B\u5206\u53D1\u5230\u5BF9\u5E94\u7684\u6E32\u67D3\u5668\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u6D88\u606F\u5185\u5BB9\u6E32\u67D3\u8BBE\u8BA1\n */\n\nimport React from 'react'\nimport type { MessageContent as MessageContentType, MessageRenderer } from '../types'\nimport { MessageRendererRegistry } from '../utils/messageRenderers'\n\nexport interface MessageContentProps {\n /**\n * \u6D88\u606F\u5185\u5BB9\n */\n content: MessageContentType\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem: boolean\n\n /**\n * \u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n */\n rendererRegistry?: MessageRendererRegistry\n\n /**\n * \u9ED8\u8BA4\u6E32\u67D3\u5668\uFF08\u5F53\u627E\u4E0D\u5230\u5BF9\u5E94\u6E32\u67D3\u5668\u65F6\u4F7F\u7528\uFF09\n */\n defaultRenderer?: MessageRenderer\n\n /**\n * \u81EA\u5B9A\u4E49\u6837\u5F0F\u7C7B\u540D\n */\n className?: string\n\n /**\n * \u5546\u54C1\u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u56DE\u8C03\n */\n onAddToCart?: (product: any) => void\n}\n\n/**\n * \u9ED8\u8BA4\u6E32\u67D3\u5668 - \u663E\u793A\u672A\u77E5\u7C7B\u578B\u63D0\u793A\n */\nconst defaultFallbackRenderer: MessageRenderer = {\n render: content => <div className=\"text-sm italic text-gray-500\">\u672A\u77E5\u6D88\u606F\u7C7B\u578B: {content.type}</div>,\n}\n\n/**\n * \u6D88\u606F\u5185\u5BB9\u5BB9\u5668\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u6839\u636E content.type \u5206\u53D1\u5230\u5BF9\u5E94\u7684\u6E32\u67D3\u5668\n * - \u652F\u6301\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n * - \u63D0\u4F9B\u9ED8\u8BA4\u515C\u5E95\u6E32\u67D3\u5668\n *\n * \u6E32\u67D3\u6D41\u7A0B\uFF1A\n * 1. \u68C0\u67E5\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\u6CE8\u518C\u8868\u662F\u5426\u6709\u5BF9\u5E94\u7C7B\u578B\n * 2. \u5982\u679C\u6709\uFF0C\u4F7F\u7528\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\n * 3. \u5982\u679C\u6CA1\u6709\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u6E32\u67D3\u5668\n * 4. \u5982\u679C\u9ED8\u8BA4\u6E32\u67D3\u5668\u4E5F\u6CA1\u6709\uFF0C\u663E\u793A\u672A\u77E5\u7C7B\u578B\u63D0\u793A\n *\n * @example\n * ```tsx\n * <MessageContent\n * content={content}\n * isUser={message.role === 'user'}\n * isSystem={message.role === 'system'}\n * rendererRegistry={customRegistry}\n * />\n * ```\n */\nexport const MessageContent: React.FC<MessageContentProps> = ({\n content,\n isUser,\n isSystem,\n rendererRegistry,\n defaultRenderer,\n className = '',\n onAddToCart,\n}) => {\n // \u52A8\u6001\u6CE8\u5165 onAddToCart \u5230
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oBAAAE,IAAA,eAAAC,EAAAH,GAmDqB,IAAAI,EAAA,6BADrB,MAAMC,EAA2C,CAC/C,OAAQC,MAAW,QAAC,OAAI,UAAU,+BAA+B,mDAASA,EAAQ,MAAK,CACzF,EA0BaJ,EAAgD,CAAC,CAC5D,QAAAI,EACA,OAAAC,EACA,SAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,UAAAC,EAAY,GACZ,YAAAC,CACF,IAAM,CAEJ,IAAIC,EAAmBP,
|
|
4
|
+
"sourcesContent": ["/**\n * \u6D88\u606F\u5185\u5BB9\u5BB9\u5668\u7EC4\u4EF6\n * \u6839\u636E\u6D88\u606F\u5185\u5BB9\u7C7B\u578B\u5206\u53D1\u5230\u5BF9\u5E94\u7684\u6E32\u67D3\u5668\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u6D88\u606F\u5185\u5BB9\u6E32\u67D3\u8BBE\u8BA1\n */\n\nimport React from 'react'\nimport type { MessageContent as MessageContentType, MessageRenderer } from '../types'\nimport { MessageRendererRegistry } from '../utils/messageRenderers'\n\nexport interface MessageContentProps {\n /**\n * \u6D88\u606F\u5185\u5BB9\n */\n content: MessageContentType\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem: boolean\n\n /**\n * \u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n */\n rendererRegistry?: MessageRendererRegistry\n\n /**\n * \u9ED8\u8BA4\u6E32\u67D3\u5668\uFF08\u5F53\u627E\u4E0D\u5230\u5BF9\u5E94\u6E32\u67D3\u5668\u65F6\u4F7F\u7528\uFF09\n */\n defaultRenderer?: MessageRenderer\n\n /**\n * \u81EA\u5B9A\u4E49\u6837\u5F0F\u7C7B\u540D\n */\n className?: string\n\n /**\n * \u5546\u54C1\u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u56DE\u8C03\n */\n onAddToCart?: (product: any) => void\n}\n\n/**\n * \u9ED8\u8BA4\u6E32\u67D3\u5668 - \u663E\u793A\u672A\u77E5\u7C7B\u578B\u63D0\u793A\n */\nconst defaultFallbackRenderer: MessageRenderer = {\n render: content => <div className=\"text-sm italic text-gray-500\">\u672A\u77E5\u6D88\u606F\u7C7B\u578B: {content.type}</div>,\n}\n\n/**\n * \u6D88\u606F\u5185\u5BB9\u5BB9\u5668\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u6839\u636E content.type \u5206\u53D1\u5230\u5BF9\u5E94\u7684\u6E32\u67D3\u5668\n * - \u652F\u6301\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n * - \u63D0\u4F9B\u9ED8\u8BA4\u515C\u5E95\u6E32\u67D3\u5668\n *\n * \u6E32\u67D3\u6D41\u7A0B\uFF1A\n * 1. \u68C0\u67E5\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\u6CE8\u518C\u8868\u662F\u5426\u6709\u5BF9\u5E94\u7C7B\u578B\n * 2. \u5982\u679C\u6709\uFF0C\u4F7F\u7528\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\n * 3. \u5982\u679C\u6CA1\u6709\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u6E32\u67D3\u5668\n * 4. \u5982\u679C\u9ED8\u8BA4\u6E32\u67D3\u5668\u4E5F\u6CA1\u6709\uFF0C\u663E\u793A\u672A\u77E5\u7C7B\u578B\u63D0\u793A\n *\n * @example\n * ```tsx\n * <MessageContent\n * content={content}\n * isUser={message.role === 'user'}\n * isSystem={message.role === 'system'}\n * rendererRegistry={customRegistry}\n * />\n * ```\n */\nexport const MessageContent: React.FC<MessageContentProps> = ({\n content,\n isUser,\n isSystem,\n rendererRegistry,\n defaultRenderer,\n className = '',\n onAddToCart,\n}) => {\n // \u52A8\u6001\u6CE8\u5165 onAddToCart \u5230 product_card\u3001product_list \u548C product_comparison \u7C7B\u578B\u7684\u5185\u5BB9\u4E2D\n let processedContent = content\n if (\n (content.type === 'product_card' || content.type === 'product_list' || content.type === 'product_comparison') &&\n onAddToCart\n ) {\n processedContent = {\n ...content,\n data: {\n ...(content as any).data,\n onAddToCart,\n },\n }\n }\n\n // \u5C1D\u8BD5\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u6E32\u67D3\u5668\n const customRenderer = rendererRegistry?.get(processedContent.type)\n\n // \u786E\u5B9A\u6700\u7EC8\u4F7F\u7528\u7684\u6E32\u67D3\u5668\n const renderer = customRenderer || defaultRenderer || defaultFallbackRenderer\n\n // \u6E32\u67D3\u5185\u5BB9\n const rendered = renderer.render(processedContent, isUser, isSystem)\n\n return <div className={className}>{rendered}</div>\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oBAAAE,IAAA,eAAAC,EAAAH,GAmDqB,IAAAI,EAAA,6BADrB,MAAMC,EAA2C,CAC/C,OAAQC,MAAW,QAAC,OAAI,UAAU,+BAA+B,mDAASA,EAAQ,MAAK,CACzF,EA0BaJ,EAAgD,CAAC,CAC5D,QAAAI,EACA,OAAAC,EACA,SAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,UAAAC,EAAY,GACZ,YAAAC,CACF,IAAM,CAEJ,IAAIC,EAAmBP,GAEpBA,EAAQ,OAAS,gBAAkBA,EAAQ,OAAS,gBAAkBA,EAAQ,OAAS,uBACxFM,IAEAC,EAAmB,CACjB,GAAGP,EACH,KAAM,CACJ,GAAIA,EAAgB,KACpB,YAAAM,CACF,CACF,GAUF,MAAME,GANiBL,GAAkB,IAAII,EAAiB,IAAI,GAG/BH,GAAmBL,GAG5B,OAAOQ,EAAkBN,EAAQC,CAAQ,EAEnE,SAAO,OAAC,OAAI,UAAWG,EAAY,SAAAG,EAAS,CAC9C",
|
|
6
6
|
"names": ["MessageContent_exports", "__export", "MessageContent", "__toCommonJS", "import_jsx_runtime", "defaultFallbackRenderer", "content", "isUser", "isSystem", "rendererRegistry", "defaultRenderer", "className", "onAddToCart", "processedContent", "rendered"]
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";var f=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var L=(r,o)=>{for(var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var L=(r,o)=>{for(var i in o)f(r,i,{get:o[i],enumerable:!0})},k=(r,o,i,c)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of M(o))!C.call(r,s)&&s!==i&&f(r,s,{get:()=>o[s],enumerable:!(c=w(o,s))||c.enumerable});return r};var B=r=>k(f({},"__esModule",{value:!0}),r);var z={};L(z,{MessageList:()=>S});module.exports=B(z);var e=require("react/jsx-runtime"),n=require("react"),v=require("./ChatMessage"),h=require("./ScrollAnchor");const E=()=>(0,e.jsx)("div",{className:"flex h-full items-center justify-center text-gray-400",children:(0,e.jsx)("p",{className:"text-sm",children:"No messages yet"})}),H=()=>(0,e.jsx)("div",{className:"flex justify-center py-4",children:(0,e.jsxs)("div",{className:"flex gap-1",children:[(0,e.jsx)("div",{className:"size-2 animate-bounce rounded-full bg-gray-400"}),(0,e.jsx)("div",{className:"size-2 animate-bounce rounded-full bg-gray-400",style:{animationDelay:"0.1s"}}),(0,e.jsx)("div",{className:"size-2 animate-bounce rounded-full bg-gray-400",style:{animationDelay:"0.2s"}})]})}),S=({messages:r,rendererRegistry:o,defaultRenderer:i,showTimestamp:c=!0,autoScroll:s=!0,isLoadingHistory:p=!1,emptyPlaceholder:y,className:g="",onAddToCart:b})=>{const a=(0,n.useRef)(null),[u,m]=(0,n.useState)(!1),d=(0,n.useCallback)((t=100)=>{const l=a.current;if(!l)return!0;const{scrollTop:R,scrollHeight:N,clientHeight:T}=l;return N-R-T<t},[]),x=(0,n.useCallback)(()=>{const t=a.current;t&&t.scrollTo({top:t.scrollHeight,behavior:"smooth"})},[]);return(0,n.useEffect)(()=>{const t=a.current;if(!t)return;const l=()=>{m(!d())};return l(),t.addEventListener("scroll",l,{passive:!0}),()=>t.removeEventListener("scroll",l)},[d]),(0,n.useEffect)(()=>{if(s)return;const t=setTimeout(()=>{m(!d())},150);return()=>clearTimeout(t)},[r,s,d]),(0,n.useEffect)(()=>{if(!s||!a.current)return;const t=setTimeout(()=>{a.current&&(a.current.scrollTop=a.current.scrollHeight,m(!1))},100);return()=>clearTimeout(t)},[r,s]),r.length===0&&!p?(0,e.jsx)("div",{className:`flex-1 overflow-hidden ${g}`,children:y||(0,e.jsx)(E,{})}):(0,e.jsxs)("div",{className:"relative flex-1 overflow-hidden",children:[(0,e.jsxs)("div",{ref:a,className:`
|
|
2
2
|
livechat-message-list absolute inset-0 overflow-y-auto p-4
|
|
3
3
|
${g}
|
|
4
|
-
`,children:[p&&(0,e.jsx)(H,{}),(0,e.jsx)("div",{className:"flex flex-col gap-1",children:r.map(t=>(0,e.jsx)(v.ChatMessage,{message:t,rendererRegistry:o,defaultRenderer:
|
|
4
|
+
`,children:[p&&(0,e.jsx)(H,{}),(0,e.jsx)("div",{className:"flex flex-col gap-1",children:r.map(t=>(0,e.jsx)(v.ChatMessage,{message:t,rendererRegistry:o,defaultRenderer:i,showTimestamp:c,onAddToCart:b},t.id))}),s&&(0,e.jsx)(h.ScrollAnchor,{dependencies:[r]})]}),(0,e.jsx)("button",{onClick:x,className:`flex -translate-x-1/2 items-center justify-center ${u?"":"pointer-events-none"}`,style:{position:"absolute",bottom:"24px",left:"50%",zIndex:10,width:"40px",height:"40px",borderRadius:"50%",backgroundColor:"rgba(255, 255, 255, 0.95)",boxShadow:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",transition:"all 300ms ease-in-out",opacity:u?1:0,cursor:"pointer",border:"none"},"aria-label":"Scroll to bottom","aria-hidden":!u,children:(0,e.jsx)("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-gray-700",children:(0,e.jsx)("polyline",{points:"6 9 12 15 18 9"})})})]})};
|
|
5
5
|
//# sourceMappingURL=MessageList.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/LiveChatWidget/components/MessageList.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u6D88\u606F\u5217\u8868\u7EC4\u4EF6\n * \u663E\u793A\u6240\u6709\u804A\u5929\u6D88\u606F\uFF0C\u652F\u6301\u6EDA\u52A8\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u6D88\u606F\u5217\u8868\u8BBE\u8BA1\n */\n\nimport React, { useRef, useEffect, useState, useCallback } from 'react'\nimport type { Message, MessageRenderer } from '../types'\nimport { ChatMessage } from './ChatMessage'\nimport { ScrollAnchor } from './ScrollAnchor'\nimport { MessageRendererRegistry } from '../utils/messageRenderers'\n\nexport interface MessageListProps {\n /**\n * \u6D88\u606F\u5217\u8868\n */\n messages: Message[]\n\n /**\n * \u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n */\n rendererRegistry?: MessageRendererRegistry\n\n /**\n * \u9ED8\u8BA4\u6E32\u67D3\u5668\n */\n defaultRenderer?: MessageRenderer\n\n /**\n * \u662F\u5426\u663E\u793A\u65F6\u95F4\u6233\n * @default true\n */\n showTimestamp?: boolean\n\n /**\n * \u662F\u5426\u81EA\u52A8\u6EDA\u52A8\u5230\u5E95\u90E8\n * @default true\n */\n autoScroll?: boolean\n\n /**\n * \u662F\u5426\u6B63\u5728\u52A0\u8F7D\u5386\u53F2\u6D88\u606F\n * @default false\n */\n isLoadingHistory?: boolean\n\n /**\n * \u7A7A\u72B6\u6001\u5360\u4F4D\u5185\u5BB9\n */\n emptyPlaceholder?: React.ReactNode\n\n /**\n * \u81EA\u5B9A\u4E49\u6837\u5F0F\u7C7B\u540D\n */\n className?: string\n\n /**\n * \u5546\u54C1\u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u56DE\u8C03\n */\n onAddToCart?: (product: any) => void\n}\n\n/**\n * \u9ED8\u8BA4\u7A7A\u72B6\u6001\u5360\u4F4D\n */\nconst DefaultEmptyPlaceholder: React.FC = () => (\n <div className=\"flex h-full items-center justify-center text-gray-400\">\n <p className=\"text-sm\"
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,IAAA,eAAAC,EAAAH,GAmEI,IAAAI,EAAA,6BA7DJC,EAAgE,iBAEhEC,EAA4B,yBAC5BC,EAA6B,0BAwD7B,MAAMC,EAAoC,OACxC,OAAC,OAAI,UAAU,wDACb,mBAAC,KAAE,UAAU,UAAU,
|
|
4
|
+
"sourcesContent": ["/**\n * \u6D88\u606F\u5217\u8868\u7EC4\u4EF6\n * \u663E\u793A\u6240\u6709\u804A\u5929\u6D88\u606F\uFF0C\u652F\u6301\u6EDA\u52A8\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u6D88\u606F\u5217\u8868\u8BBE\u8BA1\n */\n\nimport React, { useRef, useEffect, useState, useCallback } from 'react'\nimport type { Message, MessageRenderer } from '../types'\nimport { ChatMessage } from './ChatMessage'\nimport { ScrollAnchor } from './ScrollAnchor'\nimport { MessageRendererRegistry } from '../utils/messageRenderers'\n\nexport interface MessageListProps {\n /**\n * \u6D88\u606F\u5217\u8868\n */\n messages: Message[]\n\n /**\n * \u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n */\n rendererRegistry?: MessageRendererRegistry\n\n /**\n * \u9ED8\u8BA4\u6E32\u67D3\u5668\n */\n defaultRenderer?: MessageRenderer\n\n /**\n * \u662F\u5426\u663E\u793A\u65F6\u95F4\u6233\n * @default true\n */\n showTimestamp?: boolean\n\n /**\n * \u662F\u5426\u81EA\u52A8\u6EDA\u52A8\u5230\u5E95\u90E8\n * @default true\n */\n autoScroll?: boolean\n\n /**\n * \u662F\u5426\u6B63\u5728\u52A0\u8F7D\u5386\u53F2\u6D88\u606F\n * @default false\n */\n isLoadingHistory?: boolean\n\n /**\n * \u7A7A\u72B6\u6001\u5360\u4F4D\u5185\u5BB9\n */\n emptyPlaceholder?: React.ReactNode\n\n /**\n * \u81EA\u5B9A\u4E49\u6837\u5F0F\u7C7B\u540D\n */\n className?: string\n\n /**\n * \u5546\u54C1\u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u56DE\u8C03\n */\n onAddToCart?: (product: any) => void\n}\n\n/**\n * \u9ED8\u8BA4\u7A7A\u72B6\u6001\u5360\u4F4D\n */\nconst DefaultEmptyPlaceholder: React.FC = () => (\n <div className=\"flex h-full items-center justify-center text-gray-400\">\n <p className=\"text-sm\">No messages yet</p>\n </div>\n)\n\n/**\n * \u52A0\u8F7D\u6307\u793A\u5668\n */\nconst LoadingIndicator: React.FC = () => (\n <div className=\"flex justify-center py-4\">\n <div className=\"flex gap-1\">\n <div className=\"size-2 animate-bounce rounded-full bg-gray-400\" />\n <div className=\"size-2 animate-bounce rounded-full bg-gray-400\" style={{ animationDelay: '0.1s' }} />\n <div className=\"size-2 animate-bounce rounded-full bg-gray-400\" style={{ animationDelay: '0.2s' }} />\n </div>\n </div>\n)\n\n/**\n * \u6D88\u606F\u5217\u8868\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u663E\u793A\u6240\u6709\u6D88\u606F\uFF08\u7528\u6237\u3001\u52A9\u624B\u3001\u7CFB\u7EDF\uFF09\n * - \u81EA\u52A8\u6EDA\u52A8\u5230\u6700\u65B0\u6D88\u606F\n * - \u52A0\u8F7D\u5386\u53F2\u6D88\u606F\u65F6\u663E\u793A\u6307\u793A\u5668\n * - \u7A7A\u72B6\u6001\u5360\u4F4D\n *\n * \u6837\u5F0F\uFF1A\n * - \u4F7F\u7528\u81EA\u5B9A\u4E49\u6EDA\u52A8\u6761\u6837\u5F0F\uFF08livechat.css\uFF09\n * - \u5185\u5BB9\u95F4\u8DDD\u5408\u7406\n * - \u652F\u6301\u54CD\u5E94\u5F0F\u5E03\u5C40\n *\n * @example\n * ```tsx\n * <MessageList\n * messages={messages}\n * rendererRegistry={customRegistry}\n * autoScroll={true}\n * isLoadingHistory={isLoading}\n * />\n * ```\n */\nexport const MessageList: React.FC<MessageListProps> = ({\n messages,\n rendererRegistry,\n defaultRenderer,\n showTimestamp = true,\n autoScroll = true,\n isLoadingHistory = false,\n emptyPlaceholder,\n className = '',\n onAddToCart,\n}) => {\n const listRef = useRef<HTMLDivElement>(null)\n const [showScrollButton, setShowScrollButton] = useState(false)\n\n // \u68C0\u67E5\u662F\u5426\u63A5\u8FD1\u5E95\u90E8\n const isNearBottom = useCallback((threshold = 100) => {\n const container = listRef.current\n if (!container) return true\n\n const { scrollTop, scrollHeight, clientHeight } = container\n return scrollHeight - scrollTop - clientHeight < threshold\n }, [])\n\n // \u5E73\u6ED1\u6EDA\u52A8\u5230\u5E95\u90E8\n const scrollToBottom = useCallback(() => {\n const container = listRef.current\n if (!container) return\n\n container.scrollTo({\n top: container.scrollHeight,\n behavior: 'smooth',\n })\n }, [])\n\n // \u76D1\u542C\u6EDA\u52A8\u4E8B\u4EF6\uFF0C\u63A7\u5236\u6309\u94AE\u663E\u793A\n useEffect(() => {\n const container = listRef.current\n if (!container) return\n\n const handleScroll = () => {\n setShowScrollButton(!isNearBottom())\n }\n\n // \u521D\u59CB\u68C0\u67E5\n handleScroll()\n\n container.addEventListener('scroll', handleScroll, { passive: true })\n return () => container.removeEventListener('scroll', handleScroll)\n }, [isNearBottom])\n\n // \u5F53\u6D88\u606F\u5217\u8868\u53D8\u5316\u65F6\uFF0C\u91CD\u65B0\u68C0\u67E5\u6309\u94AE\u72B6\u6001\uFF08\u4F46\u4E0D\u5728\u81EA\u52A8\u6EDA\u52A8\u65F6\uFF09\n useEffect(() => {\n if (autoScroll) return // \u81EA\u52A8\u6EDA\u52A8\u4F1A\u5728\u53E6\u4E00\u4E2A effect \u4E2D\u5904\u7406\n\n const timeoutId = setTimeout(() => {\n setShowScrollButton(!isNearBottom())\n }, 150)\n\n return () => clearTimeout(timeoutId)\n }, [messages, autoScroll, isNearBottom])\n\n // \u76D1\u542C\u6D88\u606F\u5217\u8868\u53D8\u5316\uFF0C\u81EA\u52A8\u6EDA\u52A8\n useEffect(() => {\n if (!autoScroll || !listRef.current) return\n\n // \u5EF6\u8FDF\u6EDA\u52A8\u4EE5\u786E\u4FDD DOM \u5DF2\u66F4\u65B0\n const timeoutId = setTimeout(() => {\n if (listRef.current) {\n listRef.current.scrollTop = listRef.current.scrollHeight\n // \u81EA\u52A8\u6EDA\u52A8\u5230\u5E95\u90E8\u540E\uFF0C\u9690\u85CF\u6309\u94AE\n setShowScrollButton(false)\n }\n }, 100)\n\n return () => clearTimeout(timeoutId)\n }, [messages, autoScroll])\n\n // \u7A7A\u72B6\u6001\n if (messages.length === 0 && !isLoadingHistory) {\n return (\n <div className={`flex-1 overflow-hidden ${className}`}>{emptyPlaceholder || <DefaultEmptyPlaceholder />}</div>\n )\n }\n\n return (\n <div className=\"relative flex-1 overflow-hidden\">\n <div\n ref={listRef}\n className={`\n livechat-message-list absolute inset-0 overflow-y-auto p-4\n ${className}\n `}\n >\n {/* \u52A0\u8F7D\u5386\u53F2\u6D88\u606F\u6307\u793A\u5668 */}\n {isLoadingHistory && <LoadingIndicator />}\n\n {/* \u6D88\u606F\u5217\u8868 */}\n <div className=\"flex flex-col gap-1\">\n {messages.map(message => (\n <ChatMessage\n key={message.id}\n message={message}\n rendererRegistry={rendererRegistry}\n defaultRenderer={defaultRenderer}\n showTimestamp={showTimestamp}\n onAddToCart={onAddToCart}\n />\n ))}\n </div>\n\n {/* \u6EDA\u52A8\u951A\u70B9 */}\n {autoScroll && <ScrollAnchor dependencies={[messages]} />}\n </div>\n\n {/* \u56DE\u5230\u5E95\u90E8\u6309\u94AE */}\n <button\n onClick={scrollToBottom}\n className={`flex -translate-x-1/2 items-center justify-center ${showScrollButton ? '' : 'pointer-events-none'}`}\n style={{\n position: 'absolute',\n bottom: '24px',\n left: '50%',\n zIndex: 10,\n width: '40px',\n height: '40px',\n borderRadius: '50%',\n backgroundColor: 'rgba(255, 255, 255, 0.95)',\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',\n transition: 'all 300ms ease-in-out',\n opacity: showScrollButton ? 1 : 0,\n cursor: 'pointer',\n border: 'none',\n }}\n aria-label=\"Scroll to bottom\"\n aria-hidden={!showScrollButton}\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-gray-700\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,IAAA,eAAAC,EAAAH,GAmEI,IAAAI,EAAA,6BA7DJC,EAAgE,iBAEhEC,EAA4B,yBAC5BC,EAA6B,0BAwD7B,MAAMC,EAAoC,OACxC,OAAC,OAAI,UAAU,wDACb,mBAAC,KAAE,UAAU,UAAU,2BAAe,EACxC,EAMIC,EAA6B,OACjC,OAAC,OAAI,UAAU,2BACb,oBAAC,OAAI,UAAU,aACb,oBAAC,OAAI,UAAU,iDAAiD,KAChE,OAAC,OAAI,UAAU,iDAAiD,MAAO,CAAE,eAAgB,MAAO,EAAG,KACnG,OAAC,OAAI,UAAU,iDAAiD,MAAO,CAAE,eAAgB,MAAO,EAAG,GACrG,EACF,EA2BWP,EAA0C,CAAC,CACtD,SAAAQ,EACA,iBAAAC,EACA,gBAAAC,EACA,cAAAC,EAAgB,GAChB,WAAAC,EAAa,GACb,iBAAAC,EAAmB,GACnB,iBAAAC,EACA,UAAAC,EAAY,GACZ,YAAAC,CACF,IAAM,CACJ,MAAMC,KAAU,UAAuB,IAAI,EACrC,CAACC,EAAkBC,CAAmB,KAAI,YAAS,EAAK,EAGxDC,KAAe,eAAY,CAACC,EAAY,MAAQ,CACpD,MAAMC,EAAYL,EAAQ,QAC1B,GAAI,CAACK,EAAW,MAAO,GAEvB,KAAM,CAAE,UAAAC,EAAW,aAAAC,EAAc,aAAAC,CAAa,EAAIH,EAClD,OAAOE,EAAeD,EAAYE,EAAeJ,CACnD,EAAG,CAAC,CAAC,EAGCK,KAAiB,eAAY,IAAM,CACvC,MAAMJ,EAAYL,EAAQ,QACrBK,GAELA,EAAU,SAAS,CACjB,IAAKA,EAAU,aACf,SAAU,QACZ,CAAC,CACH,EAAG,CAAC,CAAC,EA8CL,SA3CA,aAAU,IAAM,CACd,MAAMA,EAAYL,EAAQ,QAC1B,GAAI,CAACK,EAAW,OAEhB,MAAMK,EAAe,IAAM,CACzBR,EAAoB,CAACC,EAAa,CAAC,CACrC,EAGA,OAAAO,EAAa,EAEbL,EAAU,iBAAiB,SAAUK,EAAc,CAAE,QAAS,EAAK,CAAC,EAC7D,IAAML,EAAU,oBAAoB,SAAUK,CAAY,CACnE,EAAG,CAACP,CAAY,CAAC,KAGjB,aAAU,IAAM,CACd,GAAIR,EAAY,OAEhB,MAAMgB,EAAY,WAAW,IAAM,CACjCT,EAAoB,CAACC,EAAa,CAAC,CACrC,EAAG,GAAG,EAEN,MAAO,IAAM,aAAaQ,CAAS,CACrC,EAAG,CAACpB,EAAUI,EAAYQ,CAAY,CAAC,KAGvC,aAAU,IAAM,CACd,GAAI,CAACR,GAAc,CAACK,EAAQ,QAAS,OAGrC,MAAMW,EAAY,WAAW,IAAM,CAC7BX,EAAQ,UACVA,EAAQ,QAAQ,UAAYA,EAAQ,QAAQ,aAE5CE,EAAoB,EAAK,EAE7B,EAAG,GAAG,EAEN,MAAO,IAAM,aAAaS,CAAS,CACrC,EAAG,CAACpB,EAAUI,CAAU,CAAC,EAGrBJ,EAAS,SAAW,GAAK,CAACK,KAE1B,OAAC,OAAI,UAAW,0BAA0BE,CAAS,GAAK,SAAAD,MAAoB,OAACR,EAAA,EAAwB,EAAG,KAK1G,QAAC,OAAI,UAAU,kCACb,qBAAC,OACC,IAAKW,EACL,UAAW;AAAA;AAAA,YAEPF,CAAS;AAAA,UAIZ,UAAAF,MAAoB,OAACN,EAAA,EAAiB,KAGvC,OAAC,OAAI,UAAU,sBACZ,SAAAC,EAAS,IAAIqB,MACZ,OAAC,eAEC,QAASA,EACT,iBAAkBpB,EAClB,gBAAiBC,EACjB,cAAeC,EACf,YAAaK,GALRa,EAAQ,EAMf,CACD,EACH,EAGCjB,MAAc,OAAC,gBAAa,aAAc,CAACJ,CAAQ,EAAG,GACzD,KAGA,OAAC,UACC,QAASkB,EACT,UAAW,qDAAqDR,EAAmB,GAAK,qBAAqB,GAC7G,MAAO,CACL,SAAU,WACV,OAAQ,OACR,KAAM,MACN,OAAQ,GACR,MAAO,OACP,OAAQ,OACR,aAAc,MACd,gBAAiB,4BACjB,UAAW,qEACX,WAAY,wBACZ,QAASA,EAAmB,EAAI,EAChC,OAAQ,UACR,OAAQ,MACV,EACA,aAAW,mBACX,cAAa,CAACA,EAEd,mBAAC,OACC,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,QACf,UAAU,gBAEV,mBAAC,YAAS,OAAO,iBAAiB,EACpC,EACF,GACF,CAEJ",
|
|
6
6
|
"names": ["MessageList_exports", "__export", "MessageList", "__toCommonJS", "import_jsx_runtime", "import_react", "import_ChatMessage", "import_ScrollAnchor", "DefaultEmptyPlaceholder", "LoadingIndicator", "messages", "rendererRegistry", "defaultRenderer", "showTimestamp", "autoScroll", "isLoadingHistory", "emptyPlaceholder", "className", "onAddToCart", "listRef", "showScrollButton", "setShowScrollButton", "isNearBottom", "threshold", "container", "scrollTop", "scrollHeight", "clientHeight", "scrollToBottom", "handleScroll", "timeoutId", "message"]
|
|
7
7
|
}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LiveChat 组件常量定义
|
|
3
3
|
*/
|
|
4
|
+
import type { CommonText } from './types';
|
|
4
5
|
/**
|
|
5
6
|
* 货币符号映射表
|
|
6
7
|
* 用于将货币代码转换为对应的符号
|
|
7
8
|
*/
|
|
8
9
|
export declare const CURRENCY_SYMBOLS: Record<string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* 默认文案配置
|
|
12
|
+
*/
|
|
13
|
+
export declare const DEFAULT_COMMON_TEXT: Required<CommonText>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var s=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var n=Object.prototype.hasOwnProperty;var N=(e,o)=>{for(var r in o)s(e,r,{get:o[r],enumerable:!0})},a=(e,o,r,D)=>{if(o&&typeof o=="object"||typeof o=="function")for(let t of T(o))!n.call(e,t)&&t!==r&&s(e,t,{get:()=>o[t],enumerable:!(D=C(o,t))||D.enumerable});return e};var i=e=>a(s({},"__esModule",{value:!0}),e);var M={};N(M,{CURRENCY_SYMBOLS:()=>A,DEFAULT_COMMON_TEXT:()=>L});module.exports=i(M);const A={USD:"$",CAD:"CA$",GBP:"\xA3",EUR:"\u20AC",AUD:"$",SGD:"$",NZD:"NZ$",AED:"AED ",VND:"\u20AB",TWD:"NT$",PLN:"z\u0142",RON:"Lei"},L={learnMore:"Learn More",showLess:"Show Less",addToCart:"Add to Cart",viewMore:"View More",off:"OFF",total:"Total"};
|
|
2
2
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/LiveChatWidget/constants.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * LiveChat \u7EC4\u4EF6\u5E38\u91CF\u5B9A\u4E49\n */\n\n/**\n * \u8D27\u5E01\u7B26\u53F7\u6620\u5C04\u8868\n * \u7528\u4E8E\u5C06\u8D27\u5E01\u4EE3\u7801\u8F6C\u6362\u4E3A\u5BF9\u5E94\u7684\u7B26\u53F7\n */\nexport const CURRENCY_SYMBOLS: Record<string, string> = {\n
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,IAAA,eAAAC,
|
|
6
|
-
"names": ["constants_exports", "__export", "CURRENCY_SYMBOLS", "__toCommonJS"]
|
|
4
|
+
"sourcesContent": ["/**\n * LiveChat \u7EC4\u4EF6\u5E38\u91CF\u5B9A\u4E49\n */\n\nimport type { CommonText } from './types'\n\n/**\n * \u8D27\u5E01\u7B26\u53F7\u6620\u5C04\u8868\n * \u7528\u4E8E\u5C06\u8D27\u5E01\u4EE3\u7801\u8F6C\u6362\u4E3A\u5BF9\u5E94\u7684\u7B26\u53F7\n */\nexport const CURRENCY_SYMBOLS: Record<string, string> = {\n USD: \"$\",\n CAD: \"CA$\",\n GBP: \"\u00A3\",\n EUR: \"\u20AC\",\n AUD: \"$\",\n SGD: \"$\",\n NZD: \"NZ$\",\n AED: \"AED \",\n VND: \"\u20AB\",\n TWD: \"NT$\",\n PLN: \"z\u0142\",\n RON: \"Lei\"\n}\n\n/**\n * \u9ED8\u8BA4\u6587\u6848\u914D\u7F6E\n */\nexport const DEFAULT_COMMON_TEXT: Required<CommonText> = {\n learnMore: 'Learn More',\n showLess: 'Show Less',\n addToCart: 'Add to Cart',\n viewMore: 'View More',\n off: 'OFF',\n total: 'Total',\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,wBAAAC,IAAA,eAAAC,EAAAJ,GAUO,MAAME,EAA2C,CACpD,IAAK,IACL,IAAK,MACL,IAAK,OACL,IAAK,SACL,IAAK,IACL,IAAK,IACL,IAAK,MACL,IAAK,OACL,IAAK,SACL,IAAK,MACL,IAAK,UACL,IAAK,KACT,EAKaC,EAA4C,CACvD,UAAW,aACX,SAAU,YACV,UAAW,cACX,SAAU,YACV,IAAK,MACL,MAAO,OACT",
|
|
6
|
+
"names": ["constants_exports", "__export", "CURRENCY_SYMBOLS", "DEFAULT_COMMON_TEXT", "__toCommonJS"]
|
|
7
7
|
}
|
|
@@ -4,11 +4,20 @@
|
|
|
4
4
|
* 基于 specs/livechat-widget/plan.md 的 API 调用策略
|
|
5
5
|
*/
|
|
6
6
|
import type { ChatStreamRequest, SSEEvent, NewSessionRequest, NewSessionResponse } from '../types';
|
|
7
|
+
import { type RecaptchaConfig } from '../api/chat';
|
|
7
8
|
export interface UseChatAPIOptions {
|
|
8
9
|
/**
|
|
9
10
|
* API 基础 URL
|
|
10
11
|
*/
|
|
11
12
|
apiBaseUrl: string;
|
|
13
|
+
/**
|
|
14
|
+
* 自定义请求头
|
|
15
|
+
*/
|
|
16
|
+
headers?: Record<string, string>;
|
|
17
|
+
/**
|
|
18
|
+
* reCAPTCHA 配置
|
|
19
|
+
*/
|
|
20
|
+
recaptchaConfig?: RecaptchaConfig;
|
|
12
21
|
/**
|
|
13
22
|
* 错误处理回调
|
|
14
23
|
*/
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var E=(t,e)=>{for(var s in e)f(t,s,{get:e[s],enumerable:!0})},g=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of R(e))!d.call(t,r)&&r!==s&&f(t,r,{get:()=>e[r],enumerable:!(o=m(e,r))||o.enumerable});return t};var w=t=>g(f({},"__esModule",{value:!0}),t);var b={};E(b,{useChatAPI:()=>v});module.exports=w(b);var a=require("react"),l=require("../api/chat");function v(t){const{apiBaseUrl:e,headers:s,recaptchaConfig:o,onError:r}=t,n=(0,a.useRef)(null),u=(0,a.useRef)(!1),h=(0,a.useCallback)(async(S,i)=>{n.current&&n.current.abort(),n.current=new AbortController,u.current=!0;try{await(0,l.sendMessage)(e,S,i,s,o)}catch(c){if(c instanceof Error&&c.name==="AbortError")return;throw console.error("[useChatAPI] Stream error:",c),r?.(c),c}finally{u.current=!1,n.current=null}},[e,s,o,r]),p=(0,a.useCallback)(async S=>{try{return await(0,l.createNewSession)(e,S,s,o)}catch(i){throw console.error("[useChatAPI] Create session error:",i),r?.(i),i}},[e,s,o,r]),C=(0,a.useCallback)(()=>{n.current&&(n.current.abort(),n.current=null,u.current=!1)},[]);return{sendMessageStream:h,createSession:p,abortStream:C,isSending:u.current}}
|
|
2
2
|
//# sourceMappingURL=useChatAPI.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/LiveChatWidget/hooks/useChatAPI.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u804A\u5929 API \u8C03\u7528 Hook\n * \u5C01\u88C5 SSE \u6D41\u5F0F\u6D88\u606F\u63A5\u6536\u3001\u5386\u53F2\u6D88\u606F\u52A0\u8F7D\u3001\u65B0\u4F1A\u8BDD\u521B\u5EFA\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684 API \u8C03\u7528\u7B56\u7565\n */\n\nimport { useCallback, useRef } from 'react'\nimport type { ChatStreamRequest, SSEEvent, NewSessionRequest, NewSessionResponse } from '../types'\nimport { sendMessage, createNewSession } from '../api/chat'\n\nexport interface UseChatAPIOptions {\n /**\n * API \u57FA\u7840 URL\n */\n apiBaseUrl: string\n\n /**\n * \u9519\u8BEF\u5904\u7406\u56DE\u8C03\n */\n onError?: (error: Error) => void\n}\n\nexport interface UseChatAPIReturn {\n /**\n * \u53D1\u9001\u6D88\u606F\u5E76\u63A5\u6536 SSE \u6D41\u5F0F\u54CD\u5E94\n * @param request \u8BF7\u6C42\u53C2\u6570\n * @param onEvent SSE \u4E8B\u4EF6\u56DE\u8C03\n * @returns Promise<void>\n */\n sendMessageStream: (request: ChatStreamRequest, onEvent: (event: SSEEvent) => void) => Promise<void>\n\n /**\n * \u521B\u5EFA\u65B0\u4F1A\u8BDD\u6216\u6062\u590D\u73B0\u6709\u4F1A\u8BDD\n * @param request \u8BF7\u6C42\u53C2\u6570\n * @returns \u65B0\u4F1A\u8BDD\u4FE1\u606F\uFF0C\u53EF\u80FD\u5305\u542B\u5386\u53F2\u6D88\u606F\n */\n createSession: (request: NewSessionRequest) => Promise<NewSessionResponse>\n\n /**\n * \u4E2D\u65AD\u5F53\u524D\u7684 SSE \u6D41\n */\n abortStream: () => void\n\n /**\n * \u662F\u5426\u6B63\u5728\u53D1\u9001\u6D88\u606F\n */\n isSending: boolean\n}\n\n/**\n * \u804A\u5929 API \u8C03\u7528 Hook\n *\n * \u529F\u80FD\uFF1A\n * 1. sendMessageStream: \u53D1\u9001\u6D88\u606F\u5E76\u63A5\u6536 SSE \u6D41\u5F0F\u54CD\u5E94\n * 2. createSession: \u521B\u5EFA\u65B0\u4F1A\u8BDD\u6216\u6062\u590D\u73B0\u6709\u4F1A\u8BDD\n * 3. abortStream: \u4E2D\u65AD\u5F53\u524D\u6D41\n *\n * @param options Hook \u914D\u7F6E\u9009\u9879\n * @returns API \u8C03\u7528\u5DE5\u5177\u5BF9\u8C61\n */\nexport function useChatAPI(options: UseChatAPIOptions): UseChatAPIReturn {\n const { apiBaseUrl, onError } = options\n\n // \u7528\u4E8E\u4E2D\u65AD\u5F53\u524D\u8BF7\u6C42\u7684 AbortController\n const abortControllerRef = useRef<AbortController | null>(null)\n\n // \u53D1\u9001\u72B6\u6001\u6807\u8BB0\n const isSendingRef = useRef(false)\n\n /**\n * \u53D1\u9001\u6D88\u606F\u5E76\u63A5\u6536 SSE \u6D41\u5F0F\u54CD\u5E94\n */\n const sendMessageStream = useCallback(\n async (request: ChatStreamRequest, onEvent: (event: SSEEvent) => void) => {\n // \u5982\u679C\u6B63\u5728\u53D1\u9001\uFF0C\u5148\u4E2D\u65AD\u4E4B\u524D\u7684\u8BF7\u6C42\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n }\n\n // \u521B\u5EFA\u65B0\u7684 AbortController\n abortControllerRef.current = new AbortController()\n isSendingRef.current = true\n\n try {\n await sendMessage(apiBaseUrl, request, onEvent)\n } catch (error) {\n // \u5FFD\u7565\u624B\u52A8\u4E2D\u65AD\u7684\u9519\u8BEF\n if (error instanceof Error && error.name === 'AbortError') {\n return\n }\n\n console.error('[useChatAPI] Stream error:', error)\n onError?.(error as Error)\n throw error\n } finally {\n isSendingRef.current = false\n abortControllerRef.current = null\n }\n },\n [apiBaseUrl, onError]\n )\n\n /**\n * \u521B\u5EFA\u65B0\u4F1A\u8BDD\u6216\u6062\u590D\u73B0\u6709\u4F1A\u8BDD\n */\n const createSession = useCallback(\n async (request: NewSessionRequest): Promise<NewSessionResponse> => {\n try {\n return await createNewSession(apiBaseUrl, request)\n } catch (error) {\n console.error('[useChatAPI] Create session error:', error)\n onError?.(error as Error)\n throw error\n }\n },\n [apiBaseUrl, onError]\n )\n\n /**\n * \u4E2D\u65AD\u5F53\u524D\u7684 SSE \u6D41\n */\n const abortStream = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n abortControllerRef.current = null\n isSendingRef.current = false\n }\n }, [])\n\n return {\n sendMessageStream,\n createSession,\n abortStream,\n isSending: isSendingRef.current,\n }\n}\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,IAAA,eAAAC,EAAAH,GAMA,IAAAI,EAAoC,iBAEpCC,
|
|
6
|
-
"names": ["useChatAPI_exports", "__export", "useChatAPI", "__toCommonJS", "import_react", "import_chat", "options", "apiBaseUrl", "onError", "abortControllerRef", "isSendingRef", "sendMessageStream", "request", "onEvent", "error", "createSession", "abortStream"]
|
|
4
|
+
"sourcesContent": ["/**\n * \u804A\u5929 API \u8C03\u7528 Hook\n * \u5C01\u88C5 SSE \u6D41\u5F0F\u6D88\u606F\u63A5\u6536\u3001\u5386\u53F2\u6D88\u606F\u52A0\u8F7D\u3001\u65B0\u4F1A\u8BDD\u521B\u5EFA\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684 API \u8C03\u7528\u7B56\u7565\n */\n\nimport { useCallback, useRef } from 'react'\nimport type { ChatStreamRequest, SSEEvent, NewSessionRequest, NewSessionResponse } from '../types'\nimport { sendMessage, createNewSession, type RecaptchaConfig } from '../api/chat'\n\nexport interface UseChatAPIOptions {\n /**\n * API \u57FA\u7840 URL\n */\n apiBaseUrl: string\n\n /**\n * \u81EA\u5B9A\u4E49\u8BF7\u6C42\u5934\n */\n headers?: Record<string, string>\n\n /**\n * reCAPTCHA \u914D\u7F6E\n */\n recaptchaConfig?: RecaptchaConfig\n\n /**\n * \u9519\u8BEF\u5904\u7406\u56DE\u8C03\n */\n onError?: (error: Error) => void\n}\n\nexport interface UseChatAPIReturn {\n /**\n * \u53D1\u9001\u6D88\u606F\u5E76\u63A5\u6536 SSE \u6D41\u5F0F\u54CD\u5E94\n * @param request \u8BF7\u6C42\u53C2\u6570\n * @param onEvent SSE \u4E8B\u4EF6\u56DE\u8C03\n * @returns Promise<void>\n */\n sendMessageStream: (request: ChatStreamRequest, onEvent: (event: SSEEvent) => void) => Promise<void>\n\n /**\n * \u521B\u5EFA\u65B0\u4F1A\u8BDD\u6216\u6062\u590D\u73B0\u6709\u4F1A\u8BDD\n * @param request \u8BF7\u6C42\u53C2\u6570\n * @returns \u65B0\u4F1A\u8BDD\u4FE1\u606F\uFF0C\u53EF\u80FD\u5305\u542B\u5386\u53F2\u6D88\u606F\n */\n createSession: (request: NewSessionRequest) => Promise<NewSessionResponse>\n\n /**\n * \u4E2D\u65AD\u5F53\u524D\u7684 SSE \u6D41\n */\n abortStream: () => void\n\n /**\n * \u662F\u5426\u6B63\u5728\u53D1\u9001\u6D88\u606F\n */\n isSending: boolean\n}\n\n/**\n * \u804A\u5929 API \u8C03\u7528 Hook\n *\n * \u529F\u80FD\uFF1A\n * 1. sendMessageStream: \u53D1\u9001\u6D88\u606F\u5E76\u63A5\u6536 SSE \u6D41\u5F0F\u54CD\u5E94\n * 2. createSession: \u521B\u5EFA\u65B0\u4F1A\u8BDD\u6216\u6062\u590D\u73B0\u6709\u4F1A\u8BDD\n * 3. abortStream: \u4E2D\u65AD\u5F53\u524D\u6D41\n *\n * @param options Hook \u914D\u7F6E\u9009\u9879\n * @returns API \u8C03\u7528\u5DE5\u5177\u5BF9\u8C61\n */\nexport function useChatAPI(options: UseChatAPIOptions): UseChatAPIReturn {\n const { apiBaseUrl, headers, recaptchaConfig, onError } = options\n\n // \u7528\u4E8E\u4E2D\u65AD\u5F53\u524D\u8BF7\u6C42\u7684 AbortController\n const abortControllerRef = useRef<AbortController | null>(null)\n\n // \u53D1\u9001\u72B6\u6001\u6807\u8BB0\n const isSendingRef = useRef(false)\n\n /**\n * \u53D1\u9001\u6D88\u606F\u5E76\u63A5\u6536 SSE \u6D41\u5F0F\u54CD\u5E94\n */\n const sendMessageStream = useCallback(\n async (request: ChatStreamRequest, onEvent: (event: SSEEvent) => void) => {\n // \u5982\u679C\u6B63\u5728\u53D1\u9001\uFF0C\u5148\u4E2D\u65AD\u4E4B\u524D\u7684\u8BF7\u6C42\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n }\n\n // \u521B\u5EFA\u65B0\u7684 AbortController\n abortControllerRef.current = new AbortController()\n isSendingRef.current = true\n\n try {\n await sendMessage(apiBaseUrl, request, onEvent, headers, recaptchaConfig)\n } catch (error) {\n // \u5FFD\u7565\u624B\u52A8\u4E2D\u65AD\u7684\u9519\u8BEF\n if (error instanceof Error && error.name === 'AbortError') {\n return\n }\n\n console.error('[useChatAPI] Stream error:', error)\n onError?.(error as Error)\n throw error\n } finally {\n isSendingRef.current = false\n abortControllerRef.current = null\n }\n },\n [apiBaseUrl, headers, recaptchaConfig, onError]\n )\n\n /**\n * \u521B\u5EFA\u65B0\u4F1A\u8BDD\u6216\u6062\u590D\u73B0\u6709\u4F1A\u8BDD\n */\n const createSession = useCallback(\n async (request: NewSessionRequest): Promise<NewSessionResponse> => {\n try {\n return await createNewSession(apiBaseUrl, request, headers, recaptchaConfig)\n } catch (error) {\n console.error('[useChatAPI] Create session error:', error)\n onError?.(error as Error)\n throw error\n }\n },\n [apiBaseUrl, headers, recaptchaConfig, onError]\n )\n\n /**\n * \u4E2D\u65AD\u5F53\u524D\u7684 SSE \u6D41\n */\n const abortStream = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n abortControllerRef.current = null\n isSendingRef.current = false\n }\n }, [])\n\n return {\n sendMessageStream,\n createSession,\n abortStream,\n isSending: isSendingRef.current,\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,IAAA,eAAAC,EAAAH,GAMA,IAAAI,EAAoC,iBAEpCC,EAAoE,uBA8D7D,SAASH,EAAWI,EAA8C,CACvE,KAAM,CAAE,WAAAC,EAAY,QAAAC,EAAS,gBAAAC,EAAiB,QAAAC,CAAQ,EAAIJ,EAGpDK,KAAqB,UAA+B,IAAI,EAGxDC,KAAe,UAAO,EAAK,EAK3BC,KAAoB,eACxB,MAAOC,EAA4BC,IAAuC,CAEpEJ,EAAmB,SACrBA,EAAmB,QAAQ,MAAM,EAInCA,EAAmB,QAAU,IAAI,gBACjCC,EAAa,QAAU,GAEvB,GAAI,CACF,QAAM,eAAYL,EAAYO,EAASC,EAASP,EAASC,CAAe,CAC1E,OAASO,EAAO,CAEd,GAAIA,aAAiB,OAASA,EAAM,OAAS,aAC3C,OAGF,cAAQ,MAAM,6BAA8BA,CAAK,EACjDN,IAAUM,CAAc,EAClBA,CACR,QAAE,CACAJ,EAAa,QAAU,GACvBD,EAAmB,QAAU,IAC/B,CACF,EACA,CAACJ,EAAYC,EAASC,EAAiBC,CAAO,CAChD,EAKMO,KAAgB,eACpB,MAAOH,GAA4D,CACjE,GAAI,CACF,OAAO,QAAM,oBAAiBP,EAAYO,EAASN,EAASC,CAAe,CAC7E,OAASO,EAAO,CACd,cAAQ,MAAM,qCAAsCA,CAAK,EACzDN,IAAUM,CAAc,EAClBA,CACR,CACF,EACA,CAACT,EAAYC,EAASC,EAAiBC,CAAO,CAChD,EAKMQ,KAAc,eAAY,IAAM,CAChCP,EAAmB,UACrBA,EAAmB,QAAQ,MAAM,EACjCA,EAAmB,QAAU,KAC7BC,EAAa,QAAU,GAE3B,EAAG,CAAC,CAAC,EAEL,MAAO,CACL,kBAAAC,EACA,cAAAI,EACA,YAAAC,EACA,UAAWN,EAAa,OAC1B,CACF",
|
|
6
|
+
"names": ["useChatAPI_exports", "__export", "useChatAPI", "__toCommonJS", "import_react", "import_chat", "options", "apiBaseUrl", "headers", "recaptchaConfig", "onError", "abortControllerRef", "isSendingRef", "sendMessageStream", "request", "onEvent", "error", "createSession", "abortStream"]
|
|
7
7
|
}
|
|
@@ -14,11 +14,23 @@ export interface UseChatStateOptions {
|
|
|
14
14
|
*/
|
|
15
15
|
site?: string;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* 受控模式:是否打开聊天窗口
|
|
18
|
+
* 提供此参数时,组件处于受控模式
|
|
19
|
+
*/
|
|
20
|
+
open?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* 受控模式:状态变化回调(必需)
|
|
23
|
+
* 用于同步状态到父组件
|
|
24
|
+
*/
|
|
25
|
+
onOpenChange?: (open: boolean) => void;
|
|
26
|
+
/**
|
|
27
|
+
* 窗口打开事件监听(可选)
|
|
28
|
+
* 用于埋点、日志等副作用
|
|
18
29
|
*/
|
|
19
30
|
onOpen?: () => void;
|
|
20
31
|
/**
|
|
21
|
-
*
|
|
32
|
+
* 窗口关闭事件监听(可选)
|
|
33
|
+
* 用于埋点、日志等副作用
|
|
22
34
|
*/
|
|
23
35
|
onClose?: () => void;
|
|
24
36
|
/**
|
|
@@ -29,6 +41,21 @@ export interface UseChatStateOptions {
|
|
|
29
41
|
* 错误处理回调
|
|
30
42
|
*/
|
|
31
43
|
onError?: (error: Error) => void;
|
|
44
|
+
/**
|
|
45
|
+
* AI 消息回调
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* AI 回复文本消息时触发
|
|
49
|
+
*/
|
|
50
|
+
onTextMessage?: () => void;
|
|
51
|
+
/**
|
|
52
|
+
* AI 回复商品列表卡片时触发
|
|
53
|
+
*/
|
|
54
|
+
onProductList?: () => void;
|
|
55
|
+
/**
|
|
56
|
+
* AI 回复促销卡片时触发
|
|
57
|
+
*/
|
|
58
|
+
onPromotionList?: () => void;
|
|
32
59
|
/**
|
|
33
60
|
* 商品添加到购物车回调
|
|
34
61
|
*/
|
|
@@ -37,6 +64,12 @@ export interface UseChatStateOptions {
|
|
|
37
64
|
* 购物车按钮点击回调
|
|
38
65
|
*/
|
|
39
66
|
onCart?: (cartId: string, checkoutUrl?: string) => void;
|
|
67
|
+
/**
|
|
68
|
+
* 自定义产品卡片渲染函数
|
|
69
|
+
* @param product 产品数据(如果在 product_list 中找到),否则为 undefined
|
|
70
|
+
* @param productHandle 文本占位符中的产品 ID,可用于应用层查询产品数据
|
|
71
|
+
*/
|
|
72
|
+
productCardRender?: (product: any, productHandle: string) => React.ReactNode;
|
|
40
73
|
}
|
|
41
74
|
export interface UseChatStateReturn {
|
|
42
75
|
/**
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var z=Object.defineProperty;var ct=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var dt=Object.prototype.hasOwnProperty;var ut=(e,r)=>{for(var f in r)z(e,f,{get:r[f],enumerable:!0})},lt=(e,r,f,M)=>{if(r&&typeof r=="object"||typeof r=="function")for(let d of it(r))!dt.call(e,d)&&d!==f&&z(e,d,{get:()=>r[d],enumerable:!(M=ct(r,d))||M.enumerable});return e};var gt=e=>lt(z({},"__esModule",{value:!0}),e);var xt={};ut(xt,{useChatState:()=>mt});module.exports=gt(xt);var i=require("react"),j=require("../utils/userId"),G=require("./useSession"),V=require("../utils/productTransformers"),J=require("../utils/cartTransformers");function pt(e,r,f,M,d){const o=[],g=/\{\{(?:product:)?([^}]+)\}\}/g;let u=0,l,m=!1;for(;(l=g.exec(e))!==null;){m=!0;const C=e.slice(u,l.index);C&&o.push({type:"text",text:C});const p=l[1].trim(),y=r.get(p),I=f.get(p);y?console.log("[useChatState] \u{1F3AF} \u5B9E\u65F6\u68C0\u6D4B\u5230\u4EA7\u54C1:",p,"\u2192",y.title):console.log("[useChatState] \u{1F4E6} \u5B9E\u65F6\u68C0\u6D4B\u5230\u4EA7\u54C1\u5360\u4F4D\u7B26\uFF0C\u4EA7\u54C1\u6570\u636E\u5F85\u5E94\u7528\u5C42\u67E5\u8BE2:",p),o.push({type:"product_card",data:{product:y,rawProduct:I,productHandle:p,onAddToCart:M,productCardRender:d}}),u=g.lastIndex}if(m){const C=e.slice(u);return{contents:o,remainingBuffer:C}}else{const C=e.match(/\{\{[^}]*$/);if(C){const p=e.slice(0,C.index);return p&&o.push({type:"text",text:p}),{contents:o,remainingBuffer:C[0]}}else return e&&o.push({type:"text",text:e}),{contents:o,remainingBuffer:""}}}function ft(e,r,f,M,d){const o=[],g=/\{\{(?:product:)?([^}]+)\}\}/g;let u=0,l;for(;(l=g.exec(e))!==null;){const C=e.slice(u,l.index).trim(),p=l[1].trim();C&&o.push({type:"text",text:C});const y=r.get(p),I=f.get(p);console.log(y?`[useChatState] \u2705 \u627E\u5230\u4EA7\u54C1\u5339\u914D: ${p} \u2192 ${y.title}`:`[useChatState] \u{1F4E6} \u4EA7\u54C1\u5360\u4F4D\u7B26\uFF0C\u4EA7\u54C1\u6570\u636E\u5F85\u5E94\u7528\u5C42\u67E5\u8BE2: ${p}`),o.push({type:"product_card",data:{product:y,rawProduct:I,productHandle:p,onAddToCart:M,productCardRender:d}}),u=g.lastIndex}const m=e.slice(u).trim();return m&&o.push({type:"text",text:m}),o}function ht(e,r,f,M,d){const o=[];for(const g of e)if(g.type==="text"){const l=ft(g.text,r,f,M,d);o.push(...l)}else{if(g.type==="product_list")continue;o.push(g)}return o}function Ct(e,r,f){if(!e.content.some(u=>u.type==="text"&&/\{\{(?:product:)?[^}]+\}\}/.test(u.text)))return e;console.log("[useChatState] \u68C0\u6D4B\u5230\u5386\u53F2\u6D88\u606F\u9700\u8981\u91CD\u7EC4, \u6D88\u606FID:",e.id);const d=new Map,o=new Map;e.structured_content&&e.structured_content.forEach(u=>{u.type==="product_list"&&Array.isArray(u.data)&&u.data.forEach(l=>{l&&l.handle&&(o.set(l.handle,l),console.log("[useChatState] \u4ECE structured_content \u63D0\u53D6\u539F\u59CB\u4EA7\u54C1\u6570\u636E, handle:",l.handle))})}),e.content.forEach(u=>{u.type==="product_list"&&u.data.products.forEach(m=>{m&&m.handle&&d.set(m.handle,m)})});const g=ht(e.content,d,o,r,f);return{...e,content:g}}function mt(e={}){const{welcomeMessage:r,site:f,open:M,onOpenChange:d,onOpen:o,onClose:g,onMessageSend:u,onError:l,onTextMessage:m,onProductList:C,onPromotionList:p,onAddToCart:y,onCart:I,productCardRender:O}=e,{sessionId:B,saveSession:H,clearSession:L}=(0,G.useSession)(),[K,Q]=(0,i.useState)("");(0,i.useEffect)(()=>{(0,j.getUserId)().then(x=>Q(x))},[]);const[X,D]=(0,i.useState)(()=>r?[{id:`welcome-${Date.now()}`,role:"assistant",content:[{type:"text",text:r}],timestamp:Date.now()}]:[]),[Y,$]=(0,i.useState)(!1),T=M!==void 0,U=T?M:Y,[Z,tt]=(0,i.useState)(""),[et,b]=(0,i.useState)(!1),t=(0,i.useRef)(null),N=(0,i.useRef)(!1),P=(0,i.useRef)(new Map),w=(0,i.useRef)(new Map),S=(0,i.useRef)(""),k=(0,i.useRef)([]),nt=(0,i.useCallback)(()=>{T||$(!0),d?.(!0),o?.()},[T,d,o]),st=(0,i.useCallback)(()=>{T||$(!1),d?.(!1),g?.()},[T,d,g]),at=(0,i.useCallback)(()=>{const x=!U;T||$(x),d?.(x),x?o?.():g?.()},[T,U,d,o,g]),A=(0,i.useCallback)(x=>{if(!x){console.warn("[useChatState] Attempted to add null/undefined message");return}D(R=>[...R,x])},[]),ot=(0,i.useCallback)(x=>{const R=x.filter(s=>s!=null);R.length!==x.length&&console.warn("[useChatState] Filtered out null/undefined messages from batch set");const E=R.map(s=>Ct(s,y,O));D(E)},[y,O]),q=(0,i.useCallback)(()=>{D([])},[]),rt=(0,i.useCallback)(x=>{const{event:R,data:E}=x;switch(R){case"message_start":{b(!0),N.current=!1,S.current="",k.current=[];const s=E;s.sessionId&&s.sessionId!==B&&H(s.sessionId),D(a=>{const n=a[a.length-1];if(n&&n.role==="assistant"&&n.content.length===1&&n.content[0].type==="thinking")return t.current=n,a;{const _=`msg-${Date.now()}`;return t.current={id:_,role:"assistant",content:[{type:"thinking",data:{status:"thinking"}}],timestamp:Date.now()},[...a,t.current]}});break}case"content_delta":{const s=E,a=s.delta||s.text||"";if(t.current&&a){N.current||(N.current=!0,m?.()),t.current.content.some(c=>c.type==="thinking")&&(t.current.content=t.current.content.filter(c=>c.type!=="thinking")),S.current+=a;const{contents:h,remainingBuffer:_}=pt(S.current,P.current,w.current,y,O);S.current=_,h.length>0&&(h.forEach(c=>{const v=t.current.content[t.current.content.length-1];c.type==="text"&&v&&v.type==="text"?v.text+=c.text:t.current.content.push(c)}),D(c=>{if(!t.current)return c;const v=[...c],F=v.findIndex(W=>W&&W.id===t.current.id);return F>=0?v[F]={...t.current}:v.push({...t.current}),v}))}break}case"content_block":{const s=E;if(t.current){const a=s.type||s.data?.type,n=s.data;if(!a||!n){console.warn("[useChatState] Invalid content_block:",s);break}let h;if(a==="product_list"&&Array.isArray(n)){C?.(),n.forEach(c=>{c&&c.handle&&(w.current.set(c.handle,c),console.log("[useChatState] \u7F13\u5B58\u539F\u59CB\u4EA7\u54C1\u6570\u636E, handle:",c.handle))}),(0,V.transformProducts)(n,f).forEach(c=>{c&&c.handle&&(P.current.set(c.handle,c),console.log("[useChatState] \u5EFA\u7ACB\u4EA7\u54C1\u6620\u5C04:",{handle:c.handle,title:c.title}))}),console.log("[useChatState] \u2705 \u4EA7\u54C1\u5217\u8868\u5DF2\u7F13\u5B58\uFF0C\u4E0D\u6DFB\u52A0\u5230\u6D88\u606F\u4E2D\uFF08\u907F\u514D\u95EA\u70C1\uFF09");break}else a==="product_comparison"&&n.products?h={type:"product_comparison",data:{products:(0,V.transformProducts)(n.products,f),dimensions:n.dimensions||{}}}:a==="faq_list"&&n.found!==void 0?h={type:"faq_list",data:n}:a==="quick_replies"&&n.replies?h={type:"quick_replies",data:{replies:n.replies}}:a==="policy"&&n.title&&n.content?h={type:"policy",data:{title:n.title,content:n.content}}:a==="promotion_list"&&n.found!==void 0?(p?.(),h={type:"promotion_list",data:n}):a==="cart"&&n.id!==void 0?h={type:"cart",data:{...(0,J.transformCartData)(n),onCart:I}}:h={type:a,data:n};console.log("[useChatState] \u2705 \u5361\u7247\u5DF2\u7F13\u5B58\uFF0C\u7B49\u5F85\u6587\u672C\u5B8C\u6210\u540E\u663E\u793A:",a),k.current.push(h)}break}case"tool_start":case"tool_end":break;case"message_end":{if(b(!1),t.current&&S.current){console.log("[useChatState] \u5904\u7406\u5269\u4F59\u7F13\u51B2\u533A:",S.current);const s=t.current.content[t.current.content.length-1];s&&s.type==="text"?s.text+=S.current:t.current.content.push({type:"text",text:S.current})}t.current&&k.current.length>0&&(console.log("[useChatState] \u{1F4CB} \u6587\u672C\u5DF2\u5B8C\u6210\uFF0C\u73B0\u5728\u6DFB\u52A0",k.current.length,"\u4E2A\u7F13\u5B58\u7684\u5361\u7247"),t.current.content.push(...k.current)),t.current&&t.current.content.some(a=>a.type==="thinking")&&(console.log("[useChatState] \u26A0\uFE0F message_end \u65F6\u4ECD\u5B58\u5728 thinking block\uFF0C\u7ACB\u5373\u79FB\u9664\uFF08\u89C6\u4E3A\u8D85\u65F6\uFF09"),t.current.content=t.current.content.filter(a=>a.type!=="thinking"),t.current.content.length===0&&t.current.content.push({type:"text",text:"Response timed out, please try again."})),t.current&&D(s=>{if(!t.current)return s;const a=[...s],n=a.findIndex(h=>h&&h.id===t.current.id);return n>=0&&(a[n]={...t.current}),a}),S.current="",k.current=[],P.current.clear(),w.current.clear(),t.current=null;break}case"status":{E.type==="session_expired"&&(q(),L(),r&&A({id:`welcome-${Date.now()}`,role:"assistant",content:[{type:"text",text:r}],timestamp:Date.now()}));break}case"error":{const s=E;b(!1),S.current="",k.current=[],P.current.clear(),w.current.clear(),t.current=null,A({id:`error-${Date.now()}`,role:"system",content:[{type:"error",data:{message:s.message,code:s.code}}],timestamp:Date.now()}),l?.(new Error(s.message));break}case"done":{b(!1),S.current="",k.current=[],P.current.clear(),w.current.clear(),t.current=null;break}default:break}},[r,f,A,q,L,H,B,l,m,C,p,y,I]);return{messages:X,isOpen:U,userId:K,sessionId:B,inputValue:Z,isStreaming:et,openChat:nt,closeChat:st,toggleChat:at,setInputValue:tt,addMessage:A,setMessages:ot,clearMessages:q,handleSSEEvent:rt,saveSession:H,clearSession:L}}
|
|
2
2
|
//# sourceMappingURL=useChatState.js.map
|