open-chat-studio-widget 0.4.0 → 0.4.2

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.
Files changed (26) hide show
  1. package/README.md +76 -10
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/open-chat-studio-widget.cjs.entry.js +124 -64
  4. package/dist/cjs/open-chat-studio-widget.cjs.entry.js.map +1 -1
  5. package/dist/cjs/open-chat-studio-widget.cjs.js +1 -1
  6. package/dist/collection/components/ocs-chat/heroicons.js +6 -6
  7. package/dist/collection/components/ocs-chat/heroicons.js.map +1 -1
  8. package/dist/collection/components/ocs-chat/ocs-chat.css +558 -374
  9. package/dist/collection/components/ocs-chat/ocs-chat.js +174 -73
  10. package/dist/collection/components/ocs-chat/ocs-chat.js.map +1 -1
  11. package/dist/components/open-chat-studio-widget.js +131 -66
  12. package/dist/components/open-chat-studio-widget.js.map +1 -1
  13. package/dist/esm/loader.js +1 -1
  14. package/dist/esm/open-chat-studio-widget.entry.js +124 -64
  15. package/dist/esm/open-chat-studio-widget.entry.js.map +1 -1
  16. package/dist/esm/open-chat-studio-widget.js +1 -1
  17. package/dist/open-chat-studio-widget/open-chat-studio-widget.esm.js +1 -1
  18. package/dist/open-chat-studio-widget/open-chat-studio-widget.esm.js.map +1 -1
  19. package/dist/open-chat-studio-widget/p-d47dbd2f.entry.js +3 -0
  20. package/dist/open-chat-studio-widget/p-d47dbd2f.entry.js.map +1 -0
  21. package/dist/types/components/ocs-chat/heroicons.d.ts +2 -2
  22. package/dist/types/components/ocs-chat/ocs-chat.d.ts +26 -6
  23. package/dist/types/components.d.ts +24 -8
  24. package/package.json +3 -2
  25. package/dist/open-chat-studio-widget/p-d2d76b54.entry.js +0 -3
  26. package/dist/open-chat-studio-widget/p-d2d76b54.entry.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { Host, h } from "@stencil/core";
2
- import { XMarkIcon, ChevronDownIcon, ChevronUpIcon, GripDotsVerticalIcon, PencilSquare, } from "./heroicons";
2
+ import { XMarkIcon, GripDotsVerticalIcon, PencilSquare, ArrowsPointingOutIcon, ArrowsPointingInIcon, } from "./heroicons";
3
3
  import { renderMarkdownSync as renderMarkdownComplete } from "../../utils/markdown";
4
4
  export class OcsChat {
5
5
  constructor() {
@@ -19,10 +19,6 @@ export class OcsChat {
19
19
  * The initial position of the chat widget on the screen.
20
20
  */
21
21
  this.position = 'right';
22
- /**
23
- * Whether the chat widget is initially expanded.
24
- */
25
- this.expanded = false;
26
22
  /**
27
23
  * Whether to persist session data to local storage to allow resuming previous conversations after page reload.
28
24
  */
@@ -32,6 +28,10 @@ export class OcsChat {
32
28
  * `0` to never expire.
33
29
  */
34
30
  this.persistentSessionExpire = 60 * 24;
31
+ /**
32
+ * Allow the user to make the chat window full screen.
33
+ */
34
+ this.allowFullScreen = true;
35
35
  this.loaded = false;
36
36
  this.error = "";
37
37
  this.messages = [];
@@ -42,11 +42,13 @@ export class OcsChat {
42
42
  this.isDragging = false;
43
43
  this.dragOffset = { x: 0, y: 0 };
44
44
  this.windowPosition = { x: 0, y: 0 };
45
+ this.fullscreenPosition = { x: 0 };
45
46
  this.showStarterQuestions = true;
46
47
  this.parsedWelcomeMessages = [];
47
48
  this.parsedStarterQuestions = [];
49
+ this.isFullscreen = false;
48
50
  this.handleMouseDown = (event) => {
49
- if (window.innerWidth < OcsChat.MOBILE_BREAKPOINT)
51
+ if (!this.isFullscreen && window.innerWidth < OcsChat.MOBILE_BREAKPOINT)
50
52
  return;
51
53
  if (event.target.closest('button'))
52
54
  return;
@@ -164,18 +166,24 @@ export class OcsChat {
164
166
  try {
165
167
  this.isLoading = true;
166
168
  this.error = '';
169
+ const userId = this.getOrGenerateUserId();
170
+ const requestBody = {
171
+ chatbot_id: this.chatbotId,
172
+ session_data: {
173
+ source: 'widget',
174
+ page_url: window.location.href
175
+ },
176
+ participant_remote_id: userId
177
+ };
178
+ if (this.userName) {
179
+ requestBody.participant_name = this.userName;
180
+ }
167
181
  const response = await fetch(`${this.getApiBaseUrl()}/api/chat/start/`, {
168
182
  method: 'POST',
169
183
  headers: {
170
184
  'Content-Type': 'application/json',
171
185
  },
172
- body: JSON.stringify({
173
- chatbot_id: this.chatbotId,
174
- session_data: {
175
- source: 'widget',
176
- page_url: window.location.href
177
- }
178
- })
186
+ body: JSON.stringify(requestBody)
179
187
  });
180
188
  if (!response.ok) {
181
189
  throw new Error(`Failed to start session: ${response.statusText}`);
@@ -398,13 +406,31 @@ export class OcsChat {
398
406
  return;
399
407
  this.position = position;
400
408
  }
401
- toggleSize() {
402
- this.expanded = !this.expanded;
403
- }
404
409
  getPositionClasses() {
405
- 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`;
410
+ if (this.isFullscreen) {
411
+ return 'chat-window-fullscreen';
412
+ }
413
+ const baseClasses = 'chat-window-normal';
414
+ const draggingClass = this.isDragging ? ' chat-window-dragging' : '';
415
+ return baseClasses + draggingClass;
416
+ }
417
+ getFullscreenBounds() {
418
+ const windowWidth = window.innerWidth;
419
+ const actualChatWidth = Math.min(windowWidth, OcsChat.CHAT_MAX_WIDTH);
420
+ const centeredX = (windowWidth - actualChatWidth) / 2;
421
+ const maxOffset = (windowWidth - actualChatWidth) / 2;
422
+ return { windowWidth, actualChatWidth, centeredX, maxOffset };
406
423
  }
407
424
  getPositionStyles() {
425
+ if (this.isFullscreen) {
426
+ const { centeredX } = this.getFullscreenBounds();
427
+ const finalX = centeredX + this.fullscreenPosition.x;
428
+ return {
429
+ left: `${finalX}px`,
430
+ top: '0px',
431
+ transform: 'none',
432
+ };
433
+ }
408
434
  return {
409
435
  left: `${this.windowPosition.x}px`,
410
436
  top: `${this.windowPosition.y}px`,
@@ -414,9 +440,7 @@ export class OcsChat {
414
440
  const windowWidth = window.innerWidth;
415
441
  const windowHeight = window.innerHeight;
416
442
  const chatWidth = windowWidth < OcsChat.MOBILE_BREAKPOINT ? windowWidth : OcsChat.CHAT_WIDTH_DESKTOP;
417
- const chatHeight = this.expanded
418
- ? (windowHeight * OcsChat.CHAT_HEIGHT_EXPANDED_RATIO)
419
- : (windowHeight * OcsChat.CHAT_HEIGHT_COLLAPSED_RATIO);
443
+ const chatHeight = windowHeight * OcsChat.CHAT_HEIGHT_EXPANDED_RATIO;
420
444
  const isMobile = windowWidth < OcsChat.MOBILE_BREAKPOINT;
421
445
  if (isMobile) {
422
446
  this.windowPosition = { x: 0, y: 0 };
@@ -457,28 +481,45 @@ export class OcsChat {
457
481
  if (!this.chatWindowRef)
458
482
  return;
459
483
  this.isDragging = true;
460
- const rect = this.chatWindowRef.getBoundingClientRect();
461
- this.dragOffset = {
462
- x: pointer.clientX - rect.left,
463
- y: pointer.clientY - rect.top
464
- };
484
+ if (this.isFullscreen) {
485
+ // For fullscreen, track relative to current position
486
+ this.dragOffset = {
487
+ x: pointer.clientX,
488
+ y: pointer.clientY
489
+ };
490
+ }
491
+ else {
492
+ const rect = this.chatWindowRef.getBoundingClientRect();
493
+ this.dragOffset = {
494
+ x: pointer.clientX - rect.left,
495
+ y: pointer.clientY - rect.top
496
+ };
497
+ }
465
498
  }
466
499
  updateDragPosition(pointer) {
467
500
  if (!this.isDragging)
468
501
  return;
469
- const newX = pointer.clientX - this.dragOffset.x;
470
- const newY = pointer.clientY - this.dragOffset.y;
471
- // Constrain chatbox to window
472
- const windowWidth = window.innerWidth;
473
- const windowHeight = window.innerHeight;
474
- const chatWidth = windowWidth < OcsChat.MOBILE_BREAKPOINT ? windowWidth : OcsChat.CHAT_WIDTH_DESKTOP;
475
- const chatHeight = this.expanded
476
- ? (windowHeight * OcsChat.CHAT_HEIGHT_EXPANDED_RATIO)
477
- : (windowHeight * OcsChat.CHAT_HEIGHT_COLLAPSED_RATIO);
478
- this.windowPosition = {
479
- x: Math.max(0, Math.min(newX, windowWidth - chatWidth)),
480
- y: Math.max(0, Math.min(newY, windowHeight - chatHeight))
481
- };
502
+ if (this.isFullscreen) {
503
+ // In fullscreen, only allow horizontal dragging
504
+ const { maxOffset } = this.getFullscreenBounds();
505
+ const deltaX = pointer.clientX - this.dragOffset.x;
506
+ this.fullscreenPosition = {
507
+ x: Math.max(-maxOffset, Math.min(maxOffset, deltaX))
508
+ };
509
+ }
510
+ else {
511
+ const newX = pointer.clientX - this.dragOffset.x;
512
+ const newY = pointer.clientY - this.dragOffset.y;
513
+ // Constrain chatbox to window
514
+ const windowWidth = window.innerWidth;
515
+ const windowHeight = window.innerHeight;
516
+ const chatWidth = windowWidth < OcsChat.MOBILE_BREAKPOINT ? windowWidth : OcsChat.CHAT_WIDTH_DESKTOP;
517
+ const chatHeight = windowHeight * OcsChat.CHAT_HEIGHT_EXPANDED_RATIO;
518
+ this.windowPosition = {
519
+ x: Math.max(0, Math.min(newX, windowWidth - chatWidth)),
520
+ y: Math.max(0, Math.min(newY, windowHeight - chatHeight))
521
+ };
522
+ }
482
523
  }
483
524
  endDrag() {
484
525
  this.isDragging = false;
@@ -576,6 +617,27 @@ export class OcsChat {
576
617
  return { messages: [] };
577
618
  }
578
619
  }
620
+ getOrGenerateUserId() {
621
+ if (this.userId) {
622
+ return this.userId;
623
+ }
624
+ if (this.generatedUserId) {
625
+ return this.generatedUserId;
626
+ }
627
+ const storageKey = `ocs-user-id`;
628
+ const stored = localStorage.getItem(storageKey);
629
+ if (stored) {
630
+ this.generatedUserId = stored;
631
+ return stored;
632
+ }
633
+ const array = new Uint8Array(9);
634
+ window.crypto.getRandomValues(array);
635
+ const randomString = Array.from(array, byte => byte.toString(36)).join('').substr(0, 9);
636
+ const newUserId = `ocs:${Date.now()}_${randomString}`;
637
+ this.generatedUserId = newUserId;
638
+ localStorage.setItem(storageKey, newUserId);
639
+ return newUserId;
640
+ }
579
641
  clearSessionStorage() {
580
642
  const keys = this.getStorageKeys();
581
643
  try {
@@ -607,24 +669,22 @@ export class OcsChat {
607
669
  this.cleanup();
608
670
  await this.startSession();
609
671
  }
672
+ toggleFullscreen() {
673
+ this.isFullscreen = !this.isFullscreen;
674
+ // Reset fullscreen position when toggling
675
+ this.fullscreenPosition = { x: 0 };
676
+ }
610
677
  render() {
611
678
  if (this.error) {
612
- return (h(Host, null, h("p", { class: "text-red-500 p-2" }, this.error)));
613
- }
614
- return (h(Host, null, this.renderButton(), this.visible && (h("div", { ref: (el) => this.chatWindowRef = el, id: "ocs-chat-window", class: this.getPositionClasses(), style: this.getPositionStyles() }, h("div", { 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`, onMouseDown: this.handleMouseDown, onTouchStart: this.handleTouchStart }, h("div", { class: "hidden sm:flex gap-1" }, h("div", { class: "flex gap-0.5 ml-2 pointer-events-none" }, h(GripDotsVerticalIcon, null))), h("div", null), h("div", { class: "flex gap-1 items-center" }, this.sessionId && this.messages.length > 0 && (h("button", { class: "p-1.5 rounded-md transition-colors duration-200 hover:bg-gray-100 text-gray-500", onClick: () => this.startNewChat(), title: "Start new chat", "aria-label": "Start new chat" }, h(PencilSquare, null))), h("button", { class: "p-1.5 rounded-md transition-colors duration-200 hover:bg-gray-100 text-gray-500", onClick: () => this.toggleSize(), "aria-label": this.expanded ? "Collapse" : "Expand", title: this.expanded ? "Collapse" : "Expand" }, this.expanded ? h(ChevronDownIcon, null) : h(ChevronUpIcon, null)), h("button", { class: "p-1.5 hover:bg-gray-100 rounded-md transition-colors duration-200 text-gray-500", onClick: () => this.visible = false, "aria-label": "Close" }, h(XMarkIcon, null)))), h("div", { class: "flex flex-col flex-grow overflow-hidden" }, this.isLoading && !this.sessionId && (h("div", { class: "flex items-center justify-center flex-grow" }, h("div", { class: "loading-spinner" }), h("span", { class: "ml-2 text-gray-500" }, "Starting chat..."))), this.sessionId && (h("div", { ref: (el) => this.messageListRef = el, class: "flex-grow overflow-y-auto p-4 space-y-4" }, this.messages.length === 0 && !this.isTyping && this.parsedWelcomeMessages.length > 0 && (h("div", { class: "space-y-4" }, this.parsedWelcomeMessages.map((message, index) => (h("div", { key: `welcome-${index}`, class: "flex justify-start" }, h("div", { class: "bg-gray-200 text-gray-800 max-w-xs lg:max-w-md px-4 py-2 rounded-lg" }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message) }))))))), this.messages.map((message, index) => (h("div", { key: index, class: {
615
- 'flex': true,
616
- 'justify-end': message.role === 'user',
617
- 'justify-start': message.role !== 'user'
618
- } }, h("div", { class: {
619
- 'max-w-xs lg:max-w-md px-4 py-2 rounded-lg': true,
620
- 'bg-blue-500 text-white': message.role === 'user',
621
- 'bg-gray-200 text-gray-800': message.role === 'assistant',
622
- 'bg-gray-100 text-gray-600 text-sm': message.role === 'system'
623
- } }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message.content) }), message.attachments && message.attachments.length > 0 && (h("div", { class: "mt-2 space-y-1" }, message.attachments.map((attachment, attachmentIndex) => (h("a", { key: attachmentIndex, href: attachment.content_url, target: "_blank", rel: "noopener noreferrer", class: "block text-sm underline hover:no-underline" }, "\uD83D\uDCCE ", attachment.name))))), h("div", { class: "text-xs opacity-70 mt-1" }, this.formatTime(message.created_at)))))), this.isTyping && (h("div", { class: "flex justify-start" }, h("div", { class: "bg-gray-200 text-gray-800 max-w-xs lg:max-w-md px-2 py-2 rounded-lg" }, h("div", { class: "flex items-center gap-0.5" }, h("span", { class: "inline-block w-2 h-2 rounded-full bg-gray-400 animate-bounce" }), h("span", { class: "inline-block w-2 h-2 rounded-full bg-gray-400 animate-bounce", style: { animationDelay: '0.1s' } }), h("span", { class: "inline-block w-2 h-2 rounded-full bg-gray-400 animate-bounce", style: { animationDelay: '0.2s' } }))))))), this.sessionId && this.showStarterQuestions && this.messages.length === 0 && !this.isTyping && (h("div", { class: "p-4 space-y-2" }, this.parsedStarterQuestions.map((question, index) => (h("div", { key: `starter-${index}`, class: "flex justify-end" }, h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.sessionId && (h("div", { class: "border-t border-gray-200 p-4" }, h("div", { class: "flex gap-2" }, h("textarea", { ref: (el) => this.textareaRef = el, 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", rows: 1, placeholder: "Type your message...", value: this.messageInput, onInput: (e) => this.handleInputChange(e), onKeyPress: (e) => this.handleKeyPress(e), disabled: this.isTyping }), h("button", { class: {
624
- 'px-4 py-2 rounded-md font-medium transition-colors duration-200': true,
625
- 'bg-blue-500 hover:bg-blue-600 text-white': !this.isTyping && !!this.messageInput.trim(),
626
- 'bg-gray-300 text-gray-500 cursor-not-allowed': this.isTyping || !this.messageInput.trim()
627
- }, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || !this.messageInput.trim() }, "Send")))))))));
679
+ return (h(Host, null, h("p", { class: "error-message" }, this.error)));
680
+ }
681
+ return (h(Host, null, this.renderButton(), this.visible && (h("div", { ref: (el) => this.chatWindowRef = el, id: "ocs-chat-window", class: this.getPositionClasses(), style: this.getPositionStyles() }, h("div", { class: `chat-header ${this.isDragging ? 'chat-header-dragging' : 'chat-header-draggable'}`, onMouseDown: this.handleMouseDown, onTouchStart: this.handleTouchStart }, h("div", { class: "drag-indicator" }, h("div", { class: "drag-dots" }, h(GripDotsVerticalIcon, null))), h("div", { class: "drag-spacer" }), h("div", { class: "header-buttons" }, this.allowFullScreen && h("button", { class: "header-button fullscreen-button", onClick: () => this.toggleFullscreen(), title: this.isFullscreen ? "Exit fullscreen" : "Enter fullscreen", "aria-label": this.isFullscreen ? "Exit fullscreen" : "Enter fullscreen" }, this.isFullscreen ? h(ArrowsPointingInIcon, null) : h(ArrowsPointingOutIcon, null)), this.sessionId && this.messages.length > 0 && (h("button", { class: "header-button", onClick: () => this.startNewChat(), title: "Start new chat", "aria-label": "Start new chat" }, h(PencilSquare, null))), h("button", { class: "header-button", onClick: () => this.visible = false, "aria-label": "Close" }, h(XMarkIcon, null)))), h("div", { class: "chat-content" }, this.isLoading && !this.sessionId && (h("div", { class: "loading-container" }, h("div", { class: "loading-spinner" }), h("span", { class: "loading-text" }, "Starting chat..."))), this.sessionId && (h("div", { ref: (el) => this.messageListRef = el, class: "messages-container" }, this.messages.length === 0 && !this.isTyping && this.parsedWelcomeMessages.length > 0 && (h("div", { class: "welcome-messages" }, this.parsedWelcomeMessages.map((message, index) => (h("div", { key: `welcome-${index}`, class: "message-row message-row-assistant" }, h("div", { class: "message-bubble message-bubble-assistant" }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message) }))))))), this.messages.map((message, index) => (h("div", { key: index, class: `message-row ${message.role === 'user' ? 'message-row-user' : 'message-row-assistant'}` }, h("div", { class: `message-bubble ${message.role === 'user'
682
+ ? 'message-bubble-user'
683
+ : message.role === 'assistant'
684
+ ? 'message-bubble-assistant'
685
+ : 'message-bubble-system'}` }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message.content) }), message.attachments && message.attachments.length > 0 && (h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (h("a", { key: attachmentIndex, href: attachment.content_url, target: "_blank", rel: "noopener noreferrer", class: "attachment-link" }, "\uD83D\uDCCE ", attachment.name))))), h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (h("div", null, h("div", { class: "typing-indicator" }, h("div", { class: "typing-progress" })), h("div", { class: "typing-text" }, h("span", null, "Preparing response"), h("span", { class: "typing-dots" })))))), this.sessionId && this.showStarterQuestions && this.messages.length === 0 && !this.isTyping && (h("div", { class: "starter-questions" }, this.parsedStarterQuestions.map((question, index) => (h("div", { key: `starter-${index}`, class: "starter-question-row" }, h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.sessionId && (h("div", { class: "input-area" }, h("div", { class: "input-container" }, h("textarea", { ref: (el) => this.textareaRef = el, class: "message-textarea", rows: 1, placeholder: "Type your message...", value: this.messageInput, onInput: (e) => this.handleInputChange(e), onKeyPress: (e) => this.handleKeyPress(e), disabled: this.isTyping }), h("button", { class: `send-button ${!this.isTyping && !!this.messageInput.trim()
686
+ ? 'send-button-enabled'
687
+ : 'send-button-disabled'}`, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || !this.messageInput.trim() }, "Send")))))))));
628
688
  }
629
689
  static get is() { return "open-chat-studio-widget"; }
630
690
  static get encapsulation() { return "shadow"; }
@@ -777,27 +837,26 @@ export class OcsChat {
777
837
  "reflect": false,
778
838
  "defaultValue": "'right'"
779
839
  },
780
- "expanded": {
781
- "type": "boolean",
782
- "mutable": true,
840
+ "welcomeMessages": {
841
+ "type": "string",
842
+ "mutable": false,
783
843
  "complexType": {
784
- "original": "boolean",
785
- "resolved": "boolean",
844
+ "original": "string",
845
+ "resolved": "string",
786
846
  "references": {}
787
847
  },
788
848
  "required": false,
789
- "optional": false,
849
+ "optional": true,
790
850
  "docs": {
791
851
  "tags": [],
792
- "text": "Whether the chat widget is initially expanded."
852
+ "text": "Welcome messages to display above starter questions (JSON array of strings)"
793
853
  },
794
854
  "getter": false,
795
855
  "setter": false,
796
- "attribute": "expanded",
797
- "reflect": false,
798
- "defaultValue": "false"
856
+ "attribute": "welcome-messages",
857
+ "reflect": false
799
858
  },
800
- "welcomeMessages": {
859
+ "starterQuestions": {
801
860
  "type": "string",
802
861
  "mutable": false,
803
862
  "complexType": {
@@ -809,14 +868,14 @@ export class OcsChat {
809
868
  "optional": true,
810
869
  "docs": {
811
870
  "tags": [],
812
- "text": "Welcome messages to display above starter questions (JSON array of strings)"
871
+ "text": "Array of starter questions that users can click to send (JSON array of strings)"
813
872
  },
814
873
  "getter": false,
815
874
  "setter": false,
816
- "attribute": "welcome-messages",
875
+ "attribute": "starter-questions",
817
876
  "reflect": false
818
877
  },
819
- "starterQuestions": {
878
+ "userId": {
820
879
  "type": "string",
821
880
  "mutable": false,
822
881
  "complexType": {
@@ -828,11 +887,30 @@ export class OcsChat {
828
887
  "optional": true,
829
888
  "docs": {
830
889
  "tags": [],
831
- "text": "Array of starter questions that users can click to send (JSON array of strings)"
890
+ "text": "Used to associate chat sessions with a specific user across multiple visits/sessions"
832
891
  },
833
892
  "getter": false,
834
893
  "setter": false,
835
- "attribute": "starter-questions",
894
+ "attribute": "user-id",
895
+ "reflect": false
896
+ },
897
+ "userName": {
898
+ "type": "string",
899
+ "mutable": false,
900
+ "complexType": {
901
+ "original": "string",
902
+ "resolved": "string",
903
+ "references": {}
904
+ },
905
+ "required": false,
906
+ "optional": true,
907
+ "docs": {
908
+ "tags": [],
909
+ "text": "Display name for the user."
910
+ },
911
+ "getter": false,
912
+ "setter": false,
913
+ "attribute": "user-name",
836
914
  "reflect": false
837
915
  },
838
916
  "persistentSession": {
@@ -874,6 +952,26 @@ export class OcsChat {
874
952
  "attribute": "persistent-session-expire",
875
953
  "reflect": false,
876
954
  "defaultValue": "60 * 24"
955
+ },
956
+ "allowFullScreen": {
957
+ "type": "boolean",
958
+ "mutable": false,
959
+ "complexType": {
960
+ "original": "boolean",
961
+ "resolved": "boolean",
962
+ "references": {}
963
+ },
964
+ "required": false,
965
+ "optional": false,
966
+ "docs": {
967
+ "tags": [],
968
+ "text": "Allow the user to make the chat window full screen."
969
+ },
970
+ "getter": false,
971
+ "setter": false,
972
+ "attribute": "allow-full-screen",
973
+ "reflect": false,
974
+ "defaultValue": "true"
877
975
  }
878
976
  };
879
977
  }
@@ -892,9 +990,12 @@ export class OcsChat {
892
990
  "isDragging": {},
893
991
  "dragOffset": {},
894
992
  "windowPosition": {},
993
+ "fullscreenPosition": {},
895
994
  "showStarterQuestions": {},
896
995
  "parsedWelcomeMessages": {},
897
- "parsedStarterQuestions": {}
996
+ "parsedStarterQuestions": {},
997
+ "generatedUserId": {},
998
+ "isFullscreen": {}
898
999
  };
899
1000
  }
900
1001
  }
@@ -904,8 +1005,8 @@ OcsChat.MESSAGE_POLLING_INTERVAL_MS = 30000;
904
1005
  OcsChat.SCROLL_DELAY_MS = 100;
905
1006
  OcsChat.FOCUS_DELAY_MS = 100;
906
1007
  OcsChat.CHAT_WIDTH_DESKTOP = 450;
907
- OcsChat.CHAT_HEIGHT_EXPANDED_RATIO = 0.83; // 83% of window height
908
- OcsChat.CHAT_HEIGHT_COLLAPSED_RATIO = 0.6; // 60% of window height
1008
+ OcsChat.CHAT_MAX_WIDTH = 1024;
1009
+ OcsChat.CHAT_HEIGHT_EXPANDED_RATIO = 0.83; // 83% of window height (h-5/6)
909
1010
  OcsChat.MOBILE_BREAKPOINT = 640;
910
1011
  OcsChat.WINDOW_MARGIN = 20;
911
1012
  OcsChat.LOCALSTORAGE_TEST_KEY = '__ocs_test__';