open-chat-studio-widget 0.3.1 → 0.4.0
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/README.md +14 -7
- package/dist/cjs/{index-d39b7c53.js → index-b700441a.js} +83 -4
- package/dist/cjs/index-b700441a.js.map +1 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js +4846 -50
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js.map +1 -1
- package/dist/cjs/open-chat-studio-widget.cjs.js +2 -2
- package/dist/collection/components/ocs-chat/heroicons.js +6 -12
- package/dist/collection/components/ocs-chat/heroicons.js.map +1 -1
- package/dist/collection/components/ocs-chat/ocs-chat.css +1094 -73
- package/dist/collection/components/ocs-chat/ocs-chat.js +752 -40
- package/dist/collection/components/ocs-chat/ocs-chat.js.map +1 -1
- package/dist/collection/utils/markdown.js +64 -0
- package/dist/collection/utils/markdown.js.map +1 -0
- package/dist/components/open-chat-studio-widget.js +4869 -52
- package/dist/components/open-chat-studio-widget.js.map +1 -1
- package/dist/esm/{index-b73ebc69.js → index-b188b488.js} +83 -4
- package/dist/esm/index-b188b488.js.map +1 -0
- package/dist/esm/loader.js +3 -3
- package/dist/esm/open-chat-studio-widget.entry.js +4846 -50
- package/dist/esm/open-chat-studio-widget.entry.js.map +1 -1
- package/dist/esm/open-chat-studio-widget.js +3 -3
- package/dist/open-chat-studio-widget/open-chat-studio-widget.esm.js +1 -1
- package/dist/open-chat-studio-widget/open-chat-studio-widget.esm.js.map +1 -1
- package/dist/open-chat-studio-widget/p-a0fbe1b4.js +3 -0
- package/dist/open-chat-studio-widget/p-a0fbe1b4.js.map +1 -0
- package/dist/open-chat-studio-widget/p-d2d76b54.entry.js +3 -0
- package/dist/open-chat-studio-widget/p-d2d76b54.entry.js.map +1 -0
- package/dist/types/components/ocs-chat/heroicons.d.ts +2 -4
- package/dist/types/components/ocs-chat/ocs-chat.d.ts +129 -4
- package/dist/types/components.d.ts +61 -5
- package/dist/types/utils/markdown.d.ts +6 -0
- package/package.json +4 -3
- package/dist/cjs/index-d39b7c53.js.map +0 -1
- package/dist/esm/index-b73ebc69.js.map +0 -1
- package/dist/open-chat-studio-widget/p-4cdc34c1.js +0 -3
- package/dist/open-chat-studio-widget/p-4cdc34c1.js.map +0 -1
- package/dist/open-chat-studio-widget/p-c4c7c404.entry.js +0 -2
- package/dist/open-chat-studio-widget/p-c4c7c404.entry.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ocs-chat.js","sourceRoot":"","sources":["../../../src/components/ocs-chat/ocs-chat.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Host, h, Prop, State, Build } from '@stencil/core';\nimport {\n ArrowLeftEndOnRectangleIcon,\n ArrowRightEndOnRectangleIcon,\n ArrowDownOnSquareIcon,\n ViewfinderCircleIcon,\n XMarkIcon,\n ChevronDownIcon,\n ChevronUpIcon,\n} from './heroicons';\n\nconst allowedHosts = [\"chatbots.dimagi.com\"];\n\n@Component({\n tag: 'open-chat-studio-widget',\n styleUrl: 'ocs-chat.css',\n shadow: true,\n})\nexport class OcsChat {\n\n /**\n * The URL of the bot to connect to.\n */\n @Prop() botUrl!: string;\n\n /**\n * The text to display on the button.\n */\n @Prop() buttonText: string = \"Chat\";\n\n /**\n * Whether the chat widget is visible on load.\n */\n @Prop({ mutable: true }) visible: boolean = false;\n\n /**\n * The initial position of the chat widget on the screen.\n */\n @Prop({ mutable: true }) position: 'left' | 'center' | 'right' = 'right';\n\n /**\n * Whether the chat widget is initially expanded.\n */\n @Prop({ mutable: true }) expanded: boolean = false;\n\n @State() loaded: boolean = false;\n @State() error: string = \"\";\n\n componentWillLoad() {\n this.loaded = this.visible;\n if (!Build.isDev) {\n try {\n const url = new URL(this.botUrl);\n if (!allowedHosts.includes(url.host)) {\n this.error = `Invalid Bot URL: ${this.botUrl}`;\n }\n } catch {\n this.error = `Invalid Bot URL: ${this.botUrl}`;\n }\n }\n }\n\n load() {\n this.visible = !this.visible;\n this.loaded = true;\n }\n\n setPosition(position: 'left' | 'center' | 'right') {\n if (position === this.position) return;\n this.position = position;\n }\n\n toggleSize() {\n this.expanded = !this.expanded;\n }\n\n getPositionClasses() {\n const baseClasses = `fixed w-full sm:w-[450px] ${this.expanded ? 'h-5/6' : 'h-3/5'} bg-white border border-gray-200 shadow-lg rounded-lg overflow-hidden flex flex-col`;\n\n const positionClasses = {\n left: 'left-0 sm:left-5 bottom-0 sm:bottom-5',\n right: 'right-0 sm:right-5 bottom-0 sm:bottom-5',\n center: 'left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'\n }[this.position];\n\n return `${baseClasses} ${positionClasses}`;\n }\n\n render() {\n if (this.error) {\n return (\n <Host>\n <p>{this.error}</p>\n </Host>\n );\n }\n\n return (\n <Host>\n <button class=\"btn\" onClick={() => this.load()}>{this.buttonText}</button>\n {this.visible && (\n <div id=\"ocs-chat-window\" class={this.getPositionClasses()}>\n <div class=\"flex justify-between items-center px-2 py-2 border-b border-gray-100\">\n <div class=\"flex gap-1\">\n <button\n class={{\n 'hidden sm:block p-1.5 rounded-md transition-colors duration-200 hover:bg-gray-100': true,\n 'text-blue-600': this.position === 'left',\n 'text-gray-500': this.position !== 'left'\n }}\n onClick={() => this.setPosition('left')}\n aria-label=\"Dock to left\"\n title=\"Dock to left\"\n >\n <ArrowLeftEndOnRectangleIcon/>\n </button>\n <button\n class={{\n 'p-1.5 rounded-md transition-colors duration-200 hover:bg-gray-100': true,\n 'text-blue-600': this.position === 'center',\n 'text-gray-500': this.position !== 'center'\n }}\n onClick={() => this.setPosition('center')}\n aria-label=\"Center\"\n title=\"Center\"\n >\n <ViewfinderCircleIcon/>\n </button>\n <button\n class={{\n 'p-1.5 rounded-md transition-colors duration-200 hover:bg-gray-100': true,\n 'text-blue-600': this.position === 'right',\n 'text-gray-500': this.position !== 'right'\n }}\n onClick={() => this.setPosition('right')}\n aria-label=\"Dock to right\"\n title=\"Dock to right\"\n >\n <span class=\"hidden sm:block\"><ArrowRightEndOnRectangleIcon/></span>\n <span class=\"sm:hidden\"><ArrowDownOnSquareIcon/></span>\n </button>\n </div>\n <div class=\"flex gap-1\">\n <button\n class=\"p-1.5 rounded-md transition-colors duration-200 hover:bg-gray-100 text-gray-500\"\n onClick={() => this.toggleSize()}\n aria-label={this.expanded ? \"Collapse\" : \"Expand\"}\n title={this.expanded ? \"Collapse\" : \"Expand\"}\n >\n {this.expanded ? <ChevronDownIcon/> : <ChevronUpIcon/>}\n </button>\n <button\n class=\"p-1.5 hover:bg-gray-100 rounded-md transition-colors duration-200 text-gray-500\"\n onClick={() => this.visible = false}\n aria-label=\"Close\"\n >\n <XMarkIcon/>\n </button>\n </div>\n </div>\n {this.loaded && (\n <iframe\n class=\"flex-grow w-full border-none iframe-placeholder\"\n src={this.botUrl}\n ></iframe>\n )}\n </div>\n )}\n </Host>\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ocs-chat.js","sourceRoot":"","sources":["../../../src/components/ocs-chat/ocs-chat.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Host, h, Prop, State } from '@stencil/core';\nimport {\n XMarkIcon,\n ChevronDownIcon,\n ChevronUpIcon,\n GripDotsVerticalIcon, PencilSquare,\n} from './heroicons';\nimport { renderMarkdownSync as renderMarkdownComplete } from '../../utils/markdown';\n\ninterface ChatMessage {\n created_at: string;\n role: 'system' | 'user' | 'assistant';\n content: string;\n metadata?: any;\n attachments?: ChatAttachment[];\n}\n\ninterface ChatAttachment {\n name: string;\n content_type: string;\n size: number;\n content_url: string;\n}\n\ninterface ChatStartSessionResponse {\n session_id: string;\n chatbot: any;\n participant: any;\n seed_message_task_id?: string;\n}\n\ninterface ChatSendMessageResponse {\n task_id: string;\n status: 'processing' | 'completed' | 'error';\n error?: string;\n}\n\ninterface ChatTaskPollResponse {\n message?: ChatMessage;\n status: 'processing' | 'complete';\n error?: string;\n}\n\ninterface ChatPollResponse {\n messages: ChatMessage[];\n has_more: boolean;\n session_status: 'active' | 'ended';\n}\n\ninterface PointerEvent {\n clientX: number;\n clientY: number;\n}\n\ninterface SessionStorageData {\n sessionId?: string;\n messages: ChatMessage[];\n}\n\n@Component({\n tag: 'open-chat-studio-widget',\n styleUrl: 'ocs-chat.css',\n shadow: true,\n})\nexport class OcsChat {\n\n private static readonly TASK_POLLING_MAX_ATTEMPTS = 30;\n private static readonly TASK_POLLING_INTERVAL_MS = 1000;\n private static readonly MESSAGE_POLLING_INTERVAL_MS = 30000;\n\n private static readonly SCROLL_DELAY_MS = 100;\n private static readonly FOCUS_DELAY_MS = 100;\n\n private static readonly CHAT_WIDTH_DESKTOP = 450;\n private static readonly CHAT_HEIGHT_EXPANDED_RATIO = 0.83; // 83% of window height\n private static readonly CHAT_HEIGHT_COLLAPSED_RATIO = 0.6; // 60% of window height\n private static readonly MOBILE_BREAKPOINT = 640;\n private static readonly WINDOW_MARGIN = 20;\n\n private static readonly LOCALSTORAGE_TEST_KEY = '__ocs_test__';\n\n /**\n * The ID of the chatbot to connect to.\n */\n @Prop() chatbotId!: string;\n\n /**\n * The base URL for the API (defaults to current origin).\n */\n @Prop() apiBaseUrl?: string = \"https://chatbots.dimagi.com\";\n\n /**\n * The text to display on the button.\n */\n @Prop() buttonText?: string;\n\n /**\n * URL of the icon to display on the button. If not provided, uses the default OCS logo.\n */\n @Prop() iconUrl?: string;\n\n /**\n * The shape of the chat button. 'round' makes it circular, 'square' keeps it rectangular.\n */\n @Prop() buttonShape: 'round' | 'square' = 'square';\n\n /**\n * Whether the chat widget is visible on load.\n */\n @Prop({ mutable: true }) visible: boolean = false;\n\n /**\n * The initial position of the chat widget on the screen.\n */\n @Prop({ mutable: true }) position: 'left' | 'center' | 'right' = 'right';\n\n /**\n * Whether the chat widget is initially expanded.\n */\n @Prop({ mutable: true }) expanded: boolean = false;\n\n /**\n * Welcome messages to display above starter questions (JSON array of strings)\n */\n @Prop() welcomeMessages?: string;\n\n /**\n * Array of starter questions that users can click to send (JSON array of strings)\n */\n @Prop() starterQuestions?: string;\n\n /**\n * Whether to persist session data to local storage to allow resuming previous conversations after page reload.\n */\n @Prop() persistentSession: boolean = true;\n\n /**\n * Minutes since the most recent message after which the session data in local storage will expire. Set this to\n * `0` to never expire.\n */\n @Prop() persistentSessionExpire: number = 60 * 24;\n\n @State() loaded: boolean = false;\n @State() error: string = \"\";\n @State() messages: ChatMessage[] = [];\n @State() sessionId?: string;\n @State() isLoading: boolean = false;\n @State() isTyping: boolean = false;\n @State() messageInput: string = \"\";\n @State() pollingInterval?: any;\n @State() lastPollTime?: Date;\n @State() isTaskPolling: boolean = false;\n @State() isDragging: boolean = false;\n @State() dragOffset: { x: number; y: number } = { x: 0, y: 0 };\n @State() windowPosition: { x: number; y: number } = { x: 0, y: 0 };\n @State() showStarterQuestions: boolean = true;\n @State() parsedWelcomeMessages: string[] = [];\n @State() parsedStarterQuestions: string[] = [];\n\n private messageListRef?: HTMLDivElement;\n private textareaRef?: HTMLTextAreaElement;\n private chatWindowRef?: HTMLDivElement;\n\n\n componentWillLoad() {\n this.loaded = this.visible;\n if (!this.chatbotId) {\n this.error = 'Chatbot ID is required';\n return;\n }\n // Always try to load existing session if localStorage is available\n if (this.persistentSession && this.isLocalStorageAvailable()) {\n const { sessionId, messages } = this.loadSessionFromStorage();\n if (sessionId && messages) {\n this.sessionId = sessionId;\n this.messages = messages;\n this.showStarterQuestions = messages.length === 0;\n }\n }\n this.parseWelcomeMessages();\n this.parseStarterQuestions();\n }\n\n componentDidLoad() {\n // Only auto-start session if we don't have an existing one\n if (this.visible && !this.sessionId) {\n this.startSession();\n } else if (this.visible && this.sessionId) {\n // Resume polling for existing session\n this.startPolling();\n }\n this.initializePosition();\n window.addEventListener('resize', this.handleWindowResize);\n }\n\n disconnectedCallback() {\n this.cleanup();\n this.removeEventListeners();\n window.removeEventListener('resize', this.handleWindowResize);\n }\n\n private parseJSONProp(propValue: string | undefined, propName: string): string[] {\n try {\n if (propValue) {\n try {\n return JSON.parse(propValue);\n } catch {\n const fixedValue = propValue.replace(/'/g, '\"');\n return JSON.parse(fixedValue);\n }\n }\n } catch (error) {\n console.warn(`Failed to parse ${propName}:`, error);\n }\n return [];\n }\n\n private parseWelcomeMessages() {\n this.parsedWelcomeMessages = this.parseJSONProp(this.welcomeMessages, 'welcome messages');\n }\n\n private parseStarterQuestions() {\n this.parsedStarterQuestions = this.parseJSONProp(this.starterQuestions, 'starter questions');\n }\n\n private cleanup() {\n if (this.pollingInterval) {\n clearInterval(this.pollingInterval);\n this.pollingInterval = undefined;\n }\n this.isTaskPolling = false;\n }\n\n private getApiBaseUrl(): string {\n return this.apiBaseUrl || window.location.origin;\n }\n\n private async startSession(): Promise<void> {\n try {\n this.isLoading = true;\n this.error = '';\n\n const response = await fetch(`${this.getApiBaseUrl()}/api/chat/start/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n chatbot_id: this.chatbotId,\n session_data: {\n source: 'widget',\n page_url: window.location.href\n }\n })\n });\n\n if (!response.ok) {\n throw new Error(`Failed to start session: ${response.statusText}`);\n }\n\n const data: ChatStartSessionResponse = await response.json();\n this.sessionId = data.session_id;\n this.saveSessionToStorage();\n\n // Handle seed message if present\n if (data.seed_message_task_id) {\n this.isTyping = true; // Show typing indicator for seed message\n await this.pollTaskResponse(data.seed_message_task_id);\n }\n\n // Start polling for messages\n this.startPolling();\n } catch (error) {\n this.error = error instanceof Error ? error.message : 'Failed to start chat session';\n } finally {\n this.isLoading = false;\n }\n }\n\n private async sendMessage(message: string): Promise<void> {\n if (!this.sessionId || !message.trim()) return;\n\n // Hide starter questions on any user interaction\n this.showStarterQuestions = false;\n\n try {\n // If this is the first user message and there are welcome messages,\n // add them to chat history as assistant messages\n if (this.messages.length === 0 && this.parsedWelcomeMessages.length > 0) {\n const now = new Date();\n const welcomeMessages: ChatMessage[] = this.parsedWelcomeMessages.map((welcomeMsg, index) => ({\n created_at: new Date(now.getTime() - (this.parsedWelcomeMessages.length - index) * 1000).toISOString(),\n role: 'assistant' as const,\n content: welcomeMsg,\n attachments: []\n }));\n this.messages = [...this.messages, ...welcomeMessages];\n }\n // Add user message immediately\n const userMessage: ChatMessage = {\n created_at: new Date().toISOString(),\n role: 'user',\n content: message.trim(),\n attachments: []\n };\n this.messages = [...this.messages, userMessage];\n this.saveSessionToStorage();\n this.messageInput = '';\n this.scrollToBottom();\n\n // Start typing indicator - it will stay on during task polling\n this.isTyping = true;\n\n const response = await fetch(`${this.getApiBaseUrl()}/api/chat/${this.sessionId}/message/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ message: message.trim() })\n });\n\n if (!response.ok) {\n throw new Error(`Failed to send message: ${response.statusText}`);\n }\n\n const data: ChatSendMessageResponse = await response.json();\n\n if (data.status === 'error') {\n throw new Error(data.error || 'Failed to send message');\n }\n\n // Poll for the response - typing indicator will be managed in pollTaskResponse\n await this.pollTaskResponse(data.task_id);\n } catch (error) {\n this.error = error instanceof Error ? error.message : 'Failed to send message';\n // Clear typing indicator on error\n this.isTyping = false;\n }\n }\n\n private handleStarterQuestionClick(question: string): void {\n this.sendMessage(question);\n }\n\n private async pollTaskResponse(taskId: string): Promise<void> {\n if (!this.sessionId) return;\n\n // Stop message polling while task polling is active\n this.isTaskPolling = true;\n this.pauseMessagePolling();\n\n let attempts = 0;\n\n const poll = async (): Promise<void> => {\n try {\n const response = await fetch(`${this.getApiBaseUrl()}/api/chat/${this.sessionId}/${taskId}/poll/`);\n\n if (!response.ok) {\n throw new Error(`Failed to poll task: ${response.statusText}`);\n }\n\n const data: ChatTaskPollResponse = await response.json();\n\n if (data.error) {\n throw new Error(data.error);\n }\n\n if (data.status === 'complete' && data.message) {\n this.messages = [...this.messages, data.message];\n this.saveSessionToStorage();\n this.scrollToBottom();\n // Task polling complete, clear typing indicator and resume message polling\n this.isTyping = false;\n this.isTaskPolling = false;\n this.resumeMessagePolling();\n this.focusInput();\n return;\n }\n\n if (data.status === 'processing' && attempts < OcsChat.TASK_POLLING_MAX_ATTEMPTS) {\n attempts++;\n setTimeout(poll, OcsChat.TASK_POLLING_INTERVAL_MS);\n } else if (attempts >= OcsChat.TASK_POLLING_MAX_ATTEMPTS) {\n // Task polling timed out, clear typing indicator and resume message polling\n this.isTyping = false;\n this.isTaskPolling = false;\n this.resumeMessagePolling();\n }\n } catch (error) {\n this.error = error instanceof Error ? error.message : 'Failed to get response';\n // Error in task polling, clear typing indicator and resume message polling\n this.isTyping = false;\n this.isTaskPolling = false;\n this.resumeMessagePolling();\n }\n };\n\n await poll();\n }\n\n private startPolling(): void {\n if (this.pollingInterval) return;\n\n this.pollingInterval = setInterval(async () => {\n // Only poll for messages if not currently polling for a task\n if (!this.isTaskPolling) {\n await this.pollForMessages();\n }\n }, OcsChat.MESSAGE_POLLING_INTERVAL_MS);\n }\n\n private pauseMessagePolling(): void {\n if (this.pollingInterval) {\n clearInterval(this.pollingInterval);\n this.pollingInterval = undefined;\n }\n }\n\n private resumeMessagePolling(): void {\n // Resume message polling after task polling is complete\n this.startPolling();\n }\n\n private async pollForMessages(): Promise<void> {\n if (!this.sessionId) return;\n\n try {\n const url = new URL(`${this.getApiBaseUrl()}/api/chat/${this.sessionId}/poll/`);\n if (this.messages && this.messages.length > 0) {\n url.searchParams.set('since', this.messages.at(-1).created_at);\n }\n\n const response = await fetch(url.toString());\n\n if (!response.ok) return; // Silently fail for polling\n\n const data: ChatPollResponse = await response.json();\n\n if (data.messages.length > 0) {\n this.messages = [...this.messages, ...data.messages];\n this.saveSessionToStorage();\n this.scrollToBottom();\n this.focusInput();\n }\n\n this.lastPollTime = new Date();\n } catch (error) {\n // Silently fail for polling\n }\n }\n\n private clearError() {\n this.error = '';\n }\n\n private scrollToBottom(): void {\n setTimeout(() => {\n if (this.messageListRef) {\n this.messageListRef.scrollTop = this.messageListRef.scrollHeight;\n }\n }, OcsChat.SCROLL_DELAY_MS);\n }\n\n private focusInput(): void {\n setTimeout(() => {\n if (this.textareaRef && !this.isTyping) {\n this.textareaRef.focus();\n }\n }, OcsChat.FOCUS_DELAY_MS);\n }\n\n private handleKeyPress(event: KeyboardEvent): void {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.sendMessage(this.messageInput);\n }\n }\n\n private handleInputChange(event: Event): void {\n this.messageInput = (event.target as HTMLTextAreaElement).value;\n // Hide starter questions when user starts typing\n if (this.messageInput.trim().length > 0) {\n this.showStarterQuestions = false;\n }\n }\n\n private formatTime(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n\n async load() {\n this.visible = !this.visible;\n this.loaded = true;\n\n if (this.visible && !this.sessionId) {\n this.clearError();\n await this.startSession();\n } else if (!this.visible) {\n // Don't reset session when closing, allow resume\n }\n }\n\n setPosition(position: 'left' | 'center' | 'right') {\n if (position === this.position) return;\n this.position = position;\n }\n\n toggleSize() {\n this.expanded = !this.expanded;\n }\n\n getPositionClasses() {\n return `fixed w-full sm:w-[450px] ${this.expanded ? 'h-5/6' : 'h-3/5'} bg-white border border-gray-200 ${this.isDragging ? 'shadow-2xl cursor-grabbing' : 'shadow-lg transition-shadow duration-200'} rounded-lg overflow-hidden flex flex-col`;\n }\n\n getPositionStyles() {\n return {\n left: `${this.windowPosition.x}px`,\n top: `${this.windowPosition.y}px`,\n };\n }\n\n private initializePosition(): void {\n const windowWidth = window.innerWidth;\n const windowHeight = window.innerHeight;\n const chatWidth = windowWidth < OcsChat.MOBILE_BREAKPOINT ? windowWidth : OcsChat.CHAT_WIDTH_DESKTOP;\n const chatHeight = this.expanded\n ? (windowHeight * OcsChat.CHAT_HEIGHT_EXPANDED_RATIO)\n : (windowHeight * OcsChat.CHAT_HEIGHT_COLLAPSED_RATIO);\n const isMobile = windowWidth < OcsChat.MOBILE_BREAKPOINT;\n\n if (isMobile) {\n this.windowPosition = { x: 0, y: 0 };\n return;\n }\n\n switch (this.position) {\n case 'left':\n this.windowPosition = {\n x: OcsChat.WINDOW_MARGIN,\n y: windowHeight - chatHeight - OcsChat.WINDOW_MARGIN\n };\n break;\n case 'right':\n this.windowPosition = {\n x: windowWidth - chatWidth - OcsChat.WINDOW_MARGIN,\n y: windowHeight - chatHeight - OcsChat.WINDOW_MARGIN\n };\n break;\n case 'center':\n this.windowPosition = {\n x: (windowWidth - chatWidth) / 2,\n y: (windowHeight - chatHeight) / 2\n };\n break;\n }\n }\n\n private getPointerCoordinates(event: MouseEvent | TouchEvent): PointerEvent | null {\n if (event instanceof MouseEvent) {\n return { clientX: event.clientX, clientY: event.clientY };\n } else if (event instanceof TouchEvent && event.touches.length === 1) {\n const touch = event.touches[0];\n return { clientX: touch.clientX, clientY: touch.clientY };\n }\n return null;\n }\n\n private startDrag(pointer: PointerEvent): void {\n if (!this.chatWindowRef) return;\n\n this.isDragging = true;\n const rect = this.chatWindowRef.getBoundingClientRect();\n this.dragOffset = {\n x: pointer.clientX - rect.left,\n y: pointer.clientY - rect.top\n };\n }\n\n private updateDragPosition(pointer: PointerEvent): void {\n if (!this.isDragging) return;\n\n const newX = pointer.clientX - this.dragOffset.x;\n const newY = pointer.clientY - this.dragOffset.y;\n\n // Constrain chatbox to window\n const windowWidth = window.innerWidth;\n const windowHeight = window.innerHeight;\n const chatWidth = windowWidth < OcsChat.MOBILE_BREAKPOINT ? windowWidth : OcsChat.CHAT_WIDTH_DESKTOP;\n const chatHeight = this.expanded\n ? (windowHeight * OcsChat.CHAT_HEIGHT_EXPANDED_RATIO)\n : (windowHeight * OcsChat.CHAT_HEIGHT_COLLAPSED_RATIO);\n\n this.windowPosition = {\n x: Math.max(0, Math.min(newX, windowWidth - chatWidth)),\n y: Math.max(0, Math.min(newY, windowHeight - chatHeight))\n };\n }\n\n private endDrag(): void {\n this.isDragging = false;\n this.removeEventListeners();\n }\n\n private addEventListeners(): void {\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n document.addEventListener('touchmove', this.handleTouchMove, { passive: false });\n document.addEventListener('touchend', this.handleTouchEnd);\n }\n\n private removeEventListeners(): void {\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n document.removeEventListener('touchmove', this.handleTouchMove);\n document.removeEventListener('touchend', this.handleTouchEnd);\n }\n\n private handleMouseDown = (event: MouseEvent): void => {\n if (window.innerWidth < OcsChat.MOBILE_BREAKPOINT) return;\n if ((event.target as HTMLElement).closest('button')) return;\n\n const pointer = this.getPointerCoordinates(event);\n if (!pointer) return;\n\n this.startDrag(pointer);\n this.addEventListeners();\n event.preventDefault();\n };\n\n private handleMouseMove = (event: MouseEvent): void => {\n const pointer = this.getPointerCoordinates(event);\n if (!pointer) return;\n\n this.updateDragPosition(pointer);\n };\n\n private handleMouseUp = (): void => {\n this.endDrag();\n };\n\n private handleTouchStart = (event: TouchEvent): void => {\n if ((event.target as HTMLElement).closest('button')) return;\n if (!this.chatWindowRef) return;\n\n const pointer = this.getPointerCoordinates(event);\n if (!pointer) return;\n\n this.startDrag(pointer);\n this.addEventListeners();\n event.preventDefault();\n };\n\n private handleTouchMove = (event: TouchEvent): void => {\n const pointer = this.getPointerCoordinates(event);\n if (!pointer) return;\n\n this.updateDragPosition(pointer);\n event.preventDefault();\n };\n\n private handleTouchEnd = (): void => {\n this.endDrag();\n };\n\n private handleWindowResize = (): void => {\n this.initializePosition();\n };\n\n private getDefaultIconUrl(): string {\n return `${this.getApiBaseUrl()}/static/images/favicons/favicon.svg`;\n }\n\n private getButtonClasses(): string {\n const hasText = this.buttonText && this.buttonText.trim();\n const baseClass = hasText ? 'chat-btn-text' : 'chat-btn-icon';\n const shapeClass = this.buttonShape === 'round' ? 'round' : '';\n return `${baseClass} ${shapeClass}`.trim();\n }\n\n private renderButton() {\n const hasText = this.buttonText && this.buttonText.trim();\n const hasCustomIcon = this.iconUrl && this.iconUrl.trim();\n const iconSrc = hasCustomIcon ? this.iconUrl : this.getDefaultIconUrl();\n const buttonClasses = this.getButtonClasses();\n\n if (hasText) {\n return (\n <button\n class={buttonClasses}\n onClick={() => this.load()}\n aria-label={`Open chat - ${this.buttonText}`}\n title={this.buttonText}\n >\n <img src={iconSrc} alt=\"\" />\n <span>{this.buttonText}</span>\n </button>\n );\n } else {\n return (\n <button\n class={buttonClasses}\n onClick={() => this.load()}\n aria-label=\"Open chat\"\n title=\"Open chat\"\n >\n <img src={iconSrc} alt=\"Chat\" />\n </button>\n );\n }\n }\n\n private getStorageKeys() {\n return {\n sessionId: `ocs-chat-session-${this.chatbotId}`,\n messages: `ocs-chat-messages-${this.chatbotId}`,\n lastActivity: `ocs-chat-activity-${this.chatbotId}`\n };\n }\n\n private saveSessionToStorage(): void {\n if (!this.persistentSession) {\n return\n }\n const keys = this.getStorageKeys();\n try {\n if (this.sessionId) {\n localStorage.setItem(keys.sessionId, this.sessionId);\n localStorage.setItem(keys.lastActivity, new Date().toISOString());\n }\n localStorage.setItem(keys.messages, JSON.stringify(this.messages));\n } catch (error) {\n console.warn('Failed to save chat session to localStorage:', error);\n }\n }\n\n private loadSessionFromStorage(): SessionStorageData {\n const keys = this.getStorageKeys();\n try {\n if (this.persistentSessionExpire > 0) {\n const lastActivity = localStorage.getItem(keys.lastActivity);\n if (lastActivity) {\n const lastActivityDate = new Date(lastActivity);\n const minutesSinceActivity = (Date.now() - lastActivityDate.getTime()) / (1000 * 60);\n if (minutesSinceActivity > this.persistentSessionExpire) {\n this.clearSessionStorage();\n return {messages: []};\n }\n }\n }\n\n const storedSessionId = localStorage.getItem(keys.sessionId);\n const sessionId = storedSessionId ? storedSessionId : undefined;\n\n const messagesJson = localStorage.getItem(keys.messages);\n let messages: ChatMessage[] = [];\n\n if (messagesJson) {\n try {\n const parsedMessages = JSON.parse(messagesJson);\n messages = Array.isArray(parsedMessages) ? parsedMessages : [];\n } catch (parseError) {\n console.warn('Failed to parse messages from localStorage:', parseError);\n messages = [];\n }\n }\n\n return { sessionId, messages };\n } catch (error) {\n // fall back to starting a new session\n console.warn('Failed to load chat session from localStorage, starting new session:', error);\n return { messages: [] };\n }\n }\n\n private clearSessionStorage(): void {\n const keys = this.getStorageKeys();\n try {\n localStorage.removeItem(keys.sessionId);\n localStorage.removeItem(keys.messages);\n localStorage.removeItem(keys.lastActivity);\n } catch (error) {\n console.warn('Failed to clear chat session from localStorage:', error);\n }\n }\n\n private isLocalStorageAvailable(): boolean {\n try {\n localStorage.setItem(OcsChat.LOCALSTORAGE_TEST_KEY, 'test');\n localStorage.removeItem(OcsChat.LOCALSTORAGE_TEST_KEY);\n return true;\n } catch {\n return false;\n }\n }\n\n private async startNewChat(): Promise<void> {\n this.clearSessionStorage();\n this.sessionId = undefined;\n this.messages = [];\n this.showStarterQuestions = true;\n this.isTyping = false;\n this.error = '';\n this.cleanup();\n\n await this.startSession();\n }\n\n render() {\n if (this.error) {\n return (\n <Host>\n <p class=\"text-red-500 p-2\">{this.error}</p>\n </Host>\n );\n }\n\n return (\n <Host>\n {this.renderButton()}\n {this.visible && (\n <div\n ref={(el) => this.chatWindowRef = el}\n id=\"ocs-chat-window\"\n class={this.getPositionClasses()}\n style={this.getPositionStyles()}\n >\n {/* Header */}\n <div\n class={`flex justify-between items-center px-2 py-2 border-b border-gray-100 sm:${this.isDragging ? 'cursor-grabbing' : 'cursor-grab'} active:bg-gray-50 sm:hover:bg-gray-25 transition-colors duration-150`}\n onMouseDown={this.handleMouseDown}\n onTouchStart={this.handleTouchStart}\n >\n {/* Drag indicator */}\n <div class=\"hidden sm:flex gap-1\">\n <div class=\"flex gap-0.5 ml-2 pointer-events-none\">\n <GripDotsVerticalIcon/>\n </div>\n </div>\n <div></div>\n <div class=\"flex gap-1 items-center\">\n {/* New Chat button */}\n {this.sessionId && this.messages.length > 0 && (\n <button\n class=\"p-1.5 rounded-md transition-colors duration-200 hover:bg-gray-100 text-gray-500\"\n onClick={() => this.startNewChat()}\n title=\"Start new chat\"\n aria-label=\"Start new chat\"\n >\n <PencilSquare/>\n </button>\n )}\n <button\n class=\"p-1.5 rounded-md transition-colors duration-200 hover:bg-gray-100 text-gray-500\"\n onClick={() => this.toggleSize()}\n aria-label={this.expanded ? \"Collapse\" : \"Expand\"}\n title={this.expanded ? \"Collapse\" : \"Expand\"}\n >\n {this.expanded ? <ChevronDownIcon/> : <ChevronUpIcon/>}\n </button>\n <button\n class=\"p-1.5 hover:bg-gray-100 rounded-md transition-colors duration-200 text-gray-500\"\n onClick={() => this.visible = false}\n aria-label=\"Close\"\n >\n <XMarkIcon/>\n </button>\n </div>\n </div>\n\n {/* Chat Content */}\n <div class=\"flex flex-col flex-grow overflow-hidden\">\n {/* Loading State */}\n {this.isLoading && !this.sessionId && (\n <div class=\"flex items-center justify-center flex-grow\">\n <div class=\"loading-spinner\"></div>\n <span class=\"ml-2 text-gray-500\">Starting chat...</span>\n </div>\n )}\n\n {/* Messages */}\n {this.sessionId && (\n <div\n ref={(el) => this.messageListRef = el}\n class=\"flex-grow overflow-y-auto p-4 space-y-4\"\n >\n {this.messages.length === 0 && !this.isTyping && this.parsedWelcomeMessages.length > 0 && (\n <div class=\"space-y-4\">\n {/* Welcome Messages */}\n {this.parsedWelcomeMessages.map((message, index) => (\n <div key={`welcome-${index}`} class=\"flex justify-start\">\n <div class=\"bg-gray-200 text-gray-800 max-w-xs lg:max-w-md px-4 py-2 rounded-lg\">\n <div\n class=\"chat-markdown\"\n innerHTML={renderMarkdownComplete(message)}\n ></div>\n </div>\n </div>\n ))}\n </div>\n )}\n {/* Regular Chat Messages */}\n {this.messages.map((message, index) => (\n <div\n key={index}\n class={{\n 'flex': true,\n 'justify-end': message.role === 'user',\n 'justify-start': message.role !== 'user'\n }}\n >\n <div\n class={{\n 'max-w-xs lg:max-w-md px-4 py-2 rounded-lg': true,\n 'bg-blue-500 text-white': message.role === 'user',\n 'bg-gray-200 text-gray-800': message.role === 'assistant',\n 'bg-gray-100 text-gray-600 text-sm': message.role === 'system'\n }}\n >\n <div\n class=\"chat-markdown\"\n innerHTML={renderMarkdownComplete(message.content)}\n ></div>\n {message.attachments && message.attachments.length > 0 && (\n <div class=\"mt-2 space-y-1\">\n {message.attachments.map((attachment, attachmentIndex) => (\n <a\n key={attachmentIndex}\n href={attachment.content_url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"block text-sm underline hover:no-underline\"\n >\n 📎 {attachment.name}\n </a>\n ))}\n </div>\n )}\n <div class=\"text-xs opacity-70 mt-1\">\n {this.formatTime(message.created_at)}\n </div>\n </div>\n </div>\n ))}\n {/* Typing Indicator */}\n {this.isTyping && (\n <div class=\"flex justify-start\">\n <div class=\"bg-gray-200 text-gray-800 max-w-xs lg:max-w-md px-2 py-2 rounded-lg\">\n <div class=\"flex items-center gap-0.5\">\n <span class=\"inline-block w-2 h-2 rounded-full bg-gray-400 animate-bounce\"></span>\n <span class=\"inline-block w-2 h-2 rounded-full bg-gray-400 animate-bounce\" style={{animationDelay: '0.1s'}}></span>\n <span class=\"inline-block w-2 h-2 rounded-full bg-gray-400 animate-bounce\" style={{animationDelay: '0.2s'}}></span>\n </div>\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Starter Questions */}\n {this.sessionId && this.showStarterQuestions && this.messages.length === 0 && !this.isTyping && (\n <div class=\"p-4 space-y-2\">\n {this.parsedStarterQuestions.map((question, index) => (\n <div key={`starter-${index}`} class=\"flex justify-end\">\n <button\n class=\"starter-question\"\n onClick={() => this.handleStarterQuestionClick(question)}\n >\n {question}\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Input Area */}\n {this.sessionId && (\n <div class=\"border-t border-gray-200 p-4\">\n <div class=\"flex gap-2\">\n <textarea\n ref={(el) => this.textareaRef = el}\n class=\"flex-grow px-3 py-2 border border-gray-300 rounded-md resize-none focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent\"\n rows={1}\n placeholder=\"Type your message...\"\n value={this.messageInput}\n onInput={(e) => this.handleInputChange(e)}\n onKeyPress={(e) => this.handleKeyPress(e)}\n disabled={this.isTyping}\n ></textarea>\n <button\n class={{\n 'px-4 py-2 rounded-md font-medium transition-colors duration-200': true,\n 'bg-blue-500 hover:bg-blue-600 text-white': !this.isTyping && !!this.messageInput.trim(),\n 'bg-gray-300 text-gray-500 cursor-not-allowed': this.isTyping || !this.messageInput.trim()\n }}\n onClick={() => this.sendMessage(this.messageInput)}\n disabled={this.isTyping || !this.messageInput.trim()}\n >\n Send\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n </Host>\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { marked } from "marked";
|
|
2
|
+
import DOMPurify from "dompurify";
|
|
3
|
+
marked.setOptions({
|
|
4
|
+
breaks: true,
|
|
5
|
+
gfm: true,
|
|
6
|
+
smartypants: true,
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* Post-processes rendered HTML to add additional attributes
|
|
10
|
+
* This is called after DOMPurify to ensure external links open in new tabs
|
|
11
|
+
*/
|
|
12
|
+
export function postProcessMarkdownHTML(html) {
|
|
13
|
+
if (typeof window === 'undefined') {
|
|
14
|
+
return html;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const tempDiv = document.createElement('div');
|
|
18
|
+
tempDiv.innerHTML = html;
|
|
19
|
+
// Add target="_blank" and rel="noopener noreferrer" to external links
|
|
20
|
+
const links = tempDiv.querySelectorAll('a[href]');
|
|
21
|
+
links.forEach((link) => {
|
|
22
|
+
const href = link.getAttribute('href');
|
|
23
|
+
if (href && (href.startsWith('http://') || href.startsWith('https://'))) {
|
|
24
|
+
link.setAttribute('target', '_blank');
|
|
25
|
+
link.setAttribute('rel', 'noopener noreferrer');
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return tempDiv.innerHTML;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('Error post-processing markdown HTML:', error);
|
|
32
|
+
return html;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function renderMarkdownSync(content) {
|
|
36
|
+
if (!content || typeof content !== 'string') {
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const html = marked.parse(content);
|
|
41
|
+
const sanitized = DOMPurify.sanitize(html, {
|
|
42
|
+
ALLOWED_TAGS: [
|
|
43
|
+
'p', 'br', 'strong', 'b', 'em', 'i', 'u', 'code', 'pre',
|
|
44
|
+
'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
|
45
|
+
'blockquote', 'a', 'img', 'hr', 'table', 'thead', 'tbody',
|
|
46
|
+
'tr', 'td', 'th', 'del', 'ins', 'sub', 'sup'
|
|
47
|
+
],
|
|
48
|
+
ALLOWED_ATTR: [
|
|
49
|
+
'href', 'target', 'rel', 'class', 'src', 'alt', 'title',
|
|
50
|
+
'width', 'height', 'align', 'colspan', 'rowspan'
|
|
51
|
+
],
|
|
52
|
+
ALLOWED_URI_REGEXP: /^(?:(?:https?):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
|
|
53
|
+
ADD_ATTR: ['target'],
|
|
54
|
+
FORBID_TAGS: ['script', 'style', 'form', 'input', 'button'],
|
|
55
|
+
FORBID_ATTR: ['onclick', 'onload', 'onerror', 'onmouseover'],
|
|
56
|
+
});
|
|
57
|
+
return postProcessMarkdownHTML(sanitized);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('Error rendering markdown sync:', error);
|
|
61
|
+
return DOMPurify.sanitize(content);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"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","sourcesContent":["import { marked } from 'marked';\nimport DOMPurify from 'dompurify';\n\nmarked.setOptions({\n breaks: true,\n gfm: true,\n smartypants: true,\n});\n\n/**\n * Post-processes rendered HTML to add additional attributes\n * This is called after DOMPurify to ensure external links open in new tabs\n */\nexport function postProcessMarkdownHTML(html: string): string {\n if (typeof window === 'undefined') {\n return html;\n }\n\n try {\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = html;\n\n // Add target=\"_blank\" and rel=\"noopener noreferrer\" to external links\n const links = tempDiv.querySelectorAll('a[href]');\n links.forEach((link) => {\n const href = link.getAttribute('href');\n if (href && (href.startsWith('http://') || href.startsWith('https://'))) {\n link.setAttribute('target', '_blank');\n link.setAttribute('rel', 'noopener noreferrer');\n }\n });\n\n return tempDiv.innerHTML;\n } catch (error) {\n console.error('Error post-processing markdown HTML:', error);\n return html;\n }\n}\n\n\nexport function renderMarkdownSync(content: string): string {\n if (!content || typeof content !== 'string') {\n return '';\n }\n\n try {\n const html = marked.parse(content);\n const sanitized = DOMPurify.sanitize(html, {\n ALLOWED_TAGS: [\n 'p', 'br', 'strong', 'b', 'em', 'i', 'u', 'code', 'pre',\n 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'blockquote', 'a', 'img', 'hr', 'table', 'thead', 'tbody',\n 'tr', 'td', 'th', 'del', 'ins', 'sub', 'sup'\n ],\n ALLOWED_ATTR: [\n 'href', 'target', 'rel', 'class', 'src', 'alt', 'title',\n 'width', 'height', 'align', 'colspan', 'rowspan'\n ],\n ALLOWED_URI_REGEXP: /^(?:(?:https?):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\n ADD_ATTR: ['target'],\n FORBID_TAGS: ['script', 'style', 'form', 'input', 'button'],\n FORBID_ATTR: ['onclick', 'onload', 'onerror', 'onmouseover'],\n });\n\n return postProcessMarkdownHTML(sanitized);\n } catch (error) {\n console.error('Error rendering markdown sync:', error);\n return DOMPurify.sanitize(content);\n }\n}\n"]}
|