@clikvn/agent-widget-embedded 1.1.5-dev-21 → 1.1.5-dev-23
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/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/commons/constants/bookMeeting.d.ts +60 -7
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/commons/constants/bookMeeting.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/commons/constants/bookMeeting.js +25 -17
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/commons/constants/bookMeeting.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingDetail.d.ts +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingDetail.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingDetail.js +5 -6
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingDetail.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingForm.d.ts +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingForm.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingForm.js +30 -22
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingForm.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingList.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingList.js +8 -11
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingList.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Chat.js +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Chat.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Icons.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Icons.js +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Icons.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Message.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Message.js +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Message.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/MultimodalInput.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/MultimodalInput.js +7 -5
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/MultimodalInput.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductList.d.ts +3 -3
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductList.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductList.js +2 -2
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductList.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/UserContactForm.js +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/UserContactForm.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/PhoneNumberInput.d.ts +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/PhoneNumberInput.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/PhoneNumberInput.js +4 -2
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/PhoneNumberInput.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/hooks/useConfiguration.d.ts +4 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/hooks/useConfiguration.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/hooks/useConfiguration.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/bookMeeting.type.d.ts +2 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/bookMeeting.type.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/bookMeeting.type.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/wdyr.d.ts +2 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/wdyr.d.ts.map +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/wdyr.js +15 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/wdyr.js.map +1 -0
- package/dist/commons/constants/bookMeeting.d.ts +60 -7
- package/dist/commons/constants/bookMeeting.d.ts.map +1 -1
- package/dist/components/Chat/BookMeetingDetail.d.ts +1 -1
- package/dist/components/Chat/BookMeetingDetail.d.ts.map +1 -1
- package/dist/components/Chat/BookMeetingForm.d.ts +1 -0
- package/dist/components/Chat/BookMeetingForm.d.ts.map +1 -1
- package/dist/components/Chat/BookMeetingList.d.ts.map +1 -1
- package/dist/components/Chat/Icons.d.ts.map +1 -1
- package/dist/components/Chat/Message.d.ts.map +1 -1
- package/dist/components/Chat/MultimodalInput.d.ts.map +1 -1
- package/dist/components/Chat/ProductList.d.ts +3 -3
- package/dist/components/Chat/ProductList.d.ts.map +1 -1
- package/dist/components/Chat/ui/PhoneNumberInput.d.ts +1 -0
- package/dist/components/Chat/ui/PhoneNumberInput.d.ts.map +1 -1
- package/dist/hooks/useConfiguration.d.ts +4 -1
- package/dist/hooks/useConfiguration.d.ts.map +1 -1
- package/dist/index.html +4 -4
- package/dist/types/bookMeeting.type.d.ts +2 -1
- package/dist/types/bookMeeting.type.d.ts.map +1 -1
- package/dist/wdyr.d.ts +2 -0
- package/dist/wdyr.d.ts.map +1 -0
- package/dist/web.js +1 -1
- package/dist/web.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Message.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAiC,MAAM,OAAO,CAAC;AAGtD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAa,MAAM,0BAA0B,CAAC;AAsCtE,KAAK,SAAS,GAAG;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;
|
|
1
|
+
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Message.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAiC,MAAM,OAAO,CAAC;AAGtD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAa,MAAM,0BAA0B,CAAC;AAsCtE,KAAK,SAAS,GAAG;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AA2MF,eAAO,MAAM,eAAe,YAAa;IAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,4CAyC/D,CAAC;;AAEF,wBAA0C"}
|
|
@@ -60,7 +60,7 @@ const PreviewMessage = ({ chatId, message, bot, enableTTS, isLoading, }) => {
|
|
|
60
60
|
const outputData = parseToolOutput(toolOutput);
|
|
61
61
|
return (_jsxs("div", { className: "custom-tool-result", children: [!!outputData && isWeatherTool(tool) && (_jsx(Weather, { weatherAtLocation: outputData })), !!outputData?.data?.getCMSLocationInfoDetail &&
|
|
62
62
|
tool === LOCATION_TOOLS.GET_ASSIGNED_LOCATION_DETAIL && (_jsx(LocationCard, { location: outputData.data.getCMSLocationInfoDetail })), !!outputData &&
|
|
63
|
-
tool === LOCATION_TOOLS.SEARCH_TRAVELING_PLACES && (_jsx("div", { className: "flex flex-row overflow-x-auto", children: outputData.map((place) => (_jsx("div", { className: "flex-shrink-0 pr-2 max-w-full", children: _jsx(LocationCard, { location: place }) }, place.id))) })), !!toolOutput && isDisplayProductListTool(tool) && (_jsx(ProductList, { productCodes: outputData.product_codes, tourCode: overrideConfig?.vars?.TOUR_CODE, languageCode: overrideConfig?.vars?.LANGUAGE_CODE, apiUrl: overrideConfig?.vars?.CLIK_GRAPHQL_API })), !!toolOutput && isDisplayProductDetailTool(tool) && (_jsx(ProductDetail, { productCode: outputData.product_code, tourCode: overrideConfig?.vars?.TOUR_CODE, languageCode: overrideConfig?.vars?.LANGUAGE_CODE, apiUrl: overrideConfig?.vars?.CLIK_GRAPHQL_API })), !!toolOutput && isDisplayScenariosTool(tool) && (_jsx(ScenariosList, { scenarioCodes: outputData?.scenario_codes, tourCode: overrideConfig?.vars?.TOUR_CODE, languageCode: overrideConfig?.vars?.LANGUAGE_CODE, apiUrl: overrideConfig?.vars?.CLIK_GRAPHQL_API })), !!toolOutput && isDisplayBookingFormTool(tool) && (_jsx(BookMeetingForm, { chatId: chatId || '', brandAlias: overrideConfig?.vars?.BRAND_ALIAS })), !!toolOutput && isDisplayContactFormTool(tool) && (_jsx(UserContactForm, {})), !!toolOutput && isHtmlContent(usedTool) && (_jsx(HtmlContent, { content: outputData.content })), !!toolOutput && isDisplayBookingListTool(tool) && (_jsx(BookMeetingList, { apiHost: apiHost, userId: overrideConfig?.vars?.USER_ID, theme: theme }))] }, `${tool}-${index}`));
|
|
63
|
+
tool === LOCATION_TOOLS.SEARCH_TRAVELING_PLACES && (_jsx("div", { className: "flex flex-row overflow-x-auto", children: outputData.map((place) => (_jsx("div", { className: "flex-shrink-0 pr-2 max-w-full", children: _jsx(LocationCard, { location: place }) }, place.id))) })), !!toolOutput && isDisplayProductListTool(tool) && (_jsx(ProductList, { productCodes: outputData.product_codes, tourCode: overrideConfig?.vars?.TOUR_CODE, languageCode: overrideConfig?.vars?.LANGUAGE_CODE, apiUrl: overrideConfig?.vars?.CLIK_GRAPHQL_API })), !!toolOutput && isDisplayProductDetailTool(tool) && (_jsx(ProductDetail, { productCode: outputData.product_code, tourCode: overrideConfig?.vars?.TOUR_CODE, languageCode: overrideConfig?.vars?.LANGUAGE_CODE, apiUrl: overrideConfig?.vars?.CLIK_GRAPHQL_API })), !!toolOutput && isDisplayScenariosTool(tool) && (_jsx(ScenariosList, { scenarioCodes: outputData?.scenario_codes, tourCode: overrideConfig?.vars?.TOUR_CODE, languageCode: overrideConfig?.vars?.LANGUAGE_CODE, apiUrl: overrideConfig?.vars?.CLIK_GRAPHQL_API })), !!toolOutput && isDisplayBookingFormTool(tool) && (_jsx(BookMeetingForm, { chatId: chatId || '', brandAlias: overrideConfig?.vars?.BRAND_ALIAS, userId: overrideConfig?.vars?.USER_ID })), !!toolOutput && isDisplayContactFormTool(tool) && (_jsx(UserContactForm, {})), !!toolOutput && isHtmlContent(usedTool) && (_jsx(HtmlContent, { content: outputData.content })), !!toolOutput && isDisplayBookingListTool(tool) && (_jsx(BookMeetingList, { apiHost: apiHost, userId: overrideConfig?.vars?.USER_ID, theme: theme }))] }, `${tool}-${index}`));
|
|
64
64
|
}) }))] })] })] }));
|
|
65
65
|
};
|
|
66
66
|
export const ThinkingMessage = ({ bot }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.js","sourceRoot":"","sources":["../../../src/components/Chat/Message.tsx"],"names":[],"mappings":"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","sourcesContent":["import { motion } from 'framer-motion';\nimport { useConfiguration } from 'hooks/useConfiguration';\nimport React, { FC, useEffect, useMemo } from 'react';\nimport { LOCATION_TOOLS } from '../../constants/toolNames';\nimport { useChatData } from '../../hooks/useChatData';\nimport { BotType } from '../../types/bot.type';\nimport { ChatMessageType, ToolUsage } from '../../types/flowise.type';\nimport { cn } from '../../utils/commonUtils';\nimport {\n getAvatarSource,\n getMessageBackgroundColor,\n getMessageTextColor,\n getRole,\n shouldShowAvatar,\n} from '../../utils/messageUtils';\nimport {\n categorizeTools,\n hasFocusToolOutput,\n isDisplayBookingFormTool,\n isDisplayBookingListTool,\n isDisplayContactFormTool,\n isDisplayProductDetailTool,\n isDisplayProductListTool,\n isDisplayScenariosTool,\n isHtmlContent,\n isWeatherTool,\n parseToolOutput,\n removeToolOutputFromContent,\n} from '../../utils/toolUtils';\nimport AgentThinking from './AgentThinking';\nimport AudioPlayer from './AudioPlayer';\nimport BookMeetingForm from './BookMeetingForm';\nimport BookMeetingList from './BookMeetingList';\nimport { HtmlContent } from './HtmlContent';\nimport { SparklesIcon } from './Icons';\nimport { LocationCard } from './LocationCard';\nimport { Markdown } from './Markdown';\nimport { PreviewAttachment } from './PreviewAttachment';\nimport ProductDetail from './ProductDetail';\nimport ProductList from './ProductList';\nimport ScenariosList from './ScenariosList';\nimport UserContactForm from './UserContactForm';\nimport { Weather } from './Weather';\n\ntype PropsType = {\n chatId?: string;\n message: ChatMessageType;\n isLoading: boolean;\n bot: BotType | null;\n enableTTS?: boolean;\n};\n\nconst PreviewMessage: FC<PropsType> = ({\n chatId,\n message,\n bot,\n enableTTS,\n isLoading,\n}) => {\n const { theme, overrideConfig, apiHost } = useConfiguration();\n const { listeners } = useChatData();\n\n const usedTools = useMemo(() => {\n return categorizeTools(message.usedTools || [], !!message.new);\n }, [message.usedTools, message.new]);\n\n const role = useMemo(() => {\n return getRole(message.role);\n }, [message.role]);\n\n const assistantAvatar = getAvatarSource(role, theme, bot?.avatar);\n\n const focusToolOutput = useMemo(() => {\n return hasFocusToolOutput(message.usedTools || []);\n }, [message.usedTools]);\n\n const messageContent = useMemo(() => {\n if (!focusToolOutput) {\n return message.content;\n }\n\n return removeToolOutputFromContent(\n message.content,\n message.usedTools || []\n );\n }, [focusToolOutput, message.content, message.usedTools]);\n\n useEffect(() => {\n const cmdTool = usedTools?.cmdToolResult as any;\n if (!cmdTool || !listeners?.['CMD_CALLBACK']) {\n return;\n }\n\n const tool = cmdTool as ToolUsage;\n listeners['CMD_CALLBACK']({\n tool: tool.tool,\n output: tool.toolOutput,\n });\n }, [usedTools]);\n\n return (\n <motion.div\n className=\"w-full mx-auto max-w-3xl px-4 group/message\"\n initial={{ y: 5, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n data-role={role}\n >\n <div className=\"flex justify-end text-[14px]\">\n {message?.fileUploads && !!message.fileUploads.length && (\n <PreviewAttachment attachment={message.fileUploads[0]} />\n )}\n </div>\n <div\n className={cn(\n `group-data-[role=user]/message:bg-[#FFF] group-data-[role=user]/message:rounded-[24px] text-[#18181B] group-data-[role=user]/message:px-[16px] group-data-[role=user]/message:py-[10px] flex gap-4 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl overflow-x-hidden break-all`\n )}\n style={{\n backgroundColor: getMessageBackgroundColor(role, theme),\n }}\n >\n {shouldShowAvatar(theme, message.role) && (\n <div className=\"size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border\">\n {assistantAvatar ? (\n <img\n src={assistantAvatar}\n alt={bot?.name ?? 'User Avatar'}\n width={24}\n height={24}\n className=\"rounded-full\"\n />\n ) : (\n <SparklesIcon size={14} />\n )}\n </div>\n )}\n\n <div className=\"flex flex-col gap-2 w-full\">\n {/* Agent Thinking Display */}\n {message?.agentSteps && !!message.agentSteps.length && (\n <AgentThinking steps={message.agentSteps} isLoading={isLoading} />\n )}\n\n {/* Message Content */}\n {!!messageContent && (\n <div\n className=\"flex flex-col gap-4\"\n style={{\n color: getMessageTextColor(role, theme),\n }}\n >\n <Markdown\n usedTools={focusToolOutput ? undefined : message?.usedTools}\n >\n {messageContent as string}\n </Markdown>\n </div>\n )}\n\n {/* Audio Player */}\n {!focusToolOutput && (role === 'assistant' || message?.ttsUrl) && (\n <AudioPlayer\n chatId={chatId}\n message={message}\n autoplay={!!enableTTS}\n />\n )}\n\n {/* Custom Tool Results */}\n {!!usedTools?.customToolResults?.length && (\n <div className=\"flex flex-col gap-4 custom-tools\">\n {usedTools.customToolResults.map((usedTool, index) => {\n const { tool, toolOutput, toolInput } = usedTool;\n const outputData = parseToolOutput(toolOutput);\n return (\n <div key={`${tool}-${index}`} className=\"custom-tool-result\">\n {!!outputData && isWeatherTool(tool) && (\n <Weather weatherAtLocation={outputData} />\n )}\n {!!outputData?.data?.getCMSLocationInfoDetail &&\n tool === LOCATION_TOOLS.GET_ASSIGNED_LOCATION_DETAIL && (\n <LocationCard\n location={outputData.data.getCMSLocationInfoDetail}\n />\n )}\n {!!outputData &&\n tool === LOCATION_TOOLS.SEARCH_TRAVELING_PLACES && (\n <div className=\"flex flex-row overflow-x-auto\">\n {outputData.map((place: any) => (\n <div\n key={place.id}\n className=\"flex-shrink-0 pr-2 max-w-full\"\n >\n <LocationCard location={place} />\n </div>\n ))}\n </div>\n )}\n {!!toolOutput && isDisplayProductListTool(tool) && (\n <ProductList\n productCodes={(outputData as any).product_codes}\n tourCode={overrideConfig?.vars?.TOUR_CODE}\n languageCode={overrideConfig?.vars?.LANGUAGE_CODE}\n apiUrl={overrideConfig?.vars?.CLIK_GRAPHQL_API}\n />\n )}\n {!!toolOutput && isDisplayProductDetailTool(tool) && (\n <ProductDetail\n productCode={(outputData as any).product_code}\n tourCode={overrideConfig?.vars?.TOUR_CODE}\n languageCode={overrideConfig?.vars?.LANGUAGE_CODE}\n apiUrl={overrideConfig?.vars?.CLIK_GRAPHQL_API}\n />\n )}\n {!!toolOutput && isDisplayScenariosTool(tool) && (\n <ScenariosList\n scenarioCodes={(outputData as any)?.scenario_codes}\n tourCode={overrideConfig?.vars?.TOUR_CODE}\n languageCode={overrideConfig?.vars?.LANGUAGE_CODE}\n apiUrl={overrideConfig?.vars?.CLIK_GRAPHQL_API}\n />\n )}\n {!!toolOutput && isDisplayBookingFormTool(tool) && (\n <BookMeetingForm\n chatId={chatId || ''}\n brandAlias={overrideConfig?.vars?.BRAND_ALIAS}\n />\n )}\n {!!toolOutput && isDisplayContactFormTool(tool) && (\n <UserContactForm />\n )}\n {!!toolOutput && isHtmlContent(usedTool) && (\n <HtmlContent content={outputData.content} />\n )}\n\n {!!toolOutput && isDisplayBookingListTool(tool) && (\n <BookMeetingList\n apiHost={apiHost}\n userId={overrideConfig?.vars?.USER_ID}\n theme={theme}\n />\n )}\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n </motion.div>\n );\n};\n\nexport const ThinkingMessage = ({ bot }: { bot: BotType | null }) => {\n const role = 'assistant';\n\n const { theme } = useConfiguration();\n\n const assistantAvatar = getAvatarSource(role, theme, bot?.avatar);\n\n return (\n <motion.div\n className=\"w-full mx-auto max-w-3xl px-4 group/message\"\n initial={{ y: 5, opacity: 0 }}\n animate={{ y: 0, opacity: 1, transition: { delay: 1 } }}\n data-role={role}\n >\n <div\n className={cn(\n 'flex gap-4 group-data-[role=user]/message:px-3 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl group-data-[role=user]/message:py-2 rounded-xl',\n {\n 'group-data-[role=user]/message:bg-muted': true,\n }\n )}\n >\n {shouldShowAvatar(theme, 'apiMessage') && (\n <div className=\"size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border\">\n <img\n src={assistantAvatar}\n alt={bot?.name ?? 'User Avatar'}\n width={24}\n height={24}\n className=\"rounded-full\"\n />\n </div>\n )}\n <div className=\"flex flex-col gap-2 w-full\">\n <div className=\"flex flex-col gap-4 text-muted-foreground\">\n Thinking...\n </div>\n </div>\n </div>\n </motion.div>\n );\n};\n\nexport default React.memo(PreviewMessage);\n"]}
|
|
1
|
+
{"version":3,"file":"Message.js","sourceRoot":"","sources":["../../../src/components/Chat/Message.tsx"],"names":[],"mappings":"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","sourcesContent":["import { motion } from 'framer-motion';\nimport { useConfiguration } from 'hooks/useConfiguration';\nimport React, { FC, useEffect, useMemo } from 'react';\nimport { LOCATION_TOOLS } from '../../constants/toolNames';\nimport { useChatData } from '../../hooks/useChatData';\nimport { BotType } from '../../types/bot.type';\nimport { ChatMessageType, ToolUsage } from '../../types/flowise.type';\nimport { cn } from '../../utils/commonUtils';\nimport {\n getAvatarSource,\n getMessageBackgroundColor,\n getMessageTextColor,\n getRole,\n shouldShowAvatar,\n} from '../../utils/messageUtils';\nimport {\n categorizeTools,\n hasFocusToolOutput,\n isDisplayBookingFormTool,\n isDisplayBookingListTool,\n isDisplayContactFormTool,\n isDisplayProductDetailTool,\n isDisplayProductListTool,\n isDisplayScenariosTool,\n isHtmlContent,\n isWeatherTool,\n parseToolOutput,\n removeToolOutputFromContent,\n} from '../../utils/toolUtils';\nimport AgentThinking from './AgentThinking';\nimport AudioPlayer from './AudioPlayer';\nimport BookMeetingForm from './BookMeetingForm';\nimport BookMeetingList from './BookMeetingList';\nimport { HtmlContent } from './HtmlContent';\nimport { SparklesIcon } from './Icons';\nimport { LocationCard } from './LocationCard';\nimport { Markdown } from './Markdown';\nimport { PreviewAttachment } from './PreviewAttachment';\nimport ProductDetail from './ProductDetail';\nimport ProductList from './ProductList';\nimport ScenariosList from './ScenariosList';\nimport UserContactForm from './UserContactForm';\nimport { Weather } from './Weather';\n\ntype PropsType = {\n chatId?: string;\n message: ChatMessageType;\n isLoading: boolean;\n bot: BotType | null;\n enableTTS?: boolean;\n};\n\nconst PreviewMessage: FC<PropsType> = ({\n chatId,\n message,\n bot,\n enableTTS,\n isLoading,\n}) => {\n const { theme, overrideConfig, apiHost } = useConfiguration();\n const { listeners } = useChatData();\n\n const usedTools = useMemo(() => {\n return categorizeTools(message.usedTools || [], !!message.new);\n }, [message.usedTools, message.new]);\n\n const role = useMemo(() => {\n return getRole(message.role);\n }, [message.role]);\n\n const assistantAvatar = getAvatarSource(role, theme, bot?.avatar);\n\n const focusToolOutput = useMemo(() => {\n return hasFocusToolOutput(message.usedTools || []);\n }, [message.usedTools]);\n\n const messageContent = useMemo(() => {\n if (!focusToolOutput) {\n return message.content;\n }\n\n return removeToolOutputFromContent(\n message.content,\n message.usedTools || []\n );\n }, [focusToolOutput, message.content, message.usedTools]);\n\n useEffect(() => {\n const cmdTool = usedTools?.cmdToolResult as any;\n if (!cmdTool || !listeners?.['CMD_CALLBACK']) {\n return;\n }\n\n const tool = cmdTool as ToolUsage;\n listeners['CMD_CALLBACK']({\n tool: tool.tool,\n output: tool.toolOutput,\n });\n }, [usedTools]);\n\n return (\n <motion.div\n className=\"w-full mx-auto max-w-3xl px-4 group/message\"\n initial={{ y: 5, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n data-role={role}\n >\n <div className=\"flex justify-end text-[14px]\">\n {message?.fileUploads && !!message.fileUploads.length && (\n <PreviewAttachment attachment={message.fileUploads[0]} />\n )}\n </div>\n <div\n className={cn(\n `group-data-[role=user]/message:bg-[#FFF] group-data-[role=user]/message:rounded-[24px] text-[#18181B] group-data-[role=user]/message:px-[16px] group-data-[role=user]/message:py-[10px] flex gap-4 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl overflow-x-hidden break-all`\n )}\n style={{\n backgroundColor: getMessageBackgroundColor(role, theme),\n }}\n >\n {shouldShowAvatar(theme, message.role) && (\n <div className=\"size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border\">\n {assistantAvatar ? (\n <img\n src={assistantAvatar}\n alt={bot?.name ?? 'User Avatar'}\n width={24}\n height={24}\n className=\"rounded-full\"\n />\n ) : (\n <SparklesIcon size={14} />\n )}\n </div>\n )}\n\n <div className=\"flex flex-col gap-2 w-full\">\n {/* Agent Thinking Display */}\n {message?.agentSteps && !!message.agentSteps.length && (\n <AgentThinking steps={message.agentSteps} isLoading={isLoading} />\n )}\n\n {/* Message Content */}\n {!!messageContent && (\n <div\n className=\"flex flex-col gap-4\"\n style={{\n color: getMessageTextColor(role, theme),\n }}\n >\n <Markdown\n usedTools={focusToolOutput ? undefined : message?.usedTools}\n >\n {messageContent as string}\n </Markdown>\n </div>\n )}\n\n {/* Audio Player */}\n {!focusToolOutput && (role === 'assistant' || message?.ttsUrl) && (\n <AudioPlayer\n chatId={chatId}\n message={message}\n autoplay={!!enableTTS}\n />\n )}\n\n {/* Custom Tool Results */}\n {!!usedTools?.customToolResults?.length && (\n <div className=\"flex flex-col gap-4 custom-tools\">\n {usedTools.customToolResults.map((usedTool, index) => {\n const { tool, toolOutput, toolInput } = usedTool;\n const outputData = parseToolOutput(toolOutput);\n return (\n <div key={`${tool}-${index}`} className=\"custom-tool-result\">\n {!!outputData && isWeatherTool(tool) && (\n <Weather weatherAtLocation={outputData} />\n )}\n {!!outputData?.data?.getCMSLocationInfoDetail &&\n tool === LOCATION_TOOLS.GET_ASSIGNED_LOCATION_DETAIL && (\n <LocationCard\n location={outputData.data.getCMSLocationInfoDetail}\n />\n )}\n {!!outputData &&\n tool === LOCATION_TOOLS.SEARCH_TRAVELING_PLACES && (\n <div className=\"flex flex-row overflow-x-auto\">\n {outputData.map((place: any) => (\n <div\n key={place.id}\n className=\"flex-shrink-0 pr-2 max-w-full\"\n >\n <LocationCard location={place} />\n </div>\n ))}\n </div>\n )}\n {!!toolOutput && isDisplayProductListTool(tool) && (\n <ProductList\n productCodes={(outputData as any).product_codes}\n tourCode={overrideConfig?.vars?.TOUR_CODE}\n languageCode={overrideConfig?.vars?.LANGUAGE_CODE}\n apiUrl={overrideConfig?.vars?.CLIK_GRAPHQL_API}\n />\n )}\n {!!toolOutput && isDisplayProductDetailTool(tool) && (\n <ProductDetail\n productCode={(outputData as any).product_code}\n tourCode={overrideConfig?.vars?.TOUR_CODE}\n languageCode={overrideConfig?.vars?.LANGUAGE_CODE}\n apiUrl={overrideConfig?.vars?.CLIK_GRAPHQL_API}\n />\n )}\n {!!toolOutput && isDisplayScenariosTool(tool) && (\n <ScenariosList\n scenarioCodes={(outputData as any)?.scenario_codes}\n tourCode={overrideConfig?.vars?.TOUR_CODE}\n languageCode={overrideConfig?.vars?.LANGUAGE_CODE}\n apiUrl={overrideConfig?.vars?.CLIK_GRAPHQL_API}\n />\n )}\n {!!toolOutput && isDisplayBookingFormTool(tool) && (\n <BookMeetingForm\n chatId={chatId || ''}\n brandAlias={overrideConfig?.vars?.BRAND_ALIAS}\n userId={overrideConfig?.vars?.USER_ID}\n />\n )}\n {!!toolOutput && isDisplayContactFormTool(tool) && (\n <UserContactForm />\n )}\n {!!toolOutput && isHtmlContent(usedTool) && (\n <HtmlContent content={outputData.content} />\n )}\n\n {!!toolOutput && isDisplayBookingListTool(tool) && (\n <BookMeetingList\n apiHost={apiHost}\n userId={overrideConfig?.vars?.USER_ID}\n theme={theme}\n />\n )}\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n </motion.div>\n );\n};\n\nexport const ThinkingMessage = ({ bot }: { bot: BotType | null }) => {\n const role = 'assistant';\n\n const { theme } = useConfiguration();\n\n const assistantAvatar = getAvatarSource(role, theme, bot?.avatar);\n\n return (\n <motion.div\n className=\"w-full mx-auto max-w-3xl px-4 group/message\"\n initial={{ y: 5, opacity: 0 }}\n animate={{ y: 0, opacity: 1, transition: { delay: 1 } }}\n data-role={role}\n >\n <div\n className={cn(\n 'flex gap-4 group-data-[role=user]/message:px-3 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl group-data-[role=user]/message:py-2 rounded-xl',\n {\n 'group-data-[role=user]/message:bg-muted': true,\n }\n )}\n >\n {shouldShowAvatar(theme, 'apiMessage') && (\n <div className=\"size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border\">\n <img\n src={assistantAvatar}\n alt={bot?.name ?? 'User Avatar'}\n width={24}\n height={24}\n className=\"rounded-full\"\n />\n </div>\n )}\n <div className=\"flex flex-col gap-2 w-full\">\n <div className=\"flex flex-col gap-4 text-muted-foreground\">\n Thinking...\n </div>\n </div>\n </div>\n </motion.div>\n );\n};\n\nexport default React.memo(PreviewMessage);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultimodalInput.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/MultimodalInput.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,EAAE,EAKH,MAAM,OAAO,CAAC;AAIf,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AASnD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAqBxE,KAAK,SAAS,GAAG;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,WAAW,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,CACZ,KAAK,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,EACvC,KAAK,CAAC,EAAE,WAAW,EAAE,KAClB,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,IAAI,CAAC;IACzE,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"MultimodalInput.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/MultimodalInput.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,EAAE,EAKH,MAAM,OAAO,CAAC;AAIf,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AASnD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAqBxE,KAAK,SAAS,GAAG;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,WAAW,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,CACZ,KAAK,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,EACvC,KAAK,CAAC,EAAE,WAAW,EAAE,KAClB,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,IAAI,CAAC;IACzE,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,SAAS,CA4oBzC,CAAC"}
|
|
@@ -87,6 +87,7 @@ export const MultimodalInput = ({ input, setInput, isLoading, stop, messages, se
|
|
|
87
87
|
textareaRef.current.setSelectionRange(length, length);
|
|
88
88
|
// Scroll tới cuối
|
|
89
89
|
textareaRef.current.scrollTop = textareaRef.current.scrollHeight;
|
|
90
|
+
adjustHeight();
|
|
90
91
|
}
|
|
91
92
|
}, [isMultiline]);
|
|
92
93
|
useEffect(() => {
|
|
@@ -106,8 +107,8 @@ export const MultimodalInput = ({ input, setInput, isLoading, stop, messages, se
|
|
|
106
107
|
});
|
|
107
108
|
}
|
|
108
109
|
}, []);
|
|
109
|
-
const handleInput = (event) => {
|
|
110
|
-
const newValue = event
|
|
110
|
+
const handleInput = (event, valueInput) => {
|
|
111
|
+
const newValue = event?.target.value || valueInput || '';
|
|
111
112
|
handleSetInput(newValue);
|
|
112
113
|
// Nếu có newline (Enter) thì chuyển sang textarea ngay
|
|
113
114
|
if (!isMultiline && newValue.includes('\n')) {
|
|
@@ -140,6 +141,7 @@ export const MultimodalInput = ({ input, setInput, isLoading, stop, messages, se
|
|
|
140
141
|
const submitForm = useCallback(async () => {
|
|
141
142
|
handleSubmit(undefined, attachments);
|
|
142
143
|
setLocalStorageInput('');
|
|
144
|
+
setIsMultiline(false);
|
|
143
145
|
if (setAttachments) {
|
|
144
146
|
setAttachments((_) => []);
|
|
145
147
|
if (fileInputRef.current) {
|
|
@@ -260,7 +262,7 @@ export const MultimodalInput = ({ input, setInput, isLoading, stop, messages, se
|
|
|
260
262
|
const speechToText = async (blob) => {
|
|
261
263
|
try {
|
|
262
264
|
setTranscribing(true);
|
|
263
|
-
setIsMultiline(true);
|
|
265
|
+
// setIsMultiline(true);
|
|
264
266
|
const fileUpload = await toAudioBase64(blob);
|
|
265
267
|
const base64Data = fileUpload.data.replace(/^data:.+;base64,/, '');
|
|
266
268
|
const byteCharacters = atob(base64Data); // Decode Base64 string
|
|
@@ -275,7 +277,7 @@ export const MultimodalInput = ({ input, setInput, isLoading, stop, messages, se
|
|
|
275
277
|
});
|
|
276
278
|
const text = await getAudioTranscript({ file, apiHost, language });
|
|
277
279
|
if (text) {
|
|
278
|
-
|
|
280
|
+
handleInput(undefined, text);
|
|
279
281
|
}
|
|
280
282
|
}
|
|
281
283
|
catch (error) {
|
|
@@ -331,7 +333,7 @@ export const MultimodalInput = ({ input, setInput, isLoading, stop, messages, se
|
|
|
331
333
|
name: filename,
|
|
332
334
|
mime: '',
|
|
333
335
|
type: '',
|
|
334
|
-
}, isUploading: true }, filename)))] })), _jsxs("div", { className: " w-full flex gap-4 justify-end items-end", children: [isRecording ? (_jsx(Button, { className: ` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white `, onClick: (event) => {
|
|
336
|
+
}, isUploading: true }, filename)))] })), _jsxs("div", { className: " w-full flex gap-4 justify-end items-end", children: [isRecording ? (_jsx(Button, { className: ` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white px-0`, onClick: (event) => {
|
|
335
337
|
event.preventDefault();
|
|
336
338
|
handleFinishRecording();
|
|
337
339
|
}, children: _jsx("div", { className: "w-[12px] h-[12px] bg-muted-foreground rounded-full" }) })) : (_jsxs(DropdownMenu, { open: dropdownOpen, onOpenChange: setDropdownOpen, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { className: ` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white`, onClick: (event) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultimodalInput.js","sourceRoot":"","sources":["../../../src/components/Chat/MultimodalInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import { LAYOUT_MODE } from 'commons/constants';\nimport {\n type ChangeEvent,\n FC,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { Volume2, Paperclip } from 'lucide-react';\n\nimport { SuggestionType } from 'types/common.type';\nimport { useLocalStorage, useWindowSize } from 'usehooks-ts';\nimport { useAudioRecording } from '../../hooks/useAudioRecording';\nimport { useChatData } from '../../hooks/useChatData';\nimport { useConfiguration } from '../../hooks/useConfiguration';\nimport {\n createAttachments,\n getAudioTranscript,\n} from '../../services/chat.service';\nimport { BotType } from '../../types/bot.type';\nimport { ChatMessageType, IFileUpload } from '../../types/flowise.type';\nimport {\n cn,\n generateExtendedFileName,\n generateUUID,\n} from '../../utils/commonUtils';\nimport { getBestMimeType, getFileExtension } from '../../utils/fileUtils';\nimport { ArrowUpIcon, ClikMicrophoneIcon, PlusIcon, StopIcon } from './Icons';\nimport SuggestedActions from './SuggestedActions';\nimport { Button } from './ui/Button';\nimport { Textarea } from './ui/Textarea';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from './ui/DropdownMenu';\n\nimport { VoiceRecordingUI } from './VoiceRecordingUI';\nimport { PreviewFileAttachment } from './PreviewFileAttachment';\n\ntype PropsType = {\n input: string;\n setInput: (value: string) => void;\n isLoading: boolean;\n stop: () => void;\n messages: ChatMessageType[];\n setMessages: (messages: ChatMessageType[]) => void;\n chatId: string;\n handleSubmit: (\n event?: { preventDefault?: () => void },\n files?: IFileUpload[]\n ) => void;\n className?: string;\n append?: (message: ChatMessageType) => Promise<void>;\n attachments?: IFileUpload[];\n setAttachments?: (func: (files: IFileUpload[]) => IFileUpload[]) => void;\n bot: BotType | null;\n apiHost: string;\n setEnableTTS: (value: boolean) => void;\n enableTTS: boolean;\n suggestedActions?: SuggestionType[];\n};\n\nexport const MultimodalInput: FC<PropsType> = ({\n input,\n setInput,\n isLoading,\n stop,\n messages,\n setMessages,\n chatId,\n handleSubmit,\n className,\n append,\n attachments,\n setAttachments,\n bot,\n apiHost,\n setEnableTTS,\n enableTTS,\n suggestedActions,\n}) => {\n const { theme, onLoaded } = useConfiguration();\n const {\n isRecording,\n onRecordingCancelled,\n onRecordingStopped,\n onRecordingStarted,\n elapsedTime,\n audioData,\n updateMaxHistoryLength,\n } = useAudioRecording();\n const { listeners } = useChatData();\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const setInputRef = useRef<((input: string) => void) | null>(null);\n\n const { width } = useWindowSize();\n\n const defaultRows = theme?.suggestion?.defaultRows || 1;\n const expandedRows = theme?.suggestion?.expandedRows || 2;\n const suggestedActionLayoutMode =\n theme?.suggestion?.layoutMode || LAYOUT_MODE.SCROLL;\n\n const language =\n theme?.language?.options\n ?.find((option) => option.code === theme?.language?.code)\n ?.name?.toLowerCase() || 'en';\n\n const [suggestedActionRows, setSuggestedActionRows] =\n useState<number>(defaultRows); // only use for scroll mode SuggestedActions\n\n const [transcribing, setTranscribing] = useState<boolean>(false);\n const [isMultiline, setIsMultiline] = useState<boolean>(false);\n const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);\n\n const adjustHeight = () => {\n if (textareaRef.current) {\n (textareaRef.current as HTMLTextAreaElement).style.height = 'auto';\n (textareaRef.current as HTMLTextAreaElement).style.height =\n `${textareaRef.current?.scrollHeight + 2}px`;\n }\n };\n\n const [localStorageInput, setLocalStorageInput] = useLocalStorage(\n 'input',\n ''\n );\n\n useEffect(() => {\n if (textareaRef.current) {\n const domValue = textareaRef.current?.value;\n // Prefer DOM value over localStorage to handle hydration\n const finalValue = domValue || localStorageInput || '';\n setInput(finalValue);\n adjustHeight();\n\n setTimeout(() => {\n if (textareaRef.current) {\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n }, 500);\n }\n // Only run once after hydration\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n setLocalStorageInput(input);\n }, [input, setLocalStorageInput]);\n\n const readonly = isRecording || transcribing;\n const handleSetInput = (value: string) => {\n setInput(value);\n };\n\n useEffect(() => {\n adjustHeight();\n if (suggestedActionRows !== defaultRows) {\n setSuggestedActionRows(defaultRows);\n }\n }, [input, readonly]);\n\n // Focus vào element đúng khi chuyển đổi giữa input và textarea\n useEffect(() => {\n if (!isMultiline && !!inputRef.current) {\n inputRef.current.focus();\n // Set cursor tới cuối\n const length = inputRef.current.value.length;\n inputRef.current.setSelectionRange(length, length);\n } else if (isMultiline && textareaRef.current) {\n textareaRef.current.focus();\n // Set cursor tới cuối\n const length = textareaRef.current.value.length;\n textareaRef.current.setSelectionRange(length, length);\n // Scroll tới cuối\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n }, [isMultiline]);\n\n useEffect(() => {\n setInputRef.current = setInput;\n }, [setInput]);\n\n useEffect(() => {\n if (onLoaded) {\n onLoaded({\n setInput: (txt): void => {\n if (setInputRef.current) {\n setInputRef.current(txt || '');\n }\n },\n startRecording: async () => {\n handleStartRecording();\n },\n });\n }\n }, []);\n\n const handleInput = (\n event: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>\n ) => {\n const newValue = event.target.value;\n handleSetInput(newValue);\n\n // Nếu có newline (Enter) thì chuyển sang textarea ngay\n if (!isMultiline && newValue.includes('\\n')) {\n setIsMultiline(true);\n return;\n }\n\n // Kiểm tra scroll ngay khi input thay đổi\n if (!isMultiline && inputRef.current && newValue) {\n // Đợi DOM update rồi kiểm tra scroll\n setTimeout(() => {\n const currentInput = inputRef.current;\n if (currentInput) {\n const hasScroll = currentInput.scrollWidth > currentInput.clientWidth;\n if (hasScroll) {\n setIsMultiline(true);\n }\n }\n }, 0);\n }\n\n // Nếu xóa hết text thì chuyển về input\n if (!newValue && isMultiline) {\n setIsMultiline(false);\n }\n\n if (textareaRef.current) {\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n };\n\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const [uploadQueue, setUploadQueue] = useState<Array<string>>([]);\n\n const submitForm = useCallback(async () => {\n handleSubmit(undefined, attachments);\n setLocalStorageInput('');\n if (setAttachments) {\n setAttachments((_) => []);\n if (fileInputRef.current) {\n (fileInputRef.current as HTMLInputElement).value = '';\n }\n }\n if (width && width > 768) {\n textareaRef.current?.focus();\n }\n }, [handleSubmit, setLocalStorageInput, width, attachments, chatId, bot]);\n\n const uploadFile = useCallback(\n async (file: File) => {\n const formData = new FormData();\n formData.append('file', file, generateExtendedFileName(file.name));\n try {\n return await createAttachments({\n chatId,\n apiHost,\n body: formData,\n });\n } catch (error) {\n console.error('Failed to upload file, please try again!');\n }\n },\n [chatId]\n );\n\n const toAudioBase64 = (blob: Blob) => {\n return new Promise<IFileUpload>((resolve) => {\n let mimeType = getBestMimeType();\n const pos = blob.type.indexOf(';');\n if (pos === -1) {\n mimeType = blob.type;\n } else {\n mimeType = blob.type.substring(0, pos);\n }\n\n // read blob and add to previews\n const reader = new FileReader();\n reader.readAsDataURL(blob);\n reader.onloadend = () => {\n const base64data = reader.result as string;\n const upload: IFileUpload = {\n tempId: generateUUID(),\n data: base64data,\n type: 'audio',\n name: `audio_${Date.now()}.${getFileExtension(mimeType)}`,\n mime: mimeType,\n };\n resolve(upload);\n };\n });\n };\n\n const toBase64 = async (\n file: File,\n type = 'file'\n ): Promise<IFileUpload | undefined> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = () => {\n resolve({\n tempId: generateUUID(),\n data: reader.result as string,\n type,\n name: generateExtendedFileName(file.name),\n mime: file.type,\n });\n };\n reader.onerror = () => {\n reject();\n };\n });\n };\n\n const checkUploadFile = useCallback(\n async (file: File): Promise<IFileUpload | undefined> => {\n if (file.type.startsWith('image')) {\n return toBase64(file);\n } else {\n setUploadQueue([file.name]);\n const response: any = await uploadFile(file);\n if (response?.type == 'file:full') {\n const f = response.result[0];\n if (!f) {\n return;\n }\n return {\n tempId: generateUUID(),\n data: f.content,\n name: f.name,\n mime: f.mimeType,\n type: response?.type,\n };\n } else if (response?.type == 'file:rag') {\n const { addedDocs } = response.result;\n if (!addedDocs.length) {\n return;\n }\n return toBase64(file, response?.type);\n }\n }\n },\n [setUploadQueue, uploadFile]\n );\n\n const handleFileChange = useCallback(\n async (event: ChangeEvent<HTMLInputElement>) => {\n const files = Array.from(event.target.files || []);\n try {\n const uploadPromises = files.map((file) => checkUploadFile(file));\n const uploadedAttachments = await Promise.all(uploadPromises);\n const successfullyUploadedAttachments = uploadedAttachments.filter(\n (attachment) => attachment !== undefined\n ) as IFileUpload[];\n if (setAttachments) {\n setAttachments((currentAttachments: IFileUpload[]) => [\n ...currentAttachments,\n ...successfullyUploadedAttachments,\n ]);\n }\n } catch (error) {\n console.error('Error uploading files!', error);\n } finally {\n setUploadQueue([]);\n }\n },\n [setAttachments, checkUploadFile]\n );\n\n const speechToText = async (blob: Blob) => {\n try {\n setTranscribing(true);\n setIsMultiline(true);\n const fileUpload = await toAudioBase64(blob);\n const base64Data = fileUpload.data!.replace(/^data:.+;base64,/, '');\n const byteCharacters = atob(base64Data); // Decode Base64 string\n const byteNumbers = new Array(byteCharacters.length);\n\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n const file = new File([byteArray], fileUpload.name, {\n lastModified: new Date().getTime(),\n type: fileUpload.type,\n });\n\n const text = await getAudioTranscript({ file, apiHost, language });\n if (text) {\n handleSetInput(text);\n }\n } catch (error) {\n console.error('Error getting audio transcript!', error);\n } finally {\n setTranscribing(false);\n }\n };\n\n const handleFinishRecording = () => {\n if (isRecording) {\n onRecordingStopped(speechToText);\n }\n if (listeners?.['ON_FINISHED_RECORDING']) {\n listeners['ON_FINISHED_RECORDING']();\n }\n };\n\n const handleStartRecording = () => {\n setIsMultiline(false);\n onRecordingStarted();\n handleSetInput('');\n if (listeners?.['ON_START_RECORDING']) {\n listeners['ON_START_RECORDING']();\n }\n };\n\n const handleCancelRecording = () => {\n onRecordingCancelled();\n handleSetInput('');\n if (listeners?.['ON_CANCEL_RECORDING']) {\n listeners['ON_CANCEL_RECORDING']();\n }\n };\n\n const handleSend = useCallback(async () => {\n if (!isRecording) {\n submitForm();\n }\n }, [submitForm, isRecording]);\n\n const handleWidthChange = useCallback(\n (maxBars: number) => {\n updateMaxHistoryLength(maxBars);\n },\n [updateMaxHistoryLength]\n );\n\n const placeholder =\n !isRecording && !transcribing\n ? theme?.input?.placeholder || 'Send a message...'\n : theme?.input?.transcribingPlaceholder || 'Transcribing...';\n\n const recordingPlaceholder =\n isRecording && !transcribing\n ? theme?.input?.recordingPlaceholder || 'Recording...'\n : '';\n\n return (\n <div className=\"relative w-full flex gap-4 flex-col\">\n {!!suggestedActions?.length && (\n <SuggestedActions\n suggestedActions={suggestedActions}\n append={append}\n layoutMode={suggestedActionLayoutMode}\n suggestedActionRows={suggestedActionRows}\n />\n )}\n {((attachments && attachments.length > 0) || uploadQueue.length > 0) && (\n <div className=\"list-attachments flex flex-row gap-2 overflow-x-scroll items-end\">\n {attachments?.map((attachment) => (\n <PreviewFileAttachment\n key={attachment.tempId}\n attachment={attachment}\n onRemoveAttachment={() => {\n setAttachments?.((currentAttachments: IFileUpload[]) =>\n currentAttachments.filter(\n (f) => f.tempId !== attachment.tempId\n )\n );\n }}\n />\n ))}\n {uploadQueue.map((filename) => (\n <PreviewFileAttachment\n key={filename}\n onRemoveAttachment={() => {\n setUploadQueue(uploadQueue.filter((f) => f !== filename));\n }}\n attachment={{\n data: '',\n name: filename,\n mime: '',\n type: '',\n }}\n isUploading\n />\n ))}\n </div>\n )}\n <div className=\" w-full flex gap-4 justify-end items-end\">\n {isRecording ? (\n <Button\n className={` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white `}\n onClick={(event) => {\n event.preventDefault();\n handleFinishRecording();\n }}\n >\n <div className=\"w-[12px] h-[12px] bg-muted-foreground rounded-full\"></div>\n </Button>\n ) : (\n <DropdownMenu open={dropdownOpen} onOpenChange={setDropdownOpen}>\n <DropdownMenuTrigger asChild>\n <Button\n className={` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white`}\n onClick={(event) => {\n event.preventDefault();\n }}\n >\n <PlusIcon size={20} color={'#71717A'} />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n side=\"top\"\n align=\"start\"\n className=\"w-48 rounded-2xl border py-[6px] border-[#0d0d0d0d] shadow-sm\"\n >\n <DropdownMenuItem\n onClick={() => {\n // Trigger file input\n fileInputRef.current?.click();\n setDropdownOpen(false);\n }}\n className=\"flex items-center gap-2 px-4\"\n >\n <Paperclip size={16} />\n <span className=\"text-[14px]\">Upload File</span>\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => {\n setEnableTTS(!enableTTS);\n }}\n className={`flex items-center gap-2 px-4 ${enableTTS ? 'bg-[#CBE1F3] text-[#0A82F7]' : ''}`}\n >\n <Volume2 />\n <span className=\"text-[14px]\">\n {theme?.buttons?.textBtnSpeak || 'Speak'}\n </span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <div className=\"block flex-1 min-w-0 relative\">\n {/* Animated Input/Textarea Container */}\n <AnimatePresence mode=\"wait\">\n {!isRecording && (\n <>\n <motion.input\n key=\"input\"\n type=\"text\"\n id=\"input-multimodal-container\"\n readOnly={readonly}\n ref={inputRef}\n placeholder={placeholder}\n value={input}\n onChange={handleInput}\n className={cn(\n `h-[40px] outline-none text-base bg-muted bg-[#ffffff] scrollbar-hidden p-[12px] pr-[68px] rounded-[24px] backdrop-blur-[50px] w-full ${readonly ? 'hidden' : ''}`,\n className\n )}\n autoFocus\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 40 }}\n exit={{ opacity: 0, height: 0 }}\n transition={{\n duration: 0.2,\n ease: 'easeInOut',\n }}\n style={{\n display: isMultiline || transcribing ? 'none' : 'block',\n }}\n onKeyDown={(event) => {\n if (isRecording) {\n return;\n }\n\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n if (isLoading) {\n console.error(\n 'Please wait for the model to finish its response!'\n );\n } else if (uploadQueue.length) {\n console.error('Please wait for file is uploading!');\n } else if (input.length > 0) {\n handleSend();\n }\n }\n }}\n />\n <motion.div\n key=\"textarea\"\n initial={{ opacity: 0, height: 40 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 40 }}\n transition={{\n duration: 0.2,\n ease: 'easeInOut',\n }}\n style={{\n display: isMultiline || transcribing ? 'block' : 'none',\n }}\n >\n <Textarea\n readOnly={readonly}\n ref={textareaRef}\n placeholder={placeholder}\n value={input}\n onChange={handleInput}\n className={cn(\n `min-h-[24px] max-h-[160px] resize-none text-base bg-muted bg-[#ffffff] scrollbar-hidden p-[12px] pb-[32px] rounded-[24px] border border-[#E5E5E5] shadow-[0px_2px_6px_0px_rgba(0,0,0,0.08)] backdrop-blur-[50px] ${suggestedActionRows === expandedRows && 'p-[12px]'} `,\n className\n )}\n style={{\n height:\n suggestedActionRows === expandedRows ? 60 : undefined,\n }}\n autoFocus\n onKeyDown={(event) => {\n if (isRecording) {\n return;\n }\n\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n if (isLoading) {\n console.error(\n 'Please wait for the model to finish its response!'\n );\n } else if (uploadQueue.length) {\n console.error('Please wait for file is uploading!');\n } else if (input.length > 0) {\n handleSend();\n }\n }\n }}\n />\n </motion.div>\n </>\n )}\n </AnimatePresence>\n {/* Voice Recording UI Overlay */}\n <div className=\"w-full \">\n <VoiceRecordingUI\n isRecording={isRecording}\n elapsedTime={elapsedTime}\n onCancel={handleCancelRecording}\n transcribing={transcribing}\n audioData={audioData}\n label={recordingPlaceholder}\n onWidthChange={handleWidthChange}\n />\n </div>\n\n <div className=\"button-voice right-[4px] absolute bottom-[4px] flex gap-[12px]\">\n {!isRecording && (\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 bg-transparent\"\n onClick={(event) => {\n event.preventDefault();\n handleStartRecording();\n }}\n disabled={isLoading}\n >\n <ClikMicrophoneIcon size={20} />\n </Button>\n )}\n\n {isLoading ? (\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 border bg-[#71717A]\"\n onClick={(event) => {\n event.preventDefault();\n stop();\n setMessages(messages);\n }}\n >\n <StopIcon size={20} />\n </Button>\n ) : (\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 border bg-[#71717A]\"\n onClick={(event) => {\n event.preventDefault();\n handleSend();\n }}\n disabled={\n isRecording || input.length === 0 || !!uploadQueue.length\n }\n >\n <ArrowUpIcon size={20} />\n </Button>\n )}\n </div>\n </div>\n {/* Hidden file input */}\n <input\n type=\"file\"\n ref={fileInputRef}\n onChange={handleFileChange}\n multiple\n accept=\"image/*,video/*,audio/*,.pdf,.doc,.docx,.txt\"\n style={{ display: 'none' }}\n />\n </div>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"MultimodalInput.js","sourceRoot":"","sources":["../../../src/components/Chat/MultimodalInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import { LAYOUT_MODE } from 'commons/constants';\nimport {\n type ChangeEvent,\n FC,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { Volume2, Paperclip } from 'lucide-react';\n\nimport { SuggestionType } from 'types/common.type';\nimport { useLocalStorage, useWindowSize } from 'usehooks-ts';\nimport { useAudioRecording } from '../../hooks/useAudioRecording';\nimport { useChatData } from '../../hooks/useChatData';\nimport { useConfiguration } from '../../hooks/useConfiguration';\nimport {\n createAttachments,\n getAudioTranscript,\n} from '../../services/chat.service';\nimport { BotType } from '../../types/bot.type';\nimport { ChatMessageType, IFileUpload } from '../../types/flowise.type';\nimport {\n cn,\n generateExtendedFileName,\n generateUUID,\n} from '../../utils/commonUtils';\nimport { getBestMimeType, getFileExtension } from '../../utils/fileUtils';\nimport { ArrowUpIcon, ClikMicrophoneIcon, PlusIcon, StopIcon } from './Icons';\nimport SuggestedActions from './SuggestedActions';\nimport { Button } from './ui/Button';\nimport { Textarea } from './ui/Textarea';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from './ui/DropdownMenu';\n\nimport { VoiceRecordingUI } from './VoiceRecordingUI';\nimport { PreviewFileAttachment } from './PreviewFileAttachment';\n\ntype PropsType = {\n input: string;\n setInput: (value: string) => void;\n isLoading: boolean;\n stop: () => void;\n messages: ChatMessageType[];\n setMessages: (messages: ChatMessageType[]) => void;\n chatId: string;\n handleSubmit: (\n event?: { preventDefault?: () => void },\n files?: IFileUpload[]\n ) => void;\n className?: string;\n append?: (message: ChatMessageType) => Promise<void>;\n attachments?: IFileUpload[];\n setAttachments?: (func: (files: IFileUpload[]) => IFileUpload[]) => void;\n bot: BotType | null;\n apiHost: string;\n setEnableTTS: (value: boolean) => void;\n enableTTS: boolean;\n suggestedActions?: SuggestionType[];\n};\n\nexport const MultimodalInput: FC<PropsType> = ({\n input,\n setInput,\n isLoading,\n stop,\n messages,\n setMessages,\n chatId,\n handleSubmit,\n className,\n append,\n attachments,\n setAttachments,\n bot,\n apiHost,\n setEnableTTS,\n enableTTS,\n suggestedActions,\n}) => {\n const { theme, onLoaded } = useConfiguration();\n const {\n isRecording,\n onRecordingCancelled,\n onRecordingStopped,\n onRecordingStarted,\n elapsedTime,\n audioData,\n updateMaxHistoryLength,\n } = useAudioRecording();\n const { listeners } = useChatData();\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const setInputRef = useRef<((input: string) => void) | null>(null);\n\n const { width } = useWindowSize();\n\n const defaultRows = theme?.suggestion?.defaultRows || 1;\n const expandedRows = theme?.suggestion?.expandedRows || 2;\n const suggestedActionLayoutMode =\n theme?.suggestion?.layoutMode || LAYOUT_MODE.SCROLL;\n\n const language =\n theme?.language?.options\n ?.find((option) => option.code === theme?.language?.code)\n ?.name?.toLowerCase() || 'en';\n\n const [suggestedActionRows, setSuggestedActionRows] =\n useState<number>(defaultRows); // only use for scroll mode SuggestedActions\n\n const [transcribing, setTranscribing] = useState<boolean>(false);\n const [isMultiline, setIsMultiline] = useState<boolean>(false);\n const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);\n\n const adjustHeight = () => {\n if (textareaRef.current) {\n (textareaRef.current as HTMLTextAreaElement).style.height = 'auto';\n (textareaRef.current as HTMLTextAreaElement).style.height =\n `${textareaRef.current?.scrollHeight + 2}px`;\n }\n };\n\n const [localStorageInput, setLocalStorageInput] = useLocalStorage(\n 'input',\n ''\n );\n\n useEffect(() => {\n if (textareaRef.current) {\n const domValue = textareaRef.current?.value;\n // Prefer DOM value over localStorage to handle hydration\n const finalValue = domValue || localStorageInput || '';\n setInput(finalValue);\n adjustHeight();\n\n setTimeout(() => {\n if (textareaRef.current) {\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n }, 500);\n }\n // Only run once after hydration\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n setLocalStorageInput(input);\n }, [input, setLocalStorageInput]);\n\n const readonly = isRecording || transcribing;\n const handleSetInput = (value: string) => {\n setInput(value);\n };\n\n useEffect(() => {\n adjustHeight();\n if (suggestedActionRows !== defaultRows) {\n setSuggestedActionRows(defaultRows);\n }\n }, [input, readonly]);\n\n // Focus vào element đúng khi chuyển đổi giữa input và textarea\n useEffect(() => {\n if (!isMultiline && !!inputRef.current) {\n inputRef.current.focus();\n // Set cursor tới cuối\n const length = inputRef.current.value.length;\n inputRef.current.setSelectionRange(length, length);\n } else if (isMultiline && textareaRef.current) {\n textareaRef.current.focus();\n // Set cursor tới cuối\n const length = textareaRef.current.value.length;\n textareaRef.current.setSelectionRange(length, length);\n // Scroll tới cuối\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n adjustHeight();\n }\n }, [isMultiline]);\n\n useEffect(() => {\n setInputRef.current = setInput;\n }, [setInput]);\n\n useEffect(() => {\n if (onLoaded) {\n onLoaded({\n setInput: (txt): void => {\n if (setInputRef.current) {\n setInputRef.current(txt || '');\n }\n },\n startRecording: async () => {\n handleStartRecording();\n },\n });\n }\n }, []);\n\n const handleInput = (\n event?: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,\n valueInput?: string\n ) => {\n const newValue = event?.target.value || valueInput || '';\n handleSetInput(newValue);\n\n // Nếu có newline (Enter) thì chuyển sang textarea ngay\n if (!isMultiline && newValue.includes('\\n')) {\n setIsMultiline(true);\n return;\n }\n\n // Kiểm tra scroll ngay khi input thay đổi\n if (!isMultiline && inputRef.current && newValue) {\n // Đợi DOM update rồi kiểm tra scroll\n setTimeout(() => {\n const currentInput = inputRef.current;\n if (currentInput) {\n const hasScroll = currentInput.scrollWidth > currentInput.clientWidth;\n if (hasScroll) {\n setIsMultiline(true);\n }\n }\n }, 0);\n }\n\n // Nếu xóa hết text thì chuyển về input\n if (!newValue && isMultiline) {\n setIsMultiline(false);\n }\n\n if (textareaRef.current) {\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n };\n\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const [uploadQueue, setUploadQueue] = useState<Array<string>>([]);\n\n const submitForm = useCallback(async () => {\n handleSubmit(undefined, attachments);\n setLocalStorageInput('');\n setIsMultiline(false);\n if (setAttachments) {\n setAttachments((_) => []);\n if (fileInputRef.current) {\n (fileInputRef.current as HTMLInputElement).value = '';\n }\n }\n if (width && width > 768) {\n textareaRef.current?.focus();\n }\n }, [handleSubmit, setLocalStorageInput, width, attachments, chatId, bot]);\n\n const uploadFile = useCallback(\n async (file: File) => {\n const formData = new FormData();\n formData.append('file', file, generateExtendedFileName(file.name));\n try {\n return await createAttachments({\n chatId,\n apiHost,\n body: formData,\n });\n } catch (error) {\n console.error('Failed to upload file, please try again!');\n }\n },\n [chatId]\n );\n\n const toAudioBase64 = (blob: Blob) => {\n return new Promise<IFileUpload>((resolve) => {\n let mimeType = getBestMimeType();\n const pos = blob.type.indexOf(';');\n if (pos === -1) {\n mimeType = blob.type;\n } else {\n mimeType = blob.type.substring(0, pos);\n }\n\n // read blob and add to previews\n const reader = new FileReader();\n reader.readAsDataURL(blob);\n reader.onloadend = () => {\n const base64data = reader.result as string;\n const upload: IFileUpload = {\n tempId: generateUUID(),\n data: base64data,\n type: 'audio',\n name: `audio_${Date.now()}.${getFileExtension(mimeType)}`,\n mime: mimeType,\n };\n resolve(upload);\n };\n });\n };\n\n const toBase64 = async (\n file: File,\n type = 'file'\n ): Promise<IFileUpload | undefined> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = () => {\n resolve({\n tempId: generateUUID(),\n data: reader.result as string,\n type,\n name: generateExtendedFileName(file.name),\n mime: file.type,\n });\n };\n reader.onerror = () => {\n reject();\n };\n });\n };\n\n const checkUploadFile = useCallback(\n async (file: File): Promise<IFileUpload | undefined> => {\n if (file.type.startsWith('image')) {\n return toBase64(file);\n } else {\n setUploadQueue([file.name]);\n const response: any = await uploadFile(file);\n if (response?.type == 'file:full') {\n const f = response.result[0];\n if (!f) {\n return;\n }\n return {\n tempId: generateUUID(),\n data: f.content,\n name: f.name,\n mime: f.mimeType,\n type: response?.type,\n };\n } else if (response?.type == 'file:rag') {\n const { addedDocs } = response.result;\n if (!addedDocs.length) {\n return;\n }\n return toBase64(file, response?.type);\n }\n }\n },\n [setUploadQueue, uploadFile]\n );\n\n const handleFileChange = useCallback(\n async (event: ChangeEvent<HTMLInputElement>) => {\n const files = Array.from(event.target.files || []);\n try {\n const uploadPromises = files.map((file) => checkUploadFile(file));\n const uploadedAttachments = await Promise.all(uploadPromises);\n const successfullyUploadedAttachments = uploadedAttachments.filter(\n (attachment) => attachment !== undefined\n ) as IFileUpload[];\n if (setAttachments) {\n setAttachments((currentAttachments: IFileUpload[]) => [\n ...currentAttachments,\n ...successfullyUploadedAttachments,\n ]);\n }\n } catch (error) {\n console.error('Error uploading files!', error);\n } finally {\n setUploadQueue([]);\n }\n },\n [setAttachments, checkUploadFile]\n );\n\n const speechToText = async (blob: Blob) => {\n try {\n setTranscribing(true);\n // setIsMultiline(true);\n const fileUpload = await toAudioBase64(blob);\n const base64Data = fileUpload.data!.replace(/^data:.+;base64,/, '');\n const byteCharacters = atob(base64Data); // Decode Base64 string\n const byteNumbers = new Array(byteCharacters.length);\n\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n const file = new File([byteArray], fileUpload.name, {\n lastModified: new Date().getTime(),\n type: fileUpload.type,\n });\n\n const text = await getAudioTranscript({ file, apiHost, language });\n if (text) {\n handleInput(undefined, text);\n }\n } catch (error) {\n console.error('Error getting audio transcript!', error);\n } finally {\n setTranscribing(false);\n }\n };\n\n const handleFinishRecording = () => {\n if (isRecording) {\n onRecordingStopped(speechToText);\n }\n if (listeners?.['ON_FINISHED_RECORDING']) {\n listeners['ON_FINISHED_RECORDING']();\n }\n };\n\n const handleStartRecording = () => {\n setIsMultiline(false);\n onRecordingStarted();\n handleSetInput('');\n if (listeners?.['ON_START_RECORDING']) {\n listeners['ON_START_RECORDING']();\n }\n };\n\n const handleCancelRecording = () => {\n onRecordingCancelled();\n handleSetInput('');\n if (listeners?.['ON_CANCEL_RECORDING']) {\n listeners['ON_CANCEL_RECORDING']();\n }\n };\n\n const handleSend = useCallback(async () => {\n if (!isRecording) {\n submitForm();\n }\n }, [submitForm, isRecording]);\n\n const handleWidthChange = useCallback(\n (maxBars: number) => {\n updateMaxHistoryLength(maxBars);\n },\n [updateMaxHistoryLength]\n );\n\n const placeholder =\n !isRecording && !transcribing\n ? theme?.input?.placeholder || 'Send a message...'\n : theme?.input?.transcribingPlaceholder || 'Transcribing...';\n\n const recordingPlaceholder =\n isRecording && !transcribing\n ? theme?.input?.recordingPlaceholder || 'Recording...'\n : '';\n\n return (\n <div className=\"relative w-full flex gap-4 flex-col\">\n {!!suggestedActions?.length && (\n <SuggestedActions\n suggestedActions={suggestedActions}\n append={append}\n layoutMode={suggestedActionLayoutMode}\n suggestedActionRows={suggestedActionRows}\n />\n )}\n {((attachments && attachments.length > 0) || uploadQueue.length > 0) && (\n <div className=\"list-attachments flex flex-row gap-2 overflow-x-scroll items-end\">\n {attachments?.map((attachment) => (\n <PreviewFileAttachment\n key={attachment.tempId}\n attachment={attachment}\n onRemoveAttachment={() => {\n setAttachments?.((currentAttachments: IFileUpload[]) =>\n currentAttachments.filter(\n (f) => f.tempId !== attachment.tempId\n )\n );\n }}\n />\n ))}\n {uploadQueue.map((filename) => (\n <PreviewFileAttachment\n key={filename}\n onRemoveAttachment={() => {\n setUploadQueue(uploadQueue.filter((f) => f !== filename));\n }}\n attachment={{\n data: '',\n name: filename,\n mime: '',\n type: '',\n }}\n isUploading\n />\n ))}\n </div>\n )}\n <div className=\" w-full flex gap-4 justify-end items-end\">\n {isRecording ? (\n <Button\n className={` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white px-0`}\n onClick={(event) => {\n event.preventDefault();\n handleFinishRecording();\n }}\n >\n <div className=\"w-[12px] h-[12px] bg-muted-foreground rounded-full\"></div>\n </Button>\n ) : (\n <DropdownMenu open={dropdownOpen} onOpenChange={setDropdownOpen}>\n <DropdownMenuTrigger asChild>\n <Button\n className={` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white`}\n onClick={(event) => {\n event.preventDefault();\n }}\n >\n <PlusIcon size={20} color={'#71717A'} />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n side=\"top\"\n align=\"start\"\n className=\"w-48 rounded-2xl border py-[6px] border-[#0d0d0d0d] shadow-sm\"\n >\n <DropdownMenuItem\n onClick={() => {\n // Trigger file input\n fileInputRef.current?.click();\n setDropdownOpen(false);\n }}\n className=\"flex items-center gap-2 px-4\"\n >\n <Paperclip size={16} />\n <span className=\"text-[14px]\">Upload File</span>\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => {\n setEnableTTS(!enableTTS);\n }}\n className={`flex items-center gap-2 px-4 ${enableTTS ? 'bg-[#CBE1F3] text-[#0A82F7]' : ''}`}\n >\n <Volume2 />\n <span className=\"text-[14px]\">\n {theme?.buttons?.textBtnSpeak || 'Speak'}\n </span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <div className=\"block flex-1 min-w-0 relative\">\n {/* Animated Input/Textarea Container */}\n <AnimatePresence mode=\"wait\">\n {!isRecording && (\n <>\n <motion.input\n key=\"input\"\n type=\"text\"\n id=\"input-multimodal-container\"\n readOnly={readonly}\n ref={inputRef}\n placeholder={placeholder}\n value={input}\n onChange={handleInput}\n className={cn(\n `h-[40px] outline-none text-base bg-muted bg-[#ffffff] scrollbar-hidden p-[12px] pr-[68px] rounded-[24px] backdrop-blur-[50px] w-full ${readonly ? 'hidden' : ''}`,\n className\n )}\n autoFocus\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 40 }}\n exit={{ opacity: 0, height: 0 }}\n transition={{\n duration: 0.2,\n ease: 'easeInOut',\n }}\n style={{\n display: isMultiline || transcribing ? 'none' : 'block',\n }}\n onKeyDown={(event) => {\n if (isRecording) {\n return;\n }\n\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n if (isLoading) {\n console.error(\n 'Please wait for the model to finish its response!'\n );\n } else if (uploadQueue.length) {\n console.error('Please wait for file is uploading!');\n } else if (input.length > 0) {\n handleSend();\n }\n }\n }}\n />\n <motion.div\n key=\"textarea\"\n initial={{ opacity: 0, height: 40 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 40 }}\n transition={{\n duration: 0.2,\n ease: 'easeInOut',\n }}\n style={{\n display: isMultiline || transcribing ? 'block' : 'none',\n }}\n >\n <Textarea\n readOnly={readonly}\n ref={textareaRef}\n placeholder={placeholder}\n value={input}\n onChange={handleInput}\n className={cn(\n `min-h-[24px] max-h-[160px] resize-none text-base bg-muted bg-[#ffffff] scrollbar-hidden p-[12px] pb-[32px] rounded-[24px] border border-[#E5E5E5] shadow-[0px_2px_6px_0px_rgba(0,0,0,0.08)] backdrop-blur-[50px] ${suggestedActionRows === expandedRows && 'p-[12px]'} `,\n className\n )}\n style={{\n height:\n suggestedActionRows === expandedRows ? 60 : undefined,\n }}\n autoFocus\n onKeyDown={(event) => {\n if (isRecording) {\n return;\n }\n\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n if (isLoading) {\n console.error(\n 'Please wait for the model to finish its response!'\n );\n } else if (uploadQueue.length) {\n console.error('Please wait for file is uploading!');\n } else if (input.length > 0) {\n handleSend();\n }\n }\n }}\n />\n </motion.div>\n </>\n )}\n </AnimatePresence>\n {/* Voice Recording UI Overlay */}\n <div className=\"w-full \">\n <VoiceRecordingUI\n isRecording={isRecording}\n elapsedTime={elapsedTime}\n onCancel={handleCancelRecording}\n transcribing={transcribing}\n audioData={audioData}\n label={recordingPlaceholder}\n onWidthChange={handleWidthChange}\n />\n </div>\n\n <div className=\"button-voice right-[4px] absolute bottom-[4px] flex gap-[12px]\">\n {!isRecording && (\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 bg-transparent\"\n onClick={(event) => {\n event.preventDefault();\n handleStartRecording();\n }}\n disabled={isLoading}\n >\n <ClikMicrophoneIcon size={20} />\n </Button>\n )}\n\n {isLoading ? (\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 border bg-[#71717A]\"\n onClick={(event) => {\n event.preventDefault();\n stop();\n setMessages(messages);\n }}\n >\n <StopIcon size={20} />\n </Button>\n ) : (\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 border bg-[#71717A]\"\n onClick={(event) => {\n event.preventDefault();\n handleSend();\n }}\n disabled={\n isRecording || input.length === 0 || !!uploadQueue.length\n }\n >\n <ArrowUpIcon size={20} />\n </Button>\n )}\n </div>\n </div>\n {/* Hidden file input */}\n <input\n type=\"file\"\n ref={fileInputRef}\n onChange={handleFileChange}\n multiple\n accept=\"image/*,video/*,audio/*,.pdf,.doc,.docx,.txt\"\n style={{ display: 'none' }}\n />\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FC } from 'react';
|
|
2
2
|
interface PropTypes {
|
|
3
3
|
productCodes?: string[];
|
|
4
4
|
tourCode?: string;
|
|
5
5
|
languageCode?: string;
|
|
6
6
|
apiUrl?: string;
|
|
7
7
|
}
|
|
8
|
-
declare const
|
|
9
|
-
export default
|
|
8
|
+
declare const ProductList: FC<PropTypes>;
|
|
9
|
+
export default ProductList;
|
|
10
10
|
//# sourceMappingURL=ProductList.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductList.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ProductList.tsx"],"names":[],"mappings":"AACA,
|
|
1
|
+
{"version":3,"file":"ProductList.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ProductList.tsx"],"names":[],"mappings":"AACA,OAAc,EAAE,EAAE,EAA8C,MAAM,OAAO,CAAC;AAkB9E,UAAU,SAAS;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,QAAA,MAAM,WAAW,EAAE,EAAE,CAAC,SAAS,CA8P9B,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import { useEffect, useState, useMemo } from 'react';
|
|
3
3
|
import { useChatData } from '../../hooks/useChatData';
|
|
4
4
|
import { getProducts } from '../../services/vt360.service';
|
|
5
5
|
import { BookmarkIcon } from './Icons';
|
|
@@ -148,5 +148,5 @@ const ProductList = ({ productCodes, tourCode, languageCode = 'VN', apiUrl, }) =
|
|
|
148
148
|
}, [data, handleActionClick, handleOnClick, FORMATTER]);
|
|
149
149
|
return (_jsxs(_Fragment, { children: [loading && loadingComponent, productListComponent] }));
|
|
150
150
|
};
|
|
151
|
-
export default
|
|
151
|
+
export default ProductList;
|
|
152
152
|
//# sourceMappingURL=ProductList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductList.js","sourceRoot":"","sources":["../../../src/components/Chat/ProductList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Marked, Renderer } from '@ts-stack/markdown';\nimport React, { FC, useEffect, useRef, useState, useMemo } from 'react';\nimport { useChatData } from '../../hooks/useChatData';\nimport { getProducts } from '../../services/vt360.service';\nimport { BookmarkIcon } from './Icons';\nimport { convertCurrencyVnd, formatPriceProduct } from 'utils/currency';\nimport { ProductType } from 'types/product.type';\nimport LoadingComponent from './LoadingComponent';\n\nconst FORMATTER = new Intl.NumberFormat('vi-VN', {\n style: 'currency',\n currency: 'VND',\n});\n\ninterface ProductDataResultType {\n products: ProductType[];\n scenarioUrl: string;\n}\n\ninterface PropTypes {\n productCodes?: string[];\n tourCode?: string;\n languageCode?: string;\n apiUrl?: string;\n}\n\nconst ProductList: FC<PropTypes> = ({\n productCodes,\n tourCode,\n languageCode = 'VN',\n apiUrl,\n}) => {\n const [data, setData] = useState<ProductDataResultType | null>(null);\n const [loading, setLoading] = useState<boolean>(false);\n const { listeners } = useChatData();\n\n useEffect(() => {\n const fetchProductsData = async () => {\n if (!productCodes || !productCodes.length || !tourCode) {\n return;\n }\n\n setLoading(true);\n\n try {\n const productsData = await getProducts(\n productCodes,\n tourCode,\n languageCode,\n apiUrl ? { api: apiUrl } : undefined\n );\n setData(productsData);\n } catch (err) {\n console.error('Error fetching products:', err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchProductsData();\n }, [productCodes, tourCode, languageCode, apiUrl]);\n\n const handleOnClick = (url: string) => {\n if (listeners?.['ON_LINK_CLICK']) {\n listeners['ON_LINK_CLICK'](url);\n } else {\n window?.open(url, '_blank');\n }\n };\n\n const handleActionClick = (action: string, productCode: string) => {\n if (!listeners?.['CMD_CALLBACK']) {\n return;\n }\n // template command tool {\"tool\":\"show_product_image_gallery\",\"toolInput\":{\"product_code\":\"ITEM27GETN2D2M94\"},\"toolOutput\":\"[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"{\\\\n \\\\\\\"action\\\\\\\": \\\\\\\"show_product_image_gallery\\\\\\\",\\\\n \\\\\\\"product_code\\\\\\\": \\\\\\\"ITEM27GETN2D2M94\\\\\\\",\\\\n \\\\\\\"status\\\\\\\": \\\\\\\"opening\\\\\\\",\\\\n \\\\\\\"message\\\\\\\": \\\\\\\"Opening image gallery for product ITEM27GETN2D2M94\\\\\\\"\\\\n}\\\"}]\"}\n let cmdTool = null;\n switch (action) {\n case 'PRODUCT_INFO':\n cmdTool = {\n tool: 'show_product_info',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_info',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_GALLERY':\n cmdTool = {\n tool: 'show_product_image_gallery',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_image_gallery',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_360':\n cmdTool = {\n tool: 'show_product_360_image',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_360_image',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_AR':\n cmdTool = {\n tool: 'show_product_AR',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_AR',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n default:\n break;\n }\n if (cmdTool) {\n listeners['CMD_CALLBACK'](cmdTool);\n }\n };\n\n const loadingComponent = useMemo(() => <LoadingComponent />, []);\n\n const productListComponent = useMemo(() => {\n if (!data || (!data?.products?.length && !data?.scenarioUrl)) return null;\n return (\n <div className=\"py-4\">\n {/* item-card: 358px x 252px with 12px padding and 12px gap */}\n <div\n className=\"bg-white rounded-lg overflow-hidden w-full\"\n style={{\n padding: '12px',\n gap: '12px',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'flex-start',\n }}\n >\n {/* Message bubble: 334px x 228px with 12px gap */}\n <div\n className=\"flex flex-col w-full\"\n style={{\n gap: '12px',\n }}\n >\n {!!data?.products?.length &&\n data.products.map((product, index) => (\n <div\n key={product.code || index}\n className=\"flex flex-row items-start w-full\"\n style={{\n gap: '12px',\n minHeight: '82px',\n }}\n >\n {/* Image: 80px x 80px */}\n <div\n className=\"flex-shrink-0 w-[80px] h-[80px] rounded-[5px] bg-cover bg-center \"\n style={{\n backgroundImage: `url(${product.icon?.url})`,\n }}\n />\n\n {/* Content: 242px x 82px */}\n <div\n className=\"flex flex-col font-vietnam-pro flex-1 min-w-0\"\n style={{\n minHeight: '82px',\n }}\n >\n {/* Product Name */}\n <div className=\"flex flex-row items-center w-full h-5 gap-1\">\n <h3\n className=\"text-card-foreground truncate mb-[4px] font-medium text-[14px] leading-[14px] underline cursor-pointer hover:opacity-80 flex-1 min-w-0 \"\n onClick={(e) => {\n e.preventDefault();\n handleActionClick('PRODUCT_INFO', product.code);\n }}\n >\n {product.name}\n </h3>\n </div>\n\n {/* Price section */}\n <div className=\"flex flex-row gap-[4px] min-h-[28px] justify-between w-full\">\n <div className=\"min-w-0\">\n {/* Original Price (crossed out) */}\n {product.tourProductQuotations.length > 0 && (\n <span className=\"text-card-foreground text-[16px] leading-[24px] mr-[4px] font-semibold\">\n {`${formatPriceProduct(\n convertCurrencyVnd(\n product.tourProductQuotations[0]?.price.toString() ??\n ''\n ),\n product.currencyUnit ?? '',\n product.unit ?? ''\n )} `}\n </span>\n )}\n <span\n className={`${product.tourProductQuotations.length > 0 ? 'line-through text-muted-foreground text-[14px] leading-[14px] font-medium' : 'text-card-foreground text-[16px] leading-[24px] font-semibold'}`}\n >\n {`${formatPriceProduct(\n convertCurrencyVnd(product?.price.toString() ?? ''),\n product.currencyUnit ?? '',\n product.unit ?? ''\n )} `}\n </span>\n </div>\n {/* Bookmark Icon */}\n <div\n className=\"flex justify-center items-center\"\n style={{ width: '20px', height: '20px' }}\n >\n <BookmarkIcon size={20} color=\"#71717A\" />\n </div>\n </div>\n\n {/* Description */}\n <p\n className=\"font-normal text-[14px] leading-[20px] text-muted-foreground overflow-hidden w-full text-ellipsis\"\n style={{\n minHeight: '20px',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n wordBreak: 'break-word',\n }}\n >\n {product.description}\n </p>\n </div>\n </div>\n ))}\n\n {/* View all products button */}\n {!!data?.scenarioUrl && (\n <button\n className=\"flex h-[40px] px-[16px] py-[8px] gap-[10px] font-medium leading-[24px] flex-row justify-center items-center hover:opacity-80 transition-opacity bg-secondary border rounded-md text-sm text-card-foreground w-full\"\n onClick={(e) => {\n e.preventDefault();\n handleOnClick(data?.scenarioUrl);\n }}\n >\n View all products\n </button>\n )}\n </div>\n </div>\n </div>\n );\n }, [data, handleActionClick, handleOnClick, FORMATTER]);\n\n return (\n <>\n {loading && loadingComponent}\n {productListComponent}\n </>\n );\n};\n\nexport default React.memo(ProductList);\n"]}
|
|
1
|
+
{"version":3,"file":"ProductList.js","sourceRoot":"","sources":["../../../src/components/Chat/ProductList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Marked, Renderer } from '@ts-stack/markdown';\nimport React, { FC, useEffect, useRef, memo, useState, useMemo } from 'react';\nimport { useChatData } from '../../hooks/useChatData';\nimport { getProducts } from '../../services/vt360.service';\nimport { BookmarkIcon } from './Icons';\nimport { convertCurrencyVnd, formatPriceProduct } from 'utils/currency';\nimport { ProductType } from 'types/product.type';\nimport LoadingComponent from './LoadingComponent';\n\nconst FORMATTER = new Intl.NumberFormat('vi-VN', {\n style: 'currency',\n currency: 'VND',\n});\n\ninterface ProductDataResultType {\n products: ProductType[];\n scenarioUrl: string;\n}\n\ninterface PropTypes {\n productCodes?: string[];\n tourCode?: string;\n languageCode?: string;\n apiUrl?: string;\n}\n\nconst ProductList: FC<PropTypes> = ({\n productCodes,\n tourCode,\n languageCode = 'VN',\n apiUrl,\n}) => {\n const [data, setData] = useState<ProductDataResultType | null>(null);\n const [loading, setLoading] = useState<boolean>(false);\n const { listeners } = useChatData();\n\n useEffect(() => {\n const fetchProductsData = async () => {\n if (!productCodes || !productCodes.length || !tourCode) {\n return;\n }\n\n setLoading(true);\n\n try {\n const productsData = await getProducts(\n productCodes,\n tourCode,\n languageCode,\n apiUrl ? { api: apiUrl } : undefined\n );\n setData(productsData);\n } catch (err) {\n console.error('Error fetching products:', err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchProductsData();\n }, [productCodes, tourCode, languageCode, apiUrl]);\n\n const handleOnClick = (url: string) => {\n if (listeners?.['ON_LINK_CLICK']) {\n listeners['ON_LINK_CLICK'](url);\n } else {\n window?.open(url, '_blank');\n }\n };\n\n const handleActionClick = (action: string, productCode: string) => {\n if (!listeners?.['CMD_CALLBACK']) {\n return;\n }\n // template command tool {\"tool\":\"show_product_image_gallery\",\"toolInput\":{\"product_code\":\"ITEM27GETN2D2M94\"},\"toolOutput\":\"[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"{\\\\n \\\\\\\"action\\\\\\\": \\\\\\\"show_product_image_gallery\\\\\\\",\\\\n \\\\\\\"product_code\\\\\\\": \\\\\\\"ITEM27GETN2D2M94\\\\\\\",\\\\n \\\\\\\"status\\\\\\\": \\\\\\\"opening\\\\\\\",\\\\n \\\\\\\"message\\\\\\\": \\\\\\\"Opening image gallery for product ITEM27GETN2D2M94\\\\\\\"\\\\n}\\\"}]\"}\n let cmdTool = null;\n switch (action) {\n case 'PRODUCT_INFO':\n cmdTool = {\n tool: 'show_product_info',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_info',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_GALLERY':\n cmdTool = {\n tool: 'show_product_image_gallery',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_image_gallery',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_360':\n cmdTool = {\n tool: 'show_product_360_image',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_360_image',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_AR':\n cmdTool = {\n tool: 'show_product_AR',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_AR',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n default:\n break;\n }\n if (cmdTool) {\n listeners['CMD_CALLBACK'](cmdTool);\n }\n };\n\n const loadingComponent = useMemo(() => <LoadingComponent />, []);\n\n const productListComponent = useMemo(() => {\n if (!data || (!data?.products?.length && !data?.scenarioUrl)) return null;\n return (\n <div className=\"py-4\">\n {/* item-card: 358px x 252px with 12px padding and 12px gap */}\n <div\n className=\"bg-white rounded-lg overflow-hidden w-full\"\n style={{\n padding: '12px',\n gap: '12px',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'flex-start',\n }}\n >\n {/* Message bubble: 334px x 228px with 12px gap */}\n <div\n className=\"flex flex-col w-full\"\n style={{\n gap: '12px',\n }}\n >\n {!!data?.products?.length &&\n data.products.map((product, index) => (\n <div\n key={product.code || index}\n className=\"flex flex-row items-start w-full\"\n style={{\n gap: '12px',\n minHeight: '82px',\n }}\n >\n {/* Image: 80px x 80px */}\n <div\n className=\"flex-shrink-0 w-[80px] h-[80px] rounded-[5px] bg-cover bg-center \"\n style={{\n backgroundImage: `url(${product.icon?.url})`,\n }}\n />\n\n {/* Content: 242px x 82px */}\n <div\n className=\"flex flex-col font-vietnam-pro flex-1 min-w-0\"\n style={{\n minHeight: '82px',\n }}\n >\n {/* Product Name */}\n <div className=\"flex flex-row items-center w-full h-5 gap-1\">\n <h3\n className=\"text-card-foreground truncate mb-[4px] font-medium text-[14px] leading-[14px] underline cursor-pointer hover:opacity-80 flex-1 min-w-0 \"\n onClick={(e) => {\n e.preventDefault();\n handleActionClick('PRODUCT_INFO', product.code);\n }}\n >\n {product.name}\n </h3>\n </div>\n\n {/* Price section */}\n <div className=\"flex flex-row gap-[4px] min-h-[28px] justify-between w-full\">\n <div className=\"min-w-0\">\n {/* Original Price (crossed out) */}\n {product.tourProductQuotations.length > 0 && (\n <span className=\"text-card-foreground text-[16px] leading-[24px] mr-[4px] font-semibold\">\n {`${formatPriceProduct(\n convertCurrencyVnd(\n product.tourProductQuotations[0]?.price.toString() ??\n ''\n ),\n product.currencyUnit ?? '',\n product.unit ?? ''\n )} `}\n </span>\n )}\n <span\n className={`${product.tourProductQuotations.length > 0 ? 'line-through text-muted-foreground text-[14px] leading-[14px] font-medium' : 'text-card-foreground text-[16px] leading-[24px] font-semibold'}`}\n >\n {`${formatPriceProduct(\n convertCurrencyVnd(product?.price.toString() ?? ''),\n product.currencyUnit ?? '',\n product.unit ?? ''\n )} `}\n </span>\n </div>\n {/* Bookmark Icon */}\n <div\n className=\"flex justify-center items-center\"\n style={{ width: '20px', height: '20px' }}\n >\n <BookmarkIcon size={20} color=\"#71717A\" />\n </div>\n </div>\n\n {/* Description */}\n <p\n className=\"font-normal text-[14px] leading-[20px] text-muted-foreground overflow-hidden w-full text-ellipsis\"\n style={{\n minHeight: '20px',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n wordBreak: 'break-word',\n }}\n >\n {product.description}\n </p>\n </div>\n </div>\n ))}\n\n {/* View all products button */}\n {!!data?.scenarioUrl && (\n <button\n className=\"flex h-[40px] px-[16px] py-[8px] gap-[10px] font-medium leading-[24px] flex-row justify-center items-center hover:opacity-80 transition-opacity bg-secondary border rounded-md text-sm text-card-foreground w-full\"\n onClick={(e) => {\n e.preventDefault();\n handleOnClick(data?.scenarioUrl);\n }}\n >\n View all products\n </button>\n )}\n </div>\n </div>\n </div>\n );\n }, [data, handleActionClick, handleOnClick, FORMATTER]);\n\n return (\n <>\n {loading && loadingComponent}\n {productListComponent}\n </>\n );\n};\n\nexport default ProductList;\n"]}
|
|
@@ -141,7 +141,7 @@ const UserContactForm = () => {
|
|
|
141
141
|
contact: val,
|
|
142
142
|
}));
|
|
143
143
|
};
|
|
144
|
-
return (_jsx(motion.div, { className: "w-full mx-auto max-w-[358px] px-4 group/message", initial: { y: 5, opacity: 0 }, animate: { y: 0, opacity: 1 }, children: _jsxs("form", { className: "flex flex-col gap-3 bg-white px-3 py-3 pb-4 rounded-lg w-full", onSubmit: handleSubmit, children: [_jsx("div", { className: "text-[#18181B] font-semibold text-base", children: theme?.userContactForm?.title || 'Your contact' }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "w-1/4 text-[#18181B] font-medium text-[14px] leading-[14px]", htmlFor: "inline-full-name", children: theme?.userContactForm?.labelName || 'Name' }), _jsxs("div", { className: "flex flex-col gap-3 w-full", children: [_jsx("input", { className: `rounded-lg border-solid border h-[40px] pt-2 pr-2 pb-2 pl-3 disabled:text-gray-500 disabled:cursor-not-allowed disabled:bg-gray-100 ${errors?.name ? 'border-red-500' : 'border-[#E2E8F0]'}`, id: "name", name: "name", type: "text", placeholder: theme?.userContactForm?.labelName || 'Name', onChange: handleChange, value: formData?.name || '', disabled: disabled }), !!errors?.name && (_jsx("span", { className: "text-red-500 text-sm mt-1", children: errors.name }))] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "w-1/4 text-[#18181B] font-medium text-[14px] leading-[14px]", htmlFor: "inline-contact", children: theme?.userContactForm?.labelContact || 'Contact' }), _jsxs("div", { className: "flex flex-col gap-3 w-full", children: [_jsx(PhoneNumberInput, { onChange: handleChangeContact, placeholder: theme?.userContactForm?.labelContact || 'Contact', value: formData?.contact, disabled: disabled }), !!errors?.contact && (_jsx("p", { className: "text-red-500 text-sm mt-1", children: errors.contact }))] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "w-1/4 text-[#18181B] font-medium text-[14px] leading-[14px]", htmlFor: "inline-email", children: theme?.userContactForm?.labelEmail || 'Email' }), _jsxs("div", { className: "flex flex-col gap-3 w-full", children: [_jsx("input", { className: `rounded-lg border-solid border h-[40px] pt-2 pr-2 pb-2 pl-3 disabled:text-gray-500 disabled:cursor-not-allowed disabled:bg-gray-100 ${errors?.host ? 'border-red-500' : 'border-[#E2E8F0]'}`, id: "email", name: "email", placeholder: theme?.userContactForm?.labelContact || 'Email', onChange: handleChange, value: formData?.email || '', type: "email", disabled: disabled }), !!errors?.host && (_jsx("p", { className: "text-red-500 text-sm mt-1", children: errors.host }))] })] })] }), statusSubmit && (_jsx("div", { className: "flex items-center w-full justify-center", children: _jsx("p", { className: `text-green-500 text-sm mt-1 ${statusSubmit?.status === 200 ? 'text-green-500' : 'text-red-500'}`, children: statusSubmit.message }) })), _jsx("div", { className: "flex items-center", children: _jsx("div", { className: "w-full", children: _jsx("button", { className: `shadow bg-[#1E6EB4] hover:bg-[#4096ff] focus:shadow-outline focus:outline-none text-white font-bold py-2 px-8 rounded-lg w-full h-[40px] disabled:
|
|
144
|
+
return (_jsx(motion.div, { className: "w-full mx-auto max-w-[358px] px-4 group/message", initial: { y: 5, opacity: 0 }, animate: { y: 0, opacity: 1 }, children: _jsxs("form", { className: "flex flex-col gap-3 bg-white px-3 py-3 pb-4 rounded-lg w-full", onSubmit: handleSubmit, children: [_jsx("div", { className: "text-[#18181B] font-semibold text-base", children: theme?.userContactForm?.title || 'Your contact' }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "w-1/4 text-[#18181B] font-medium text-[14px] leading-[14px]", htmlFor: "inline-full-name", children: theme?.userContactForm?.labelName || 'Name' }), _jsxs("div", { className: "flex flex-col gap-3 w-full", children: [_jsx("input", { className: `rounded-lg border-solid border h-[40px] pt-2 pr-2 pb-2 pl-3 disabled:text-gray-500 disabled:cursor-not-allowed disabled:bg-gray-100 ${errors?.name ? 'border-red-500' : 'border-[#E2E8F0]'}`, id: "name", name: "name", type: "text", placeholder: theme?.userContactForm?.labelName || 'Name', onChange: handleChange, value: formData?.name || '', disabled: disabled }), !!errors?.name && (_jsx("span", { className: "text-red-500 text-sm mt-1", children: errors.name }))] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "w-1/4 text-[#18181B] font-medium text-[14px] leading-[14px]", htmlFor: "inline-contact", children: theme?.userContactForm?.labelContact || 'Contact' }), _jsxs("div", { className: "flex flex-col gap-3 w-full", children: [_jsx(PhoneNumberInput, { onChange: handleChangeContact, placeholder: theme?.userContactForm?.labelContact || 'Contact', value: formData?.contact, disabled: disabled }), !!errors?.contact && (_jsx("p", { className: "text-red-500 text-sm mt-1", children: errors.contact }))] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "w-1/4 text-[#18181B] font-medium text-[14px] leading-[14px]", htmlFor: "inline-email", children: theme?.userContactForm?.labelEmail || 'Email' }), _jsxs("div", { className: "flex flex-col gap-3 w-full", children: [_jsx("input", { className: `rounded-lg border-solid border h-[40px] pt-2 pr-2 pb-2 pl-3 disabled:text-gray-500 disabled:cursor-not-allowed disabled:bg-gray-100 ${errors?.host ? 'border-red-500' : 'border-[#E2E8F0]'}`, id: "email", name: "email", placeholder: theme?.userContactForm?.labelContact || 'Email', onChange: handleChange, value: formData?.email || '', type: "email", disabled: disabled }), !!errors?.host && (_jsx("p", { className: "text-red-500 text-sm mt-1", children: errors.host }))] })] })] }), statusSubmit && (_jsx("div", { className: "flex items-center w-full justify-center", children: _jsx("p", { className: `text-green-500 text-sm mt-1 ${statusSubmit?.status === 200 ? 'text-green-500' : 'text-red-500'}`, children: statusSubmit.message }) })), _jsx("div", { className: "flex items-center", children: _jsx("div", { className: "w-full", children: _jsx("button", { className: `shadow bg-[#1E6EB4] hover:bg-[#4096ff] focus:shadow-outline focus:outline-none text-white font-bold py-2 px-8 rounded-lg w-full h-[40px] disabled:cursor-not-allowed disabled:!bg-[#0000000a] disabled:!text-[#00000040] ${loading ? 'flex items-center justify-center' : ''}`, type: "submit", disabled: disabled, children: loading ? (_jsx(Spinner, {})) : (`${theme?.buttons?.textBtnSubmit || 'Submit'}`) }) }) }), _jsxs("div", { className: "flex flex-col gap-3 items-center", children: [_jsx("div", { className: "font-medium text-[14px] leading-[14px] text-[#18181B]", children: theme?.userContactForm?.orConnect || 'Or connect with' }), _jsxs("div", { className: "flex gap-4", children: [_jsx(ZaloIcon, {}), _jsx(FacebookMessageIcon, {})] })] })] }) }));
|
|
145
145
|
};
|
|
146
146
|
export default UserContactForm;
|
|
147
147
|
//# sourceMappingURL=UserContactForm.js.map
|