@om_patel_26/chat-widget 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ChatWidget.vue.cjs.js +1 -1
- package/dist/components/ChatWidget.vue.cjs2.js +1 -1
- package/dist/components/ChatWidget.vue.cjs2.js.map +1 -1
- package/dist/components/ChatWidget.vue.esm.js +1 -1
- package/dist/components/ChatWidget.vue.esm2.js +63 -56
- package/dist/components/ChatWidget.vue.esm2.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./ChatWidget.vue.cjs2.js");;/* empty css */const t=require("../_virtual/_plugin-vue_export-helper.cjs.js").default(e.default,[["__scopeId","data-v-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./ChatWidget.vue.cjs2.js");;/* empty css */const t=require("../_virtual/_plugin-vue_export-helper.cjs.js").default(e.default,[["__scopeId","data-v-0ea40880"]]);exports.default=t;
|
|
2
2
|
//# sourceMappingURL=ChatWidget.vue.cjs.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),t=require("../composables/useChatWidget.cjs.js"),o=require("../utils/sanitize.cjs.js"),a={class:"blockspark-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),t=require("../composables/useChatWidget.cjs.js"),o=require("../utils/sanitize.cjs.js"),a={class:"blockspark-welcome-header"},l={class:"blockspark-welcome-title"},n={class:"blockspark-welcome-message"},c={class:"blockspark-welcome-cta"},s={key:2,class:"blockspark-chat-window"},r={class:"blockspark-chat-header"},i={class:"blockspark-chat-header-content"},p={class:"blockspark-chat-title"},k={class:"blockspark-chat-subtitle"},d={key:0,class:"blockspark-mode-indicator"},m={key:0,class:"blockspark-mode-badge"},u={key:1,class:"blockspark-agent-info"},g={class:"blockspark-agent-name"},b={key:2,class:"blockspark-mode-badge"},h={key:0,class:"blockspark-chat-empty"},y=["innerHTML"],E={key:0,class:"blockspark-chips-container"},f={key:0,class:"blockspark-chips-group"},B=["onClick"],v={key:0,class:"blockspark-chips-group"},V=["onClick"],N={class:"blockspark-message-time"},C={key:1,class:"blockspark-message blockspark-message-bot"},w={key:2,class:"blockspark-agent-typing-indicator"},M=["value","placeholder","disabled"],S=["disabled"],x=e.defineComponent({inheritAttrs:!1,__name:"ChatWidget",props:{dfProjectId:{},dfLocation:{},dfAgentId:{},serviceAccountKey:{},accessToken:{},languageCode:{},backendBaseUrl:{},backendWsUrl:{},title:{default:"💬 BlockSpark AI Assistant"},subtitle:{default:"We're here to help"},welcomeTitle:{default:"👋 Welcome to BlockSpark"},welcomeMessage:{default:"My name is BlockSpark AI Assistant and I'll guide you."},welcomeCta:{default:"💬 Click here to start chatting!"},showWelcomePopup:{type:Boolean,default:!0},welcomePopupDelay:{default:1500},fallbackWelcomeMessage:{default:"Hello! I'm BlockSpark AI Assistant. How can I help you today?"},inputPlaceholder:{default:"Type your message..."},emptyStateMessage:{default:"Hi! I'm BlockSpark AI Assistant. How can I help you today?"},debug:{type:Boolean,default:!1}},setup(x){const A=x,{state:I,isOpen:L,messages:D,isLoading:W,error:P,chatMode:T,wsConnected:j,agentTyping:F,currentAgent:H,openChat:O,closeChat:_,sendMessage:z,toggleChat:$,setInputValue:q,clearError:U,manager:K}=t.useChatWidget(A),R=e.ref(null),G=e.ref(null),J=e.computed(()=>A);e.watch(()=>D.value.length,()=>{e.nextTick(()=>{R.value?.scrollIntoView({behavior:"smooth"})})});const Q=async()=>{I.value.isOpen||(I.value.isOpen=!0,I.value.showWelcomePopup=!1),await O()},X=()=>{_()},Y=()=>{K.closeWelcomePopup()},Z=e=>{const t=e.target;q(t.value)},ee=async e=>{e.preventDefault(),I.value.inputValue.trim()&&await z(I.value.inputValue)},te=async(e,t)=>{const o=e||t||"";await z(o)},oe=e=>e.includes("👤")||e.includes("being connected")||e.includes("live support agent")||e.includes("transfer your conversation");return e.onMounted(()=>{J.value.showWelcomePopup&&"undefined"!=typeof window&&K.initializeWelcomePopup()}),(t,x)=>(e.openBlock(),e.createElementBlock("div",e.mergeProps({class:"blockspark-chat-widget"},t.$attrs),[e.unref(I).showWelcomePopup&&!e.unref(I).isOpen?(e.openBlock(),e.createElementBlock("div",{key:0,class:"blockspark-welcome-popup",onClick:Q},[e.createElementVNode("div",a,[e.createElementVNode("div",l,e.toDisplayString(J.value.welcomeTitle),1),e.createElementVNode("button",{class:"blockspark-close-popup",onClick:e.withModifiers(Y,["stop"]),"aria-label":"Close welcome popup"}," × ")]),e.createElementVNode("div",n,e.toDisplayString(J.value.welcomeMessage),1),e.createElementVNode("div",c,e.toDisplayString(J.value.welcomeCta),1)])):e.createCommentVNode("",!0),e.unref(I).isOpen?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:1,class:"blockspark-chat-toggle-btn",onClick:Q,"aria-label":"Open chat"},[...x[0]||(x[0]=[e.createElementVNode("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[e.createElementVNode("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})],-1)])])),e.unref(I).isOpen?(e.openBlock(),e.createElementBlock("div",s,[e.createElementVNode("div",r,[e.createElementVNode("div",i,[e.createElementVNode("div",p,e.toDisplayString(J.value.title),1),e.createElementVNode("div",k,[e.createTextVNode(e.toDisplayString(J.value.subtitle)+" ",1),"human"===e.unref(I).chatMode?(e.openBlock(),e.createElementBlock("span",d," • "+e.toDisplayString(e.unref(j)?"🟢 Connected":"🟡 Connecting..."),1)):e.createCommentVNode("",!0)]),"human"===e.unref(I).chatMode?(e.openBlock(),e.createElementBlock("div",m," Human Support Mode ")):e.createCommentVNode("",!0),"human"===e.unref(I).chatMode?(e.openBlock(),e.createElementBlock("div",u,[x[1]||(x[1]=e.createElementVNode("span",{class:"blockspark-agent-label"},"Agent:",-1)),e.createElementVNode("span",g,e.toDisplayString(e.unref(H).name),1)])):e.createCommentVNode("",!0),"ai"===e.unref(I).chatMode?(e.openBlock(),e.createElementBlock("div",b," Bot Mode ")):e.createCommentVNode("",!0)]),e.createElementVNode("button",{class:"blockspark-chat-close-btn",onClick:X,"aria-label":"Close chat"}," × ")]),e.createElementVNode("div",{class:"blockspark-chat-messages",ref_key:"messagesContainer",ref:G},[0===e.unref(I).messages.length?(e.openBlock(),e.createElementBlock("div",h,[x[2]||(x[2]=e.createElementVNode("div",{class:"blockspark-chat-empty-icon"},"👋",-1)),e.createElementVNode("p",null,e.toDisplayString(J.value.emptyStateMessage),1)])):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(I).messages,t=>{return e.openBlock(),e.createElementBlock("div",{key:t.id,class:e.normalizeClass(["blockspark-message",`blockspark-message-${t.sender}`,{"blockspark-handoff-message":oe(t.text)}])},[e.createElementVNode("div",{class:e.normalizeClass(["blockspark-message-content",{"blockspark-handoff-content":oe(t.text)}])},[e.createElementVNode("span",{innerHTML:e.unref(o.safeLinkifyText)(t.text).replace(/\n/g,"<br>")},null,8,y)],2),t.richContent&&Array.isArray(t.richContent)&&t.richContent.length>0?(e.openBlock(),e.createElementBlock("div",E,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.richContent,(t,o)=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:o},[Array.isArray(t)?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:1},e.renderList(t,(t,a)=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:`${o}-${a}`},["chips"===t.type&&t.options?(e.openBlock(),e.createElementBlock("div",v,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.options,(t,o)=>(e.openBlock(),e.createElementBlock("button",{key:o,class:"blockspark-chip-button",type:"button",onClick:e=>te(t.text,t.payload)},e.toDisplayString(t.text),9,V))),128))])):e.createCommentVNode("",!0)],64))),128)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},["chips"===t.type&&t.options?(e.openBlock(),e.createElementBlock("div",f,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.options,(t,o)=>(e.openBlock(),e.createElementBlock("button",{key:o,class:"blockspark-chip-button",type:"button",onClick:e=>te(t.text,t.payload)},e.toDisplayString(t.text),9,B))),128))])):e.createCommentVNode("",!0)],64))],64))),128))])):e.createCommentVNode("",!0),e.createElementVNode("div",N,e.toDisplayString((a=t.timestamp,a.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}))),1)],2);var a}),128)),e.unref(I).isLoading?(e.openBlock(),e.createElementBlock("div",C,[...x[3]||(x[3]=[e.createElementVNode("div",{class:"blockspark-typing-indicator"},[e.createElementVNode("span"),e.createElementVNode("span"),e.createElementVNode("span")],-1)])])):e.createCommentVNode("",!0),"human"===e.unref(I).chatMode&&e.unref(F)?(e.openBlock(),e.createElementBlock("div",w,[...x[4]||(x[4]=[e.createElementVNode("span",{class:"blockspark-typing-dots"},[e.createElementVNode("span"),e.createElementVNode("span"),e.createElementVNode("span")],-1),e.createElementVNode("span",{class:"blockspark-typing-text"},"Agent is typing...",-1)])])):e.createCommentVNode("",!0),e.createElementVNode("div",{ref_key:"messagesEndRef",ref:R},null,512)],512),e.createElementVNode("form",{class:"blockspark-chat-input-form",onSubmit:e.withModifiers(ee,["prevent"])},[e.createElementVNode("input",{type:"text",class:"blockspark-chat-input",value:e.unref(I).inputValue,onInput:Z,placeholder:J.value.inputPlaceholder,disabled:e.unref(I).isLoading},null,40,M),e.createElementVNode("button",{type:"submit",class:"blockspark-chat-send-btn",disabled:!e.unref(I).inputValue.trim()||e.unref(I).isLoading},[...x[5]||(x[5]=[e.createElementVNode("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[e.createElementVNode("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),e.createElementVNode("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})],-1)])],8,S)],32)])):e.createCommentVNode("",!0)],16))}});exports.default=x;
|
|
2
2
|
//# sourceMappingURL=ChatWidget.vue.cjs2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatWidget.vue.cjs2.js","sources":["../../src/components/ChatWidget.vue"],"sourcesContent":["<template>\n <div class=\"blockspark-chat-widget\">\n <!-- Welcome Popup -->\n <div\n v-if=\"state.showWelcomePopup && !state.isOpen\"\n class=\"blockspark-welcome-popup\"\n @click=\"handleOpenChat\"\n >\n <div class=\"blockspark-welcome-header\">\n <div class=\"blockspark-welcome-title\">{{ config.welcomeTitle }}</div>\n <button\n class=\"blockspark-close-popup\"\n @click.stop=\"handleCloseWelcomePopup\"\n aria-label=\"Close welcome popup\"\n >\n ×\n </button>\n </div>\n <div class=\"blockspark-welcome-message\">{{ config.welcomeMessage }}</div>\n <div class=\"blockspark-welcome-cta\">{{ config.welcomeCta }}</div>\n </div>\n\n <!-- Chat Toggle Button -->\n <button\n v-if=\"!state.isOpen\"\n class=\"blockspark-chat-toggle-btn\"\n @click=\"handleOpenChat\"\n aria-label=\"Open chat\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n </button>\n\n <!-- Chat Window -->\n <div v-if=\"state.isOpen\" class=\"blockspark-chat-window\">\n <div class=\"blockspark-chat-header\">\n <div class=\"blockspark-chat-header-content\">\n <div class=\"blockspark-chat-title\">{{ config.title }}</div>\n <div class=\"blockspark-chat-subtitle\">\n {{ config.subtitle }}\n <span v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-indicator\">\n • {{ wsConnected ? '🟢 Connected' : '🟡 Connecting...' }}\n </span>\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-badge\">\n Human Support Mode\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-agent-info\">\n <span class=\"blockspark-agent-label\">Agent:</span>\n <span class=\"blockspark-agent-name\">{{ currentAgent.name }}</span>\n </div>\n <div v-if=\"state.chatMode === 'ai'\" class=\"blockspark-mode-badge\">\n Bot Mode\n </div>\n </div>\n <button\n class=\"blockspark-chat-close-btn\"\n @click=\"handleCloseChat\"\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div class=\"blockspark-chat-messages\" ref=\"messagesContainer\">\n <!-- Empty State -->\n <div v-if=\"state.messages.length === 0\" class=\"blockspark-chat-empty\">\n <div class=\"blockspark-chat-empty-icon\">👋</div>\n <p>{{ config.emptyStateMessage }}</p>\n </div>\n\n <!-- Messages -->\n <div\n v-for=\"message in state.messages\"\n :key=\"message.id\"\n :class=\"[\n 'blockspark-message', \n `blockspark-message-${message.sender}`,\n { 'blockspark-handoff-message': isHandoffMessage(message.text) }\n ]\"\n >\n <div \n class=\"blockspark-message-content\"\n :class=\"{ 'blockspark-handoff-content': isHandoffMessage(message.text) }\"\n >\n <!-- Safe HTML rendering with sanitization -->\n <!-- Preserve line breaks for better formatting -->\n <span v-html=\"safeLinkifyText(message.text).replace(/\\n/g, '<br>')\"></span>\n </div>\n\n <!-- Rich Content (Chips) -->\n <div\n v-if=\"message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0\"\n class=\"blockspark-chips-container\"\n >\n <template v-for=\"(contentGroup, groupIndex) in message.richContent\" :key=\"groupIndex\">\n <template v-if=\"!Array.isArray(contentGroup)\">\n <div\n v-if=\"contentGroup.type === 'chips' && contentGroup.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in contentGroup.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n <template v-else>\n <template\n v-for=\"(content, contentIndex) in contentGroup\"\n :key=\"`${groupIndex}-${contentIndex}`\"\n >\n <div\n v-if=\"content.type === 'chips' && content.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in content.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n\n <div class=\"blockspark-message-time\">\n {{ formatTime(message.timestamp) }}\n </div>\n </div>\n\n <!-- Loading Indicator -->\n <div v-if=\"state.isLoading\" class=\"blockspark-message blockspark-message-bot\">\n <div class=\"blockspark-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Agent Typing Indicator -->\n <div v-if=\"state.chatMode === 'human' && agentTyping\" class=\"blockspark-agent-typing-indicator\">\n <span class=\"blockspark-typing-dots\">\n <span></span>\n <span></span>\n <span></span>\n </span>\n <span class=\"blockspark-typing-text\">Agent is typing...</span>\n </div>\n\n <div ref=\"messagesEndRef\"></div>\n </div>\n\n <!-- Input Form -->\n <form class=\"blockspark-chat-input-form\" @submit.prevent=\"handleSubmit\">\n <input\n type=\"text\"\n class=\"blockspark-chat-input\"\n :value=\"state.inputValue\"\n @input=\"handleInput\"\n :placeholder=\"config.inputPlaceholder\"\n :disabled=\"state.isLoading\"\n />\n <button\n type=\"submit\"\n class=\"blockspark-chat-send-btn\"\n :disabled=\"!state.inputValue.trim() || state.isLoading\"\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </form>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, nextTick, watch } from 'vue';\nimport { useChatWidget } from '../composables/useChatWidget';\nimport { safeLinkifyText } from '../utils/sanitize';\nimport type { WidgetConfig } from '../core/types';\n\n// Props\nconst props = withDefaults(defineProps<WidgetConfig>(), {\n title: '💬 BlockSpark AI Assistant',\n subtitle: \"We're here to help\",\n welcomeTitle: '👋 Welcome to BlockSpark',\n welcomeMessage: \"My name is BlockSpark AI Assistant and I'll guide you.\",\n welcomeCta: '💬 Click here to start chatting!',\n showWelcomePopup: true,\n welcomePopupDelay: 1500,\n fallbackWelcomeMessage: \"Hello! I'm BlockSpark AI Assistant. How can I help you today?\",\n inputPlaceholder: 'Type your message...',\n emptyStateMessage: \"Hi! I'm BlockSpark AI Assistant. How can I help you today?\",\n debug: false,\n});\n\n// Use headless composable\nconst {\n state,\n isOpen,\n messages,\n isLoading,\n error,\n chatMode,\n wsConnected,\n agentTyping,\n currentAgent,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n} = useChatWidget(props);\n\n// Refs\nconst messagesEndRef = ref<HTMLDivElement | null>(null);\nconst messagesContainer = ref<HTMLDivElement | null>(null);\n\n// Computed config (for reactivity)\nconst config = computed(() => props);\n\n// Auto-scroll to bottom when messages change\nwatch(\n () => messages.value.length,\n () => {\n nextTick(() => {\n messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n);\n\n// Handlers\nconst handleOpenChat = async () => {\n await openChat();\n};\n\nconst handleCloseChat = () => {\n closeChat();\n};\n\nconst handleCloseWelcomePopup = () => {\n manager.closeWelcomePopup();\n};\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n setInputValue(target.value);\n};\n\nconst handleSubmit = async (event: Event) => {\n event.preventDefault();\n if (state.value.inputValue.trim()) {\n await sendMessage(state.value.inputValue);\n }\n};\n\nconst handleChipClick = async (chipText: string, payload?: string) => {\n const messageToSend = chipText || payload || '';\n await sendMessage(messageToSend);\n};\n\n// Utility functions\nconst formatTime = (date: Date): string => {\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\n// Check if message is a handoff message\nconst isHandoffMessage = (text: string): boolean => {\n return text.includes('👤') || \n text.includes('being connected') || \n text.includes('live support agent') ||\n text.includes('transfer your conversation');\n};\n\n// Initialize welcome popup on mount (SSR-safe)\nonMounted(() => {\n if (config.value.showWelcomePopup && typeof window !== 'undefined') {\n manager.initializeWelcomePopup();\n }\n});\n</script>\n\n<style scoped>\n/* Styles are imported separately by users */\n/* This ensures SSR compatibility */\n</style>\n"],"names":["props","__props","state","isOpen","messages","isLoading","error","chatMode","wsConnected","agentTyping","currentAgent","openChat","closeChat","sendMessage","toggleChat","setInputValue","clearError","manager","useChatWidget","messagesEndRef","ref","messagesContainer","config","computed","watch","value","length","nextTick","scrollIntoView","behavior","handleOpenChat","async","handleCloseChat","handleCloseWelcomePopup","closeWelcomePopup","handleInput","event","target","handleSubmit","preventDefault","inputValue","trim","handleChipClick","chipText","payload","messageToSend","isHandoffMessage","text","includes","onMounted","showWelcomePopup","window","initializeWelcomePopup","_openBlock","_createElementBlock","_hoisted_1","_unref","class","onClick","_createElementVNode","_hoisted_2","_hoisted_3","_toDisplayString","welcomeTitle","_hoisted_4","welcomeMessage","_hoisted_5","welcomeCta","width","height","viewBox","fill","stroke","d","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","title","_hoisted_10","subtitle","_hoisted_11","_hoisted_12","_hoisted_13","_cache","_hoisted_14","name","_hoisted_15","_hoisted_16","emptyStateMessage","_Fragment","_renderList","message","key","id","_normalizeClass","sender","innerHTML","safeLinkifyText","replace","richContent","Array","isArray","_hoisted_18","contentGroup","groupIndex","content","contentIndex","type","options","_hoisted_21","chip","chipIndex","$event","_hoisted_22","_hoisted_19","_hoisted_20","_hoisted_23","date","timestamp","toLocaleTimeString","hour","minute","_hoisted_24","_hoisted_25","onSubmit","onInput","placeholder","inputPlaceholder","disabled","x1","y1","x2","y2","points"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChatWidget.vue.cjs2.js","sources":["../../src/components/ChatWidget.vue"],"sourcesContent":["<template>\n <div class=\"blockspark-chat-widget\" v-bind=\"$attrs\">\n <!-- Welcome Popup -->\n <div\n v-if=\"state.showWelcomePopup && !state.isOpen\"\n class=\"blockspark-welcome-popup\"\n @click=\"handleOpenChat\"\n >\n <div class=\"blockspark-welcome-header\">\n <div class=\"blockspark-welcome-title\">{{ config.welcomeTitle }}</div>\n <button\n class=\"blockspark-close-popup\"\n @click.stop=\"handleCloseWelcomePopup\"\n aria-label=\"Close welcome popup\"\n >\n ×\n </button>\n </div>\n <div class=\"blockspark-welcome-message\">{{ config.welcomeMessage }}</div>\n <div class=\"blockspark-welcome-cta\">{{ config.welcomeCta }}</div>\n </div>\n\n <!-- Chat Toggle Button -->\n <button\n v-if=\"!state.isOpen\"\n class=\"blockspark-chat-toggle-btn\"\n @click=\"handleOpenChat\"\n aria-label=\"Open chat\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n </button>\n\n <!-- Chat Window -->\n <div v-if=\"state.isOpen\" class=\"blockspark-chat-window\">\n <div class=\"blockspark-chat-header\">\n <div class=\"blockspark-chat-header-content\">\n <div class=\"blockspark-chat-title\">{{ config.title }}</div>\n <div class=\"blockspark-chat-subtitle\">\n {{ config.subtitle }}\n <span v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-indicator\">\n • {{ wsConnected ? '🟢 Connected' : '🟡 Connecting...' }}\n </span>\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-badge\">\n Human Support Mode\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-agent-info\">\n <span class=\"blockspark-agent-label\">Agent:</span>\n <span class=\"blockspark-agent-name\">{{ currentAgent.name }}</span>\n </div>\n <div v-if=\"state.chatMode === 'ai'\" class=\"blockspark-mode-badge\">\n Bot Mode\n </div>\n </div>\n <button\n class=\"blockspark-chat-close-btn\"\n @click=\"handleCloseChat\"\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div class=\"blockspark-chat-messages\" ref=\"messagesContainer\">\n <!-- Empty State -->\n <div v-if=\"state.messages.length === 0\" class=\"blockspark-chat-empty\">\n <div class=\"blockspark-chat-empty-icon\">👋</div>\n <p>{{ config.emptyStateMessage }}</p>\n </div>\n\n <!-- Messages -->\n <div\n v-for=\"message in state.messages\"\n :key=\"message.id\"\n :class=\"[\n 'blockspark-message', \n `blockspark-message-${message.sender}`,\n { 'blockspark-handoff-message': isHandoffMessage(message.text) }\n ]\"\n >\n <div \n class=\"blockspark-message-content\"\n :class=\"{ 'blockspark-handoff-content': isHandoffMessage(message.text) }\"\n >\n <!-- Safe HTML rendering with sanitization -->\n <!-- Preserve line breaks for better formatting -->\n <span v-html=\"safeLinkifyText(message.text).replace(/\\n/g, '<br>')\"></span>\n </div>\n\n <!-- Rich Content (Chips) -->\n <div\n v-if=\"message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0\"\n class=\"blockspark-chips-container\"\n >\n <template v-for=\"(contentGroup, groupIndex) in message.richContent\" :key=\"groupIndex\">\n <template v-if=\"!Array.isArray(contentGroup)\">\n <div\n v-if=\"contentGroup.type === 'chips' && contentGroup.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in contentGroup.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n <template v-else>\n <template\n v-for=\"(content, contentIndex) in contentGroup\"\n :key=\"`${groupIndex}-${contentIndex}`\"\n >\n <div\n v-if=\"content.type === 'chips' && content.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in content.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n\n <div class=\"blockspark-message-time\">\n {{ formatTime(message.timestamp) }}\n </div>\n </div>\n\n <!-- Loading Indicator -->\n <div v-if=\"state.isLoading\" class=\"blockspark-message blockspark-message-bot\">\n <div class=\"blockspark-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Agent Typing Indicator -->\n <div v-if=\"state.chatMode === 'human' && agentTyping\" class=\"blockspark-agent-typing-indicator\">\n <span class=\"blockspark-typing-dots\">\n <span></span>\n <span></span>\n <span></span>\n </span>\n <span class=\"blockspark-typing-text\">Agent is typing...</span>\n </div>\n\n <div ref=\"messagesEndRef\"></div>\n </div>\n\n <!-- Input Form -->\n <form class=\"blockspark-chat-input-form\" @submit.prevent=\"handleSubmit\">\n <input\n type=\"text\"\n class=\"blockspark-chat-input\"\n :value=\"state.inputValue\"\n @input=\"handleInput\"\n :placeholder=\"config.inputPlaceholder\"\n :disabled=\"state.isLoading\"\n />\n <button\n type=\"submit\"\n class=\"blockspark-chat-send-btn\"\n :disabled=\"!state.inputValue.trim() || state.isLoading\"\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </form>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, nextTick, watch } from 'vue';\nimport { useChatWidget } from '../composables/useChatWidget';\nimport { safeLinkifyText } from '../utils/sanitize';\nimport type { WidgetConfig } from '../core/types';\n\n// Handle attributes properly to avoid Vue warnings\n// For Vue 3.3+, defineOptions is available as a compiler macro\n// @ts-ignore - defineOptions is a compiler macro\ndefineOptions({\n inheritAttrs: false, // We handle attrs manually via v-bind=\"$attrs\"\n});\n\n// Props\nconst props = withDefaults(defineProps<WidgetConfig>(), {\n title: '💬 BlockSpark AI Assistant',\n subtitle: \"We're here to help\",\n welcomeTitle: '👋 Welcome to BlockSpark',\n welcomeMessage: \"My name is BlockSpark AI Assistant and I'll guide you.\",\n welcomeCta: '💬 Click here to start chatting!',\n showWelcomePopup: true,\n welcomePopupDelay: 1500,\n fallbackWelcomeMessage: \"Hello! I'm BlockSpark AI Assistant. How can I help you today?\",\n inputPlaceholder: 'Type your message...',\n emptyStateMessage: \"Hi! I'm BlockSpark AI Assistant. How can I help you today?\",\n debug: false,\n});\n\n// Use headless composable\nconst {\n state,\n isOpen,\n messages,\n isLoading,\n error,\n chatMode,\n wsConnected,\n agentTyping,\n currentAgent,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n} = useChatWidget(props);\n\n// Refs\nconst messagesEndRef = ref<HTMLDivElement | null>(null);\nconst messagesContainer = ref<HTMLDivElement | null>(null);\n\n// Computed config (for reactivity)\nconst config = computed(() => props);\n\n// Auto-scroll to bottom when messages change\nwatch(\n () => messages.value.length,\n () => {\n nextTick(() => {\n messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n);\n\n// Handlers\nconst handleOpenChat = async () => {\n // Ensure immediate UI response\n if (!state.value.isOpen) {\n state.value.isOpen = true;\n state.value.showWelcomePopup = false;\n }\n await openChat();\n};\n\nconst handleCloseChat = () => {\n closeChat();\n};\n\nconst handleCloseWelcomePopup = () => {\n manager.closeWelcomePopup();\n};\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n setInputValue(target.value);\n};\n\nconst handleSubmit = async (event: Event) => {\n event.preventDefault();\n if (state.value.inputValue.trim()) {\n await sendMessage(state.value.inputValue);\n }\n};\n\nconst handleChipClick = async (chipText: string, payload?: string) => {\n const messageToSend = chipText || payload || '';\n await sendMessage(messageToSend);\n};\n\n// Utility functions\nconst formatTime = (date: Date): string => {\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\n// Check if message is a handoff message\nconst isHandoffMessage = (text: string): boolean => {\n return text.includes('👤') || \n text.includes('being connected') || \n text.includes('live support agent') ||\n text.includes('transfer your conversation');\n};\n\n// Initialize welcome popup on mount (SSR-safe)\nonMounted(() => {\n if (config.value.showWelcomePopup && typeof window !== 'undefined') {\n manager.initializeWelcomePopup();\n }\n});\n</script>\n\n<style scoped>\n/* Styles are imported separately by users */\n/* This ensures SSR compatibility */\n</style>\n"],"names":["props","__props","state","isOpen","messages","isLoading","error","chatMode","wsConnected","agentTyping","currentAgent","openChat","closeChat","sendMessage","toggleChat","setInputValue","clearError","manager","useChatWidget","messagesEndRef","ref","messagesContainer","config","computed","watch","value","length","nextTick","scrollIntoView","behavior","handleOpenChat","async","showWelcomePopup","handleCloseChat","handleCloseWelcomePopup","closeWelcomePopup","handleInput","event","target","handleSubmit","preventDefault","inputValue","trim","handleChipClick","chipText","payload","messageToSend","isHandoffMessage","text","includes","onMounted","window","initializeWelcomePopup","_openBlock","_createElementBlock","_mergeProps","class","$attrs","_unref","onClick","_createElementVNode","_hoisted_1","_hoisted_2","_toDisplayString","welcomeTitle","_hoisted_3","welcomeMessage","_hoisted_4","welcomeCta","width","height","viewBox","fill","stroke","d","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","title","_hoisted_9","subtitle","_hoisted_10","_hoisted_11","_hoisted_12","_cache","_hoisted_13","name","_hoisted_14","_hoisted_15","emptyStateMessage","_Fragment","_renderList","message","key","id","_normalizeClass","sender","innerHTML","safeLinkifyText","replace","richContent","Array","isArray","_hoisted_17","contentGroup","groupIndex","content","contentIndex","type","options","_hoisted_20","chip","chipIndex","$event","_hoisted_21","_hoisted_18","_hoisted_19","_hoisted_22","date","timestamp","toLocaleTimeString","hour","minute","_hoisted_23","_hoisted_24","onSubmit","onInput","placeholder","inputPlaceholder","disabled","x1","y1","x2","y2","points"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./ChatWidget.vue.esm2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../_virtual/_plugin-vue_export-helper.esm.js";
|
|
4
|
-
const ChatWidget = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const ChatWidget = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-0ea40880"]]);
|
|
5
5
|
export {
|
|
6
6
|
ChatWidget as default
|
|
7
7
|
};
|
|
@@ -1,67 +1,70 @@
|
|
|
1
|
-
import { defineComponent, ref, computed, watch, nextTick, onMounted, openBlock, createElementBlock, unref, createElementVNode, toDisplayString, withModifiers, createCommentVNode, createTextVNode, Fragment, renderList, normalizeClass } from "vue";
|
|
1
|
+
import { defineComponent, ref, computed, watch, nextTick, onMounted, openBlock, createElementBlock, mergeProps, unref, createElementVNode, toDisplayString, withModifiers, createCommentVNode, createTextVNode, Fragment, renderList, normalizeClass } from "vue";
|
|
2
2
|
import { useChatWidget } from "../composables/useChatWidget.esm.js";
|
|
3
3
|
import { safeLinkifyText } from "../utils/sanitize.esm.js";
|
|
4
|
-
const _hoisted_1 = { class: "blockspark-
|
|
5
|
-
const _hoisted_2 = { class: "blockspark-welcome-
|
|
6
|
-
const _hoisted_3 = { class: "blockspark-welcome-
|
|
7
|
-
const _hoisted_4 = { class: "blockspark-welcome-
|
|
8
|
-
const _hoisted_5 = {
|
|
9
|
-
const _hoisted_6 = {
|
|
4
|
+
const _hoisted_1 = { class: "blockspark-welcome-header" };
|
|
5
|
+
const _hoisted_2 = { class: "blockspark-welcome-title" };
|
|
6
|
+
const _hoisted_3 = { class: "blockspark-welcome-message" };
|
|
7
|
+
const _hoisted_4 = { class: "blockspark-welcome-cta" };
|
|
8
|
+
const _hoisted_5 = {
|
|
10
9
|
key: 2,
|
|
11
10
|
class: "blockspark-chat-window"
|
|
12
11
|
};
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
12
|
+
const _hoisted_6 = { class: "blockspark-chat-header" };
|
|
13
|
+
const _hoisted_7 = { class: "blockspark-chat-header-content" };
|
|
14
|
+
const _hoisted_8 = { class: "blockspark-chat-title" };
|
|
15
|
+
const _hoisted_9 = { class: "blockspark-chat-subtitle" };
|
|
16
|
+
const _hoisted_10 = {
|
|
18
17
|
key: 0,
|
|
19
18
|
class: "blockspark-mode-indicator"
|
|
20
19
|
};
|
|
21
|
-
const
|
|
20
|
+
const _hoisted_11 = {
|
|
22
21
|
key: 0,
|
|
23
22
|
class: "blockspark-mode-badge"
|
|
24
23
|
};
|
|
25
|
-
const
|
|
24
|
+
const _hoisted_12 = {
|
|
26
25
|
key: 1,
|
|
27
26
|
class: "blockspark-agent-info"
|
|
28
27
|
};
|
|
29
|
-
const
|
|
30
|
-
const
|
|
28
|
+
const _hoisted_13 = { class: "blockspark-agent-name" };
|
|
29
|
+
const _hoisted_14 = {
|
|
31
30
|
key: 2,
|
|
32
31
|
class: "blockspark-mode-badge"
|
|
33
32
|
};
|
|
34
|
-
const
|
|
33
|
+
const _hoisted_15 = {
|
|
35
34
|
key: 0,
|
|
36
35
|
class: "blockspark-chat-empty"
|
|
37
36
|
};
|
|
38
|
-
const
|
|
39
|
-
const
|
|
37
|
+
const _hoisted_16 = ["innerHTML"];
|
|
38
|
+
const _hoisted_17 = {
|
|
40
39
|
key: 0,
|
|
41
40
|
class: "blockspark-chips-container"
|
|
42
41
|
};
|
|
43
|
-
const
|
|
42
|
+
const _hoisted_18 = {
|
|
44
43
|
key: 0,
|
|
45
44
|
class: "blockspark-chips-group"
|
|
46
45
|
};
|
|
47
|
-
const
|
|
48
|
-
const
|
|
46
|
+
const _hoisted_19 = ["onClick"];
|
|
47
|
+
const _hoisted_20 = {
|
|
49
48
|
key: 0,
|
|
50
49
|
class: "blockspark-chips-group"
|
|
51
50
|
};
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
51
|
+
const _hoisted_21 = ["onClick"];
|
|
52
|
+
const _hoisted_22 = { class: "blockspark-message-time" };
|
|
53
|
+
const _hoisted_23 = {
|
|
55
54
|
key: 1,
|
|
56
55
|
class: "blockspark-message blockspark-message-bot"
|
|
57
56
|
};
|
|
58
|
-
const
|
|
57
|
+
const _hoisted_24 = {
|
|
59
58
|
key: 2,
|
|
60
59
|
class: "blockspark-agent-typing-indicator"
|
|
61
60
|
};
|
|
62
|
-
const
|
|
63
|
-
const
|
|
61
|
+
const _hoisted_25 = ["value", "placeholder", "disabled"];
|
|
62
|
+
const _hoisted_26 = ["disabled"];
|
|
64
63
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
64
|
+
...{
|
|
65
|
+
inheritAttrs: false
|
|
66
|
+
// We handle attrs manually via v-bind="$attrs"
|
|
67
|
+
},
|
|
65
68
|
__name: "ChatWidget",
|
|
66
69
|
props: {
|
|
67
70
|
dfProjectId: {},
|
|
@@ -116,6 +119,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
116
119
|
}
|
|
117
120
|
);
|
|
118
121
|
const handleOpenChat = async () => {
|
|
122
|
+
if (!state.value.isOpen) {
|
|
123
|
+
state.value.isOpen = true;
|
|
124
|
+
state.value.showWelcomePopup = false;
|
|
125
|
+
}
|
|
119
126
|
await openChat();
|
|
120
127
|
};
|
|
121
128
|
const handleCloseChat = () => {
|
|
@@ -153,22 +160,22 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
153
160
|
}
|
|
154
161
|
});
|
|
155
162
|
return (_ctx, _cache) => {
|
|
156
|
-
return openBlock(), createElementBlock("div",
|
|
163
|
+
return openBlock(), createElementBlock("div", mergeProps({ class: "blockspark-chat-widget" }, _ctx.$attrs), [
|
|
157
164
|
unref(state).showWelcomePopup && !unref(state).isOpen ? (openBlock(), createElementBlock("div", {
|
|
158
165
|
key: 0,
|
|
159
166
|
class: "blockspark-welcome-popup",
|
|
160
167
|
onClick: handleOpenChat
|
|
161
168
|
}, [
|
|
162
|
-
createElementVNode("div",
|
|
163
|
-
createElementVNode("div",
|
|
169
|
+
createElementVNode("div", _hoisted_1, [
|
|
170
|
+
createElementVNode("div", _hoisted_2, toDisplayString(config.value.welcomeTitle), 1),
|
|
164
171
|
createElementVNode("button", {
|
|
165
172
|
class: "blockspark-close-popup",
|
|
166
173
|
onClick: withModifiers(handleCloseWelcomePopup, ["stop"]),
|
|
167
174
|
"aria-label": "Close welcome popup"
|
|
168
175
|
}, " × ")
|
|
169
176
|
]),
|
|
170
|
-
createElementVNode("div",
|
|
171
|
-
createElementVNode("div",
|
|
177
|
+
createElementVNode("div", _hoisted_3, toDisplayString(config.value.welcomeMessage), 1),
|
|
178
|
+
createElementVNode("div", _hoisted_4, toDisplayString(config.value.welcomeCta), 1)
|
|
172
179
|
])) : createCommentVNode("", true),
|
|
173
180
|
!unref(state).isOpen ? (openBlock(), createElementBlock("button", {
|
|
174
181
|
key: 1,
|
|
@@ -189,20 +196,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
189
196
|
createElementVNode("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
|
|
190
197
|
], -1)
|
|
191
198
|
])])) : createCommentVNode("", true),
|
|
192
|
-
unref(state).isOpen ? (openBlock(), createElementBlock("div",
|
|
193
|
-
createElementVNode("div",
|
|
194
|
-
createElementVNode("div",
|
|
195
|
-
createElementVNode("div",
|
|
196
|
-
createElementVNode("div",
|
|
199
|
+
unref(state).isOpen ? (openBlock(), createElementBlock("div", _hoisted_5, [
|
|
200
|
+
createElementVNode("div", _hoisted_6, [
|
|
201
|
+
createElementVNode("div", _hoisted_7, [
|
|
202
|
+
createElementVNode("div", _hoisted_8, toDisplayString(config.value.title), 1),
|
|
203
|
+
createElementVNode("div", _hoisted_9, [
|
|
197
204
|
createTextVNode(toDisplayString(config.value.subtitle) + " ", 1),
|
|
198
|
-
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("span",
|
|
205
|
+
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("span", _hoisted_10, " • " + toDisplayString(unref(wsConnected) ? "🟢 Connected" : "🟡 Connecting..."), 1)) : createCommentVNode("", true)
|
|
199
206
|
]),
|
|
200
|
-
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("div",
|
|
201
|
-
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("div",
|
|
207
|
+
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("div", _hoisted_11, " Human Support Mode ")) : createCommentVNode("", true),
|
|
208
|
+
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("div", _hoisted_12, [
|
|
202
209
|
_cache[1] || (_cache[1] = createElementVNode("span", { class: "blockspark-agent-label" }, "Agent:", -1)),
|
|
203
|
-
createElementVNode("span",
|
|
210
|
+
createElementVNode("span", _hoisted_13, toDisplayString(unref(currentAgent).name), 1)
|
|
204
211
|
])) : createCommentVNode("", true),
|
|
205
|
-
unref(state).chatMode === "ai" ? (openBlock(), createElementBlock("div",
|
|
212
|
+
unref(state).chatMode === "ai" ? (openBlock(), createElementBlock("div", _hoisted_14, " Bot Mode ")) : createCommentVNode("", true)
|
|
206
213
|
]),
|
|
207
214
|
createElementVNode("button", {
|
|
208
215
|
class: "blockspark-chat-close-btn",
|
|
@@ -215,7 +222,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
215
222
|
ref_key: "messagesContainer",
|
|
216
223
|
ref: messagesContainer
|
|
217
224
|
}, [
|
|
218
|
-
unref(state).messages.length === 0 ? (openBlock(), createElementBlock("div",
|
|
225
|
+
unref(state).messages.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_15, [
|
|
219
226
|
_cache[2] || (_cache[2] = createElementVNode("div", { class: "blockspark-chat-empty-icon" }, "👋", -1)),
|
|
220
227
|
createElementVNode("p", null, toDisplayString(config.value.emptyStateMessage), 1)
|
|
221
228
|
])) : createCommentVNode("", true),
|
|
@@ -233,34 +240,34 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
233
240
|
}, [
|
|
234
241
|
createElementVNode("span", {
|
|
235
242
|
innerHTML: unref(safeLinkifyText)(message.text).replace(/\n/g, "<br>")
|
|
236
|
-
}, null, 8,
|
|
243
|
+
}, null, 8, _hoisted_16)
|
|
237
244
|
], 2),
|
|
238
|
-
message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0 ? (openBlock(), createElementBlock("div",
|
|
245
|
+
message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_17, [
|
|
239
246
|
(openBlock(true), createElementBlock(Fragment, null, renderList(message.richContent, (contentGroup, groupIndex) => {
|
|
240
247
|
return openBlock(), createElementBlock(Fragment, { key: groupIndex }, [
|
|
241
248
|
!Array.isArray(contentGroup) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
242
|
-
contentGroup.type === "chips" && contentGroup.options ? (openBlock(), createElementBlock("div",
|
|
249
|
+
contentGroup.type === "chips" && contentGroup.options ? (openBlock(), createElementBlock("div", _hoisted_18, [
|
|
243
250
|
(openBlock(true), createElementBlock(Fragment, null, renderList(contentGroup.options, (chip, chipIndex) => {
|
|
244
251
|
return openBlock(), createElementBlock("button", {
|
|
245
252
|
key: chipIndex,
|
|
246
253
|
class: "blockspark-chip-button",
|
|
247
254
|
type: "button",
|
|
248
255
|
onClick: ($event) => handleChipClick(chip.text, chip.payload)
|
|
249
|
-
}, toDisplayString(chip.text), 9,
|
|
256
|
+
}, toDisplayString(chip.text), 9, _hoisted_19);
|
|
250
257
|
}), 128))
|
|
251
258
|
])) : createCommentVNode("", true)
|
|
252
259
|
], 64)) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(contentGroup, (content, contentIndex) => {
|
|
253
260
|
return openBlock(), createElementBlock(Fragment, {
|
|
254
261
|
key: `${groupIndex}-${contentIndex}`
|
|
255
262
|
}, [
|
|
256
|
-
content.type === "chips" && content.options ? (openBlock(), createElementBlock("div",
|
|
263
|
+
content.type === "chips" && content.options ? (openBlock(), createElementBlock("div", _hoisted_20, [
|
|
257
264
|
(openBlock(true), createElementBlock(Fragment, null, renderList(content.options, (chip, chipIndex) => {
|
|
258
265
|
return openBlock(), createElementBlock("button", {
|
|
259
266
|
key: chipIndex,
|
|
260
267
|
class: "blockspark-chip-button",
|
|
261
268
|
type: "button",
|
|
262
269
|
onClick: ($event) => handleChipClick(chip.text, chip.payload)
|
|
263
|
-
}, toDisplayString(chip.text), 9,
|
|
270
|
+
}, toDisplayString(chip.text), 9, _hoisted_21);
|
|
264
271
|
}), 128))
|
|
265
272
|
])) : createCommentVNode("", true)
|
|
266
273
|
], 64);
|
|
@@ -268,17 +275,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
268
275
|
], 64);
|
|
269
276
|
}), 128))
|
|
270
277
|
])) : createCommentVNode("", true),
|
|
271
|
-
createElementVNode("div",
|
|
278
|
+
createElementVNode("div", _hoisted_22, toDisplayString(formatTime(message.timestamp)), 1)
|
|
272
279
|
], 2);
|
|
273
280
|
}), 128)),
|
|
274
|
-
unref(state).isLoading ? (openBlock(), createElementBlock("div",
|
|
281
|
+
unref(state).isLoading ? (openBlock(), createElementBlock("div", _hoisted_23, [..._cache[3] || (_cache[3] = [
|
|
275
282
|
createElementVNode("div", { class: "blockspark-typing-indicator" }, [
|
|
276
283
|
createElementVNode("span"),
|
|
277
284
|
createElementVNode("span"),
|
|
278
285
|
createElementVNode("span")
|
|
279
286
|
], -1)
|
|
280
287
|
])])) : createCommentVNode("", true),
|
|
281
|
-
unref(state).chatMode === "human" && unref(agentTyping) ? (openBlock(), createElementBlock("div",
|
|
288
|
+
unref(state).chatMode === "human" && unref(agentTyping) ? (openBlock(), createElementBlock("div", _hoisted_24, [..._cache[4] || (_cache[4] = [
|
|
282
289
|
createElementVNode("span", { class: "blockspark-typing-dots" }, [
|
|
283
290
|
createElementVNode("span"),
|
|
284
291
|
createElementVNode("span"),
|
|
@@ -302,7 +309,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
302
309
|
onInput: handleInput,
|
|
303
310
|
placeholder: config.value.inputPlaceholder,
|
|
304
311
|
disabled: unref(state).isLoading
|
|
305
|
-
}, null, 40,
|
|
312
|
+
}, null, 40, _hoisted_25),
|
|
306
313
|
createElementVNode("button", {
|
|
307
314
|
type: "submit",
|
|
308
315
|
class: "blockspark-chat-send-btn",
|
|
@@ -326,10 +333,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
326
333
|
}),
|
|
327
334
|
createElementVNode("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
|
|
328
335
|
], -1)
|
|
329
|
-
])], 8,
|
|
336
|
+
])], 8, _hoisted_26)
|
|
330
337
|
], 32)
|
|
331
338
|
])) : createCommentVNode("", true)
|
|
332
|
-
]);
|
|
339
|
+
], 16);
|
|
333
340
|
};
|
|
334
341
|
}
|
|
335
342
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatWidget.vue.esm2.js","sources":["../../src/components/ChatWidget.vue"],"sourcesContent":["<template>\n <div class=\"blockspark-chat-widget\">\n <!-- Welcome Popup -->\n <div\n v-if=\"state.showWelcomePopup && !state.isOpen\"\n class=\"blockspark-welcome-popup\"\n @click=\"handleOpenChat\"\n >\n <div class=\"blockspark-welcome-header\">\n <div class=\"blockspark-welcome-title\">{{ config.welcomeTitle }}</div>\n <button\n class=\"blockspark-close-popup\"\n @click.stop=\"handleCloseWelcomePopup\"\n aria-label=\"Close welcome popup\"\n >\n ×\n </button>\n </div>\n <div class=\"blockspark-welcome-message\">{{ config.welcomeMessage }}</div>\n <div class=\"blockspark-welcome-cta\">{{ config.welcomeCta }}</div>\n </div>\n\n <!-- Chat Toggle Button -->\n <button\n v-if=\"!state.isOpen\"\n class=\"blockspark-chat-toggle-btn\"\n @click=\"handleOpenChat\"\n aria-label=\"Open chat\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n </button>\n\n <!-- Chat Window -->\n <div v-if=\"state.isOpen\" class=\"blockspark-chat-window\">\n <div class=\"blockspark-chat-header\">\n <div class=\"blockspark-chat-header-content\">\n <div class=\"blockspark-chat-title\">{{ config.title }}</div>\n <div class=\"blockspark-chat-subtitle\">\n {{ config.subtitle }}\n <span v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-indicator\">\n • {{ wsConnected ? '🟢 Connected' : '🟡 Connecting...' }}\n </span>\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-badge\">\n Human Support Mode\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-agent-info\">\n <span class=\"blockspark-agent-label\">Agent:</span>\n <span class=\"blockspark-agent-name\">{{ currentAgent.name }}</span>\n </div>\n <div v-if=\"state.chatMode === 'ai'\" class=\"blockspark-mode-badge\">\n Bot Mode\n </div>\n </div>\n <button\n class=\"blockspark-chat-close-btn\"\n @click=\"handleCloseChat\"\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div class=\"blockspark-chat-messages\" ref=\"messagesContainer\">\n <!-- Empty State -->\n <div v-if=\"state.messages.length === 0\" class=\"blockspark-chat-empty\">\n <div class=\"blockspark-chat-empty-icon\">👋</div>\n <p>{{ config.emptyStateMessage }}</p>\n </div>\n\n <!-- Messages -->\n <div\n v-for=\"message in state.messages\"\n :key=\"message.id\"\n :class=\"[\n 'blockspark-message', \n `blockspark-message-${message.sender}`,\n { 'blockspark-handoff-message': isHandoffMessage(message.text) }\n ]\"\n >\n <div \n class=\"blockspark-message-content\"\n :class=\"{ 'blockspark-handoff-content': isHandoffMessage(message.text) }\"\n >\n <!-- Safe HTML rendering with sanitization -->\n <!-- Preserve line breaks for better formatting -->\n <span v-html=\"safeLinkifyText(message.text).replace(/\\n/g, '<br>')\"></span>\n </div>\n\n <!-- Rich Content (Chips) -->\n <div\n v-if=\"message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0\"\n class=\"blockspark-chips-container\"\n >\n <template v-for=\"(contentGroup, groupIndex) in message.richContent\" :key=\"groupIndex\">\n <template v-if=\"!Array.isArray(contentGroup)\">\n <div\n v-if=\"contentGroup.type === 'chips' && contentGroup.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in contentGroup.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n <template v-else>\n <template\n v-for=\"(content, contentIndex) in contentGroup\"\n :key=\"`${groupIndex}-${contentIndex}`\"\n >\n <div\n v-if=\"content.type === 'chips' && content.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in content.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n\n <div class=\"blockspark-message-time\">\n {{ formatTime(message.timestamp) }}\n </div>\n </div>\n\n <!-- Loading Indicator -->\n <div v-if=\"state.isLoading\" class=\"blockspark-message blockspark-message-bot\">\n <div class=\"blockspark-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Agent Typing Indicator -->\n <div v-if=\"state.chatMode === 'human' && agentTyping\" class=\"blockspark-agent-typing-indicator\">\n <span class=\"blockspark-typing-dots\">\n <span></span>\n <span></span>\n <span></span>\n </span>\n <span class=\"blockspark-typing-text\">Agent is typing...</span>\n </div>\n\n <div ref=\"messagesEndRef\"></div>\n </div>\n\n <!-- Input Form -->\n <form class=\"blockspark-chat-input-form\" @submit.prevent=\"handleSubmit\">\n <input\n type=\"text\"\n class=\"blockspark-chat-input\"\n :value=\"state.inputValue\"\n @input=\"handleInput\"\n :placeholder=\"config.inputPlaceholder\"\n :disabled=\"state.isLoading\"\n />\n <button\n type=\"submit\"\n class=\"blockspark-chat-send-btn\"\n :disabled=\"!state.inputValue.trim() || state.isLoading\"\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </form>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, nextTick, watch } from 'vue';\nimport { useChatWidget } from '../composables/useChatWidget';\nimport { safeLinkifyText } from '../utils/sanitize';\nimport type { WidgetConfig } from '../core/types';\n\n// Props\nconst props = withDefaults(defineProps<WidgetConfig>(), {\n title: '💬 BlockSpark AI Assistant',\n subtitle: \"We're here to help\",\n welcomeTitle: '👋 Welcome to BlockSpark',\n welcomeMessage: \"My name is BlockSpark AI Assistant and I'll guide you.\",\n welcomeCta: '💬 Click here to start chatting!',\n showWelcomePopup: true,\n welcomePopupDelay: 1500,\n fallbackWelcomeMessage: \"Hello! I'm BlockSpark AI Assistant. How can I help you today?\",\n inputPlaceholder: 'Type your message...',\n emptyStateMessage: \"Hi! I'm BlockSpark AI Assistant. How can I help you today?\",\n debug: false,\n});\n\n// Use headless composable\nconst {\n state,\n isOpen,\n messages,\n isLoading,\n error,\n chatMode,\n wsConnected,\n agentTyping,\n currentAgent,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n} = useChatWidget(props);\n\n// Refs\nconst messagesEndRef = ref<HTMLDivElement | null>(null);\nconst messagesContainer = ref<HTMLDivElement | null>(null);\n\n// Computed config (for reactivity)\nconst config = computed(() => props);\n\n// Auto-scroll to bottom when messages change\nwatch(\n () => messages.value.length,\n () => {\n nextTick(() => {\n messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n);\n\n// Handlers\nconst handleOpenChat = async () => {\n await openChat();\n};\n\nconst handleCloseChat = () => {\n closeChat();\n};\n\nconst handleCloseWelcomePopup = () => {\n manager.closeWelcomePopup();\n};\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n setInputValue(target.value);\n};\n\nconst handleSubmit = async (event: Event) => {\n event.preventDefault();\n if (state.value.inputValue.trim()) {\n await sendMessage(state.value.inputValue);\n }\n};\n\nconst handleChipClick = async (chipText: string, payload?: string) => {\n const messageToSend = chipText || payload || '';\n await sendMessage(messageToSend);\n};\n\n// Utility functions\nconst formatTime = (date: Date): string => {\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\n// Check if message is a handoff message\nconst isHandoffMessage = (text: string): boolean => {\n return text.includes('👤') || \n text.includes('being connected') || \n text.includes('live support agent') ||\n text.includes('transfer your conversation');\n};\n\n// Initialize welcome popup on mount (SSR-safe)\nonMounted(() => {\n if (config.value.showWelcomePopup && typeof window !== 'undefined') {\n manager.initializeWelcomePopup();\n }\n});\n</script>\n\n<style scoped>\n/* Styles are imported separately by users */\n/* This ensures SSR compatibility */\n</style>\n"],"names":["_openBlock","_createElementBlock","_unref","_createElementVNode","_toDisplayString","_Fragment","_renderList","_normalizeClass"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChatWidget.vue.esm2.js","sources":["../../src/components/ChatWidget.vue"],"sourcesContent":["<template>\n <div class=\"blockspark-chat-widget\" v-bind=\"$attrs\">\n <!-- Welcome Popup -->\n <div\n v-if=\"state.showWelcomePopup && !state.isOpen\"\n class=\"blockspark-welcome-popup\"\n @click=\"handleOpenChat\"\n >\n <div class=\"blockspark-welcome-header\">\n <div class=\"blockspark-welcome-title\">{{ config.welcomeTitle }}</div>\n <button\n class=\"blockspark-close-popup\"\n @click.stop=\"handleCloseWelcomePopup\"\n aria-label=\"Close welcome popup\"\n >\n ×\n </button>\n </div>\n <div class=\"blockspark-welcome-message\">{{ config.welcomeMessage }}</div>\n <div class=\"blockspark-welcome-cta\">{{ config.welcomeCta }}</div>\n </div>\n\n <!-- Chat Toggle Button -->\n <button\n v-if=\"!state.isOpen\"\n class=\"blockspark-chat-toggle-btn\"\n @click=\"handleOpenChat\"\n aria-label=\"Open chat\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n </button>\n\n <!-- Chat Window -->\n <div v-if=\"state.isOpen\" class=\"blockspark-chat-window\">\n <div class=\"blockspark-chat-header\">\n <div class=\"blockspark-chat-header-content\">\n <div class=\"blockspark-chat-title\">{{ config.title }}</div>\n <div class=\"blockspark-chat-subtitle\">\n {{ config.subtitle }}\n <span v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-indicator\">\n • {{ wsConnected ? '🟢 Connected' : '🟡 Connecting...' }}\n </span>\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-badge\">\n Human Support Mode\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-agent-info\">\n <span class=\"blockspark-agent-label\">Agent:</span>\n <span class=\"blockspark-agent-name\">{{ currentAgent.name }}</span>\n </div>\n <div v-if=\"state.chatMode === 'ai'\" class=\"blockspark-mode-badge\">\n Bot Mode\n </div>\n </div>\n <button\n class=\"blockspark-chat-close-btn\"\n @click=\"handleCloseChat\"\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div class=\"blockspark-chat-messages\" ref=\"messagesContainer\">\n <!-- Empty State -->\n <div v-if=\"state.messages.length === 0\" class=\"blockspark-chat-empty\">\n <div class=\"blockspark-chat-empty-icon\">👋</div>\n <p>{{ config.emptyStateMessage }}</p>\n </div>\n\n <!-- Messages -->\n <div\n v-for=\"message in state.messages\"\n :key=\"message.id\"\n :class=\"[\n 'blockspark-message', \n `blockspark-message-${message.sender}`,\n { 'blockspark-handoff-message': isHandoffMessage(message.text) }\n ]\"\n >\n <div \n class=\"blockspark-message-content\"\n :class=\"{ 'blockspark-handoff-content': isHandoffMessage(message.text) }\"\n >\n <!-- Safe HTML rendering with sanitization -->\n <!-- Preserve line breaks for better formatting -->\n <span v-html=\"safeLinkifyText(message.text).replace(/\\n/g, '<br>')\"></span>\n </div>\n\n <!-- Rich Content (Chips) -->\n <div\n v-if=\"message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0\"\n class=\"blockspark-chips-container\"\n >\n <template v-for=\"(contentGroup, groupIndex) in message.richContent\" :key=\"groupIndex\">\n <template v-if=\"!Array.isArray(contentGroup)\">\n <div\n v-if=\"contentGroup.type === 'chips' && contentGroup.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in contentGroup.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n <template v-else>\n <template\n v-for=\"(content, contentIndex) in contentGroup\"\n :key=\"`${groupIndex}-${contentIndex}`\"\n >\n <div\n v-if=\"content.type === 'chips' && content.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in content.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n\n <div class=\"blockspark-message-time\">\n {{ formatTime(message.timestamp) }}\n </div>\n </div>\n\n <!-- Loading Indicator -->\n <div v-if=\"state.isLoading\" class=\"blockspark-message blockspark-message-bot\">\n <div class=\"blockspark-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Agent Typing Indicator -->\n <div v-if=\"state.chatMode === 'human' && agentTyping\" class=\"blockspark-agent-typing-indicator\">\n <span class=\"blockspark-typing-dots\">\n <span></span>\n <span></span>\n <span></span>\n </span>\n <span class=\"blockspark-typing-text\">Agent is typing...</span>\n </div>\n\n <div ref=\"messagesEndRef\"></div>\n </div>\n\n <!-- Input Form -->\n <form class=\"blockspark-chat-input-form\" @submit.prevent=\"handleSubmit\">\n <input\n type=\"text\"\n class=\"blockspark-chat-input\"\n :value=\"state.inputValue\"\n @input=\"handleInput\"\n :placeholder=\"config.inputPlaceholder\"\n :disabled=\"state.isLoading\"\n />\n <button\n type=\"submit\"\n class=\"blockspark-chat-send-btn\"\n :disabled=\"!state.inputValue.trim() || state.isLoading\"\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </form>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, nextTick, watch } from 'vue';\nimport { useChatWidget } from '../composables/useChatWidget';\nimport { safeLinkifyText } from '../utils/sanitize';\nimport type { WidgetConfig } from '../core/types';\n\n// Handle attributes properly to avoid Vue warnings\n// For Vue 3.3+, defineOptions is available as a compiler macro\n// @ts-ignore - defineOptions is a compiler macro\ndefineOptions({\n inheritAttrs: false, // We handle attrs manually via v-bind=\"$attrs\"\n});\n\n// Props\nconst props = withDefaults(defineProps<WidgetConfig>(), {\n title: '💬 BlockSpark AI Assistant',\n subtitle: \"We're here to help\",\n welcomeTitle: '👋 Welcome to BlockSpark',\n welcomeMessage: \"My name is BlockSpark AI Assistant and I'll guide you.\",\n welcomeCta: '💬 Click here to start chatting!',\n showWelcomePopup: true,\n welcomePopupDelay: 1500,\n fallbackWelcomeMessage: \"Hello! I'm BlockSpark AI Assistant. How can I help you today?\",\n inputPlaceholder: 'Type your message...',\n emptyStateMessage: \"Hi! I'm BlockSpark AI Assistant. How can I help you today?\",\n debug: false,\n});\n\n// Use headless composable\nconst {\n state,\n isOpen,\n messages,\n isLoading,\n error,\n chatMode,\n wsConnected,\n agentTyping,\n currentAgent,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n} = useChatWidget(props);\n\n// Refs\nconst messagesEndRef = ref<HTMLDivElement | null>(null);\nconst messagesContainer = ref<HTMLDivElement | null>(null);\n\n// Computed config (for reactivity)\nconst config = computed(() => props);\n\n// Auto-scroll to bottom when messages change\nwatch(\n () => messages.value.length,\n () => {\n nextTick(() => {\n messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n);\n\n// Handlers\nconst handleOpenChat = async () => {\n // Ensure immediate UI response\n if (!state.value.isOpen) {\n state.value.isOpen = true;\n state.value.showWelcomePopup = false;\n }\n await openChat();\n};\n\nconst handleCloseChat = () => {\n closeChat();\n};\n\nconst handleCloseWelcomePopup = () => {\n manager.closeWelcomePopup();\n};\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n setInputValue(target.value);\n};\n\nconst handleSubmit = async (event: Event) => {\n event.preventDefault();\n if (state.value.inputValue.trim()) {\n await sendMessage(state.value.inputValue);\n }\n};\n\nconst handleChipClick = async (chipText: string, payload?: string) => {\n const messageToSend = chipText || payload || '';\n await sendMessage(messageToSend);\n};\n\n// Utility functions\nconst formatTime = (date: Date): string => {\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\n// Check if message is a handoff message\nconst isHandoffMessage = (text: string): boolean => {\n return text.includes('👤') || \n text.includes('being connected') || \n text.includes('live support agent') ||\n text.includes('transfer your conversation');\n};\n\n// Initialize welcome popup on mount (SSR-safe)\nonMounted(() => {\n if (config.value.showWelcomePopup && typeof window !== 'undefined') {\n manager.initializeWelcomePopup();\n }\n});\n</script>\n\n<style scoped>\n/* Styles are imported separately by users */\n/* This ensures SSR compatibility */\n</style>\n"],"names":["_openBlock","_createElementBlock","_mergeProps","$attrs","_unref","_createElementVNode","_toDisplayString","_Fragment","_renderList","_normalizeClass"],"mappings":"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"}
|