@botonic/react 0.31.0-alpha.2 → 0.31.0-alpha.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.
Files changed (161) hide show
  1. package/lib/cjs/components/element.js +6 -6
  2. package/lib/cjs/components/element.js.map +1 -1
  3. package/lib/cjs/components/index-types.d.ts +2 -0
  4. package/lib/cjs/components/multichannel/multichannel-button.js +2 -2
  5. package/lib/cjs/components/multichannel/multichannel-button.js.map +1 -1
  6. package/lib/cjs/components/multichannel/multichannel-carousel.js +4 -4
  7. package/lib/cjs/components/multichannel/multichannel-carousel.js.map +1 -1
  8. package/lib/cjs/components/multichannel/multichannel-text.js +12 -11
  9. package/lib/cjs/components/multichannel/multichannel-text.js.map +1 -1
  10. package/lib/cjs/components/multichannel/multichannel-utils.d.ts +9 -15
  11. package/lib/cjs/components/multichannel/multichannel-utils.js +48 -27
  12. package/lib/cjs/components/multichannel/multichannel-utils.js.map +1 -1
  13. package/lib/cjs/components/multichannel/multichannel.js +7 -7
  14. package/lib/cjs/components/multichannel/multichannel.js.map +1 -1
  15. package/lib/cjs/components/multichannel/whatsapp/constants.d.ts +11 -0
  16. package/lib/cjs/components/multichannel/whatsapp/constants.js +13 -0
  17. package/lib/cjs/components/multichannel/whatsapp/constants.js.map +1 -0
  18. package/lib/cjs/components/whatsapp-button-list.js +2 -2
  19. package/lib/cjs/components/whatsapp-button-list.js.map +1 -1
  20. package/lib/cjs/components/whatsapp-cta-url-button.js +5 -5
  21. package/lib/cjs/components/whatsapp-cta-url-button.js.map +1 -1
  22. package/lib/cjs/constants.d.ts +0 -6
  23. package/lib/cjs/constants.js +1 -7
  24. package/lib/cjs/constants.js.map +1 -1
  25. package/lib/cjs/contexts.js +6 -0
  26. package/lib/cjs/contexts.js.map +1 -1
  27. package/lib/cjs/dev-app.d.ts +7 -0
  28. package/lib/cjs/index-types.d.ts +4 -7
  29. package/lib/cjs/index-types.js.map +1 -1
  30. package/lib/cjs/index.d.ts +1 -1
  31. package/lib/cjs/index.js.map +1 -1
  32. package/lib/cjs/webchat/actions.d.ts +2 -1
  33. package/lib/cjs/webchat/actions.js +1 -0
  34. package/lib/cjs/webchat/actions.js.map +1 -1
  35. package/lib/cjs/webchat/cover-component/index.d.ts +6 -0
  36. package/lib/cjs/webchat/cover-component/index.js +21 -0
  37. package/lib/cjs/webchat/cover-component/index.js.map +1 -0
  38. package/lib/cjs/webchat/hooks/use-scroll-to-bottom.d.ts +6 -4
  39. package/lib/cjs/webchat/hooks/use-scroll-to-bottom.js.map +1 -1
  40. package/lib/cjs/webchat/hooks/use-webchat.d.ts +1 -0
  41. package/lib/cjs/webchat/hooks/use-webchat.js +8 -0
  42. package/lib/cjs/webchat/hooks/use-webchat.js.map +1 -1
  43. package/lib/cjs/webchat/index-types.d.ts +1 -0
  44. package/lib/cjs/webchat/input-panel/textarea.js +8 -2
  45. package/lib/cjs/webchat/input-panel/textarea.js.map +1 -1
  46. package/lib/cjs/webchat/message-list/index.js +63 -35
  47. package/lib/cjs/webchat/message-list/index.js.map +1 -1
  48. package/lib/cjs/webchat/message-list/styles.js +3 -3
  49. package/lib/cjs/webchat/typing-indicator/index.d.ts +3 -1
  50. package/lib/cjs/webchat/typing-indicator/index.js +4 -3
  51. package/lib/cjs/webchat/typing-indicator/index.js.map +1 -1
  52. package/lib/cjs/webchat/typing-indicator/styles.d.ts +3 -2
  53. package/lib/cjs/webchat/typing-indicator/styles.js +6 -3
  54. package/lib/cjs/webchat/typing-indicator/styles.js.map +1 -1
  55. package/lib/cjs/webchat/webchat-reducer.js +2 -0
  56. package/lib/cjs/webchat/webchat-reducer.js.map +1 -1
  57. package/lib/cjs/webchat/webchat-typed/styles.d.ts +7 -0
  58. package/lib/cjs/webchat/webchat-typed/styles.js +54 -0
  59. package/lib/cjs/webchat/webchat-typed/styles.js.map +1 -0
  60. package/lib/cjs/webchat/webchat-typed/webchat-typed.d.ts +0 -0
  61. package/lib/cjs/webchat/webchat-typed/webchat-typed.js +663 -0
  62. package/lib/cjs/webchat/webchat-typed/webchat-typed.js.map +1 -0
  63. package/lib/cjs/webchat/webchat.js +16 -18
  64. package/lib/cjs/webchat/webchat.js.map +1 -1
  65. package/lib/cjs/webchat-app.d.ts +119 -73
  66. package/lib/cjs/webchat-app.js +86 -48
  67. package/lib/cjs/webchat-app.js.map +1 -1
  68. package/lib/esm/components/element.js +6 -6
  69. package/lib/esm/components/element.js.map +1 -1
  70. package/lib/esm/components/index-types.d.ts +2 -0
  71. package/lib/esm/components/multichannel/multichannel-button.js +1 -1
  72. package/lib/esm/components/multichannel/multichannel-carousel.js +5 -5
  73. package/lib/esm/components/multichannel/multichannel-carousel.js.map +1 -1
  74. package/lib/esm/components/multichannel/multichannel-text.js +2 -1
  75. package/lib/esm/components/multichannel/multichannel-text.js.map +1 -1
  76. package/lib/esm/components/multichannel/multichannel-utils.d.ts +9 -15
  77. package/lib/esm/components/multichannel/multichannel-utils.js +40 -24
  78. package/lib/esm/components/multichannel/multichannel-utils.js.map +1 -1
  79. package/lib/esm/components/multichannel/multichannel.js +7 -7
  80. package/lib/esm/components/multichannel/multichannel.js.map +1 -1
  81. package/lib/esm/components/multichannel/whatsapp/constants.d.ts +11 -0
  82. package/lib/esm/components/multichannel/whatsapp/constants.js +10 -0
  83. package/lib/esm/components/multichannel/whatsapp/constants.js.map +1 -0
  84. package/lib/esm/components/whatsapp-button-list.js +1 -1
  85. package/lib/esm/components/whatsapp-cta-url-button.js +1 -1
  86. package/lib/esm/constants.d.ts +0 -6
  87. package/lib/esm/constants.js +0 -6
  88. package/lib/esm/constants.js.map +1 -1
  89. package/lib/esm/contexts.js +6 -0
  90. package/lib/esm/contexts.js.map +1 -1
  91. package/lib/esm/dev-app.d.ts +7 -0
  92. package/lib/esm/index-types.d.ts +4 -7
  93. package/lib/esm/index-types.js.map +1 -1
  94. package/lib/esm/index.d.ts +1 -1
  95. package/lib/esm/index.js.map +1 -1
  96. package/lib/esm/webchat/actions.d.ts +2 -1
  97. package/lib/esm/webchat/actions.js +1 -0
  98. package/lib/esm/webchat/actions.js.map +1 -1
  99. package/lib/esm/webchat/cover-component/index.d.ts +6 -0
  100. package/lib/esm/webchat/cover-component/index.js +17 -0
  101. package/lib/esm/webchat/cover-component/index.js.map +1 -0
  102. package/lib/esm/webchat/hooks/use-scroll-to-bottom.d.ts +6 -4
  103. package/lib/esm/webchat/hooks/use-scroll-to-bottom.js.map +1 -1
  104. package/lib/esm/webchat/hooks/use-webchat.d.ts +1 -0
  105. package/lib/esm/webchat/hooks/use-webchat.js +8 -0
  106. package/lib/esm/webchat/hooks/use-webchat.js.map +1 -1
  107. package/lib/esm/webchat/index-types.d.ts +1 -0
  108. package/lib/esm/webchat/input-panel/textarea.js +8 -2
  109. package/lib/esm/webchat/input-panel/textarea.js.map +1 -1
  110. package/lib/esm/webchat/message-list/index.js +62 -35
  111. package/lib/esm/webchat/message-list/index.js.map +1 -1
  112. package/lib/esm/webchat/message-list/styles.js +3 -3
  113. package/lib/esm/webchat/typing-indicator/index.d.ts +3 -1
  114. package/lib/esm/webchat/typing-indicator/index.js +5 -2
  115. package/lib/esm/webchat/typing-indicator/index.js.map +1 -1
  116. package/lib/esm/webchat/typing-indicator/styles.d.ts +3 -2
  117. package/lib/esm/webchat/typing-indicator/styles.js +5 -2
  118. package/lib/esm/webchat/typing-indicator/styles.js.map +1 -1
  119. package/lib/esm/webchat/webchat-reducer.js +2 -0
  120. package/lib/esm/webchat/webchat-reducer.js.map +1 -1
  121. package/lib/esm/webchat/webchat-typed/styles.d.ts +7 -0
  122. package/lib/esm/webchat/webchat-typed/styles.js +50 -0
  123. package/lib/esm/webchat/webchat-typed/styles.js.map +1 -0
  124. package/lib/esm/webchat/webchat-typed/webchat-typed.d.ts +0 -0
  125. package/lib/esm/webchat/webchat-typed/webchat-typed.js +663 -0
  126. package/lib/esm/webchat/webchat-typed/webchat-typed.js.map +1 -0
  127. package/lib/esm/webchat/webchat.js +16 -18
  128. package/lib/esm/webchat/webchat.js.map +1 -1
  129. package/lib/esm/webchat-app.d.ts +119 -73
  130. package/lib/esm/webchat-app.js +87 -49
  131. package/lib/esm/webchat-app.js.map +1 -1
  132. package/package.json +3 -2
  133. package/src/components/element.jsx +4 -11
  134. package/src/components/index-types.ts +4 -0
  135. package/src/components/multichannel/multichannel-button.jsx +1 -1
  136. package/src/components/multichannel/multichannel-carousel.jsx +7 -5
  137. package/src/components/multichannel/multichannel-text.jsx +4 -2
  138. package/src/components/multichannel/multichannel-utils.js +45 -27
  139. package/src/components/multichannel/multichannel.jsx +12 -7
  140. package/src/components/multichannel/whatsapp/constants.ts +10 -0
  141. package/src/components/whatsapp-button-list.tsx +1 -1
  142. package/src/components/whatsapp-cta-url-button.tsx +1 -1
  143. package/src/constants.js +0 -7
  144. package/src/contexts.tsx +6 -0
  145. package/src/index-types.ts +4 -7
  146. package/src/index.ts +1 -1
  147. package/src/webchat/actions.ts +1 -0
  148. package/src/webchat/cover-component/index.tsx +31 -0
  149. package/src/webchat/hooks/use-scroll-to-bottom.ts +8 -2
  150. package/src/webchat/hooks/use-webchat.ts +9 -0
  151. package/src/webchat/index-types.ts +1 -0
  152. package/src/webchat/input-panel/textarea.tsx +12 -1
  153. package/src/webchat/message-list/index.tsx +79 -48
  154. package/src/webchat/message-list/styles.ts +3 -3
  155. package/src/webchat/typing-indicator/index.tsx +20 -12
  156. package/src/webchat/typing-indicator/styles.ts +7 -3
  157. package/src/webchat/webchat-reducer.ts +2 -0
  158. package/src/webchat/webchat-typed/styles.ts +54 -0
  159. package/src/webchat/webchat-typed/webchat-typed.tsx +728 -0
  160. package/src/webchat/webchat.jsx +48 -48
  161. package/src/{webchat-app.jsx → webchat-app.tsx} +224 -71
@@ -44,6 +44,7 @@ import {
44
44
  import { ChatArea } from './chat-area'
45
45
  import { OpenedPersistentMenu } from './components/opened-persistent-menu'
46
46
  import { BotonicContainerId } from './constants'
47
+ import { CoverComponent } from './cover-component'
47
48
  import { WebchatHeader } from './header'
48
49
  import {
49
50
  useComponentWillMount,
@@ -120,6 +121,7 @@ export const Webchat = forwardRef((props, ref) => {
120
121
  resetUnreadMessages,
121
122
  setCurrentAttachment,
122
123
  setError,
124
+ setIsInputFocused,
123
125
  setLastMessageVisible,
124
126
  setOnline,
125
127
  toggleCoverComponent,
@@ -203,7 +205,7 @@ export const Webchat = forwardRef((props, ref) => {
203
205
  const sendUserInput = async input => {
204
206
  if (props.onUserInput) {
205
207
  resetUnreadMessages()
206
- scrollToBottom({ host })
208
+ scrollToBottom({ host }) // TODO: Remove param {host}
207
209
  props.onUserInput({
208
210
  user: webchatState.session.user,
209
211
  input: input,
@@ -367,7 +369,7 @@ export const Webchat = forwardRef((props, ref) => {
367
369
  if (getBlockInputs(rule, input.data)) {
368
370
  addMessageComponent(
369
371
  <Text
370
- id={input.id}
372
+ id={input.id} //TODO: Remove id from Text component
371
373
  sentBy={SENDERS.user}
372
374
  blob={false}
373
375
  style={{
@@ -407,41 +409,23 @@ export const Webchat = forwardRef((props, ref) => {
407
409
  (props.coverComponent.component || props.coverComponent)
408
410
  )
409
411
  }
410
- const CoverComponent = getCoverComponent()
411
-
412
- const closeCoverComponent = () => {
413
- toggleCoverComponent(false)
414
- }
412
+ const coverComponent = getCoverComponent()
413
+ const coverComponentProps = props.coverComponent?.props
415
414
 
416
415
  useEffect(() => {
417
- if (!CoverComponent) return
416
+ if (!coverComponent) return
418
417
  if (
419
418
  !botonicState ||
420
- (botonicState.messages && botonicState.messages.length == 0)
419
+ (botonicState.messages && botonicState.messages.length === 0)
421
420
  )
422
421
  toggleCoverComponent(true)
423
422
  }, [])
424
423
 
425
- const coverComponent = () => {
426
- const coverComponentProps = getThemeProperty(
427
- WEBCHAT.CUSTOM_PROPERTIES.coverComponentProps,
428
- props.coverComponent && props.coverComponent.props
429
- )
430
-
431
- if (CoverComponent && webchatState.isCoverComponentOpen)
432
- return (
433
- <CoverComponent
434
- closeComponent={closeCoverComponent}
435
- {...coverComponentProps}
436
- />
437
- )
438
- return null
439
- }
440
-
441
424
  const messageComponentFromInput = input => {
442
425
  let messageComponent = null
443
426
  if (isText(input)) {
444
427
  messageComponent = (
428
+ //TODO: Remove id and payload from Text component
445
429
  <Text id={input.id} payload={input.payload} sentBy={SENDERS.user}>
446
430
  {input.data}
447
431
  </Text>
@@ -700,6 +684,7 @@ export const Webchat = forwardRef((props, ref) => {
700
684
  openWebview,
701
685
  resolveCase,
702
686
  resetUnreadMessages,
687
+ setIsInputFocused,
703
688
  setLastMessageVisible,
704
689
  sendAttachment,
705
690
  sendInput,
@@ -708,6 +693,7 @@ export const Webchat = forwardRef((props, ref) => {
708
693
  toggleWebchat,
709
694
  toggleEmojiPicker,
710
695
  togglePersistentMenu,
696
+ toggleCoverComponent,
711
697
  updateLatestInput,
712
698
  updateMessage,
713
699
  updateReplies,
@@ -744,36 +730,50 @@ export const Webchat = forwardRef((props, ref) => {
744
730
  toggleWebchat(false)
745
731
  }}
746
732
  />
747
- {webchatState.error.message && (
748
- <ErrorMessageContainer>
749
- <ErrorMessage>{webchatState.error.message}</ErrorMessage>
750
- </ErrorMessageContainer>
751
- )}
752
- <ChatArea />
753
733
 
754
- {webchatState.isPersistentMenuOpen && (
755
- <DarkenBackground component={persistentMenu()} />
756
- )}
757
- {!webchatState.handoff && userInputEnabled && (
758
- <InputPanel
759
- persistentMenu={props.persistentMenu}
760
- enableEmojiPicker={props.enableEmojiPicker}
761
- enableAttachments={props.enableAttachments}
762
- handleAttachment={handleAttachment}
763
- textareaRef={textareaRef}
764
- host={host}
765
- onUserInput={props.onUserInput}
734
+ {webchatState.isCoverComponentOpen ? (
735
+ <CoverComponent
736
+ component={coverComponent}
737
+ componentProps={coverComponentProps}
766
738
  />
739
+ ) : (
740
+ <>
741
+ {webchatState.error.message && (
742
+ <ErrorMessageContainer>
743
+ <ErrorMessage>{webchatState.error.message}</ErrorMessage>
744
+ </ErrorMessageContainer>
745
+ )}
746
+
747
+ <ChatArea />
748
+
749
+ {webchatState.isPersistentMenuOpen && (
750
+ <DarkenBackground component={persistentMenu()} />
751
+ )}
752
+
753
+ {!webchatState.handoff && userInputEnabled && (
754
+ <InputPanel
755
+ persistentMenu={props.persistentMenu}
756
+ enableEmojiPicker={props.enableEmojiPicker}
757
+ enableAttachments={props.enableAttachments}
758
+ handleAttachment={handleAttachment}
759
+ textareaRef={textareaRef}
760
+ host={host}
761
+ onUserInput={props.onUserInput}
762
+ />
763
+ )}
764
+
765
+ {webchatState.webview && webchatWebview()}
766
+
767
+ {webchatState.isCustomComponentRendered &&
768
+ customComponent &&
769
+ _renderCustomComponent()}
770
+ </>
767
771
  )}
768
- {webchatState.webview && webchatWebview()}
769
- {webchatState.isCoverComponentOpen && coverComponent()}
770
- {webchatState.isCustomComponentRendered &&
771
- customComponent &&
772
- _renderCustomComponent()}
773
772
  </StyledWebchat>
774
773
  )}
775
774
  </WebchatContext.Provider>
776
775
  )
776
+
777
777
  return props.shadowDOM ? (
778
778
  <StyleSheetManager target={host}>{WebchatComponent}</StyleSheetManager>
779
779
  ) : (
@@ -1,15 +1,128 @@
1
- import { HubtypeService, INPUT } from '@botonic/core'
1
+ import { HubtypeService, INPUT, Input, ServerConfig } from '@botonic/core'
2
2
  import merge from 'lodash.merge'
3
3
  import React, { createRef } from 'react'
4
- import { createRoot } from 'react-dom/client'
5
-
4
+ import { createRoot, Root } from 'react-dom/client'
5
+
6
+ import {
7
+ BlockInputOption,
8
+ CoverComponentOptions,
9
+ PersistentMenuTheme,
10
+ ThemeProps,
11
+ WebchatSettingsProps,
12
+ } from './components/index-types'
6
13
  import { WEBCHAT } from './constants'
7
- import { SENDERS, Typing } from './index-types'
14
+ import { CloseWebviewOptions } from './contexts'
15
+ import {
16
+ ActionRequest,
17
+ EventArgs,
18
+ SENDERS,
19
+ Typing,
20
+ WebchatMessage,
21
+ } from './index-types'
8
22
  import { msgToBotonic } from './msg-to-botonic'
9
23
  import { isShadowDOMSupported, onDOMLoaded } from './util/dom'
24
+ import { ErrorMessage } from './webchat/index-types'
10
25
  import { Webchat } from './webchat/webchat'
11
26
 
27
+ export interface WebchatAppProps {
28
+ theme?: ThemeProps
29
+ persistentMenu?: PersistentMenuTheme
30
+ coverComponent?: CoverComponentOptions
31
+ blockInputs?: BlockInputOption[]
32
+ enableEmojiPicker?: boolean
33
+ enableAttachments?: boolean
34
+ enableUserInput?: boolean
35
+ enableAnimations?: boolean
36
+ hostId?: string
37
+ shadowDOM?: boolean | (() => boolean)
38
+ defaultDelay?: number
39
+ defaultTyping?: number
40
+ storage?: Storage | null
41
+ storageKey?: string
42
+ onInit?: (app: WebchatApp, args: any) => void
43
+ onOpen?: (app: WebchatApp, args: any) => void
44
+ onClose?: (app: WebchatApp, args: any) => void
45
+ onMessage?: (app: WebchatApp, message: WebchatMessage) => void
46
+ onTrackEvent?: (
47
+ request: ActionRequest,
48
+ eventName: string,
49
+ args?: EventArgs
50
+ ) => Promise<void>
51
+ onConnectionChange?: (app: WebchatApp, isOnline: boolean) => void
52
+ appId?: string
53
+ visibility?: boolean | (() => boolean) | 'dynamic'
54
+ server?: ServerConfig
55
+ }
56
+
57
+ interface WebchatRef {
58
+ addBotResponse: ({
59
+ response,
60
+ session,
61
+ lastRoutePath,
62
+ }: AddBotResponseArgs) => void
63
+ setTyping: (typing: boolean) => void
64
+ addUserMessage: (message: any) => Promise<void>
65
+ updateUser: (userToUpdate: any) => void
66
+ openWebchat: () => void
67
+ closeWebchat: () => void
68
+ toggleWebchat: () => void
69
+ openCoverComponent: () => void
70
+ closeCoverComponent: () => void
71
+ renderCustomComponent: (customComponent: any) => void
72
+ unmountCustomComponent: () => void
73
+ toggleCoverComponent: () => void
74
+ openWebviewApi: (component: any) => void
75
+ setError: (error: ErrorMessage) => void
76
+ setOnline: (online: boolean) => void
77
+ getMessages: () => { id: string; ack: number; unsentInput: Input }[] // TODO: define MessagesJSON
78
+ isOnline: () => boolean
79
+ clearMessages: () => void
80
+ getLastMessageUpdate: () => string
81
+ updateMessageInfo: (msgId: string, messageInfo: any) => void
82
+ updateWebchatSettings: (settings: WebchatSettingsProps) => void
83
+ closeWebview: (options?: CloseWebviewOptions) => Promise<void>
84
+ }
85
+
86
+ interface AddBotResponseArgs {
87
+ response: any
88
+ session?: any
89
+ lastRoutePath?: any
90
+ }
91
+
12
92
  export class WebchatApp {
93
+ public theme?: ThemeProps
94
+ public persistentMenu?: PersistentMenuTheme
95
+ public coverComponent?: CoverComponentOptions
96
+ public blockInputs?: BlockInputOption[]
97
+ public enableEmojiPicker?: boolean
98
+ public enableAttachments?: boolean
99
+ public enableUserInput?: boolean
100
+ public enableAnimations?: boolean
101
+ public hostId?: string
102
+ public shadowDOM?: boolean | (() => boolean)
103
+ public defaultDelay?: number
104
+ public defaultTyping?: number
105
+ public storage?: Storage | null
106
+ public storageKey: string
107
+ public onInit?: (app: WebchatApp, args: any) => void
108
+ public onOpen?: (app: WebchatApp, args: any) => void
109
+ public onClose?: (app: WebchatApp, args: any) => void
110
+ public onMessage?: (app: WebchatApp, message: WebchatMessage) => void
111
+ public onTrackEvent?: (
112
+ request: ActionRequest,
113
+ eventName: string,
114
+ args?: EventArgs
115
+ ) => Promise<void>
116
+ public onConnectionChange?: (app: WebchatApp, isOnline: boolean) => void
117
+ public appId?: string
118
+ public visibility?: boolean | (() => boolean) | 'dynamic'
119
+ public server?: ServerConfig
120
+ public webchatRef: React.RefObject<WebchatRef | null>
121
+
122
+ private reactRoot: Root | null = null
123
+ private host: (HTMLElement | null) | ShadowRoot = null
124
+ private hubtypeService: HubtypeService
125
+
13
126
  constructor({
14
127
  theme = {},
15
128
  persistentMenu,
@@ -19,8 +132,8 @@ export class WebchatApp {
19
132
  enableAttachments,
20
133
  enableUserInput,
21
134
  enableAnimations,
22
- hostId,
23
- shadowDOM,
135
+ hostId = 'root',
136
+ shadowDOM = false,
24
137
  defaultDelay,
25
138
  defaultTyping,
26
139
  storage,
@@ -34,7 +147,7 @@ export class WebchatApp {
34
147
  appId,
35
148
  visibility,
36
149
  server,
37
- }) {
150
+ }: WebchatAppProps) {
38
151
  this.theme = theme
39
152
  this.persistentMenu = persistentMenu
40
153
  this.coverComponent = coverComponent
@@ -43,13 +156,15 @@ export class WebchatApp {
43
156
  this.enableAttachments = enableAttachments
44
157
  this.enableUserInput = enableUserInput
45
158
  this.enableAnimations = enableAnimations
159
+
46
160
  this.shadowDOM = Boolean(
47
161
  typeof shadowDOM === 'function' ? shadowDOM() : shadowDOM
48
162
  )
49
163
  if (this.shadowDOM && !isShadowDOMSupported()) {
50
164
  console.warn('[botonic] ShadowDOM not supported on this browser')
51
165
  this.shadowDOM = false
52
- }
166
+ } // Review this
167
+
53
168
  this.hostId = hostId || WEBCHAT.DEFAULTS.HOST_ID
54
169
  this.defaultDelay = defaultDelay
55
170
  this.defaultTyping = defaultTyping
@@ -63,12 +178,14 @@ export class WebchatApp {
63
178
  this.onConnectionChange = onConnectionChange
64
179
  this.visibility = visibility
65
180
  this.server = server
66
- this.webchatRef = createRef()
181
+ this.webchatRef = createRef<WebchatRef>()
67
182
  this.appId = appId
183
+
184
+ this.host = null
68
185
  this.reactRoot = null
69
186
  }
70
187
 
71
- createRootElement(host) {
188
+ createRootElement(host: HTMLElement | null) {
72
189
  // Create root element <div id='root'> if not exists
73
190
  // Create shadowDOM to root element if needed
74
191
  if (host) {
@@ -79,45 +196,63 @@ export class WebchatApp {
79
196
  )
80
197
  this.hostId = host.id
81
198
  }
82
- } else if (host.id) this.hostId = host.id
83
- else if (this.hostId) host.id = this.hostId
199
+ } else if (host.id) {
200
+ this.hostId = host.id
201
+ } else if (this.hostId) {
202
+ host.id = this.hostId
203
+ }
84
204
  } else {
85
- host = document.getElementById(this.hostId)
205
+ host = this.hostId ? document.getElementById(this.hostId) : null
86
206
  }
207
+
87
208
  if (!host) {
88
209
  host = document.createElement('div')
89
- host.id = this.hostId
90
- if (document.body.firstChild)
210
+ host.id = this.hostId!
211
+ if (document.body.firstChild) {
91
212
  document.body.insertBefore(host, document.body.firstChild)
92
- else document.body.appendChild(host)
213
+ } else {
214
+ document.body.appendChild(host)
215
+ }
93
216
  }
94
217
  this.host = this.shadowDOM ? host.attachShadow({ mode: 'open' }) : host
95
218
  }
96
219
 
97
- getReactMountNode(node) {
220
+ getReactMountNode(
221
+ node?: (HTMLElement | null) | ShadowRoot
222
+ ): Element | DocumentFragment {
98
223
  if (!node) {
99
224
  node = this.host
100
225
  }
101
- return node.shadowRoot ? node.shadowRoot : node
226
+
227
+ if (node === null) {
228
+ throw new Error('Host element not found')
229
+ }
230
+
231
+ // TODO: Review logic of ShadowRoot
232
+ if ('shadowRoot' in node && node.shadowRoot !== null) {
233
+ return node.shadowRoot
234
+ }
235
+
236
+ return node
102
237
  }
103
238
 
104
- onInitWebchat(...args) {
239
+ onInitWebchat(...args: [any]) {
105
240
  this.onInit && this.onInit(this, ...args)
106
241
  }
107
242
 
108
- onOpenWebchat(...args) {
243
+ onOpenWebchat(...args: [any]) {
109
244
  this.onOpen && this.onOpen(this, ...args)
110
245
  }
111
246
 
112
- onCloseWebchat(...args) {
247
+ onCloseWebchat(...args: [any]) {
113
248
  this.onClose && this.onClose(this, ...args)
114
249
  }
115
250
 
116
251
  async onUserInput({ user, input }) {
117
252
  this.onMessage &&
118
253
  this.onMessage(this, {
254
+ ...input,
119
255
  sentBy: SENDERS.user,
120
- message: input,
121
256
  isUnread: false,
122
257
  })
123
258
  return this.hubtypeService.postMessage(user, input)
@@ -133,19 +268,19 @@ export class WebchatApp {
133
268
  const lastMessageUpdateDate = this.getLastMessageUpdate()
134
269
  if (this.hubtypeService) {
135
270
  this.hubtypeService.lastMessageId = lastMessageId
136
- this.hubtypeService.lastMessageUpdateDate = lastMessageUpdateDate
271
+ this.hubtypeService.lastMessageUpdateDate = lastMessageUpdateDate!
137
272
  } else if (!this.hubtypeService && user) {
138
273
  this.hubtypeService = new HubtypeService({
139
- appId: this.appId,
274
+ appId: this.appId!,
140
275
  user,
141
276
  lastMessageId,
142
- lastMessageUpdateDate,
143
- onEvent: event => this.onServiceEvent(event),
277
+ lastMessageUpdateDate: lastMessageUpdateDate!,
278
+ onEvent: (event: any) => this.onServiceEvent(event),
144
279
  unsentInputs: () =>
145
280
  this.webchatRef.current
146
- .getMessages()
147
- .filter(msg => msg.ack === 0 && msg.unsentInput),
148
- server: this.server,
281
+ ?.getMessages()
282
+ .filter(msg => msg.ack === 0 && msg.unsentInput) || [],
283
+ server: this.server!,
149
284
  })
150
285
  }
151
286
  }
@@ -153,7 +288,7 @@ export class WebchatApp {
153
288
  onServiceEvent(event) {
154
289
  if (event.action === 'connectionChange') {
155
290
  this.onConnectionChange && this.onConnectionChange(this, event.online)
156
- this.webchatRef.current.setOnline(event.online)
291
+ this.webchatRef.current?.setOnline(event.online)
157
292
  } else if (event.action === 'update_message_info') {
158
293
  this.updateMessageInfo(event.message.id, event.message)
159
294
  } else if (event.message?.type === 'update_webchat_settings') {
@@ -162,115 +297,122 @@ export class WebchatApp {
162
297
  this.setTyping(event.message.data === Typing.On)
163
298
  } else {
164
299
  this.onMessage &&
165
- this.onMessage(this, { sentBy: SENDERS.bot, message: event.message })
300
+ this.onMessage(this, {
301
+ sentBy: SENDERS.bot,
302
+ ...event.message,
303
+ } as WebchatMessage)
166
304
  this.addBotMessage(event.message)
167
305
  }
168
306
  }
169
307
 
170
- updateUser(user) {
171
- this.webchatRef.current.updateUser(user)
308
+ updateUser(user: any) {
309
+ this.webchatRef.current?.updateUser(user)
172
310
  }
173
311
 
174
- addBotMessage(message) {
312
+ addBotMessage(message: any) {
175
313
  message.ack = 0
176
314
  message.isUnread = true
177
315
  message.sentBy = message.sent_by?.split('message_sent_by_')[1]
178
316
  delete message.sent_by
179
317
  const response = msgToBotonic(
180
318
  message,
181
- this.theme.message?.customTypes || this.theme.customMessageTypes
319
+ // TODO: Review if is neded allow declar customTypes inseide and ouside theme
320
+ // @ts-ignore
321
+ this.theme?.message?.customTypes || this.theme?.customMessageTypes || []
182
322
  )
183
323
 
184
- this.webchatRef.current.addBotResponse({
324
+ this.webchatRef.current?.addBotResponse({
185
325
  response,
186
326
  })
187
327
  }
188
328
 
189
- addBotText(text) {
329
+ addBotText(text: string) {
190
330
  this.addBotMessage({ type: INPUT.TEXT, data: text })
191
331
  }
192
332
 
193
- addUserMessage(message) {
194
- this.webchatRef.current.addUserMessage(message)
333
+ addUserMessage(message: any) {
334
+ this.webchatRef.current?.addUserMessage(message)
195
335
  }
196
336
 
197
- addUserText(text) {
337
+ addUserText(text: string) {
198
338
  this.addUserMessage({ type: INPUT.TEXT, data: text })
199
339
  }
200
340
 
201
- addUserPayload(payload) {
341
+ addUserPayload(payload: string) {
202
342
  this.addUserMessage({ type: INPUT.POSTBACK, payload })
203
343
  }
204
344
 
205
- setTyping(typing) {
206
- this.webchatRef.current.setTyping(typing)
345
+ setTyping(typing: boolean) {
346
+ this.webchatRef.current?.setTyping(typing)
207
347
  }
208
348
 
209
349
  open() {
210
- this.webchatRef.current.openWebchat()
350
+ this.webchatRef.current?.openWebchat()
211
351
  }
212
352
 
213
353
  close() {
214
- this.webchatRef.current.closeWebchat()
354
+ this.webchatRef.current?.closeWebchat()
215
355
  }
216
356
 
217
- async closeWebview() {
218
- await this.webchatRef.current.closeWebview()
357
+ async closeWebview(options?: CloseWebviewOptions) {
358
+ await this.webchatRef.current?.closeWebview(options)
219
359
  }
220
360
 
361
+ // TODO: Remove this function because we have open and close functions
221
362
  toggle() {
222
- this.webchatRef.current.toggleWebchat()
363
+ this.webchatRef.current?.toggleWebchat()
223
364
  }
224
365
 
225
366
  openCoverComponent() {
226
- this.webchatRef.current.openCoverComponent()
367
+ this.webchatRef.current?.openCoverComponent()
227
368
  }
228
369
 
229
370
  closeCoverComponent() {
230
- this.webchatRef.current.closeCoverComponent()
371
+ this.webchatRef.current?.closeCoverComponent()
231
372
  }
232
373
 
233
- renderCustomComponent(_customComponent) {
234
- this.webchatRef.current.renderCustomComponent(_customComponent)
374
+ renderCustomComponent(_customComponent: any) {
375
+ this.webchatRef.current?.renderCustomComponent(_customComponent)
235
376
  }
236
377
 
237
378
  unmountCustomComponent() {
238
- this.webchatRef.current.unmountCustomComponent()
379
+ this.webchatRef.current?.unmountCustomComponent()
239
380
  }
240
381
 
382
+ // TODO: Remove this function because we have openCoverComponent and closeCoverComponent functions
241
383
  toggleCoverComponent() {
242
- this.webchatRef.current.toggleCoverComponent()
384
+ this.webchatRef.current?.toggleCoverComponent()
243
385
  }
244
386
 
245
387
  getMessages() {
246
- return this.webchatRef.current.getMessages()
388
+ return this.webchatRef.current?.getMessages()
247
389
  }
248
390
 
249
391
  clearMessages() {
250
- this.webchatRef.current.clearMessages()
392
+ this.webchatRef.current?.clearMessages()
251
393
  }
252
394
 
253
395
  async getVisibility() {
254
396
  return this.resolveWebchatVisibility({
255
- appId: this.appId,
397
+ appId: this.appId!,
256
398
  visibility: this.visibility,
257
399
  })
258
400
  }
259
401
 
260
402
  getLastMessageUpdate() {
261
- return this.webchatRef.current.getLastMessageUpdate()
403
+ return this.webchatRef.current?.getLastMessageUpdate()
262
404
  }
263
405
 
264
- updateMessageInfo(msgId, messageInfo) {
265
- return this.webchatRef.current.updateMessageInfo(msgId, messageInfo)
406
+ updateMessageInfo(msgId: string, messageInfo: any) {
407
+ return this.webchatRef.current?.updateMessageInfo(msgId, messageInfo)
266
408
  }
267
409
 
268
- updateWebchatSettings(settings) {
269
- return this.webchatRef.current.updateWebchatSettings(settings)
410
+ updateWebchatSettings(settings: WebchatSettingsProps) {
411
+ return this.webchatRef.current?.updateWebchatSettings(settings)
270
412
  }
271
413
 
272
414
  // eslint-disable-next-line complexity
273
- getComponent(host, optionsAtRuntime = {}) {
415
+ getComponent(host, optionsAtRuntime: WebchatAppProps = {}) {
274
416
  let {
275
417
  theme = {},
276
418
  persistentMenu,
@@ -319,10 +461,12 @@ export class WebchatApp {
319
461
  this.appId = appId || this.appId
320
462
  this.hostId = hostId || this.hostId
321
463
  this.createRootElement(host)
464
+
322
465
  return (
323
466
  <Webchat
324
467
  {...webchatOptions}
325
468
  ref={this.webchatRef}
469
+ // @ts-ignore
326
470
  host={this.host}
327
471
  shadowDOM={this.shadowDOM}
328
472
  theme={theme}
@@ -337,12 +481,16 @@ export class WebchatApp {
337
481
  storageKey={this.storageKey}
338
482
  defaultDelay={defaultDelay}
339
483
  defaultTyping={defaultTyping}
340
- onInit={(...args) => this.onInitWebchat(...args)}
341
- onOpen={(...args) => this.onOpenWebchat(...args)}
342
- onClose={(...args) => this.onCloseWebchat(...args)}
343
- onUserInput={(...args) => this.onUserInput(...args)}
484
+ onInit={(...args: [any]) => this.onInitWebchat(...args)}
485
+ onOpen={(...args: [any]) => this.onOpenWebchat(...args)}
486
+ onClose={(...args: [any]) => this.onCloseWebchat(...args)}
487
+ onUserInput={(...args: [any]) => this.onUserInput(...args)}
344
488
  onStateChange={webchatState => this.onStateChange(webchatState)}
345
- onTrackEvent={(...args) => this.onTrackEvent(...args)}
489
+ onTrackEvent={(
490
+ request: ActionRequest,
491
+ eventName: string,
492
+ args?: EventArgs
493
+ ) => this.onTrackEvent && this.onTrackEvent(request, eventName, args)}
346
494
  server={server}
347
495
  />
348
496
  )
@@ -360,10 +508,15 @@ export class WebchatApp {
360
508
  }
361
509
 
362
510
  isOnline() {
363
- return this.webchatRef.current.isOnline()
511
+ return this.webchatRef.current?.isOnline()
364
512
  }
365
513
 
366
- async resolveWebchatVisibility(optionsAtRuntime) {
514
+ async resolveWebchatVisibility(optionsAtRuntime?: {
515
+ appId: string
516
+ visibility: boolean | (() => boolean) | 'dynamic' | undefined
517
+ }) {
518
+ if (!optionsAtRuntime) return true // If optionsAtRuntime is not provided, always render the webchat
519
+
367
520
  let { appId, visibility } = optionsAtRuntime
368
521
  visibility = visibility || this.visibility
369
522
  if (visibility === undefined || visibility === true) return true
@@ -379,7 +532,7 @@ export class WebchatApp {
379
532
  if (this.storage) this.storage.removeItem(this.storageKey)
380
533
  }
381
534
 
382
- async render(dest, optionsAtRuntime = {}) {
535
+ async render(dest: HTMLDivElement, optionsAtRuntime: any = undefined) {
383
536
  onDOMLoaded(async () => {
384
537
  const isVisible = await this.resolveWebchatVisibility(optionsAtRuntime)
385
538
  if (isVisible) {