@anker-in/campaign-ui 0.2.11-beta.3 → 0.2.11-beta.30
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 +63 -0
- package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js +2 -0
- package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/api/chat.d.ts +46 -0
- package/dist/cjs/components/LiveChatWidget/api/chat.js +3 -0
- package/dist/cjs/components/LiveChatWidget/api/chat.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatBubble.d.ts +68 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatBubble.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatBubble.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatHeader.d.ts +57 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatHeader.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatHeader.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatInput.d.ts +70 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatInput.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatInput.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatMessage.d.ts +59 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatMessage.js +5 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatMessage.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatWindow.d.ts +127 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatWindow.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/ChatWindow.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/CartCard.d.ts +54 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/CartCard.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/CartCard.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ErrorBlock.d.ts +33 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ErrorBlock.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ErrorBlock.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/FAQList.d.ts +16 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/FAQList.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/FAQList.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PolicyBlock.d.ts +45 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PolicyBlock.js +5 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PolicyBlock.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.d.ts +39 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.d.ts +75 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductList.d.ts +47 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductList.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductList.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.d.ts +81 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/QuickReplies.d.ts +54 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/QuickReplies.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/QuickReplies.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.d.ts +31 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ThinkingBlock.d.ts +31 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ThinkingBlock.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/ThinkingBlock.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/index.d.ts +15 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/index.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/index.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent.d.ts +63 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageContent.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageList.d.ts +74 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageList.js +5 -0
- package/dist/cjs/components/LiveChatWidget/components/MessageList.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/components/ScrollAnchor.d.ts +44 -0
- package/dist/cjs/components/LiveChatWidget/components/ScrollAnchor.js +2 -0
- package/dist/cjs/components/LiveChatWidget/components/ScrollAnchor.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/constants.d.ts +13 -0
- package/dist/cjs/components/LiveChatWidget/constants.js +2 -0
- package/dist/cjs/components/LiveChatWidget/constants.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.d.ts +60 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.js +2 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.d.ts +147 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js +2 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useSession.d.ts +37 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useSession.js +2 -0
- package/dist/cjs/components/LiveChatWidget/hooks/useSession.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/index.d.ts +12 -0
- package/dist/cjs/components/LiveChatWidget/index.js +2 -0
- package/dist/cjs/components/LiveChatWidget/index.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/types.d.ts +742 -0
- package/dist/cjs/components/LiveChatWidget/types.js +2 -0
- package/dist/cjs/components/LiveChatWidget/types.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/utils/cartTransformers.d.ts +25 -0
- package/dist/cjs/components/LiveChatWidget/utils/cartTransformers.js +2 -0
- package/dist/cjs/components/LiveChatWidget/utils/cartTransformers.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/utils/fetcher.d.ts +36 -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/LiveChatWidget/utils/messageRenderers.d.ts +64 -0
- package/dist/cjs/components/LiveChatWidget/utils/messageRenderers.js +2 -0
- package/dist/cjs/components/LiveChatWidget/utils/messageRenderers.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/utils/productTransformers.d.ts +43 -0
- package/dist/cjs/components/LiveChatWidget/utils/productTransformers.js +2 -0
- package/dist/cjs/components/LiveChatWidget/utils/productTransformers.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/utils/userId.d.ts +18 -0
- package/dist/cjs/components/LiveChatWidget/utils/userId.js +2 -0
- package/dist/cjs/components/LiveChatWidget/utils/userId.js.map +7 -0
- package/dist/cjs/components/LiveChatWidget/utils/validation.d.ts +37 -0
- package/dist/cjs/components/LiveChatWidget/utils/validation.js +2 -0
- package/dist/cjs/components/LiveChatWidget/utils/validation.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/context/hooks/useRedeemableList.js +1 -1
- package/dist/cjs/components/credits/context/hooks/useRedeemableList.js.map +2 -2
- package/dist/cjs/components/credits/context/memberPriceConst.d.ts +0 -5
- package/dist/cjs/components/credits/context/memberPriceConst.js +1 -1
- package/dist/cjs/components/credits/context/memberPriceConst.js.map +3 -3
- package/dist/cjs/components/credits/context/memberPriceTypes.d.ts +1 -22
- package/dist/cjs/components/credits/context/memberPriceTypes.js +1 -1
- package/dist/cjs/components/credits/context/memberPriceTypes.js.map +1 -1
- package/dist/cjs/components/credits/context/provider.d.ts +16 -1
- package/dist/cjs/components/credits/context/provider.js +1 -1
- package/dist/cjs/components/credits/context/provider.js.map +3 -3
- package/dist/cjs/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js +1 -1
- package/dist/cjs/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js.map +3 -3
- package/dist/cjs/components/credits/creditsBanner/index.d.ts +2 -0
- package/dist/cjs/components/credits/creditsBanner/index.js +12 -1
- package/dist/cjs/components/credits/creditsBanner/index.js.map +3 -3
- package/dist/cjs/components/credits/creditsBenefits/BenefitItem.js +2 -0
- package/dist/cjs/components/credits/creditsBenefits/BenefitItem.js.map +7 -0
- package/dist/cjs/components/credits/creditsBenefits/{iconInfo.js → IconInfo.js} +1 -1
- package/dist/cjs/components/credits/creditsBenefits/{iconInfo.js.map → IconInfo.js.map} +1 -1
- package/dist/cjs/components/credits/creditsCash/CreditsCash.js +1 -1
- package/dist/cjs/components/credits/creditsCash/CreditsCash.js.map +3 -3
- package/dist/cjs/components/credits/creditsCash/RedeemableItem.js +1 -1
- package/dist/cjs/components/credits/creditsCash/RedeemableItem.js.map +3 -3
- package/dist/cjs/components/credits/creditsCash/type.d.ts +1 -0
- package/dist/cjs/components/credits/creditsCash/type.js +1 -1
- package/dist/cjs/components/credits/creditsCash/type.js.map +1 -1
- package/dist/cjs/components/credits/creditsFaq/faqItem/FaqItem.js +1 -1
- package/dist/cjs/components/credits/creditsFaq/faqItem/FaqItem.js.map +3 -3
- package/dist/cjs/components/credits/creditsInfoCard/index.js +1 -1
- package/dist/cjs/components/credits/creditsInfoCard/index.js.map +2 -2
- package/dist/cjs/components/credits/creditsMemberPrice/CreditsMemberPrice.js +1 -1
- package/dist/cjs/components/credits/creditsMemberPrice/CreditsMemberPrice.js.map +3 -3
- package/dist/cjs/components/credits/creditsMemberPrice/MemberPriceItem.js +1 -1
- package/dist/cjs/components/credits/creditsMemberPrice/MemberPriceItem.js.map +3 -3
- package/dist/cjs/components/credits/creditsMemberPrice/type.d.ts +3 -5
- package/dist/cjs/components/credits/creditsMemberPrice/type.js +1 -1
- package/dist/cjs/components/credits/creditsMemberPrice/type.js.map +1 -1
- package/dist/cjs/components/credits/creditsNavigation/CreditsNavigation.js +1 -1
- package/dist/cjs/components/credits/creditsNavigation/CreditsNavigation.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/CreditsRedeemList.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/CreditsRedeemList.js.map +3 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/RedeemableItem.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemableItem.js.map +3 -3
- package/dist/cjs/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js +1 -1
- package/dist/cjs/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js.map +3 -3
- package/dist/cjs/components/index.d.ts +3 -1
- package/dist/cjs/components/index.js +1 -1
- package/dist/cjs/components/index.js.map +3 -3
- package/dist/cjs/components/registration/authCodeActivate/index.js +1 -1
- package/dist/cjs/components/registration/authCodeActivate/index.js.map +2 -2
- package/dist/cjs/stories/CartCard.stories.d.ts +33 -0
- package/dist/cjs/stories/CartCard.stories.js +21 -0
- package/dist/cjs/stories/CartCard.stories.js.map +7 -0
- package/dist/cjs/stories/LiveChatWidget.stories.d.ts +100 -0
- package/dist/cjs/stories/LiveChatWidget.stories.js +132 -0
- package/dist/cjs/stories/LiveChatWidget.stories.js.map +7 -0
- package/dist/cjs/templates/{credits.d.ts → Credits.d.ts} +16 -1
- package/dist/cjs/templates/Credits.js +2 -0
- package/dist/cjs/templates/Credits.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/LiveChatWidget.d.ts +63 -0
- package/dist/esm/components/LiveChatWidget/LiveChatWidget.js +2 -0
- package/dist/esm/components/LiveChatWidget/LiveChatWidget.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/api/chat.d.ts +46 -0
- package/dist/esm/components/LiveChatWidget/api/chat.js +3 -0
- package/dist/esm/components/LiveChatWidget/api/chat.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/ChatBubble.d.ts +68 -0
- package/dist/esm/components/LiveChatWidget/components/ChatBubble.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/ChatBubble.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/ChatHeader.d.ts +57 -0
- package/dist/esm/components/LiveChatWidget/components/ChatHeader.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/ChatHeader.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/ChatInput.d.ts +70 -0
- package/dist/esm/components/LiveChatWidget/components/ChatInput.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/ChatInput.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/ChatMessage.d.ts +59 -0
- package/dist/esm/components/LiveChatWidget/components/ChatMessage.js +5 -0
- package/dist/esm/components/LiveChatWidget/components/ChatMessage.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/ChatWindow.d.ts +127 -0
- package/dist/esm/components/LiveChatWidget/components/ChatWindow.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/ChatWindow.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/CartCard.d.ts +54 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/CartCard.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/CartCard.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ErrorBlock.d.ts +33 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ErrorBlock.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ErrorBlock.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/FAQList.d.ts +16 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/FAQList.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/FAQList.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PolicyBlock.d.ts +45 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PolicyBlock.js +5 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PolicyBlock.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.d.ts +39 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.d.ts +75 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductList.d.ts +47 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductList.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductList.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.d.ts +81 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/QuickReplies.d.ts +54 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/QuickReplies.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/QuickReplies.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.d.ts +31 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ThinkingBlock.d.ts +31 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ThinkingBlock.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/ThinkingBlock.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/index.d.ts +15 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/index.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent/index.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent.d.ts +63 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/MessageContent.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/MessageList.d.ts +74 -0
- package/dist/esm/components/LiveChatWidget/components/MessageList.js +5 -0
- package/dist/esm/components/LiveChatWidget/components/MessageList.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/components/ScrollAnchor.d.ts +44 -0
- package/dist/esm/components/LiveChatWidget/components/ScrollAnchor.js +2 -0
- package/dist/esm/components/LiveChatWidget/components/ScrollAnchor.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/constants.d.ts +13 -0
- package/dist/esm/components/LiveChatWidget/constants.js +2 -0
- package/dist/esm/components/LiveChatWidget/constants.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.d.ts +60 -0
- package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.js +2 -0
- package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.d.ts +147 -0
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.js +2 -0
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/hooks/useSession.d.ts +37 -0
- package/dist/esm/components/LiveChatWidget/hooks/useSession.js +2 -0
- package/dist/esm/components/LiveChatWidget/hooks/useSession.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/index.d.ts +12 -0
- package/dist/esm/components/LiveChatWidget/index.js +2 -0
- package/dist/esm/components/LiveChatWidget/index.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/types.d.ts +742 -0
- package/dist/esm/components/LiveChatWidget/types.js +1 -0
- package/dist/esm/components/LiveChatWidget/types.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/utils/cartTransformers.d.ts +25 -0
- package/dist/esm/components/LiveChatWidget/utils/cartTransformers.js +2 -0
- package/dist/esm/components/LiveChatWidget/utils/cartTransformers.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/utils/fetcher.d.ts +36 -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/LiveChatWidget/utils/messageRenderers.d.ts +64 -0
- package/dist/esm/components/LiveChatWidget/utils/messageRenderers.js +2 -0
- package/dist/esm/components/LiveChatWidget/utils/messageRenderers.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/utils/productTransformers.d.ts +43 -0
- package/dist/esm/components/LiveChatWidget/utils/productTransformers.js +2 -0
- package/dist/esm/components/LiveChatWidget/utils/productTransformers.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/utils/userId.d.ts +18 -0
- package/dist/esm/components/LiveChatWidget/utils/userId.js +2 -0
- package/dist/esm/components/LiveChatWidget/utils/userId.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/utils/validation.d.ts +37 -0
- package/dist/esm/components/LiveChatWidget/utils/validation.js +2 -0
- package/dist/esm/components/LiveChatWidget/utils/validation.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/context/hooks/useRedeemableList.js +1 -1
- package/dist/esm/components/credits/context/hooks/useRedeemableList.js.map +2 -2
- package/dist/esm/components/credits/context/memberPriceConst.d.ts +0 -5
- package/dist/esm/components/credits/context/memberPriceConst.js +1 -1
- package/dist/esm/components/credits/context/memberPriceConst.js.map +3 -3
- package/dist/esm/components/credits/context/memberPriceTypes.d.ts +1 -22
- package/dist/esm/components/credits/context/provider.d.ts +16 -1
- package/dist/esm/components/credits/context/provider.js +1 -1
- package/dist/esm/components/credits/context/provider.js.map +3 -3
- package/dist/esm/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js +1 -1
- package/dist/esm/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js.map +3 -3
- package/dist/esm/components/credits/creditsBanner/index.d.ts +2 -0
- package/dist/esm/components/credits/creditsBanner/index.js +12 -1
- package/dist/esm/components/credits/creditsBanner/index.js.map +3 -3
- package/dist/esm/components/credits/creditsBenefits/BenefitItem.js +2 -0
- package/dist/esm/components/credits/creditsBenefits/BenefitItem.js.map +7 -0
- package/dist/esm/components/credits/creditsBenefits/{iconInfo.js → IconInfo.js} +1 -1
- package/dist/esm/components/credits/creditsBenefits/{iconInfo.js.map → IconInfo.js.map} +1 -1
- package/dist/esm/components/credits/creditsCash/CreditsCash.js +1 -1
- package/dist/esm/components/credits/creditsCash/CreditsCash.js.map +3 -3
- package/dist/esm/components/credits/creditsCash/RedeemableItem.js +1 -1
- package/dist/esm/components/credits/creditsCash/RedeemableItem.js.map +3 -3
- package/dist/esm/components/credits/creditsCash/type.d.ts +1 -0
- package/dist/esm/components/credits/creditsFaq/faqItem/FaqItem.js +1 -1
- package/dist/esm/components/credits/creditsFaq/faqItem/FaqItem.js.map +3 -3
- package/dist/esm/components/credits/creditsInfoCard/index.js +1 -1
- package/dist/esm/components/credits/creditsInfoCard/index.js.map +2 -2
- package/dist/esm/components/credits/creditsMemberPrice/CreditsMemberPrice.js +1 -1
- package/dist/esm/components/credits/creditsMemberPrice/CreditsMemberPrice.js.map +3 -3
- package/dist/esm/components/credits/creditsMemberPrice/MemberPriceItem.js +1 -1
- package/dist/esm/components/credits/creditsMemberPrice/MemberPriceItem.js.map +3 -3
- package/dist/esm/components/credits/creditsMemberPrice/type.d.ts +3 -5
- package/dist/esm/components/credits/creditsNavigation/CreditsNavigation.js +1 -1
- package/dist/esm/components/credits/creditsNavigation/CreditsNavigation.js.map +2 -2
- package/dist/esm/components/credits/creditsRedeemList/CreditsRedeemList.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/CreditsRedeemList.js.map +3 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.js.map +2 -2
- package/dist/esm/components/credits/creditsRedeemList/RedeemableItem.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemableItem.js.map +3 -3
- package/dist/esm/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js +1 -1
- package/dist/esm/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js.map +3 -3
- package/dist/esm/components/index.d.ts +3 -1
- package/dist/esm/components/index.js +1 -1
- package/dist/esm/components/index.js.map +3 -3
- package/dist/esm/components/registration/authCodeActivate/index.js +1 -1
- package/dist/esm/components/registration/authCodeActivate/index.js.map +2 -2
- package/dist/esm/stories/CartCard.stories.d.ts +33 -0
- package/dist/esm/stories/CartCard.stories.js +21 -0
- package/dist/esm/stories/CartCard.stories.js.map +7 -0
- package/dist/esm/stories/LiveChatWidget.stories.d.ts +100 -0
- package/dist/esm/stories/LiveChatWidget.stories.js +132 -0
- package/dist/esm/stories/LiveChatWidget.stories.js.map +7 -0
- package/dist/esm/templates/{credits.d.ts → Credits.d.ts} +16 -1
- package/dist/esm/templates/Credits.js +2 -0
- package/dist/esm/templates/Credits.js.map +7 -0
- 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 +7 -3
- package/src/components/LiveChatWidget/LiveChatWidget.tsx +730 -0
- package/src/components/LiveChatWidget/api/chat.ts +174 -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 +216 -0
- package/src/components/LiveChatWidget/components/ChatMessage.tsx +183 -0
- package/src/components/LiveChatWidget/components/ChatWindow.tsx +353 -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 +127 -0
- package/src/components/LiveChatWidget/components/MessageContent/PolicyBlock.tsx +150 -0
- package/src/components/LiveChatWidget/components/MessageContent/ProductCard.tsx +210 -0
- package/src/components/LiveChatWidget/components/MessageContent/ProductComparison.tsx +359 -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 +89 -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 +29 -0
- package/src/components/LiveChatWidget/hooks/useChatAPI.ts +146 -0
- package/src/components/LiveChatWidget/hooks/useChatState.ts +1007 -0
- package/src/components/LiveChatWidget/hooks/useSession.ts +123 -0
- package/src/components/LiveChatWidget/index.tsx +62 -0
- package/src/components/LiveChatWidget/types.ts +923 -0
- package/src/components/LiveChatWidget/utils/cartTransformers.ts +72 -0
- package/src/components/LiveChatWidget/utils/fetcher.ts +126 -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/context/hooks/useRedeemableList.ts +1 -1
- package/src/components/credits/context/memberPriceConst.ts +0 -7
- package/src/components/credits/context/memberPriceTypes.ts +1 -26
- package/src/components/credits/context/provider.tsx +16 -0
- package/src/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.tsx +26 -26
- package/src/components/credits/creditsBanner/index.tsx +31 -3
- package/src/components/credits/creditsBenefits/BenefitItem.tsx +11 -4
- package/src/components/credits/creditsBenefits/IconInfo.tsx +1 -1
- package/src/components/credits/creditsCash/CreditsCash.tsx +6 -3
- package/src/components/credits/creditsCash/RedeemableItem.tsx +23 -10
- package/src/components/credits/creditsCash/type.ts +1 -0
- package/src/components/credits/creditsFaq/faqItem/FaqItem.tsx +25 -23
- package/src/components/credits/creditsInfoCard/index.tsx +8 -2
- package/src/components/credits/creditsMemberPrice/CreditsMemberPrice.tsx +124 -25
- package/src/components/credits/creditsMemberPrice/MemberPriceItem.tsx +113 -31
- package/src/components/credits/creditsMemberPrice/type.ts +3 -5
- package/src/components/credits/creditsNavigation/CreditsNavigation.tsx +3 -3
- package/src/components/credits/creditsRedeemList/CreditsRedeemList.tsx +31 -18
- package/src/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.tsx +6 -4
- package/src/components/credits/creditsRedeemList/RedeemableItem.tsx +19 -6
- package/src/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.tsx +20 -17
- package/src/components/index.ts +23 -1
- package/src/components/registration/authCodeActivate/index.tsx +2 -0
- package/src/stories/CartCard.stories.tsx +459 -0
- package/src/stories/LiveChatWidget.stories.tsx +572 -0
- package/src/styles/livechat.css +269 -0
- package/src/templates/Credits.tsx +27 -9
- 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/hooks/useSendEmailValidation.d.ts +0 -1
- package/dist/cjs/components/credits/context/hooks/useSendEmailValidation.js +0 -2
- package/dist/cjs/components/credits/context/hooks/useSendEmailValidation.js.map +0 -7
- package/dist/cjs/components/credits/context/hooks/useSubscriptions.d.ts +0 -9
- package/dist/cjs/components/credits/context/hooks/useSubscriptions.js +0 -2
- package/dist/cjs/components/credits/context/hooks/useSubscriptions.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/cjs/components/credits/creditsBenefits/benefitItem.js +0 -2
- package/dist/cjs/components/credits/creditsBenefits/benefitItem.js.map +0 -7
- package/dist/cjs/helpers/fetchResponse.d.ts +0 -14
- package/dist/cjs/helpers/fetchResponse.js +0 -2
- package/dist/cjs/helpers/fetchResponse.js.map +0 -7
- package/dist/cjs/helpers/fetcher.d.ts +0 -2
- package/dist/cjs/helpers/fetcher.js +0 -2
- package/dist/cjs/helpers/fetcher.js.map +0 -7
- package/dist/cjs/helpers/index.d.ts +0 -2
- package/dist/cjs/helpers/index.js +0 -2
- package/dist/cjs/helpers/index.js.map +0 -7
- package/dist/cjs/helpers/track.d.ts +0 -19
- package/dist/cjs/helpers/track.js +0 -2
- package/dist/cjs/helpers/track.js.map +0 -7
- package/dist/cjs/helpers/utils.d.ts +0 -3
- package/dist/cjs/helpers/utils.js +0 -2
- package/dist/cjs/helpers/utils.js.map +0 -7
- package/dist/cjs/templates/credits.js +0 -2
- package/dist/cjs/templates/credits.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/hooks/useSendEmailValidation.d.ts +0 -1
- package/dist/esm/components/credits/context/hooks/useSendEmailValidation.js +0 -2
- package/dist/esm/components/credits/context/hooks/useSendEmailValidation.js.map +0 -7
- package/dist/esm/components/credits/context/hooks/useSubscriptions.d.ts +0 -9
- package/dist/esm/components/credits/context/hooks/useSubscriptions.js +0 -2
- package/dist/esm/components/credits/context/hooks/useSubscriptions.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
- package/dist/esm/components/credits/creditsBenefits/benefitItem.js +0 -2
- package/dist/esm/components/credits/creditsBenefits/benefitItem.js.map +0 -7
- package/dist/esm/helpers/fetchResponse.d.ts +0 -14
- package/dist/esm/helpers/fetchResponse.js +0 -2
- package/dist/esm/helpers/fetchResponse.js.map +0 -7
- package/dist/esm/helpers/fetcher.d.ts +0 -2
- package/dist/esm/helpers/fetcher.js +0 -2
- package/dist/esm/helpers/fetcher.js.map +0 -7
- package/dist/esm/helpers/index.d.ts +0 -2
- package/dist/esm/helpers/index.js +0 -2
- package/dist/esm/helpers/index.js.map +0 -7
- package/dist/esm/helpers/track.d.ts +0 -19
- package/dist/esm/helpers/track.js +0 -2
- package/dist/esm/helpers/track.js.map +0 -7
- package/dist/esm/helpers/utils.d.ts +0 -3
- package/dist/esm/helpers/utils.js +0 -2
- package/dist/esm/helpers/utils.js.map +0 -7
- package/dist/esm/templates/credits.js +0 -2
- package/dist/esm/templates/credits.js.map +0 -7
- package/src/components/credits/context/hooks/useFunctionMemberPrice.ts +0 -33
- package/src/components/credits/context/utils/atobID.ts +0 -8
- package/src/components/credits/context/utils/functionDiscountCalculate.ts +0 -57
- package/src/components/credits/context/utils/getFunctionMemberPrice.ts +0 -135
- package/src/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.ts +0 -51
- package/src/components/credits/context/utils/variantGetCoupon.ts +0 -34
- /package/dist/cjs/components/credits/creditsBenefits/{benefitItem.d.ts → BenefitItem.d.ts} +0 -0
- /package/dist/cjs/components/credits/creditsBenefits/{iconInfo.d.ts → IconInfo.d.ts} +0 -0
- /package/dist/esm/components/credits/creditsBenefits/{benefitItem.d.ts → BenefitItem.d.ts} +0 -0
- /package/dist/esm/components/credits/creditsBenefits/{iconInfo.d.ts → IconInfo.d.ts} +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiveChat 主组件
|
|
3
|
+
* 集成所有子组件,提供完整的聊天功能
|
|
4
|
+
* 基于 specs/livechat-widget/plan.md 的三层架构设计
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { LiveChatWidgetProps } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* LiveChat 聊天组件
|
|
10
|
+
*
|
|
11
|
+
* 功能:
|
|
12
|
+
* - 气泡弹窗聊天界面
|
|
13
|
+
* - SSE 流式消息接收
|
|
14
|
+
* - 会话管理(userId, sessionId)
|
|
15
|
+
* - 历史消息加载
|
|
16
|
+
* - 多种消息类型渲染
|
|
17
|
+
* - 自定义扩展机制
|
|
18
|
+
* - reCAPTCHA v3 安全防护
|
|
19
|
+
*
|
|
20
|
+
* 架构:
|
|
21
|
+
* - UI Layer: ChatBubble, ChatWindow, MessageList, etc.
|
|
22
|
+
* - Logic Layer: useChatState, useChatAPI, useSession
|
|
23
|
+
* - Core Layer: MessageRendererRegistry, 自定义渲染器
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* // 基础使用(使用默认位置)
|
|
28
|
+
* <LiveChatWidget
|
|
29
|
+
* apiBaseUrl="https://beta-api-livechat.anker.com"
|
|
30
|
+
* site="www.eufy.com"
|
|
31
|
+
* welcomeMessage="你好!我是 AI 助手"
|
|
32
|
+
* onMessageSend={(msg) => console.log('Sent:', msg)}
|
|
33
|
+
* />
|
|
34
|
+
*
|
|
35
|
+
* // 使用自定义位置
|
|
36
|
+
* <LiveChatWidget
|
|
37
|
+
* apiBaseUrl="https://beta-api-livechat.anker.com"
|
|
38
|
+
* site="www.eufy.com"
|
|
39
|
+
* position={{ bottom: "20px", right: "30px" }}
|
|
40
|
+
* onMessageSend={(msg) => console.log('Sent:', msg)}
|
|
41
|
+
* />
|
|
42
|
+
*
|
|
43
|
+
* // 启用 reCAPTCHA v3 安全防护(提供 sitekey 即自动启用)
|
|
44
|
+
* <LiveChatWidget
|
|
45
|
+
* apiBaseUrl="https://beta-api-livechat.anker.com"
|
|
46
|
+
* site="www.eufy.com"
|
|
47
|
+
* recaptchaSitekey="6LfS4J4pAAAAACX1e_WrxutmxxzCK7FU4WzVqL14"
|
|
48
|
+
* recaptchaAction="livechat"
|
|
49
|
+
* />
|
|
50
|
+
*
|
|
51
|
+
* // 使用自定义 headers 和 reCAPTCHA
|
|
52
|
+
* <LiveChatWidget
|
|
53
|
+
* apiBaseUrl="https://beta-api-livechat.anker.com"
|
|
54
|
+
* site="www.eufy.com"
|
|
55
|
+
* headers={{
|
|
56
|
+
* "Authorization": "Bearer your-token",
|
|
57
|
+
* "X-Custom-Header": "value"
|
|
58
|
+
* }}
|
|
59
|
+
* recaptchaSitekey="your-site-key"
|
|
60
|
+
* />
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare const LiveChatWidget: React.FC<LiveChatWidgetProps>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var De=Object.create;var B=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var Ee=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var qe=(r,o)=>{for(var p in o)B(r,p,{get:o[p],enumerable:!0})},U=(r,o,p,P)=>{if(o&&typeof o=="object"||typeof o=="function")for(let i of Pe(o))!Te.call(r,i)&&i!==p&&B(r,i,{get:()=>o[i],enumerable:!(P=Me(o,i))||P.enumerable});return r};var b=(r,o,p)=>(p=r!=null?De(Ee(r)):{},U(o||!r||!r.__esModule?B(p,"default",{value:r,enumerable:!0}):p,r)),ve=r=>U(B({},"__esModule",{value:!0}),r);var Be={};qe(Be,{LiveChatWidget:()=>Fe});module.exports=ve(Be);var g=require("react/jsx-runtime"),c=b(require("react")),z=b(require("@radix-ui/react-dialog")),ee=require("./constants"),te=require("./components/ChatBubble"),se=require("./components/ChatWindow"),ae=require("./hooks/useChatState"),ne=require("./hooks/useChatAPI"),re=require("./utils/messageRenderers"),ie=require("./utils/validation"),k=require("./utils/productTransformers.js"),oe=require("./utils/cartTransformers.js"),a=require("./components/MessageContent/index.js");const Fe=({apiBaseUrl:r,headers:o,recaptchaSitekey:p,recaptchaAction:P,site:i,channelCode:w,loginUserId:h,cartId:V,accessToken:K,position:de,welcomeMessage:x,quickReplies:y,customRenderers:L,logoUrl:ce,title:pe,chatBubbleIcon:ue,open:le,onOpenChange:me,onOpen:ge,onClose:fe,onMessageSend:O,onError:_,onTextMessage:ye,onProductList:he,onPromotionList:_e,onAddToCart:E,onCart:A,showNewSessionButton:Ce,commonText:X})=>{const S=c.default.useMemo(()=>({...ee.DEFAULT_COMMON_TEXT,...X}),[X]),we=(0,ae.useChatState)({welcomeMessage:x,site:i,open:le,onOpenChange:me,onOpen:ge,onClose:fe,onMessageSend:O,onError:_,onTextMessage:ye,onProductList:he,onPromotionList:_e,onAddToCart:E,onCart:A}),{messages:I,isOpen:T,userId:u,sessionId:W,inputValue:$,isStreaming:Re,openChat:G,closeChat:H,setInputValue:N,addMessage:f,setMessages:q,clearMessages:v,handleSSEEvent:J,saveSession:F,clearSession:D}=we,{sendMessageStream:Y,createSession:R}=(0,ne.useChatAPI)({apiBaseUrl:r,headers:o,recaptchaConfig:{needRecaptcha:!!p,recaptchaSitekey:p,recaptchaAction:P},onError:_}),Z=c.default.useRef(async t=>{}),xe=c.default.useMemo(()=>{const t=new re.MessageRendererRegistry;t.register("text",a.TextBlock),t.register("product_card",a.ProductCard),t.register("product_list",a.ProductList),t.register("product_comparison",a.ProductComparisonRenderer),t.register("policy",a.PolicyBlock),t.register("thinking",a.ThinkingBlock),t.register("error",a.ErrorBlock),t.register("faq_list",a.FAQListRenderer),t.register("promotion_list",a.PromotionListRenderer),t.register("cart",a.CartCard);const s=(0,a.createQuickRepliesRenderer)(n=>{Z.current(n.value)});return t.register("quick_replies",s),L&&t.registerMany(L),t},[L]);(0,c.useEffect)(()=>{if(!T||!u)return;const t=W;t?Se(t):M()},[T,u]);const j=(0,c.useCallback)(t=>{if(Array.isArray(t.content))return t;const s=[];typeof t.content=="string"&&t.content.trim()&&s.push({type:"text",text:t.content});const n=t.structuredContent||t.structured_content;return Array.isArray(n)&&n.forEach(e=>{if(e.type==="product_list"&&Array.isArray(e.data))s.push({type:"product_list",data:{products:(0,k.transformProducts)(e.data,i),title:void 0,commonText:S}});else if(e.type==="quick_replies"&&e.data?.replies)s.push({type:"quick_replies",data:{replies:e.data.replies}});else if(e.type==="policy"&&e.data?.title&&e.data?.content)s.push({type:"policy",data:{title:e.data.title,content:e.data.content}});else if(e.type==="product_comparison"&&e.data?.products&&e.data?.dimensions)s.push({type:"product_comparison",data:{products:(0,k.transformProducts)(e.data.products,i),dimensions:e.data.dimensions,onAddToCart:E,commonText:S}});else if(e.type==="faq_list"&&e.data?.found!==void 0)s.push({type:"faq_list",data:e.data});else if(e.type==="promotion_list"&&e.data?.found!==void 0)s.push({type:"promotion_list",data:{...e.data,commonText:S}});else if(e.type==="cart"&&e.data?.id!==void 0){const l=(0,oe.transformCartData)(e.data);s.push({type:"cart",data:{...l,onCart:A,commonText:S}})}else s.push(e)}),s.length===0&&s.push({type:"text",text:""}),{...t,content:s}},[i,A,E,S]),M=(0,c.useCallback)(async()=>{if(u)try{const t=await R({user_id:u,site:i,channel_code:w,real_user_id:h});if(t.success){F(t.sessionId),v();const s=t.welcomeMessage||x;if(s){const n=[{type:"text",text:s}],e=t.quickQuestions;if(e&&e.length>0){const l=e.map((d,C)=>({id:`quick-${C}`,label:d,value:d}));n.push({type:"quick_replies",data:{replies:l}})}else y&&y.length>0&&n.push({type:"quick_replies",data:{replies:y}});f({id:`welcome-${Date.now()}`,role:"assistant",content:n,timestamp:Date.now()})}}}catch(t){console.error("[LiveChatWidget] Failed to create new session:",t),_?.(t),f({id:`error-${Date.now()}`,role:"system",content:[{type:"error",data:{message:"Failed to create session. Please refresh the page and try again.",code:"SESSION_CREATE_ERROR"}}],timestamp:Date.now()})}},[u,i,w,h,R,F,v,x,y,f,_]),Se=(0,c.useCallback)(async t=>{try{const s=await R({user_id:u,session_id:t,site:i,channel_code:w,real_user_id:h});if(s.success&&s.resumed)if(s.messages&&s.messages.length>0){const n=s.messages.filter(e=>e!=null).map(j).filter(e=>e.content&&e.content.length>0&&!(e.content.length===1&&e.content[0].type==="text"&&!e.content[0].text));q(n)}else{v();const n=s.welcomeMessage||x;if(n){const e=[{type:"text",text:n}],l=s.quickQuestions;if(l&&l.length>0){const d=l.map((C,m)=>({id:`quick-${m}`,label:C,value:C}));e.push({type:"quick_replies",data:{replies:d}})}else y&&y.length>0&&e.push({type:"quick_replies",data:{replies:y}});f({id:`welcome-${Date.now()}`,role:"assistant",content:e,timestamp:Date.now()})}}else s.resumed||(D(),M())}catch(s){console.error("[LiveChatWidget] Failed to resume session:",s),f({id:`error-${Date.now()}`,role:"system",content:[{type:"error",data:{message:"Failed to resume session. Creating a new session...",code:"SESSION_RESUME_ERROR"}}],timestamp:Date.now()}),D(),M()}},[u,i,w,h,R,q,D,v,j,M,x,y,f]),Q=(0,c.useCallback)(async t=>{const s=t||$.trim();if(!s)return;t||N("");const n=(0,ie.sanitizeInput)(s);if(!n){_?.(new Error("Invalid message"));return}const e={id:`user-${Date.now()}`,role:"user",content:[{type:"text",text:n}],timestamp:Date.now()};f(e);const l={id:`thinking-${Date.now()}`,role:"assistant",content:[{type:"thinking",data:{status:"thinking"}}],timestamp:Date.now()};f(l),O?.(n);try{let d=W;if(!d){const m=await R({user_id:u,site:i,channel_code:w,real_user_id:h});if(m.success)d=m.sessionId,F(d);else throw new Error("Failed to create session")}await Y({message:n,user_id:u,session_id:d,context:{cartId:V,accessToken:K,real_user_id:h}},m=>{J(m),m.event==="status"&&m.data.type==="session_expired"&&D()})}catch(d){console.error("[LiveChatWidget] Failed to send message:",d),_?.(d);const C=I.filter(m=>m.id!==l.id);q([...C,{id:`error-${Date.now()}`,role:"system",content:[{type:"error",data:{message:"Failed to send message. Please check your network connection and try again.",code:"NETWORK_ERROR"}}],timestamp:Date.now()}])}},[$,u,W,i,w,h,V,K,I,N,f,q,R,Y,J,F,D,O,_]);return c.default.useEffect(()=>{Z.current=Q},[Q]),(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(te.ChatBubble,{position:de,onClick:G,visible:!T,iconImageUrl:ue}),(0,g.jsx)(z.Root,{open:T,onOpenChange:t=>t?G():H(),children:(0,g.jsx)(z.Portal,{children:(0,g.jsx)(z.Content,{className:"livechat-window-enter",style:{position:"fixed",zIndex:9998},children:(0,g.jsx)(se.ChatWindow,{messages:I,inputValue:$,onInputChange:N,onSend:()=>Q(),onClose:H,onNewSession:M,title:pe,logoUrl:ce,isSending:Re,rendererRegistry:xe,inputPlaceholder:"",onAddToCart:E,showNewSessionButton:Ce})})})})]})};
|
|
2
|
+
//# sourceMappingURL=LiveChatWidget.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/components/LiveChatWidget/LiveChatWidget.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * LiveChat \u4E3B\u7EC4\u4EF6\n * \u96C6\u6210\u6240\u6709\u5B50\u7EC4\u4EF6\uFF0C\u63D0\u4F9B\u5B8C\u6574\u7684\u804A\u5929\u529F\u80FD\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u4E09\u5C42\u67B6\u6784\u8BBE\u8BA1\n */\n\nimport React, { useEffect, useCallback } from 'react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type {\n LiveChatWidgetProps,\n QuickReply,\n Message,\n MessageContent,\n ChatStreamRequest,\n BackendCartData,\n CommonText,\n} from './types'\nimport { DEFAULT_COMMON_TEXT } from './constants'\nimport { ChatBubble } from './components/ChatBubble'\nimport { ChatWindow } from './components/ChatWindow'\nimport { useChatState } from './hooks/useChatState'\nimport { useChatAPI } from './hooks/useChatAPI'\nimport { MessageRendererRegistry } from './utils/messageRenderers'\nimport { sanitizeInput } from './utils/validation'\nimport { transformProducts } from './utils/productTransformers.js'\nimport { transformCartData } from './utils/cartTransformers.js'\nimport {\n TextBlock,\n ProductCard,\n ProductList,\n ProductComparisonRenderer,\n PolicyBlock,\n createQuickRepliesRenderer,\n ThinkingBlock,\n ErrorBlock,\n FAQListRenderer,\n PromotionListRenderer,\n CartCard,\n} from './components/MessageContent/index.js'\n\n/**\n * LiveChat \u804A\u5929\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u6C14\u6CE1\u5F39\u7A97\u804A\u5929\u754C\u9762\n * - SSE \u6D41\u5F0F\u6D88\u606F\u63A5\u6536\n * - \u4F1A\u8BDD\u7BA1\u7406\uFF08userId, sessionId\uFF09\n * - \u5386\u53F2\u6D88\u606F\u52A0\u8F7D\n * - \u591A\u79CD\u6D88\u606F\u7C7B\u578B\u6E32\u67D3\n * - \u81EA\u5B9A\u4E49\u6269\u5C55\u673A\u5236\n * - reCAPTCHA v3 \u5B89\u5168\u9632\u62A4\n *\n * \u67B6\u6784\uFF1A\n * - UI Layer: ChatBubble, ChatWindow, MessageList, etc.\n * - Logic Layer: useChatState, useChatAPI, useSession\n * - Core Layer: MessageRendererRegistry, \u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\n *\n * @example\n * ```tsx\n * // \u57FA\u7840\u4F7F\u7528\uFF08\u4F7F\u7528\u9ED8\u8BA4\u4F4D\u7F6E\uFF09\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * welcomeMessage=\"\u4F60\u597D\uFF01\u6211\u662F AI \u52A9\u624B\"\n * onMessageSend={(msg) => console.log('Sent:', msg)}\n * />\n *\n * // \u4F7F\u7528\u81EA\u5B9A\u4E49\u4F4D\u7F6E\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * position={{ bottom: \"20px\", right: \"30px\" }}\n * onMessageSend={(msg) => console.log('Sent:', msg)}\n * />\n *\n * // \u542F\u7528 reCAPTCHA v3 \u5B89\u5168\u9632\u62A4\uFF08\u63D0\u4F9B sitekey \u5373\u81EA\u52A8\u542F\u7528\uFF09\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * recaptchaSitekey=\"6LfS4J4pAAAAACX1e_WrxutmxxzCK7FU4WzVqL14\"\n * recaptchaAction=\"livechat\"\n * />\n *\n * // \u4F7F\u7528\u81EA\u5B9A\u4E49 headers \u548C reCAPTCHA\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * headers={{\n * \"Authorization\": \"Bearer your-token\",\n * \"X-Custom-Header\": \"value\"\n * }}\n * recaptchaSitekey=\"your-site-key\"\n * />\n * ```\n */\nexport const LiveChatWidget: React.FC<LiveChatWidgetProps> = ({\n apiBaseUrl,\n headers,\n recaptchaSitekey,\n recaptchaAction,\n site,\n channelCode,\n loginUserId,\n cartId,\n accessToken,\n position,\n welcomeMessage,\n quickReplies,\n customRenderers,\n logoUrl,\n title,\n chatBubbleIcon,\n open,\n onOpenChange,\n onOpen,\n onClose,\n onMessageSend,\n onError,\n onTextMessage,\n onProductList,\n onPromotionList,\n onAddToCart,\n onCart,\n showNewSessionButton,\n commonText,\n}) => {\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText: Required<CommonText> = React.useMemo(\n () => ({\n ...DEFAULT_COMMON_TEXT,\n ...commonText,\n }),\n [commonText]\n )\n\n // \u72B6\u6001\u7BA1\u7406\n const chatState = useChatState({\n welcomeMessage,\n site,\n open,\n onOpenChange,\n onOpen,\n onClose,\n onMessageSend,\n onError,\n onTextMessage,\n onProductList,\n onPromotionList,\n onAddToCart,\n onCart,\n })\n\n const {\n messages,\n isOpen,\n userId,\n sessionId,\n inputValue,\n isStreaming,\n openChat,\n closeChat,\n setInputValue,\n addMessage,\n setMessages,\n clearMessages,\n handleSSEEvent,\n saveSession,\n clearSession,\n } = chatState\n\n // API \u8C03\u7528\n const { sendMessageStream, createSession } = useChatAPI({\n apiBaseUrl,\n headers,\n recaptchaConfig: {\n needRecaptcha: !!recaptchaSitekey, // \u6839\u636E sitekey \u81EA\u52A8\u5224\u65AD\u662F\u5426\u542F\u7528\n recaptchaSitekey,\n recaptchaAction,\n },\n onError,\n })\n\n // \u4F7F\u7528 ref \u5B58\u50A8\u6700\u65B0\u7684 handleSendMessage\uFF0C\u907F\u514D\u5FAA\u73AF\u4F9D\u8D56\n const handleSendMessageRef = React.useRef<(_message?: string) => Promise<void>>(async (_message?: string) => {})\n\n // \u6D88\u606F\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n const rendererRegistry = React.useMemo(() => {\n const registry = new MessageRendererRegistry()\n\n // \u6CE8\u518C\u9ED8\u8BA4\u6E32\u67D3\u5668\n registry.register('text', TextBlock)\n registry.register('product_card', ProductCard)\n registry.register('product_list', ProductList)\n registry.register('product_comparison', ProductComparisonRenderer)\n registry.register('policy', PolicyBlock)\n registry.register('thinking', ThinkingBlock)\n registry.register('error', ErrorBlock)\n registry.register('faq_list', FAQListRenderer)\n registry.register('promotion_list', PromotionListRenderer)\n registry.register('cart', CartCard)\n\n // \u6CE8\u518C\u5FEB\u6377\u56DE\u590D\u6E32\u67D3\u5668\uFF08\u5E26\u56DE\u8C03\uFF09\n const quickRepliesRenderer = createQuickRepliesRenderer((reply: QuickReply) => {\n // \u4F7F\u7528 ref \u8C03\u7528\u6700\u65B0\u7684 handleSendMessage\n handleSendMessageRef.current(reply.value)\n })\n registry.register('quick_replies', quickRepliesRenderer)\n\n // \u6CE8\u518C\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\n if (customRenderers) {\n registry.registerMany(customRenderers)\n }\n\n return registry\n }, [customRenderers])\n\n /**\n * T043: \u6253\u5F00\u804A\u5929\u7A97\u53E3\u65F6\u521D\u59CB\u5316\u4F1A\u8BDD\n * \u4F7F\u7528 API v2.0.0 \u7684\u7EDF\u4E00\u63A5\u53E3\uFF1A\n * - \u5982\u679C\u6CA1\u6709 sessionId\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n * - \u5982\u679C\u6709 sessionId\uFF0C\u6062\u590D\u4F1A\u8BDD\u5E76\u52A0\u8F7D\u5386\u53F2\u6D88\u606F\n */\n useEffect(() => {\n if (!isOpen || !userId) return\n\n const currentSessionId = sessionId\n\n if (!currentSessionId) {\n // \u6CA1\u6709\u4F1A\u8BDD\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n handleCreateNewSession()\n } else {\n // \u6709\u4F1A\u8BDD\uFF0C\u5C1D\u8BD5\u6062\u590D\u4F1A\u8BDD\u548C\u5386\u53F2\u6D88\u606F\n handleResumeSession(currentSessionId)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, userId])\n\n /**\n * \u89C4\u8303\u5316\u6D88\u606F\u683C\u5F0F\uFF08\u786E\u4FDD content \u662F\u6570\u7EC4\uFF09\n * \u540E\u7AEF\u8FD4\u56DE\u683C\u5F0F\uFF1A\n * - content: \u5B57\u7B26\u4E32\uFF08\u6587\u672C\u5185\u5BB9\uFF09\n * - structuredContent: \u6570\u7EC4\uFF08\u7ED3\u6784\u5316\u5185\u5BB9\uFF0C\u5982\u4EA7\u54C1\u5217\u8868\u3001\u653F\u7B56\u7B49\uFF09\n * \u9700\u8981\u5408\u5E76\u4E3A\u7EDF\u4E00\u7684 content \u6570\u7EC4\u683C\u5F0F\n */\n const normalizeMessage = useCallback(\n (message: any): Message => {\n // \u5982\u679C content \u5DF2\u7ECF\u662F\u6570\u7EC4\uFF0C\u76F4\u63A5\u8FD4\u56DE\n if (Array.isArray(message.content)) {\n return message as Message\n }\n\n const contentBlocks: MessageContent[] = []\n\n // \u5904\u7406\u6587\u672C\u5185\u5BB9\n if (typeof message.content === 'string' && message.content.trim()) {\n contentBlocks.push({\n type: 'text',\n text: message.content,\n })\n }\n\n // \u5904\u7406\u7ED3\u6784\u5316\u5185\u5BB9\n // \u5386\u53F2\u6D88\u606F\u683C\u5F0F: structured_content: [{type, data}]\n const structuredData = message.structuredContent || message.structured_content\n\n if (Array.isArray(structuredData)) {\n structuredData.forEach((block: any) => {\n if (block.type === 'product_list' && Array.isArray(block.data)) {\n // \u8F6C\u6362\u4EA7\u54C1\u5217\u8868\u6570\u636E\u7ED3\u6784 - data \u76F4\u63A5\u662F\u4EA7\u54C1\u6570\u7EC4\n contentBlocks.push({\n type: 'product_list',\n data: {\n products: transformProducts(block.data, site),\n title: undefined, // \u5386\u53F2\u6D88\u606F\u4E0D\u5305\u542B title\n commonText: mergedText,\n },\n })\n } else if (block.type === 'quick_replies' && block.data?.replies) {\n contentBlocks.push({\n type: 'quick_replies',\n data: {\n replies: block.data.replies,\n },\n })\n } else if (block.type === 'policy' && block.data?.title && block.data?.content) {\n contentBlocks.push({\n type: 'policy',\n data: {\n title: block.data.title,\n content: block.data.content,\n },\n })\n } else if (block.type === 'product_comparison' && block.data?.products && block.data?.dimensions) {\n // \u8F6C\u6362\u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\u7ED3\u6784\u5E76\u6CE8\u5165 onAddToCart \u56DE\u8C03\n contentBlocks.push({\n type: 'product_comparison',\n data: {\n products: transformProducts(block.data.products, site),\n dimensions: block.data.dimensions,\n onAddToCart: onAddToCart,\n commonText: mergedText,\n },\n })\n } else if (block.type === 'faq_list' && block.data?.found !== undefined) {\n // FAQ \u5217\u8868\u5361\u7247 - \u76F4\u63A5\u4F7F\u7528\u540E\u7AEF\u6570\u636E\n contentBlocks.push({\n type: 'faq_list',\n data: block.data,\n })\n } else if (block.type === 'promotion_list' && block.data?.found !== undefined) {\n // \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u5361\u7247 - \u76F4\u63A5\u4F7F\u7528\u540E\u7AEF\u6570\u636E\n contentBlocks.push({\n type: 'promotion_list',\n data: {\n ...block.data,\n commonText: mergedText,\n },\n })\n } else if (block.type === 'cart' && block.data?.id !== undefined) {\n // \u8D2D\u7269\u8F66\u5361\u7247 - \u8F6C\u6362\u540E\u7AEF\u6570\u636E\u683C\u5F0F\u5E76\u6CE8\u5165 onCart \u56DE\u8C03\n const transformedData = transformCartData(block.data as BackendCartData)\n contentBlocks.push({\n type: 'cart',\n data: {\n ...transformedData,\n onCart: onCart,\n commonText: mergedText,\n },\n })\n } else {\n // \u5176\u4ED6\u7C7B\u578B\u76F4\u63A5\u6DFB\u52A0\n contentBlocks.push(block)\n }\n })\n }\n\n // \u5982\u679C\u6CA1\u6709\u4EFB\u4F55\u5185\u5BB9\u5757\uFF0C\u8FD4\u56DE\u7A7A\u6587\u672C\u5757\n if (contentBlocks.length === 0) {\n contentBlocks.push({\n type: 'text',\n text: '',\n })\n }\n\n return {\n ...message,\n content: contentBlocks,\n } as Message\n },\n [site, onCart, onAddToCart, mergedText]\n )\n\n /**\n * \u521B\u5EFA\u65B0\u4F1A\u8BDD\n */\n const handleCreateNewSession = useCallback(async () => {\n if (!userId) return\n\n try {\n const response = await createSession({\n user_id: userId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n\n if (response.success) {\n // \u4FDD\u5B58\u65B0\u4F1A\u8BDD ID\n saveSession(response.sessionId)\n\n // \u6E05\u7A7A\u6D88\u606F\u5217\u8868\n clearMessages()\n\n // \u4F7F\u7528\u540E\u7AEF\u8FD4\u56DE\u7684\u6B22\u8FCE\u6D88\u606F\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u4F7F\u7528 props \u4E2D\u7684\u9ED8\u8BA4\u503C\n const messageText = response.welcomeMessage || welcomeMessage\n\n if (messageText) {\n const welcomeContent: MessageContent[] = [{ type: 'text', text: messageText }]\n\n // \u4F7F\u7528\u540E\u7AEF\u8FD4\u56DE\u7684\u5FEB\u6377\u95EE\u9898\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u4F7F\u7528 props \u4E2D\u7684\u5FEB\u6377\u56DE\u590D\n const questions = response.quickQuestions\n if (questions && questions.length > 0) {\n // \u5C06\u540E\u7AEF\u7684 quickQuestions (\u5B57\u7B26\u4E32\u6570\u7EC4) \u8F6C\u6362\u4E3A QuickReply \u683C\u5F0F\n const quickRepliesFromBackend = questions.map((question, index) => ({\n id: `quick-${index}`,\n label: question,\n value: question,\n }))\n\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickRepliesFromBackend,\n },\n })\n } else if (quickReplies && quickReplies.length > 0) {\n // \u5982\u679C\u540E\u7AEF\u6CA1\u6709\u8FD4\u56DE\uFF0C\u4F7F\u7528 props \u4E2D\u7684\u5FEB\u6377\u56DE\u590D\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickReplies,\n },\n })\n }\n\n addMessage({\n id: `welcome-${Date.now()}`,\n role: 'assistant',\n content: welcomeContent,\n timestamp: Date.now(),\n })\n }\n }\n } catch (error) {\n console.error('[LiveChatWidget] Failed to create new session:', error)\n onError?.(error as Error)\n\n // \u6DFB\u52A0\u9519\u8BEF\u6D88\u606F\u5230\u754C\u9762\n addMessage({\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: 'Failed to create session. Please refresh the page and try again.',\n code: 'SESSION_CREATE_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n })\n }\n }, [\n userId,\n site,\n channelCode,\n loginUserId,\n createSession,\n saveSession,\n clearMessages,\n welcomeMessage,\n quickReplies,\n addMessage,\n onError,\n ])\n\n /**\n * \u6062\u590D\u4F1A\u8BDD\u548C\u5386\u53F2\u6D88\u606F\uFF08\u4F7F\u7528\u65B0\u7684 API v2.0.0\uFF09\n */\n const handleResumeSession = useCallback(\n async (existingSessionId: string) => {\n try {\n const response = await createSession({\n user_id: userId,\n session_id: existingSessionId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n\n if (response.success && response.resumed) {\n // \u4F1A\u8BDD\u6062\u590D\u6210\u529F\n if (response.messages && response.messages.length > 0) {\n // \u6709\u5386\u53F2\u6D88\u606F\uFF0C\u89C4\u8303\u5316\u5E76\u52A0\u8F7D\uFF08\u8FC7\u6EE4\u6389 null/undefined \u503C\u548C\u7A7A\u5185\u5BB9\u6D88\u606F\uFF09\n const normalizedMessages = response.messages\n .filter((msg: any) => msg != null)\n .map(normalizeMessage)\n .filter((msg: Message) => msg.content && msg.content.length > 0 && !(msg.content.length === 1 && msg.content[0].type === 'text' && !msg.content[0].text))\n setMessages(normalizedMessages)\n } else {\n // \u6CA1\u6709\u5386\u53F2\u6D88\u606F\uFF0C\u663E\u793A\u6B22\u8FCE\u6D88\u606F\n clearMessages()\n\n // \u4F7F\u7528\u540E\u7AEF\u8FD4\u56DE\u7684\u6B22\u8FCE\u6D88\u606F\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u4F7F\u7528 props \u4E2D\u7684\u9ED8\u8BA4\u503C\n const messageText = response.welcomeMessage || welcomeMessage\n\n if (messageText) {\n const welcomeContent: MessageContent[] = [{ type: 'text', text: messageText }]\n\n // \u4F7F\u7528\u540E\u7AEF\u8FD4\u56DE\u7684\u5FEB\u6377\u95EE\u9898\n const questions = response.quickQuestions\n if (questions && questions.length > 0) {\n const quickRepliesFromBackend = questions.map((question, index) => ({\n id: `quick-${index}`,\n label: question,\n value: question,\n }))\n\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickRepliesFromBackend,\n },\n })\n } else if (quickReplies && quickReplies.length > 0) {\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickReplies,\n },\n })\n }\n\n addMessage({\n id: `welcome-${Date.now()}`,\n role: 'assistant',\n content: welcomeContent,\n timestamp: Date.now(),\n })\n }\n }\n } else if (!response.resumed) {\n // \u4F1A\u8BDD\u65E0\u6548\u6216\u8FC7\u671F\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n clearSession()\n handleCreateNewSession()\n }\n } catch (error) {\n console.error('[LiveChatWidget] Failed to resume session:', error)\n\n // \u6DFB\u52A0\u9519\u8BEF\u6D88\u606F\u5230\u754C\u9762\n addMessage({\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: 'Failed to resume session. Creating a new session...',\n code: 'SESSION_RESUME_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n })\n\n // \u6062\u590D\u5931\u8D25\uFF0C\u6E05\u7A7A\u4F1A\u8BDD\u5E76\u521B\u5EFA\u65B0\u7684\n clearSession()\n handleCreateNewSession()\n }\n },\n [\n userId,\n site,\n channelCode,\n loginUserId,\n createSession,\n setMessages,\n clearSession,\n clearMessages,\n normalizeMessage,\n handleCreateNewSession,\n welcomeMessage,\n quickReplies,\n addMessage,\n ]\n )\n\n /**\n * \u53D1\u9001\u6D88\u606F\n */\n const handleSendMessage = useCallback(\n async (message?: string) => {\n const textToSend = message || inputValue.trim()\n\n if (!textToSend) return\n\n // \u6E05\u7A7A\u8F93\u5165\u6846\n if (!message) {\n setInputValue('')\n }\n\n // \u8F93\u5165\u9A8C\u8BC1\n const sanitized = sanitizeInput(textToSend)\n if (!sanitized) {\n onError?.(new Error('Invalid message'))\n return\n }\n\n // \u6DFB\u52A0\u7528\u6237\u6D88\u606F\u5230\u754C\u9762\n const userMessage = {\n id: `user-${Date.now()}`,\n role: 'user' as const,\n content: [{ type: 'text' as const, text: sanitized }],\n timestamp: Date.now(),\n }\n addMessage(userMessage)\n\n // \u7ACB\u5373\u6DFB\u52A0\u601D\u8003\u72B6\u6001\u6D88\u606F\uFF0C\u63D0\u5347\u7528\u6237\u4F53\u9A8C\n const thinkingMessage = {\n id: `thinking-${Date.now()}`,\n role: 'assistant' as const,\n content: [{ type: 'thinking' as const, data: { status: 'thinking' } }],\n timestamp: Date.now(),\n }\n addMessage(thinkingMessage)\n\n // \u89E6\u53D1\u6D88\u606F\u53D1\u9001\u56DE\u8C03\n onMessageSend?.(sanitized)\n\n try {\n // \u786E\u4FDD\u6709 sessionId\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u5148\u521B\u5EFA\u4F1A\u8BDD\n let currentSessionId = sessionId\n if (!currentSessionId) {\n // \u6CA1\u6709\u4F1A\u8BDD\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n const response = await createSession({\n user_id: userId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n if (response.success) {\n currentSessionId = response.sessionId\n saveSession(currentSessionId)\n } else {\n throw new Error('Failed to create session')\n }\n }\n\n // \u6784\u5EFA\u8BF7\u6C42\u53C2\u6570\uFF08session_id \u73B0\u5728\u662F\u5FC5\u586B\u7684\uFF09\n const requestPayload: ChatStreamRequest = {\n message: sanitized,\n user_id: userId,\n session_id: currentSessionId,\n context: {\n cartId: cartId,\n accessToken: accessToken,\n real_user_id: loginUserId,\n },\n }\n\n // \u53D1\u9001\u6D88\u606F\u5230\u540E\u7AEF\n await sendMessageStream(requestPayload, event => {\n // \u5904\u7406 SSE \u4E8B\u4EF6\n handleSSEEvent(event)\n\n // \u7279\u6B8A\u5904\u7406\uFF1A\u4F1A\u8BDD\u8FC7\u671F\n if (event.event === 'status' && event.data.type === 'session_expired') {\n clearSession()\n }\n })\n } catch (error) {\n console.error('[LiveChatWidget] Failed to send message:', error)\n onError?.(error as Error)\n\n // \u79FB\u9664\u521A\u624D\u6DFB\u52A0\u7684 thinking \u6D88\u606F\uFF0C\u5E76\u6DFB\u52A0\u9519\u8BEF\u6D88\u606F\n const messagesWithoutThinking = messages.filter(msg => msg.id !== thinkingMessage.id)\n setMessages([\n ...messagesWithoutThinking,\n {\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: 'Failed to send message. Please check your network connection and try again.',\n code: 'NETWORK_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n },\n ])\n }\n },\n [\n inputValue,\n userId,\n sessionId,\n site,\n channelCode,\n loginUserId,\n cartId,\n accessToken,\n messages,\n setInputValue,\n addMessage,\n setMessages,\n createSession,\n sendMessageStream,\n handleSSEEvent,\n saveSession,\n clearSession,\n onMessageSend,\n onError,\n ]\n )\n\n // \u66F4\u65B0 ref \u4EE5\u4FDD\u6301\u6700\u65B0\u7684 handleSendMessage\n React.useEffect(() => {\n handleSendMessageRef.current = handleSendMessage\n }, [handleSendMessage])\n\n return (\n <>\n {/* \u6C14\u6CE1\u6309\u94AE */}\n <ChatBubble position={position} onClick={openChat} visible={!isOpen} iconImageUrl={chatBubbleIcon} />\n\n {/* \u804A\u5929\u7A97\u53E3\uFF08\u4F7F\u7528 Radix UI Dialog\uFF09 */}\n <Dialog.Root open={isOpen} onOpenChange={open => (open ? openChat() : closeChat())}>\n <Dialog.Portal>\n <Dialog.Content\n className=\"livechat-window-enter\"\n style={{\n position: 'fixed',\n zIndex: 9998,\n }}\n >\n <ChatWindow\n messages={messages}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSend={() => handleSendMessage()}\n onClose={closeChat}\n onNewSession={handleCreateNewSession}\n title={title}\n logoUrl={logoUrl}\n isSending={isStreaming}\n rendererRegistry={rendererRegistry}\n inputPlaceholder=\"\"\n onAddToCart={onAddToCart}\n showNewSessionButton={showNewSessionButton}\n />\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n </>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["LiveChatWidget_exports", "__export", "LiveChatWidget", "__toCommonJS", "import_jsx_runtime", "import_react", "Dialog", "import_constants", "import_ChatBubble", "import_ChatWindow", "import_useChatState", "import_useChatAPI", "import_messageRenderers", "import_validation", "import_productTransformers", "import_cartTransformers", "import_MessageContent", "apiBaseUrl", "headers", "recaptchaSitekey", "recaptchaAction", "site", "channelCode", "loginUserId", "cartId", "accessToken", "position", "welcomeMessage", "quickReplies", "customRenderers", "logoUrl", "title", "chatBubbleIcon", "open", "onOpenChange", "onOpen", "onClose", "onMessageSend", "onError", "onTextMessage", "onProductList", "onPromotionList", "onAddToCart", "onCart", "showNewSessionButton", "commonText", "mergedText", "React", "chatState", "messages", "isOpen", "userId", "sessionId", "inputValue", "isStreaming", "openChat", "closeChat", "setInputValue", "addMessage", "setMessages", "clearMessages", "handleSSEEvent", "saveSession", "clearSession", "sendMessageStream", "createSession", "handleSendMessageRef", "_message", "rendererRegistry", "registry", "quickRepliesRenderer", "reply", "currentSessionId", "handleResumeSession", "handleCreateNewSession", "normalizeMessage", "message", "contentBlocks", "structuredData", "block", "transformedData", "response", "messageText", "welcomeContent", "questions", "quickRepliesFromBackend", "question", "index", "error", "existingSessionId", "normalizedMessages", "msg", "handleSendMessage", "textToSend", "sanitized", "userMessage", "thinkingMessage", "event", "messagesWithoutThinking"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiveChat API 层
|
|
3
|
+
* 处理 SSE 流式通信和 HTTP 请求
|
|
4
|
+
* 基于 specs/livechat-widget/contracts/*.yaml
|
|
5
|
+
*/
|
|
6
|
+
import type { ChatStreamRequest, SSEEvent, NewSessionRequest, NewSessionResponse } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Recaptcha 配置
|
|
9
|
+
*/
|
|
10
|
+
export interface RecaptchaConfig {
|
|
11
|
+
/**
|
|
12
|
+
* 是否启用 reCAPTCHA
|
|
13
|
+
*/
|
|
14
|
+
needRecaptcha?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* reCAPTCHA site key
|
|
17
|
+
*/
|
|
18
|
+
recaptchaSitekey?: string;
|
|
19
|
+
/**
|
|
20
|
+
* reCAPTCHA action 名称
|
|
21
|
+
*/
|
|
22
|
+
recaptchaAction?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 发送消息并接收 SSE 流式响应
|
|
26
|
+
* @param apiBaseUrl API 基础 URL
|
|
27
|
+
* @param request 请求参数
|
|
28
|
+
* @param onEvent SSE 事件回调
|
|
29
|
+
* @param customHeaders 自定义请求头
|
|
30
|
+
* @param recaptchaConfig reCAPTCHA 配置
|
|
31
|
+
*/
|
|
32
|
+
export declare function sendMessage(apiBaseUrl: string, request: ChatStreamRequest, onEvent: (event: SSEEvent) => void, customHeaders?: Record<string, string>, recaptchaConfig?: RecaptchaConfig): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* 创建新会话或恢复现有会话
|
|
35
|
+
*
|
|
36
|
+
* 使用场景:
|
|
37
|
+
* 1. 创建新会话:不传 session_id,返回新的 sessionId
|
|
38
|
+
* 2. 恢复会话:传入 session_id,验证会话有效性并返回历史消息(resumed: true, messages: [...])
|
|
39
|
+
*
|
|
40
|
+
* @param apiBaseUrl API 基础 URL
|
|
41
|
+
* @param request 请求参数
|
|
42
|
+
* @param customHeaders 自定义请求头
|
|
43
|
+
* @param recaptchaConfig reCAPTCHA 配置
|
|
44
|
+
* @returns 会话信息,可能包含历史消息
|
|
45
|
+
*/
|
|
46
|
+
export declare function createNewSession(apiBaseUrl: string, request: NewSessionRequest, customHeaders?: Record<string, string>, recaptchaConfig?: RecaptchaConfig): Promise<NewSessionResponse>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";var l=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var v=(r,t)=>{for(var s in t)l(r,s,{get:t[s],enumerable:!0})},T=(r,t,s,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of g(t))!E.call(r,e)&&e!==s&&l(r,e,{get:()=>t[e],enumerable:!(a=y(t,e))||a.enumerable});return r};var b=r=>T(l({},"__esModule",{value:!0}),r);var A={};v(A,{createNewSession:()=>k,sendMessage:()=>P});module.exports=b(A);var R=require("../utils/fetcher");async function P(r,t,s,a,e){const o=await(0,R.fetcher)({url:`${r}/api/chat/stream`,method:"POST",headers:{Accept:"text/event-stream",...a},body:t,needRecaptcha:e?.needRecaptcha,recaptchaSitekey:e?.recaptchaSitekey,recaptchaAction:e?.recaptchaAction||"send_message"});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);const i=o.body?.getReader();if(!i)throw new Error("Response body is not readable");const m=new TextDecoder;let d="",p=null;try{for(;;){const{done:c,value:w}=await i.read();if(c)break;d+=m.decode(w,{stream:!0});const S=d.split(`
|
|
2
|
+
`);d=S.pop()||"";for(const f of S){const n=f.trim();if(n===""){p=null;continue}if(n.startsWith("event:"))p=n.substring(6).trim();else if(n.startsWith("data:")){const u=n.substring(5).trim();try{const h=JSON.parse(u);s({event:p||"message",data:h})}catch(h){console.error("[LiveChat API] Failed to parse SSE data:",u,h),s({event:"error",data:{message:"Failed to parse SSE data",code:"PARSE_ERROR"}})}}}}}catch(c){throw console.error("[LiveChat API] SSE stream error:",c),c}finally{i.releaseLock()}}async function k(r,t,s,a){const e=await(0,R.fetcher)({url:`${r}/api/chat/new-session`,method:"POST",headers:s,body:t,needRecaptcha:a?.needRecaptcha,recaptchaSitekey:a?.recaptchaSitekey,recaptchaAction:a?.recaptchaAction||"new_session"});if(!e.ok){const o=await e.json().catch(()=>({success:!1,error:`HTTP ${e.status}: ${e.statusText}`,code:"HTTP_ERROR"}));throw new Error(o.error||"Failed to create session")}return e.json()}
|
|
3
|
+
//# sourceMappingURL=chat.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/components/LiveChatWidget/api/chat.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * LiveChat API \u5C42\n * \u5904\u7406 SSE \u6D41\u5F0F\u901A\u4FE1\u548C HTTP \u8BF7\u6C42\n * \u57FA\u4E8E specs/livechat-widget/contracts/*.yaml\n */\n\nimport type { ChatStreamRequest, SSEEvent, NewSessionRequest, NewSessionResponse, ErrorResponse } from '../types'\nimport { fetcher } from '../utils/fetcher'\n\n/**\n * Recaptcha \u914D\u7F6E\n */\nexport interface RecaptchaConfig {\n /**\n * \u662F\u5426\u542F\u7528 reCAPTCHA\n */\n needRecaptcha?: boolean\n /**\n * reCAPTCHA site key\n */\n recaptchaSitekey?: string\n /**\n * reCAPTCHA action \u540D\u79F0\n */\n recaptchaAction?: string\n}\n\n// ============================================================================\n// SSE \u6D41\u5F0F\u6D88\u606F\u5904\u7406 (T006)\n// ============================================================================\n\n/**\n * \u53D1\u9001\u6D88\u606F\u5E76\u63A5\u6536 SSE \u6D41\u5F0F\u54CD\u5E94\n * @param apiBaseUrl API \u57FA\u7840 URL\n * @param request \u8BF7\u6C42\u53C2\u6570\n * @param onEvent SSE \u4E8B\u4EF6\u56DE\u8C03\n * @param customHeaders \u81EA\u5B9A\u4E49\u8BF7\u6C42\u5934\n * @param recaptchaConfig reCAPTCHA \u914D\u7F6E\n */\nexport async function sendMessage(\n apiBaseUrl: string,\n request: ChatStreamRequest,\n onEvent: (event: SSEEvent) => void,\n customHeaders?: Record<string, string>,\n recaptchaConfig?: RecaptchaConfig\n): Promise<void> {\n // \u4F7F\u7528 fetcher \u5904\u7406 reCAPTCHA \u548C\u81EA\u5B9A\u4E49 headers\n const response = await fetcher({\n url: `${apiBaseUrl}/api/chat/stream`,\n method: 'POST',\n headers: {\n Accept: 'text/event-stream',\n ...customHeaders,\n },\n body: request,\n needRecaptcha: recaptchaConfig?.needRecaptcha,\n recaptchaSitekey: recaptchaConfig?.recaptchaSitekey,\n recaptchaAction: recaptchaConfig?.recaptchaAction || 'send_message',\n })\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('Response body is not readable')\n }\n\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent: string | null = null\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n // \u89E3\u7801\u5E76\u8FFD\u52A0\u5230\u7F13\u51B2\u533A\n buffer += decoder.decode(value, { stream: true })\n\n // \u6309\u884C\u5206\u5272\n const lines = buffer.split('\\n')\n\n // \u4FDD\u7559\u6700\u540E\u4E00\u4E2A\u4E0D\u5B8C\u6574\u7684\u884C\n buffer = lines.pop() || ''\n\n for (const line of lines) {\n const trimmed = line.trim()\n\n if (trimmed === '') {\n // \u7A7A\u884C\u8868\u793A\u4E8B\u4EF6\u8FB9\u754C\uFF0C\u91CD\u7F6E\u5F53\u524D\u4E8B\u4EF6\u7C7B\u578B\n currentEvent = null\n continue\n }\n\n if (trimmed.startsWith('event:')) {\n // \u63D0\u53D6\u4E8B\u4EF6\u7C7B\u578B\n currentEvent = trimmed.substring(6).trim()\n } else if (trimmed.startsWith('data:')) {\n // \u63D0\u53D6\u6570\u636E\u5E76\u89E3\u6790 JSON\n const dataStr = trimmed.substring(5).trim()\n try {\n const data = JSON.parse(dataStr)\n onEvent({\n event: (currentEvent as any) || 'message',\n data,\n })\n } catch (err) {\n console.error('[LiveChat API] Failed to parse SSE data:', dataStr, err)\n onEvent({\n event: 'error',\n data: {\n message: 'Failed to parse SSE data',\n code: 'PARSE_ERROR',\n },\n })\n }\n }\n }\n }\n } catch (error) {\n console.error('[LiveChat API] SSE stream error:', error)\n throw error\n } finally {\n reader.releaseLock()\n }\n}\n\n// ============================================================================\n// \u521B\u5EFA/\u6062\u590D\u4F1A\u8BDD (T009)\n// ============================================================================\n\n/**\n * \u521B\u5EFA\u65B0\u4F1A\u8BDD\u6216\u6062\u590D\u73B0\u6709\u4F1A\u8BDD\n *\n * \u4F7F\u7528\u573A\u666F\uFF1A\n * 1. \u521B\u5EFA\u65B0\u4F1A\u8BDD\uFF1A\u4E0D\u4F20 session_id\uFF0C\u8FD4\u56DE\u65B0\u7684 sessionId\n * 2. \u6062\u590D\u4F1A\u8BDD\uFF1A\u4F20\u5165 session_id\uFF0C\u9A8C\u8BC1\u4F1A\u8BDD\u6709\u6548\u6027\u5E76\u8FD4\u56DE\u5386\u53F2\u6D88\u606F\uFF08resumed: true, messages: [...]\uFF09\n *\n * @param apiBaseUrl API \u57FA\u7840 URL\n * @param request \u8BF7\u6C42\u53C2\u6570\n * @param customHeaders \u81EA\u5B9A\u4E49\u8BF7\u6C42\u5934\n * @param recaptchaConfig reCAPTCHA \u914D\u7F6E\n * @returns \u4F1A\u8BDD\u4FE1\u606F\uFF0C\u53EF\u80FD\u5305\u542B\u5386\u53F2\u6D88\u606F\n */\nexport async function createNewSession(\n apiBaseUrl: string,\n request: NewSessionRequest,\n customHeaders?: Record<string, string>,\n recaptchaConfig?: RecaptchaConfig\n): Promise<NewSessionResponse> {\n // \u4F7F\u7528 fetcher \u5904\u7406 reCAPTCHA \u548C\u81EA\u5B9A\u4E49 headers\n const response = await fetcher({\n url: `${apiBaseUrl}/api/chat/new-session`,\n method: 'POST',\n headers: customHeaders,\n body: request,\n needRecaptcha: recaptchaConfig?.needRecaptcha,\n recaptchaSitekey: recaptchaConfig?.recaptchaSitekey,\n recaptchaAction: recaptchaConfig?.recaptchaAction || 'new_session',\n })\n\n if (!response.ok) {\n const errorData: ErrorResponse = await response.json().catch(() => ({\n success: false,\n error: `HTTP ${response.status}: ${response.statusText}`,\n code: 'HTTP_ERROR',\n }))\n throw new Error(errorData.error || 'Failed to create session')\n }\n\n return response.json()\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,gBAAAC,IAAA,eAAAC,EAAAJ,GAOA,IAAAK,EAAwB,4BAgCxB,eAAsBF,EACpBG,EACAC,EACAC,EACAC,EACAC,EACe,CAEf,MAAMC,EAAW,QAAM,WAAQ,CAC7B,IAAK,GAAGL,CAAU,mBAClB,OAAQ,OACR,QAAS,CACP,OAAQ,oBACR,GAAGG,CACL,EACA,KAAMF,EACN,cAAeG,GAAiB,cAChC,iBAAkBA,GAAiB,iBACnC,gBAAiBA,GAAiB,iBAAmB,cACvD,CAAC,EAED,GAAI,CAACC,EAAS,GACZ,MAAM,IAAI,MAAM,QAAQA,EAAS,MAAM,KAAKA,EAAS,UAAU,EAAE,EAGnE,MAAMC,EAASD,EAAS,MAAM,UAAU,EACxC,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,+BAA+B,EAGjD,MAAMC,EAAU,IAAI,YACpB,IAAIC,EAAS,GACTC,EAA8B,KAElC,GAAI,CACF,OAAa,CACX,KAAM,CAAE,KAAAC,EAAM,MAAAC,CAAM,EAAI,MAAML,EAAO,KAAK,EAC1C,GAAII,EAAM,MAGVF,GAAUD,EAAQ,OAAOI,EAAO,CAAE,OAAQ,EAAK,CAAC,EAGhD,MAAMC,EAAQJ,EAAO,MAAM;AAAA,CAAI,EAG/BA,EAASI,EAAM,IAAI,GAAK,GAExB,UAAWC,KAAQD,EAAO,CACxB,MAAME,EAAUD,EAAK,KAAK,EAE1B,GAAIC,IAAY,GAAI,CAElBL,EAAe,KACf,QACF,CAEA,GAAIK,EAAQ,WAAW,QAAQ,EAE7BL,EAAeK,EAAQ,UAAU,CAAC,EAAE,KAAK,UAChCA,EAAQ,WAAW,OAAO,EAAG,CAEtC,MAAMC,EAAUD,EAAQ,UAAU,CAAC,EAAE,KAAK,EAC1C,GAAI,CACF,MAAME,EAAO,KAAK,MAAMD,CAAO,EAC/Bb,EAAQ,CACN,MAAQO,GAAwB,UAChC,KAAAO,CACF,CAAC,CACH,OAASC,EAAK,CACZ,QAAQ,MAAM,2CAA4CF,EAASE,CAAG,EACtEf,EAAQ,CACN,MAAO,QACP,KAAM,CACJ,QAAS,2BACT,KAAM,aACR,CACF,CAAC,CACH,CACF,CACF,CACF,CACF,OAASgB,EAAO,CACd,cAAQ,MAAM,mCAAoCA,CAAK,EACjDA,CACR,QAAE,CACAZ,EAAO,YAAY,CACrB,CACF,CAmBA,eAAsBV,EACpBI,EACAC,EACAE,EACAC,EAC6B,CAE7B,MAAMC,EAAW,QAAM,WAAQ,CAC7B,IAAK,GAAGL,CAAU,wBAClB,OAAQ,OACR,QAASG,EACT,KAAMF,EACN,cAAeG,GAAiB,cAChC,iBAAkBA,GAAiB,iBACnC,gBAAiBA,GAAiB,iBAAmB,aACvD,CAAC,EAED,GAAI,CAACC,EAAS,GAAI,CAChB,MAAMc,EAA2B,MAAMd,EAAS,KAAK,EAAE,MAAM,KAAO,CAClE,QAAS,GACT,MAAO,QAAQA,EAAS,MAAM,KAAKA,EAAS,UAAU,GACtD,KAAM,YACR,EAAE,EACF,MAAM,IAAI,MAAMc,EAAU,OAAS,0BAA0B,CAC/D,CAEA,OAAOd,EAAS,KAAK,CACvB",
|
|
6
|
+
"names": ["chat_exports", "__export", "createNewSession", "sendMessage", "__toCommonJS", "import_fetcher", "apiBaseUrl", "request", "onEvent", "customHeaders", "recaptchaConfig", "response", "reader", "decoder", "buffer", "currentEvent", "done", "value", "lines", "line", "trimmed", "dataStr", "data", "err", "error", "errorData"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 聊天悬浮按钮组件
|
|
3
|
+
* 显示在页面角落的气泡按钮,点击后打开聊天窗口
|
|
4
|
+
* 基于 specs/livechat-widget/plan.md 的气泡按钮设计
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { BubblePosition } from '../types';
|
|
8
|
+
export interface ChatBubbleProps {
|
|
9
|
+
/**
|
|
10
|
+
* 气泡按钮位置
|
|
11
|
+
* @default { bottom: "1.5rem", right: "1.5rem" }
|
|
12
|
+
*/
|
|
13
|
+
position?: BubblePosition;
|
|
14
|
+
/**
|
|
15
|
+
* 点击按钮的回调
|
|
16
|
+
*/
|
|
17
|
+
onClick?: () => void;
|
|
18
|
+
/**
|
|
19
|
+
* 自定义图标
|
|
20
|
+
*/
|
|
21
|
+
icon?: React.ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* 自定义图标图片 URL
|
|
24
|
+
* 如果提供,将使用图片替代默认的 SVG 图标
|
|
25
|
+
*/
|
|
26
|
+
iconImageUrl?: string;
|
|
27
|
+
/**
|
|
28
|
+
* 是否显示气泡
|
|
29
|
+
* @default true
|
|
30
|
+
*/
|
|
31
|
+
visible?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* 自定义样式类名
|
|
34
|
+
*/
|
|
35
|
+
className?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 聊天悬浮按钮组件
|
|
39
|
+
*
|
|
40
|
+
* 功能:
|
|
41
|
+
* - 可配置位置(预设或自定义)
|
|
42
|
+
* - 支持自定义图标(React 节点或图片 URL)
|
|
43
|
+
* - 悬停和点击动画效果
|
|
44
|
+
*
|
|
45
|
+
* 样式:
|
|
46
|
+
* - 使用 livechat.css 中定义的 CSS 变量
|
|
47
|
+
* - 悬停时放大 1.05 倍
|
|
48
|
+
* - 点击时缩小 0.95 倍
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* // 使用默认图标
|
|
53
|
+
* <ChatBubble onClick={() => setIsOpen(true)} />
|
|
54
|
+
*
|
|
55
|
+
* // 使用自定义位置
|
|
56
|
+
* <ChatBubble
|
|
57
|
+
* position={{ bottom: "20px", right: "30px" }}
|
|
58
|
+
* onClick={() => setIsOpen(true)}
|
|
59
|
+
* />
|
|
60
|
+
*
|
|
61
|
+
* // 使用图片作为图标
|
|
62
|
+
* <ChatBubble
|
|
63
|
+
* iconImageUrl="https://example.com/icon.png"
|
|
64
|
+
* onClick={() => setIsOpen(true)}
|
|
65
|
+
* />
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare const ChatBubble: React.FC<ChatBubbleProps>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var n=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var d=(t,e)=>{for(var o in e)n(t,o,{get:e[o],enumerable:!0})},f=(t,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of b(e))!p.call(t,r)&&r!==o&&n(t,r,{get:()=>e[r],enumerable:!(s=u(e,r))||s.enumerable});return t};var h=t=>f(n({},"__esModule",{value:!0}),t);var v={};d(v,{ChatBubble:()=>P});module.exports=h(v);var i=require("react/jsx-runtime");function C(t){return t||{bottom:"1.5rem",right:"1.5rem"}}const m=()=>(0,i.jsx)("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:(0,i.jsx)("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})}),P=({position:t,onClick:e,icon:o,iconImageUrl:s,visible:r=!0,className:a=""})=>{if(!r)return null;const l=C(t),c=()=>s?(0,i.jsx)("img",{src:s,alt:"Chat",className:"size-full object-cover",style:{borderRadius:"inherit"}}):o||(0,i.jsx)(m,{});return(0,i.jsx)("button",{type:"button",className:`livechat-bubble ${a}`,style:{...l,...s&&{background:"transparent"}},onClick:e,"aria-label":"\u6253\u5F00\u804A\u5929\u7A97\u53E3",children:(0,i.jsx)("div",{className:"flex size-full items-center justify-center",children:c()})})};
|
|
2
|
+
//# sourceMappingURL=ChatBubble.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/components/LiveChatWidget/components/ChatBubble.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * \u804A\u5929\u60AC\u6D6E\u6309\u94AE\u7EC4\u4EF6\n * \u663E\u793A\u5728\u9875\u9762\u89D2\u843D\u7684\u6C14\u6CE1\u6309\u94AE\uFF0C\u70B9\u51FB\u540E\u6253\u5F00\u804A\u5929\u7A97\u53E3\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u6C14\u6CE1\u6309\u94AE\u8BBE\u8BA1\n */\n\nimport React from 'react'\nimport type { BubblePosition } from '../types'\n\nexport interface ChatBubbleProps {\n /**\n * \u6C14\u6CE1\u6309\u94AE\u4F4D\u7F6E\n * @default { bottom: \"1.5rem\", right: \"1.5rem\" }\n */\n position?: BubblePosition\n\n /**\n * \u70B9\u51FB\u6309\u94AE\u7684\u56DE\u8C03\n */\n onClick?: () => void\n\n /**\n * \u81EA\u5B9A\u4E49\u56FE\u6807\n */\n icon?: React.ReactNode\n\n /**\n * \u81EA\u5B9A\u4E49\u56FE\u6807\u56FE\u7247 URL\n * \u5982\u679C\u63D0\u4F9B\uFF0C\u5C06\u4F7F\u7528\u56FE\u7247\u66FF\u4EE3\u9ED8\u8BA4\u7684 SVG \u56FE\u6807\n */\n iconImageUrl?: string\n\n /**\n * \u662F\u5426\u663E\u793A\u6C14\u6CE1\n * @default true\n */\n visible?: boolean\n\n /**\n * \u81EA\u5B9A\u4E49\u6837\u5F0F\u7C7B\u540D\n */\n className?: string\n}\n\n/**\n * \u83B7\u53D6\u6C14\u6CE1\u6309\u94AE\u7684\u4F4D\u7F6E\u6837\u5F0F\n * \u5982\u679C\u6CA1\u6709\u4F20\u5165 position\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u4F4D\u7F6E\uFF08\u53F3\u4E0B\u89D2\uFF09\n */\nfunction getPositionStyles(position?: BubblePosition): React.CSSProperties {\n // \u9ED8\u8BA4\u4F4D\u7F6E\uFF1A\u53F3\u4E0B\u89D2\n const defaultPosition: React.CSSProperties = {\n bottom: '1.5rem',\n right: '1.5rem',\n }\n\n // \u5982\u679C\u4F20\u5165\u4E86\u81EA\u5B9A\u4E49\u4F4D\u7F6E\uFF0C\u4F7F\u7528\u81EA\u5B9A\u4E49\u4F4D\u7F6E\n return position ? (position as React.CSSProperties) : defaultPosition\n}\n\n/**\n * \u9ED8\u8BA4\u804A\u5929\u56FE\u6807 (\u7B80\u5355\u7684\u6D88\u606F\u6C14\u6CE1 SVG)\n */\nconst DefaultChatIcon: React.FC = () => (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n)\n\n/**\n * \u804A\u5929\u60AC\u6D6E\u6309\u94AE\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u53EF\u914D\u7F6E\u4F4D\u7F6E\uFF08\u9884\u8BBE\u6216\u81EA\u5B9A\u4E49\uFF09\n * - \u652F\u6301\u81EA\u5B9A\u4E49\u56FE\u6807\uFF08React \u8282\u70B9\u6216\u56FE\u7247 URL\uFF09\n * - \u60AC\u505C\u548C\u70B9\u51FB\u52A8\u753B\u6548\u679C\n *\n * \u6837\u5F0F\uFF1A\n * - \u4F7F\u7528 livechat.css \u4E2D\u5B9A\u4E49\u7684 CSS \u53D8\u91CF\n * - \u60AC\u505C\u65F6\u653E\u5927 1.05 \u500D\n * - \u70B9\u51FB\u65F6\u7F29\u5C0F 0.95 \u500D\n *\n * @example\n * ```tsx\n * // \u4F7F\u7528\u9ED8\u8BA4\u56FE\u6807\n * <ChatBubble onClick={() => setIsOpen(true)} />\n *\n * // \u4F7F\u7528\u81EA\u5B9A\u4E49\u4F4D\u7F6E\n * <ChatBubble\n * position={{ bottom: \"20px\", right: \"30px\" }}\n * onClick={() => setIsOpen(true)}\n * />\n *\n * // \u4F7F\u7528\u56FE\u7247\u4F5C\u4E3A\u56FE\u6807\n * <ChatBubble\n * iconImageUrl=\"https://example.com/icon.png\"\n * onClick={() => setIsOpen(true)}\n * />\n * ```\n */\nexport const ChatBubble: React.FC<ChatBubbleProps> = ({\n position,\n onClick,\n icon,\n iconImageUrl,\n visible = true,\n className = '',\n}) => {\n if (!visible) return null\n\n const positionStyles = getPositionStyles(position)\n\n // \u6E32\u67D3\u56FE\u6807\u5185\u5BB9\n const renderIcon = () => {\n // \u4F18\u5148\u4F7F\u7528\u56FE\u7247 URL\n if (iconImageUrl) {\n return (\n <img src={iconImageUrl} alt=\"Chat\" className=\"size-full object-cover\" style={{ borderRadius: 'inherit' }} />\n )\n }\n // \u5176\u6B21\u4F7F\u7528\u81EA\u5B9A\u4E49\u56FE\u6807\n if (icon) {\n return icon\n }\n // \u6700\u540E\u4F7F\u7528\u9ED8\u8BA4\u56FE\u6807\n return <DefaultChatIcon />\n }\n\n return (\n <button\n type=\"button\"\n className={`livechat-bubble ${className}`}\n style={{\n ...positionStyles,\n // \u5982\u679C\u4F20\u5165\u4E86\u56FE\u7247\uFF0C\u79FB\u9664\u9ED8\u8BA4\u80CC\u666F\u8272\n ...(iconImageUrl && { background: 'transparent' }),\n }}\n onClick={onClick}\n aria-label=\"\u6253\u5F00\u804A\u5929\u7A97\u53E3\"\n >\n <div className=\"flex size-full items-center justify-center\">{renderIcon()}</div>\n </button>\n )\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,IAAA,eAAAC,EAAAH,GAyEI,IAAAI,EAAA,6BAzBJ,SAASC,EAAkBC,EAAgD,CAQzE,OAAOA,GANsC,CAC3C,OAAQ,SACR,MAAO,QACT,CAIF,CAKA,MAAMC,EAA4B,OAChC,OAAC,OACC,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,QAEf,mBAAC,QAAK,EAAE,gEAAgE,EAC1E,EAkCWL,EAAwC,CAAC,CACpD,SAAAI,EACA,QAAAE,EACA,KAAAC,EACA,aAAAC,EACA,QAAAC,EAAU,GACV,UAAAC,EAAY,EACd,IAAM,CACJ,GAAI,CAACD,EAAS,OAAO,KAErB,MAAME,EAAiBR,EAAkBC,CAAQ,EAG3CQ,EAAa,IAEbJ,KAEA,OAAC,OAAI,IAAKA,EAAc,IAAI,OAAO,UAAU,yBAAyB,MAAO,CAAE,aAAc,SAAU,EAAG,EAI1GD,MAIG,OAACF,EAAA,EAAgB,EAG1B,SACE,OAAC,UACC,KAAK,SACL,UAAW,mBAAmBK,CAAS,GACvC,MAAO,CACL,GAAGC,EAEH,GAAIH,GAAgB,CAAE,WAAY,aAAc,CAClD,EACA,QAASF,EACT,aAAW,uCAEX,mBAAC,OAAI,UAAU,6CAA8C,SAAAM,EAAW,EAAE,EAC5E,CAEJ",
|
|
6
|
+
"names": ["ChatBubble_exports", "__export", "ChatBubble", "__toCommonJS", "import_jsx_runtime", "getPositionStyles", "position", "DefaultChatIcon", "onClick", "icon", "iconImageUrl", "visible", "className", "positionStyles", "renderIcon"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 聊天窗口头部组件
|
|
3
|
+
* 显示标题、Logo、关闭按钮和新会话按钮
|
|
4
|
+
* 基于 specs/livechat-widget/plan.md 的头部设计
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
export interface ChatHeaderProps {
|
|
8
|
+
/**
|
|
9
|
+
* 头部标题
|
|
10
|
+
*/
|
|
11
|
+
title?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Logo URL
|
|
14
|
+
*/
|
|
15
|
+
logoUrl?: string;
|
|
16
|
+
/**
|
|
17
|
+
* 关闭按钮点击回调
|
|
18
|
+
*/
|
|
19
|
+
onClose?: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* 新会话按钮点击回调
|
|
22
|
+
*/
|
|
23
|
+
onNewSession?: () => void;
|
|
24
|
+
/**
|
|
25
|
+
* 是否显示新会话按钮
|
|
26
|
+
* @default true
|
|
27
|
+
*/
|
|
28
|
+
showNewSessionButton?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* 自定义样式类名
|
|
31
|
+
*/
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 聊天窗口头部组件
|
|
36
|
+
*
|
|
37
|
+
* 功能:
|
|
38
|
+
* - 显示标题和 Logo
|
|
39
|
+
* - 关闭按钮(移动端隐藏,桌面端显示)
|
|
40
|
+
* - 新会话按钮(清空当前对话)
|
|
41
|
+
*
|
|
42
|
+
* 布局:
|
|
43
|
+
* - Logo (可选) + 标题 | 新会话按钮 + 关闭按钮
|
|
44
|
+
* - 固定高度 64px
|
|
45
|
+
* - 边框分隔下方内容
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* <ChatHeader
|
|
50
|
+
* title="AI 助手"
|
|
51
|
+
* logoUrl="/logo.png"
|
|
52
|
+
* onClose={() => setIsOpen(false)}
|
|
53
|
+
* onNewSession={() => createNewSession()}
|
|
54
|
+
* />
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare const ChatHeader: React.FC<ChatHeaderProps>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var b=(o,t)=>{for(var n in t)i(o,n,{get:t[n],enumerable:!0})},g=(o,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of c(t))!d.call(o,r)&&r!==n&&i(o,r,{get:()=>t[r],enumerable:!(s=l(t,r))||s.enumerable});return o};var u=o=>g(i({},"__esModule",{value:!0}),o);var v={};b(v,{ChatHeader:()=>p});module.exports=u(v);var e=require("react/jsx-runtime");const x=()=>(0,e.jsxs)("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,e.jsx)("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),(0,e.jsx)("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),h=()=>(0,e.jsxs)("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,e.jsx)("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),(0,e.jsx)("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]}),p=({title:o="",logoUrl:t,onClose:n,onNewSession:s,showNewSessionButton:r=!0,className:a=""})=>(0,e.jsxs)("div",{className:`flex items-center justify-between border-b border-[#DADCE0] bg-white px-4 pb-3 pt-0 tablet:pt-4 ${a}`,children:[(0,e.jsxs)("div",{className:"flex items-center gap-3",children:[t&&(0,e.jsx)("img",{src:t,alt:"Logo",className:"size-8 rounded-full object-cover"}),(0,e.jsx)("h2",{className:"text-lg font-semibold text-gray-900",children:o})]}),(0,e.jsxs)("div",{className:"flex items-center gap-2",children:[r&&s&&(0,e.jsx)("button",{type:"button",onClick:s,className:"rounded-lg p-2 text-gray-600","aria-label":"\u5F00\u59CB\u65B0\u4F1A\u8BDD",title:"\u5F00\u59CB\u65B0\u4F1A\u8BDD",children:(0,e.jsx)(h,{})}),n&&(0,e.jsx)("button",{type:"button",onClick:n,className:"tablet:block rounded-lg text-gray-600","aria-label":"Close chat",children:(0,e.jsx)(x,{})})]})]});
|
|
2
|
+
//# sourceMappingURL=ChatHeader.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/components/LiveChatWidget/components/ChatHeader.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * \u804A\u5929\u7A97\u53E3\u5934\u90E8\u7EC4\u4EF6\n * \u663E\u793A\u6807\u9898\u3001Logo\u3001\u5173\u95ED\u6309\u94AE\u548C\u65B0\u4F1A\u8BDD\u6309\u94AE\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u5934\u90E8\u8BBE\u8BA1\n */\n\nimport React from 'react'\n\nexport interface ChatHeaderProps {\n /**\n * \u5934\u90E8\u6807\u9898\n */\n title?: string\n\n /**\n * Logo URL\n */\n logoUrl?: string\n\n /**\n * \u5173\u95ED\u6309\u94AE\u70B9\u51FB\u56DE\u8C03\n */\n onClose?: () => void\n\n /**\n * \u65B0\u4F1A\u8BDD\u6309\u94AE\u70B9\u51FB\u56DE\u8C03\n */\n onNewSession?: () => void\n\n /**\n * \u662F\u5426\u663E\u793A\u65B0\u4F1A\u8BDD\u6309\u94AE\n * @default true\n */\n showNewSessionButton?: boolean\n\n /**\n * \u81EA\u5B9A\u4E49\u6837\u5F0F\u7C7B\u540D\n */\n className?: string\n}\n\n/**\n * \u9ED8\u8BA4\u5173\u95ED\u56FE\u6807 (X)\n */\nconst CloseIcon: React.FC = () => (\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 >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n)\n\n/**\n * \u65B0\u4F1A\u8BDD\u56FE\u6807 (\u52A0\u53F7)\n */\nconst NewSessionIcon: React.FC = () => (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n)\n\n/**\n * \u804A\u5929\u7A97\u53E3\u5934\u90E8\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u663E\u793A\u6807\u9898\u548C Logo\n * - \u5173\u95ED\u6309\u94AE\uFF08\u79FB\u52A8\u7AEF\u9690\u85CF\uFF0C\u684C\u9762\u7AEF\u663E\u793A\uFF09\n * - \u65B0\u4F1A\u8BDD\u6309\u94AE\uFF08\u6E05\u7A7A\u5F53\u524D\u5BF9\u8BDD\uFF09\n *\n * \u5E03\u5C40\uFF1A\n * - Logo (\u53EF\u9009) + \u6807\u9898 | \u65B0\u4F1A\u8BDD\u6309\u94AE + \u5173\u95ED\u6309\u94AE\n * - \u56FA\u5B9A\u9AD8\u5EA6 64px\n * - \u8FB9\u6846\u5206\u9694\u4E0B\u65B9\u5185\u5BB9\n *\n * @example\n * ```tsx\n * <ChatHeader\n * title=\"AI \u52A9\u624B\"\n * logoUrl=\"/logo.png\"\n * onClose={() => setIsOpen(false)}\n * onNewSession={() => createNewSession()}\n * />\n * ```\n */\nexport const ChatHeader: React.FC<ChatHeaderProps> = ({\n title = '',\n logoUrl,\n onClose,\n onNewSession,\n showNewSessionButton = true,\n className = '',\n}) => {\n return (\n <div\n className={`flex items-center justify-between border-b border-[#DADCE0] bg-white px-4 pb-3 pt-0 tablet:pt-4 ${className}`}\n >\n {/* \u5DE6\u4FA7\uFF1ALogo + \u6807\u9898 */}\n <div className=\"flex items-center gap-3\">\n {logoUrl && <img src={logoUrl} alt=\"Logo\" className=\"size-8 rounded-full object-cover\" />}\n <h2 className=\"text-lg font-semibold text-gray-900\">{title}</h2>\n </div>\n\n {/* \u53F3\u4FA7\uFF1A\u65B0\u4F1A\u8BDD\u6309\u94AE + \u5173\u95ED\u6309\u94AE */}\n <div className=\"flex items-center gap-2\">\n {/* \u65B0\u4F1A\u8BDD\u6309\u94AE */}\n {showNewSessionButton && onNewSession && (\n <button\n type=\"button\"\n onClick={onNewSession}\n className=\"rounded-lg p-2 text-gray-600\"\n aria-label=\"\u5F00\u59CB\u65B0\u4F1A\u8BDD\"\n title=\"\u5F00\u59CB\u65B0\u4F1A\u8BDD\"\n >\n <NewSessionIcon />\n </button>\n )}\n\n {/* \u5173\u95ED\u6309\u94AE */}\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"tablet:block rounded-lg text-gray-600\"\n aria-label=\"Close chat\"\n >\n <CloseIcon />\n </button>\n )}\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,IAAA,eAAAC,EAAAH,GA6CE,IAAAI,EAAA,6BADF,MAAMC,EAAsB,OAC1B,QAAC,OACC,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,QAEf,oBAAC,QAAK,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,KACpC,OAAC,QAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GACtC,EAMIC,EAA2B,OAC/B,QAAC,OACC,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,QAEf,oBAAC,QAAK,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,KACrC,OAAC,QAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GACvC,EA0BWJ,EAAwC,CAAC,CACpD,MAAAK,EAAQ,GACR,QAAAC,EACA,QAAAC,EACA,aAAAC,EACA,qBAAAC,EAAuB,GACvB,UAAAC,EAAY,EACd,OAEI,QAAC,OACC,UAAW,mGAAmGA,CAAS,GAGvH,qBAAC,OAAI,UAAU,0BACZ,UAAAJ,MAAW,OAAC,OAAI,IAAKA,EAAS,IAAI,OAAO,UAAU,mCAAmC,KACvF,OAAC,MAAG,UAAU,sCAAuC,SAAAD,EAAM,GAC7D,KAGA,QAAC,OAAI,UAAU,0BAEZ,UAAAI,GAAwBD,MACvB,OAAC,UACC,KAAK,SACL,QAASA,EACT,UAAU,+BACV,aAAW,iCACX,MAAM,iCAEN,mBAACJ,EAAA,EAAe,EAClB,EAIDG,MACC,OAAC,UACC,KAAK,SACL,QAASA,EACT,UAAU,yCACV,aAAW,aAEX,mBAACJ,EAAA,EAAU,EACb,GAEJ,GACF",
|
|
6
|
+
"names": ["ChatHeader_exports", "__export", "ChatHeader", "__toCommonJS", "import_jsx_runtime", "CloseIcon", "NewSessionIcon", "title", "logoUrl", "onClose", "onNewSession", "showNewSessionButton", "className"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 聊天输入框组件
|
|
3
|
+
* 提供文本输入和发送按钮
|
|
4
|
+
* 基于 specs/livechat-widget/plan.md 的输入框设计
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
export interface ChatInputProps {
|
|
8
|
+
/**
|
|
9
|
+
* 输入框当前值
|
|
10
|
+
*/
|
|
11
|
+
value: string;
|
|
12
|
+
/**
|
|
13
|
+
* 值变化回调
|
|
14
|
+
*/
|
|
15
|
+
onChange: (value: string) => void;
|
|
16
|
+
/**
|
|
17
|
+
* 发送消息回调
|
|
18
|
+
*/
|
|
19
|
+
onSend: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* 占位符文本
|
|
22
|
+
* @default "输入消息..."
|
|
23
|
+
*/
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
/**
|
|
26
|
+
* 是否禁用输入
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* 是否自动聚焦
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
autoFocus?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* 最大字符数
|
|
37
|
+
* @default 5000
|
|
38
|
+
*/
|
|
39
|
+
maxLength?: number;
|
|
40
|
+
/**
|
|
41
|
+
* 自定义样式类名
|
|
42
|
+
*/
|
|
43
|
+
className?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 聊天输入框组件
|
|
47
|
+
*
|
|
48
|
+
* 功能:
|
|
49
|
+
* - 多行文本输入(自动增长)
|
|
50
|
+
* - Enter 发送,Shift+Enter 换行
|
|
51
|
+
* - 字符数限制(5000)
|
|
52
|
+
* - 禁用状态(发送中)
|
|
53
|
+
* - 发送按钮(空内容时禁用)
|
|
54
|
+
*
|
|
55
|
+
* 样式:
|
|
56
|
+
* - 固定底部
|
|
57
|
+
* - 边框分隔上方内容
|
|
58
|
+
* - 自适应高度(1-5 行)
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```tsx
|
|
62
|
+
* <ChatInput
|
|
63
|
+
* value={inputValue}
|
|
64
|
+
* onChange={setInputValue}
|
|
65
|
+
* onSend={handleSend}
|
|
66
|
+
* disabled={isStreaming}
|
|
67
|
+
* />
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare const ChatInput: React.FC<ChatInputProps>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var g=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var C=(e,n)=>{for(var s in n)g(e,s,{get:n[s],enumerable:!0})},v=(e,n,s,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let a of y(n))!k.call(e,a)&&a!==s&&g(e,a,{get:()=>n[a],enumerable:!(r=b(n,a))||r.enumerable});return e};var E=e=>v(g({},"__esModule",{value:!0}),e);var A={};C(A,{ChatInput:()=>R});module.exports=E(A);var t=require("react/jsx-runtime"),l=require("react");const F=()=>(0,t.jsxs)("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,t.jsx)("path",{d:"M10.2069 15.6997V4.69971",stroke:"white","stroke-width":"2","stroke-linecap":"round"}),(0,t.jsx)("path",{d:"M15.3995 8.50341L10.9506 4.05446C10.534 3.6379 9.85866 3.63791 9.4421 4.05446L5.00005 8.49651",stroke:"white","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"})]}),R=({value:e,onChange:n,onSend:s,placeholder:r="",disabled:a=!1,autoFocus:p=!1,maxLength:i=5e3,className:u=""})=>{const h=(0,l.useRef)(null);(0,l.useEffect)(()=>{const o=h.current;if(!o)return;o.style.height="auto";const w=Math.min(o.scrollHeight,120);o.style.height=`${w}px`},[e]);const x=o=>{o.key==="Enter"&&!o.shiftKey&&(o.preventDefault(),e.trim()&&!a&&s())},f=o=>{const d=o.target.value;d.length<=i&&n(d)},m=()=>{e.trim()&&!a&&s()},c=e.trim().length>0&&!a;return(0,t.jsx)("div",{className:`flex items-end gap-2 bg-white px-4 py-3 ${u}`,children:(0,t.jsx)("div",{className:"flex flex-1 items-center gap-2 rounded-2xl",style:{background:"linear-gradient(to right, #7687F3, #7687F3, #4DA8F5, #A3DFCE)",padding:"2px"},children:(0,t.jsxs)("div",{className:"flex flex-1 items-center gap-2 bg-white px-3 py-2",style:{borderRadius:"14px"},children:[(0,t.jsx)("textarea",{ref:h,value:e,onChange:f,onKeyDown:x,placeholder:r,disabled:a,autoFocus:p,rows:1,className:"flex-1 resize-none bg-transparent text-sm text-gray-900 outline-none placeholder:text-gray-400 disabled:cursor-not-allowed disabled:opacity-50",style:{resize:"none"}}),e.length>i*.8&&(0,t.jsxs)("span",{className:"text-xs text-gray-400",children:[e.length,"/",i]}),(0,t.jsx)("button",{type:"button",onClick:m,disabled:!c,className:`shrink-0 rounded-full p-2 transition-all ${c?" active:scale-95":"cursor-not-allowed "}`,style:c?{background:"linear-gradient(to bottom, #A3DFCE, #4DA8F5, #7687F3)"}:{background:"#BEBEBE"},"aria-label":"Send message",children:(0,t.jsx)(F,{})})]})})})};
|
|
2
|
+
//# sourceMappingURL=ChatInput.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/components/LiveChatWidget/components/ChatInput.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * \u804A\u5929\u8F93\u5165\u6846\u7EC4\u4EF6\n * \u63D0\u4F9B\u6587\u672C\u8F93\u5165\u548C\u53D1\u9001\u6309\u94AE\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u8F93\u5165\u6846\u8BBE\u8BA1\n */\n\nimport React, { useRef, useEffect } from 'react'\n\nexport interface ChatInputProps {\n /**\n * \u8F93\u5165\u6846\u5F53\u524D\u503C\n */\n value: string\n\n /**\n * \u503C\u53D8\u5316\u56DE\u8C03\n */\n onChange: (value: string) => void\n\n /**\n * \u53D1\u9001\u6D88\u606F\u56DE\u8C03\n */\n onSend: () => void\n\n /**\n * \u5360\u4F4D\u7B26\u6587\u672C\n * @default \"\u8F93\u5165\u6D88\u606F...\"\n */\n placeholder?: string\n\n /**\n * \u662F\u5426\u7981\u7528\u8F93\u5165\n * @default false\n */\n disabled?: boolean\n\n /**\n * \u662F\u5426\u81EA\u52A8\u805A\u7126\n * @default false\n */\n autoFocus?: boolean\n\n /**\n * \u6700\u5927\u5B57\u7B26\u6570\n * @default 5000\n */\n maxLength?: number\n\n /**\n * \u81EA\u5B9A\u4E49\u6837\u5F0F\u7C7B\u540D\n */\n className?: string\n}\n\n/**\n * \u53D1\u9001\u56FE\u6807 (\u5411\u4E0A\u7BAD\u5934)\n */\nconst SendIcon: React.FC = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10.2069 15.6997V4.69971\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" />\n <path\n d=\"M15.3995 8.50341L10.9506 4.05446C10.534 3.6379 9.85866 3.63791 9.4421 4.05446L5.00005 8.49651\"\n stroke=\"white\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n)\n\n/**\n * \u804A\u5929\u8F93\u5165\u6846\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u591A\u884C\u6587\u672C\u8F93\u5165\uFF08\u81EA\u52A8\u589E\u957F\uFF09\n * - Enter \u53D1\u9001\uFF0CShift+Enter \u6362\u884C\n * - \u5B57\u7B26\u6570\u9650\u5236\uFF085000\uFF09\n * - \u7981\u7528\u72B6\u6001\uFF08\u53D1\u9001\u4E2D\uFF09\n * - \u53D1\u9001\u6309\u94AE\uFF08\u7A7A\u5185\u5BB9\u65F6\u7981\u7528\uFF09\n *\n * \u6837\u5F0F\uFF1A\n * - \u56FA\u5B9A\u5E95\u90E8\n * - \u8FB9\u6846\u5206\u9694\u4E0A\u65B9\u5185\u5BB9\n * - \u81EA\u9002\u5E94\u9AD8\u5EA6\uFF081-5 \u884C\uFF09\n *\n * @example\n * ```tsx\n * <ChatInput\n * value={inputValue}\n * onChange={setInputValue}\n * onSend={handleSend}\n * disabled={isStreaming}\n * />\n * ```\n */\nexport const ChatInput: React.FC<ChatInputProps> = ({\n value,\n onChange,\n onSend,\n placeholder = '',\n disabled = false,\n autoFocus = false,\n maxLength = 5000,\n className = '',\n}) => {\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n /**\n * \u81EA\u52A8\u8C03\u6574 textarea \u9AD8\u5EA6\n */\n useEffect(() => {\n const textarea = textareaRef.current\n if (!textarea) return\n\n // \u91CD\u7F6E\u9AD8\u5EA6\u4EE5\u83B7\u53D6\u6B63\u786E\u7684 scrollHeight\n textarea.style.height = 'auto'\n\n // \u8BBE\u7F6E\u9AD8\u5EA6\uFF0C\u6700\u5927 5 \u884C\uFF08\u7EA6 120px\uFF09\n const maxHeight = 120\n const newHeight = Math.min(textarea.scrollHeight, maxHeight)\n textarea.style.height = `${newHeight}px`\n }, [value])\n\n /**\n * \u5904\u7406\u952E\u76D8\u4E8B\u4EF6\n * Enter \u53D1\u9001\uFF0CShift+Enter \u6362\u884C\n */\n const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault()\n if (value.trim() && !disabled) {\n onSend()\n }\n }\n }\n\n /**\n * \u5904\u7406\u8F93\u5165\u53D8\u5316\n */\n const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = event.target.value\n\n // \u5B57\u7B26\u6570\u9650\u5236\n if (newValue.length <= maxLength) {\n onChange(newValue)\n }\n }\n\n /**\n * \u5904\u7406\u53D1\u9001\u6309\u94AE\u70B9\u51FB\n */\n const handleSendClick = () => {\n if (value.trim() && !disabled) {\n onSend()\n }\n }\n\n const canSend = value.trim().length > 0 && !disabled\n\n return (\n <div className={`flex items-end gap-2 bg-white px-4 py-3 ${className}`}>\n {/* \u8F93\u5165\u6846\u5BB9\u5668 - \u5E26\u6E10\u53D8\u8FB9\u6846 */}\n <div\n className=\"flex flex-1 items-center gap-2 rounded-2xl\"\n style={{\n background: 'linear-gradient(to right, #7687F3, #7687F3, #4DA8F5, #A3DFCE)',\n padding: '2px',\n }}\n >\n {/* \u5185\u90E8\u767D\u8272\u80CC\u666F */}\n <div className=\"flex flex-1 items-center gap-2 bg-white px-3 py-2\" style={{ borderRadius: '14px' }}>\n {/* \u6587\u672C\u8F93\u5165\u6846 */}\n <textarea\n ref={textareaRef}\n value={value}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={autoFocus}\n rows={1}\n className=\"flex-1 resize-none bg-transparent text-sm text-gray-900 outline-none placeholder:text-gray-400 disabled:cursor-not-allowed disabled:opacity-50\"\n style={{\n resize: 'none',\n }}\n />\n\n {/* \u5B57\u7B26\u6570\u63D0\u793A (\u63A5\u8FD1\u4E0A\u9650\u65F6\u663E\u793A) */}\n {value.length > maxLength * 0.8 && (\n <span className=\"text-xs text-gray-400\">\n {value.length}/{maxLength}\n </span>\n )}\n\n {/* \u53D1\u9001\u6309\u94AE */}\n <button\n type=\"button\"\n onClick={handleSendClick}\n disabled={!canSend}\n className={`shrink-0 rounded-full p-2 transition-all ${canSend ? ' active:scale-95' : 'cursor-not-allowed '}`}\n style={\n canSend\n ? {\n background: 'linear-gradient(to bottom, #A3DFCE, #4DA8F5, #7687F3)',\n }\n : { background: '#BEBEBE' }\n }\n aria-label=\"Send message\"\n >\n <SendIcon />\n </button>\n </div>\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,eAAAE,IAAA,eAAAC,EAAAH,GA0DE,IAAAI,EAAA,6BApDFC,EAAyC,iBAmDzC,MAAMC,EAAqB,OACzB,QAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,6BAChE,oBAAC,QAAK,EAAE,2BAA2B,OAAO,QAAQ,eAAa,IAAI,iBAAe,QAAQ,KAC1F,OAAC,QACC,EAAE,gGACF,OAAO,QACP,eAAa,IACb,iBAAe,QACf,kBAAgB,QAClB,GACF,EA4BWJ,EAAsC,CAAC,CAClD,MAAAK,EACA,SAAAC,EACA,OAAAC,EACA,YAAAC,EAAc,GACd,SAAAC,EAAW,GACX,UAAAC,EAAY,GACZ,UAAAC,EAAY,IACZ,UAAAC,EAAY,EACd,IAAM,CACJ,MAAMC,KAAc,UAA4B,IAAI,KAKpD,aAAU,IAAM,CACd,MAAMC,EAAWD,EAAY,QAC7B,GAAI,CAACC,EAAU,OAGfA,EAAS,MAAM,OAAS,OAIxB,MAAMC,EAAY,KAAK,IAAID,EAAS,aADlB,GACyC,EAC3DA,EAAS,MAAM,OAAS,GAAGC,CAAS,IACtC,EAAG,CAACV,CAAK,CAAC,EAMV,MAAMW,EAAiBC,GAAoD,CACrEA,EAAM,MAAQ,SAAW,CAACA,EAAM,WAClCA,EAAM,eAAe,EACjBZ,EAAM,KAAK,GAAK,CAACI,GACnBF,EAAO,EAGb,EAKMW,EAAgBD,GAAkD,CACtE,MAAME,EAAWF,EAAM,OAAO,MAG1BE,EAAS,QAAUR,GACrBL,EAASa,CAAQ,CAErB,EAKMC,EAAkB,IAAM,CACxBf,EAAM,KAAK,GAAK,CAACI,GACnBF,EAAO,CAEX,EAEMc,EAAUhB,EAAM,KAAK,EAAE,OAAS,GAAK,CAACI,EAE5C,SACE,OAAC,OAAI,UAAW,2CAA2CG,CAAS,GAElE,mBAAC,OACC,UAAU,6CACV,MAAO,CACL,WAAY,gEACZ,QAAS,KACX,EAGA,oBAAC,OAAI,UAAU,oDAAoD,MAAO,CAAE,aAAc,MAAO,EAE/F,oBAAC,YACC,IAAKC,EACL,MAAOR,EACP,SAAUa,EACV,UAAWF,EACX,YAAaR,EACb,SAAUC,EACV,UAAWC,EACX,KAAM,EACN,UAAU,iJACV,MAAO,CACL,OAAQ,MACV,EACF,EAGCL,EAAM,OAASM,EAAY,OAC1B,QAAC,QAAK,UAAU,wBACb,UAAAN,EAAM,OAAO,IAAEM,GAClB,KAIF,OAAC,UACC,KAAK,SACL,QAASS,EACT,SAAU,CAACC,EACX,UAAW,4CAA4CA,EAAU,mBAAqB,qBAAqB,GAC3G,MACEA,EACI,CACE,WAAY,uDACd,EACA,CAAE,WAAY,SAAU,EAE9B,aAAW,eAEX,mBAACjB,EAAA,EAAS,EACZ,GACF,EACF,EACF,CAEJ",
|
|
6
|
+
"names": ["ChatInput_exports", "__export", "ChatInput", "__toCommonJS", "import_jsx_runtime", "import_react", "SendIcon", "value", "onChange", "onSend", "placeholder", "disabled", "autoFocus", "maxLength", "className", "textareaRef", "textarea", "newHeight", "handleKeyDown", "event", "handleChange", "newValue", "handleSendClick", "canSend"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 单条聊天消息组件
|
|
3
|
+
* 显示消息气泡、发送者、时间戳
|
|
4
|
+
* 基于 specs/livechat-widget/plan.md 的消息展示设计
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { Message, MessageRenderer } from '../types';
|
|
8
|
+
import { MessageRendererRegistry } from '../utils/messageRenderers';
|
|
9
|
+
export interface ChatMessageProps {
|
|
10
|
+
/**
|
|
11
|
+
* 消息数据
|
|
12
|
+
*/
|
|
13
|
+
message: Message;
|
|
14
|
+
/**
|
|
15
|
+
* 自定义渲染器注册表
|
|
16
|
+
*/
|
|
17
|
+
rendererRegistry?: MessageRendererRegistry;
|
|
18
|
+
/**
|
|
19
|
+
* 默认渲染器
|
|
20
|
+
*/
|
|
21
|
+
defaultRenderer?: MessageRenderer;
|
|
22
|
+
/**
|
|
23
|
+
* 是否显示时间戳
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
showTimestamp?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* 自定义样式类名
|
|
29
|
+
*/
|
|
30
|
+
className?: string;
|
|
31
|
+
/**
|
|
32
|
+
* 商品添加到购物车回调
|
|
33
|
+
*/
|
|
34
|
+
onAddToCart?: (product: any) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 单条聊天消息组件
|
|
38
|
+
*
|
|
39
|
+
* 功能:
|
|
40
|
+
* - 显示消息气泡(用户 vs AI 助手不同样式)
|
|
41
|
+
* - 支持多个 content 块(一条消息可包含多种内容类型)
|
|
42
|
+
* - 显示时间戳
|
|
43
|
+
* - 系统消息居中显示
|
|
44
|
+
*
|
|
45
|
+
* 样式规则:
|
|
46
|
+
* - 用户消息:右对齐,灰色背景
|
|
47
|
+
* - AI 助手消息:左对齐,白色背景
|
|
48
|
+
* - 系统消息:居中,黄色背景
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <ChatMessage
|
|
53
|
+
* message={message}
|
|
54
|
+
* rendererRegistry={customRegistry}
|
|
55
|
+
* showTimestamp={true}
|
|
56
|
+
* />
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare const ChatMessage: React.FC<ChatMessageProps>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";var c=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var w=(e,t)=>{for(var r in t)c(e,r,{get:t[r],enumerable:!0})},C=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of v(t))!R.call(e,o)&&o!==r&&c(e,o,{get:()=>t[o],enumerable:!(a=x(t,o))||a.enumerable});return e};var M=e=>C(c({},"__esModule",{value:!0}),e);var S={};w(S,{ChatMessage:()=>N});module.exports=M(S);var s=require("react/jsx-runtime"),d=require("./MessageContent");function h(e){const t=new Date(e),r=t.getHours().toString().padStart(2,"0"),a=t.getMinutes().toString().padStart(2,"0");return`${r}:${a}`}const N=({message:e,rendererRegistry:t,defaultRenderer:r,showTimestamp:a=!0,className:o="",onAddToCart:p})=>{const i=e.role==="user",$=e.role==="assistant",m=e.role==="system",y=e.role==="tool";if(m)return(0,s.jsx)("div",{className:`flex justify-center py-2 ${o}`,children:(0,s.jsx)("div",{className:"",children:e.content.map((n,l)=>(0,s.jsx)(d.MessageContent,{content:n,isUser:!1,isSystem:!0,rendererRegistry:t,defaultRenderer:r},l))})});if(y)return null;const f=["product_list","product_comparison","faq_list","promotion_list","cart"],u=e.content.filter(n=>!f.includes(n.type)),g=e.content.filter(n=>f.includes(n.type));return(0,s.jsx)("div",{className:`flex ${i?"justify-end":"justify-start"} py-2 ${o}`,children:(0,s.jsxs)("div",{className:"flex w-fit max-w-full flex-col gap-2",children:[u.length>0&&(0,s.jsx)("div",{className:`w-full min-w-0 overflow-hidden rounded-2xl p-3 ${i?"text-white":"text-[#1D1D1F]"}`,style:{backgroundColor:i?"#005D8E":"#F5F6F7"},children:(0,s.jsx)("div",{className:"flex w-full min-w-0 flex-col gap-2",children:u.map((n,l)=>(0,s.jsx)(d.MessageContent,{content:n,isUser:i,isSystem:!1,rendererRegistry:t,defaultRenderer:r,onAddToCart:p},l))})}),g.map((n,l)=>(0,s.jsx)("div",{className:"w-full",children:(0,s.jsx)(d.MessageContent,{content:n,isUser:i,isSystem:!1,rendererRegistry:t,defaultRenderer:r,onAddToCart:p})},`standalone-${l}`)),a&&(0,s.jsx)("span",{className:`
|
|
2
|
+
px-2 text-xs text-gray-400
|
|
3
|
+
${i?"text-right":"text-left"}
|
|
4
|
+
`,children:h(e.timestamp)})]})})};
|
|
5
|
+
//# sourceMappingURL=ChatMessage.js.map
|