@botonic/react 0.30.0-alpha.1 → 0.30.0-alpha.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 (251) hide show
  1. package/lib/cjs/components/carousel.js +6 -3
  2. package/lib/cjs/components/carousel.js.map +1 -1
  3. package/lib/cjs/constants.d.ts +0 -6
  4. package/lib/cjs/constants.js +0 -6
  5. package/lib/cjs/constants.js.map +1 -1
  6. package/lib/cjs/contexts.d.ts +1 -1
  7. package/lib/cjs/contexts.js +9 -3
  8. package/lib/cjs/contexts.js.map +1 -1
  9. package/lib/cjs/index-types.d.ts +7 -1
  10. package/lib/cjs/index-types.js +0 -5
  11. package/lib/cjs/index-types.js.map +1 -1
  12. package/lib/cjs/node-app.d.ts +0 -5
  13. package/lib/cjs/node-app.js +0 -5
  14. package/lib/cjs/node-app.js.map +1 -1
  15. package/lib/cjs/util/dom.d.ts +0 -10
  16. package/lib/cjs/util/dom.js +3 -29
  17. package/lib/cjs/util/dom.js.map +1 -1
  18. package/lib/cjs/webchat/actions.d.ts +0 -1
  19. package/lib/cjs/webchat/actions.js +0 -1
  20. package/lib/cjs/webchat/actions.js.map +1 -1
  21. package/lib/cjs/webchat/constants.d.ts +8 -0
  22. package/lib/cjs/webchat/constants.js +13 -0
  23. package/lib/cjs/webchat/constants.js.map +1 -0
  24. package/lib/cjs/webchat/header.d.ts +2 -2
  25. package/lib/cjs/webchat/header.js +14 -13
  26. package/lib/cjs/webchat/header.js.map +1 -1
  27. package/lib/cjs/webchat/hooks/index.d.ts +6 -0
  28. package/lib/cjs/webchat/hooks/index.js +13 -1
  29. package/lib/cjs/webchat/hooks/index.js.map +1 -1
  30. package/lib/cjs/webchat/hooks/use-device-adapter.d.ts +3 -0
  31. package/lib/cjs/webchat/hooks/use-device-adapter.js +46 -0
  32. package/lib/cjs/webchat/hooks/use-device-adapter.js.map +1 -0
  33. package/lib/cjs/webchat/hooks/use-scroll-to-bottom.d.ts +7 -0
  34. package/lib/cjs/webchat/hooks/use-scroll-to-bottom.js +26 -0
  35. package/lib/cjs/webchat/hooks/use-scroll-to-bottom.js.map +1 -0
  36. package/lib/cjs/webchat/hooks/use-scrollbar-controller.d.ts +6 -0
  37. package/lib/cjs/webchat/hooks/use-scrollbar-controller.js +140 -0
  38. package/lib/cjs/webchat/hooks/use-scrollbar-controller.js.map +1 -0
  39. package/lib/cjs/webchat/hooks/use-virtual-keyboard-detection.d.ts +3 -0
  40. package/lib/cjs/webchat/hooks/use-virtual-keyboard-detection.js +28 -0
  41. package/lib/cjs/webchat/hooks/use-virtual-keyboard-detection.js.map +1 -0
  42. package/lib/cjs/webchat/hooks/use-webchat-dimensions.d.ts +4 -0
  43. package/lib/cjs/webchat/hooks/use-webchat-dimensions.js +39 -0
  44. package/lib/cjs/webchat/hooks/use-webchat-dimensions.js.map +1 -0
  45. package/lib/cjs/webchat/hooks/use-webchat-resizer.d.ts +4 -0
  46. package/lib/cjs/webchat/hooks/use-webchat-resizer.js +34 -0
  47. package/lib/cjs/webchat/hooks/use-webchat-resizer.js.map +1 -0
  48. package/lib/cjs/webchat/hooks/use-webchat.d.ts +6 -1
  49. package/lib/cjs/webchat/hooks/use-webchat.js +12 -8
  50. package/lib/cjs/webchat/hooks/use-webchat.js.map +1 -1
  51. package/lib/cjs/webchat/index-types.d.ts +0 -1
  52. package/lib/cjs/webchat/message-list/index.js +4 -9
  53. package/lib/cjs/webchat/message-list/index.js.map +1 -1
  54. package/lib/cjs/webchat/message-list/scroll-button.js.map +1 -1
  55. package/lib/cjs/webchat/message-list/styles.d.ts +1 -0
  56. package/lib/cjs/webchat/message-list/styles.js +10 -1
  57. package/lib/cjs/webchat/message-list/styles.js.map +1 -1
  58. package/lib/cjs/webchat/replies.js +8 -4
  59. package/lib/cjs/webchat/replies.js.map +1 -1
  60. package/lib/cjs/webchat/typing-indicator/index.d.ts +1 -0
  61. package/lib/cjs/webchat/typing-indicator/index.js +9 -0
  62. package/lib/cjs/webchat/typing-indicator/index.js.map +1 -0
  63. package/lib/cjs/webchat/typing-indicator/styles.d.ts +6 -0
  64. package/lib/cjs/webchat/typing-indicator/styles.js +47 -0
  65. package/lib/cjs/webchat/typing-indicator/styles.js.map +1 -0
  66. package/lib/cjs/webchat/webchat-chat-area/index.d.ts +1 -0
  67. package/lib/cjs/webchat/webchat-chat-area/index.js +22 -0
  68. package/lib/cjs/webchat/webchat-chat-area/index.js.map +1 -0
  69. package/lib/cjs/webchat/webchat-chat-area/styles.d.ts +3 -0
  70. package/lib/cjs/webchat/webchat-chat-area/styles.js +13 -0
  71. package/lib/cjs/webchat/webchat-chat-area/styles.js.map +1 -0
  72. package/lib/cjs/webchat/webchat-input-panel/index.d.ts +2 -3
  73. package/lib/cjs/webchat/webchat-input-panel/index.js +4 -3
  74. package/lib/cjs/webchat/webchat-input-panel/index.js.map +1 -1
  75. package/lib/cjs/webchat/webchat-input-panel/textarea.d.ts +2 -3
  76. package/lib/cjs/webchat/webchat-input-panel/textarea.js +5 -7
  77. package/lib/cjs/webchat/webchat-input-panel/textarea.js.map +1 -1
  78. package/lib/cjs/webchat/webchat-reducer.js +0 -2
  79. package/lib/cjs/webchat/webchat-reducer.js.map +1 -1
  80. package/lib/cjs/webchat/webchat.js +18 -18
  81. package/lib/cjs/webchat/webchat.js.map +1 -1
  82. package/lib/cjs/webchat/webview.js +13 -22
  83. package/lib/cjs/webchat/webview.js.map +1 -1
  84. package/lib/cjs/webchat-app.d.ts +1 -1
  85. package/lib/cjs/webchat-app.js +3 -1
  86. package/lib/cjs/webchat-app.js.map +1 -1
  87. package/lib/cjs/webview-app.js +11 -11
  88. package/lib/cjs/webview-app.js.map +1 -1
  89. package/lib/esm/components/carousel.js +6 -3
  90. package/lib/esm/components/carousel.js.map +1 -1
  91. package/lib/esm/constants.d.ts +0 -6
  92. package/lib/esm/constants.js +0 -6
  93. package/lib/esm/constants.js.map +1 -1
  94. package/lib/esm/contexts.d.ts +1 -1
  95. package/lib/esm/contexts.js +9 -3
  96. package/lib/esm/contexts.js.map +1 -1
  97. package/lib/esm/index-types.d.ts +7 -1
  98. package/lib/esm/index-types.js +0 -5
  99. package/lib/esm/index-types.js.map +1 -1
  100. package/lib/esm/node-app.d.ts +0 -5
  101. package/lib/esm/node-app.js +0 -5
  102. package/lib/esm/node-app.js.map +1 -1
  103. package/lib/esm/util/dom.d.ts +0 -10
  104. package/lib/esm/util/dom.js +2 -25
  105. package/lib/esm/util/dom.js.map +1 -1
  106. package/lib/esm/webchat/actions.d.ts +0 -1
  107. package/lib/esm/webchat/actions.js +0 -1
  108. package/lib/esm/webchat/actions.js.map +1 -1
  109. package/lib/esm/webchat/constants.d.ts +8 -0
  110. package/lib/esm/webchat/constants.js +10 -0
  111. package/lib/esm/webchat/constants.js.map +1 -0
  112. package/lib/esm/webchat/header.d.ts +2 -2
  113. package/lib/esm/webchat/header.js +14 -12
  114. package/lib/esm/webchat/header.js.map +1 -1
  115. package/lib/esm/webchat/hooks/index.d.ts +6 -0
  116. package/lib/esm/webchat/hooks/index.js +6 -0
  117. package/lib/esm/webchat/hooks/index.js.map +1 -1
  118. package/lib/esm/webchat/hooks/use-device-adapter.d.ts +3 -0
  119. package/lib/esm/webchat/hooks/use-device-adapter.js +42 -0
  120. package/lib/esm/webchat/hooks/use-device-adapter.js.map +1 -0
  121. package/lib/esm/webchat/hooks/use-scroll-to-bottom.d.ts +7 -0
  122. package/lib/esm/webchat/hooks/use-scroll-to-bottom.js +22 -0
  123. package/lib/esm/webchat/hooks/use-scroll-to-bottom.js.map +1 -0
  124. package/lib/esm/webchat/hooks/use-scrollbar-controller.d.ts +6 -0
  125. package/lib/esm/webchat/hooks/use-scrollbar-controller.js +136 -0
  126. package/lib/esm/webchat/hooks/use-scrollbar-controller.js.map +1 -0
  127. package/lib/esm/webchat/hooks/use-virtual-keyboard-detection.d.ts +3 -0
  128. package/lib/esm/webchat/hooks/use-virtual-keyboard-detection.js +24 -0
  129. package/lib/esm/webchat/hooks/use-virtual-keyboard-detection.js.map +1 -0
  130. package/lib/esm/webchat/hooks/use-webchat-dimensions.d.ts +4 -0
  131. package/lib/esm/webchat/hooks/use-webchat-dimensions.js +35 -0
  132. package/lib/esm/webchat/hooks/use-webchat-dimensions.js.map +1 -0
  133. package/lib/esm/webchat/hooks/use-webchat-resizer.d.ts +4 -0
  134. package/lib/esm/webchat/hooks/use-webchat-resizer.js +30 -0
  135. package/lib/esm/webchat/hooks/use-webchat-resizer.js.map +1 -0
  136. package/lib/esm/webchat/hooks/use-webchat.d.ts +6 -1
  137. package/lib/esm/webchat/hooks/use-webchat.js +13 -9
  138. package/lib/esm/webchat/hooks/use-webchat.js.map +1 -1
  139. package/lib/esm/webchat/index-types.d.ts +0 -1
  140. package/lib/esm/webchat/message-list/index.js +6 -11
  141. package/lib/esm/webchat/message-list/index.js.map +1 -1
  142. package/lib/esm/webchat/message-list/scroll-button.js.map +1 -1
  143. package/lib/esm/webchat/message-list/styles.d.ts +1 -0
  144. package/lib/esm/webchat/message-list/styles.js +9 -0
  145. package/lib/esm/webchat/message-list/styles.js.map +1 -1
  146. package/lib/esm/webchat/replies.js +8 -4
  147. package/lib/esm/webchat/replies.js.map +1 -1
  148. package/lib/esm/webchat/typing-indicator/index.d.ts +1 -0
  149. package/lib/esm/webchat/typing-indicator/index.js +5 -0
  150. package/lib/esm/webchat/typing-indicator/index.js.map +1 -0
  151. package/lib/esm/webchat/typing-indicator/styles.d.ts +6 -0
  152. package/lib/esm/webchat/typing-indicator/styles.js +43 -0
  153. package/lib/esm/webchat/typing-indicator/styles.js.map +1 -0
  154. package/lib/esm/webchat/webchat-chat-area/index.d.ts +1 -0
  155. package/lib/esm/webchat/webchat-chat-area/index.js +18 -0
  156. package/lib/esm/webchat/webchat-chat-area/index.js.map +1 -0
  157. package/lib/esm/webchat/webchat-chat-area/styles.d.ts +3 -0
  158. package/lib/esm/webchat/webchat-chat-area/styles.js +9 -0
  159. package/lib/esm/webchat/webchat-chat-area/styles.js.map +1 -0
  160. package/lib/esm/webchat/webchat-input-panel/index.d.ts +2 -3
  161. package/lib/esm/webchat/webchat-input-panel/index.js +4 -3
  162. package/lib/esm/webchat/webchat-input-panel/index.js.map +1 -1
  163. package/lib/esm/webchat/webchat-input-panel/textarea.d.ts +2 -3
  164. package/lib/esm/webchat/webchat-input-panel/textarea.js +5 -7
  165. package/lib/esm/webchat/webchat-input-panel/textarea.js.map +1 -1
  166. package/lib/esm/webchat/webchat-reducer.js +0 -2
  167. package/lib/esm/webchat/webchat-reducer.js.map +1 -1
  168. package/lib/esm/webchat/webchat.js +19 -19
  169. package/lib/esm/webchat/webchat.js.map +1 -1
  170. package/lib/esm/webchat/webview.js +14 -22
  171. package/lib/esm/webchat/webview.js.map +1 -1
  172. package/lib/esm/webchat-app.d.ts +1 -1
  173. package/lib/esm/webchat-app.js +3 -1
  174. package/lib/esm/webchat-app.js.map +1 -1
  175. package/lib/esm/webview-app.js +11 -11
  176. package/lib/esm/webview-app.js.map +1 -1
  177. package/package.json +3 -6
  178. package/src/components/carousel.jsx +8 -10
  179. package/src/constants.js +0 -6
  180. package/src/contexts.tsx +9 -3
  181. package/src/index-types.ts +7 -52
  182. package/src/node-app.jsx +0 -6
  183. package/src/util/dom.js +2 -35
  184. package/src/webchat/actions.ts +0 -1
  185. package/src/webchat/constants.ts +9 -0
  186. package/src/webchat/header.jsx +31 -20
  187. package/src/webchat/hooks/index.ts +6 -0
  188. package/src/webchat/hooks/use-device-adapter.ts +50 -0
  189. package/src/webchat/hooks/use-scroll-to-bottom.ts +29 -0
  190. package/src/webchat/hooks/use-scrollbar-controller.ts +159 -0
  191. package/src/webchat/hooks/use-virtual-keyboard-detection.ts +27 -0
  192. package/src/webchat/hooks/use-webchat-dimensions.ts +50 -0
  193. package/src/webchat/hooks/use-webchat-resizer.ts +43 -0
  194. package/src/webchat/hooks/use-webchat.ts +14 -10
  195. package/src/webchat/index-types.ts +0 -1
  196. package/src/webchat/message-list/index.tsx +9 -19
  197. package/src/webchat/message-list/scroll-button.tsx +1 -3
  198. package/src/webchat/message-list/styles.ts +10 -0
  199. package/src/webchat/replies.jsx +13 -11
  200. package/src/webchat/typing-indicator/index.tsx +16 -0
  201. package/src/webchat/typing-indicator/styles.ts +50 -0
  202. package/src/webchat/webchat-chat-area/index.tsx +35 -0
  203. package/src/webchat/webchat-chat-area/styles.ts +9 -0
  204. package/src/webchat/webchat-input-panel/index.tsx +7 -4
  205. package/src/webchat/webchat-input-panel/textarea.tsx +7 -11
  206. package/src/webchat/webchat-reducer.ts +0 -2
  207. package/src/webchat/webchat.jsx +27 -20
  208. package/src/webchat/webview.jsx +14 -23
  209. package/src/webchat-app.jsx +2 -2
  210. package/src/webview-app.tsx +16 -11
  211. package/lib/cjs/webchat/components/styled-scrollbar.d.ts +0 -2
  212. package/lib/cjs/webchat/components/styled-scrollbar.js +0 -54
  213. package/lib/cjs/webchat/components/styled-scrollbar.js.map +0 -1
  214. package/lib/cjs/webchat/components/styled-scrollbar.scss +0 -12
  215. package/lib/cjs/webchat/components/typing-indicator.d.ts +0 -1
  216. package/lib/cjs/webchat/components/typing-indicator.js +0 -11
  217. package/lib/cjs/webchat/components/typing-indicator.js.map +0 -1
  218. package/lib/cjs/webchat/components/typing-indicator.scss +0 -38
  219. package/lib/cjs/webchat/devices/device-adapter.d.ts +0 -12
  220. package/lib/cjs/webchat/devices/device-adapter.js +0 -44
  221. package/lib/cjs/webchat/devices/device-adapter.js.map +0 -1
  222. package/lib/cjs/webchat/devices/scrollbar-controller.d.ts +0 -12
  223. package/lib/cjs/webchat/devices/scrollbar-controller.js +0 -103
  224. package/lib/cjs/webchat/devices/scrollbar-controller.js.map +0 -1
  225. package/lib/cjs/webchat/devices/webchat-resizer.d.ts +0 -9
  226. package/lib/cjs/webchat/devices/webchat-resizer.js +0 -47
  227. package/lib/cjs/webchat/devices/webchat-resizer.js.map +0 -1
  228. package/lib/esm/webchat/components/styled-scrollbar.d.ts +0 -2
  229. package/lib/esm/webchat/components/styled-scrollbar.js +0 -50
  230. package/lib/esm/webchat/components/styled-scrollbar.js.map +0 -1
  231. package/lib/esm/webchat/components/styled-scrollbar.scss +0 -12
  232. package/lib/esm/webchat/components/typing-indicator.d.ts +0 -1
  233. package/lib/esm/webchat/components/typing-indicator.js +0 -6
  234. package/lib/esm/webchat/components/typing-indicator.js.map +0 -1
  235. package/lib/esm/webchat/components/typing-indicator.scss +0 -38
  236. package/lib/esm/webchat/devices/device-adapter.d.ts +0 -12
  237. package/lib/esm/webchat/devices/device-adapter.js +0 -40
  238. package/lib/esm/webchat/devices/device-adapter.js.map +0 -1
  239. package/lib/esm/webchat/devices/scrollbar-controller.d.ts +0 -12
  240. package/lib/esm/webchat/devices/scrollbar-controller.js +0 -99
  241. package/lib/esm/webchat/devices/scrollbar-controller.js.map +0 -1
  242. package/lib/esm/webchat/devices/webchat-resizer.d.ts +0 -9
  243. package/lib/esm/webchat/devices/webchat-resizer.js +0 -43
  244. package/lib/esm/webchat/devices/webchat-resizer.js.map +0 -1
  245. package/src/webchat/components/styled-scrollbar.jsx +0 -60
  246. package/src/webchat/components/styled-scrollbar.scss +0 -12
  247. package/src/webchat/components/typing-indicator.jsx +0 -17
  248. package/src/webchat/components/typing-indicator.scss +0 -38
  249. package/src/webchat/devices/device-adapter.js +0 -43
  250. package/src/webchat/devices/scrollbar-controller.js +0 -107
  251. package/src/webchat/devices/webchat-resizer.js +0 -45
@@ -0,0 +1,27 @@
1
+ import { useEffect, useState } from 'react'
2
+
3
+ export const useVirtualKeyboardDetection = originalHeight => {
4
+ const [isVirtualKeyboardVisible, setIsVirtualKeyboardVisible] =
5
+ useState(false)
6
+ useEffect(() => {
7
+ const handleResize = () => {
8
+ if (window.visualViewport) {
9
+ if (window.visualViewport.height < originalHeight) {
10
+ setIsVirtualKeyboardVisible(true)
11
+ return
12
+ }
13
+ setIsVirtualKeyboardVisible(false)
14
+ return
15
+ }
16
+ }
17
+ window.visualViewport &&
18
+ window.visualViewport.addEventListener('resize', handleResize)
19
+
20
+ return () => {
21
+ window.visualViewport &&
22
+ window.visualViewport.removeEventListener('resize', handleResize)
23
+ }
24
+ }, [originalHeight])
25
+
26
+ return { isVirtualKeyboardVisible }
27
+ }
@@ -0,0 +1,50 @@
1
+ import { useCallback, useContext } from 'react'
2
+
3
+ import { WebchatContext } from '../../contexts'
4
+
5
+ export const useWebchatDimensions = () => {
6
+ const {
7
+ webchatRef,
8
+ headerRef,
9
+ inputPanelRef,
10
+ webchatState: { isWebchatOpen },
11
+ } = useContext(WebchatContext)
12
+
13
+ const calculateResizedPercentualWebchatHeight = useCallback(() => {
14
+ const webchatElement = webchatRef.current
15
+ if (!isWebchatOpen || !webchatElement) return 0
16
+ const webchatHeight = webchatElement.clientHeight || 0
17
+ const keyboardOffset =
18
+ (window.visualViewport && window.visualViewport.height) ||
19
+ window.innerHeight
20
+ let newWebchatPercentualHeight = keyboardOffset / webchatHeight
21
+ newWebchatPercentualHeight =
22
+ Math.round(newWebchatPercentualHeight * 100 * 100) / 100 // Two decimal places
23
+ return newWebchatPercentualHeight
24
+ }, [isWebchatOpen])
25
+
26
+ const calculateResizedPxChatAreaHeight = useCallback(() => {
27
+ const webchatElement = webchatRef.current
28
+ const headerElement = headerRef.current
29
+ const inputPanelElement = inputPanelRef.current
30
+
31
+ if (
32
+ !isWebchatOpen ||
33
+ !webchatElement ||
34
+ !headerElement ||
35
+ !inputPanelElement
36
+ )
37
+ return 0
38
+
39
+ return (
40
+ webchatElement.clientHeight -
41
+ headerElement.clientHeight -
42
+ inputPanelElement.clientHeight
43
+ )
44
+ }, [isWebchatOpen])
45
+
46
+ return {
47
+ calculateResizedPercentualWebchatHeight,
48
+ calculateResizedPxChatAreaHeight,
49
+ }
50
+ }
@@ -0,0 +1,43 @@
1
+ import { useContext } from 'react'
2
+
3
+ import { WebchatContext } from '../../contexts'
4
+ import { useWebchatDimensions } from './use-webchat-dimensions'
5
+
6
+ export const useWebchatResizer = () => {
7
+ const { webchatRef, chatAreaRef, inputPanelRef, headerRef } =
8
+ useContext(WebchatContext)
9
+
10
+ const {
11
+ calculateResizedPercentualWebchatHeight,
12
+ calculateResizedPxChatAreaHeight,
13
+ } = useWebchatDimensions()
14
+
15
+ const handleKeyboardShown = () => {
16
+ if (
17
+ webchatRef.current &&
18
+ chatAreaRef.current &&
19
+ headerRef.current &&
20
+ inputPanelRef.current
21
+ ) {
22
+ webchatRef.current.style.height = `${calculateResizedPercentualWebchatHeight()}%`
23
+ chatAreaRef.current.style.height = `${calculateResizedPxChatAreaHeight()}px`
24
+ }
25
+ }
26
+
27
+ const handleKeyboardHidden = () => {
28
+ if (
29
+ webchatRef.current &&
30
+ chatAreaRef.current &&
31
+ inputPanelRef.current &&
32
+ headerRef.current
33
+ ) {
34
+ webchatRef.current.style.height = '100%'
35
+ chatAreaRef.current.style.height = `${calculateResizedPxChatAreaHeight()}px`
36
+ }
37
+ }
38
+
39
+ return {
40
+ handleKeyboardShown,
41
+ handleKeyboardHidden,
42
+ }
43
+ }
@@ -1,5 +1,5 @@
1
1
  import { Input, Session } from '@botonic/core'
2
- import { useReducer } from 'react'
2
+ import { useReducer, useRef } from 'react'
3
3
 
4
4
  import { ThemeProps, Webview } from '../../components/index-types'
5
5
  import { COLORS, WEBCHAT } from '../../constants'
@@ -42,7 +42,6 @@ export const webchatInitialState: WebchatState = {
42
42
  isCustomComponentRendered: false,
43
43
  lastMessageUpdate: undefined,
44
44
  currentAttachment: undefined,
45
- jwt: undefined,
46
45
  numUnreadMessages: 0,
47
46
  isLastMessageVisible: true,
48
47
  }
@@ -53,6 +52,13 @@ export function useWebchat() {
53
52
  webchatInitialState
54
53
  )
55
54
 
55
+ const webchatRef = useRef<HTMLDivElement | null>(null)
56
+ const chatAreaRef = useRef<HTMLDivElement | null>(null)
57
+ const inputPanelRef = useRef<HTMLDivElement | null>(null)
58
+ const headerRef = useRef<HTMLDivElement | null>(null)
59
+ const scrollableMessagesListRef = useRef<HTMLDivElement | null>(null)
60
+ const repliesRef = useRef<HTMLDivElement | null>(null)
61
+
56
62
  const addMessage = (message: WebchatMessage) =>
57
63
  webchatDispatch({ type: WebchatAction.ADD_MESSAGE, payload: message })
58
64
 
@@ -177,13 +183,6 @@ export function useWebchat() {
177
183
  })
178
184
  }
179
185
 
180
- const updateJwt = (jwt: string) => {
181
- webchatDispatch({
182
- type: WebchatAction.UPDATE_JWT,
183
- payload: jwt,
184
- })
185
- }
186
-
187
186
  const resetUnreadMessages = () => {
188
187
  webchatDispatch({
189
188
  type: WebchatAction.RESET_UNREAD_MESSAGES,
@@ -213,7 +212,6 @@ export function useWebchat() {
213
212
  toggleWebchat,
214
213
  updateDevSettings,
215
214
  updateHandoff,
216
- updateJwt,
217
215
  updateLastMessageDate,
218
216
  updateLastRoutePath,
219
217
  updateLatestInput,
@@ -225,5 +223,11 @@ export function useWebchat() {
225
223
  updateWebview,
226
224
  webchatDispatch,
227
225
  webchatState,
226
+ webchatRef,
227
+ headerRef,
228
+ chatAreaRef,
229
+ scrollableMessagesListRef,
230
+ repliesRef,
231
+ inputPanelRef,
228
232
  }
229
233
  }
@@ -47,7 +47,6 @@ export interface WebchatState {
47
47
  isCustomComponentRendered: boolean
48
48
  lastMessageUpdate?: string
49
49
  currentAttachment?: File
50
- jwt?: string
51
50
  numUnreadMessages: number
52
51
  isLastMessageVisible: boolean
53
52
  }
@@ -1,28 +1,23 @@
1
1
  import React, { useContext, useEffect, useRef, useState } from 'react'
2
2
 
3
- import { ROLES, WEBCHAT } from '../../constants'
3
+ import { ROLES } from '../../constants'
4
4
  import { WebchatContext } from '../../contexts'
5
- import { StyledScrollbar } from '../components/styled-scrollbar'
6
- import { TypingIndicator } from '../components/typing-indicator'
5
+ import { BotonicContainerId } from '../constants'
6
+ import { TypingIndicator } from '../typing-indicator'
7
7
  import { IntroMessage } from './intro-message'
8
8
  import { ScrollButton } from './scroll-button'
9
- import { ContainerMessage } from './styles'
9
+ import { ContainerMessage, ScrollableMessageList } from './styles'
10
10
  import { UnreadMessagesBanner } from './unread-messages-banner'
11
11
  import { useNotifications } from './use-notifications'
12
12
 
13
13
  export const WebchatMessageList = () => {
14
14
  const {
15
15
  webchatState,
16
- getThemeProperty,
17
16
  resetUnreadMessages,
18
17
  setLastMessageVisible,
18
+ scrollableMessagesListRef,
19
19
  } = useContext(WebchatContext)
20
20
 
21
- const scrollbarOptions = {
22
- ...{ enable: true, autoHide: true },
23
- ...getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.scrollbar),
24
- }
25
-
26
21
  const [firstUnreadMessageId, setFirstUnreadMessageId] = useState()
27
22
 
28
23
  const lastMessageBottomRef = useRef<HTMLDivElement>(null)
@@ -104,15 +99,10 @@ export const WebchatMessageList = () => {
104
99
 
105
100
  return (
106
101
  <>
107
- <StyledScrollbar
102
+ <ScrollableMessageList
103
+ id={BotonicContainerId.ScrollableMessagesList}
104
+ ref={scrollableMessagesListRef}
108
105
  role={ROLES.MESSAGE_LIST}
109
- // TODO: Distinguis between multiple instances of webchat, e.g. `${uniqueId}-botonic-scrollable`
110
- id='botonic-scrollable-content'
111
- // @ts-ignore
112
- scrollbar={scrollbarOptions}
113
- autoHide={scrollbarOptions.autoHide}
114
- ismessagescontainer={true.toString()}
115
- style={{ flex: 1 }}
116
106
  >
117
107
  <IntroMessage />
118
108
  {webchatState.messagesComponents.map((messageComponent, index) => {
@@ -136,7 +126,7 @@ export const WebchatMessageList = () => {
136
126
  )
137
127
  })}
138
128
  {webchatState.typing && <TypingIndicator />}
139
- </StyledScrollbar>
129
+ </ScrollableMessageList>
140
130
  {showScrollButton && <ScrollButton handleClick={handleScrollToBottom} />}
141
131
  </>
142
132
  )
@@ -1,8 +1,6 @@
1
- import React, { useContext } from 'react'
1
+ import React from 'react'
2
2
 
3
3
  import ArrowScrollDown from '../../assets/arrow-scroll-down.svg'
4
- import { WEBCHAT } from '../../constants'
5
- import { WebchatContext } from '../../contexts'
6
4
  import { resolveImage } from '../../util/environment'
7
5
  import { ContainerScrollButton } from './styles'
8
6
  import { useDebounce } from './use-debounce'
@@ -47,3 +47,13 @@ export const ContainerUnreadMessagesBanner = styled.div`
47
47
  width: 10px;
48
48
  }
49
49
  `
50
+
51
+ export const ScrollableMessageList = styled.div`
52
+ display: flex;
53
+ flex: 1;
54
+ flex-direction: column;
55
+ overflow-y: auto;
56
+ overflow-x: hidden;
57
+ overscroll-behavior: contain; // https://css-tricks.com/almanac/properties/o/overscroll-behavior/
58
+ -webkit-overflow-scrolling: touch;
59
+ `
@@ -3,7 +3,12 @@ import styled from 'styled-components'
3
3
 
4
4
  import { WEBCHAT } from '../constants'
5
5
  import { WebchatContext } from '../contexts'
6
- import { StyledScrollbar } from '../webchat/components/styled-scrollbar'
6
+ import { BotonicContainerId } from './constants'
7
+
8
+ const ScrollableReplies = styled.div`
9
+ overscroll-behavior: contain;
10
+ -webkit-overflow-scrolling: touch;
11
+ `
7
12
 
8
13
  const RepliesContainer = styled.div`
9
14
  display: flex;
@@ -13,6 +18,7 @@ const RepliesContainer = styled.div`
13
18
  padding-bottom: 10px;
14
19
  margin-left: 5px;
15
20
  margin-right: 5px;
21
+ overflow-x: scroll;
16
22
  `
17
23
 
18
24
  const ReplyContainer = styled.div`
@@ -28,11 +34,8 @@ const options = {
28
34
  }
29
35
 
30
36
  export const WebchatReplies = props => {
31
- const { webchatState, getThemeProperty } = useContext(WebchatContext)
32
- const scrollbarOptions = {
33
- ...{ enable: true, autoHide: true },
34
- ...getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.scrollbar),
35
- }
37
+ const { webchatState, getThemeProperty, repliesRef } =
38
+ useContext(WebchatContext)
36
39
  let justifyContent = 'center'
37
40
  const flexWrap = getThemeProperty(
38
41
  WEBCHAT.CUSTOM_PROPERTIES.wrapReplies,
@@ -44,11 +47,10 @@ export const WebchatReplies = props => {
44
47
  options[getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.alignReplies)]
45
48
 
46
49
  return (
47
- <StyledScrollbar
48
- scrollbar={scrollbarOptions}
49
- autoHide={scrollbarOptions.autoHide}
50
- >
50
+ <ScrollableReplies>
51
51
  <RepliesContainer
52
+ id={BotonicContainerId.RepliesContainer}
53
+ ref={repliesRef}
52
54
  className='replies-container'
53
55
  justify={justifyContent}
54
56
  wrap={flexWrap}
@@ -57,6 +59,6 @@ export const WebchatReplies = props => {
57
59
  <ReplyContainer key={i}>{r}</ReplyContainer>
58
60
  ))}
59
61
  </RepliesContainer>
60
- </StyledScrollbar>
62
+ </ScrollableReplies>
61
63
  )
62
64
  }
@@ -0,0 +1,16 @@
1
+ import React from 'react'
2
+
3
+ import { COLORS, ROLES } from '../../constants'
4
+ import { Dot, TypingIndicatorWrapper } from './styles'
5
+
6
+ export const TypingIndicator = () => (
7
+ <TypingIndicatorWrapper
8
+ role={ROLES.TYPING_INDICATOR}
9
+ className='typing-indicator'
10
+ backgroundColor={COLORS.SEASHELL_WHITE}
11
+ >
12
+ <Dot />
13
+ <Dot />
14
+ <Dot />
15
+ </TypingIndicatorWrapper>
16
+ )
@@ -0,0 +1,50 @@
1
+ import styled, { keyframes } from 'styled-components'
2
+
3
+ const blink = keyframes`
4
+ 50% {
5
+ opacity: 1;
6
+ }
7
+ `
8
+
9
+ const bulge = keyframes`
10
+ 50% {
11
+ transform: scale(1.05);
12
+ }
13
+ `
14
+
15
+ interface TypingIndicatorWrapperProps {
16
+ backgroundColor: string
17
+ }
18
+
19
+ export const TypingIndicatorWrapper = styled.div<TypingIndicatorWrapperProps>`
20
+ will-change: transform;
21
+ width: 44px;
22
+ line-height: 0px;
23
+ border-radius: 20px;
24
+ padding: 8px 2px 8px;
25
+ text-align: center;
26
+ display: block;
27
+ margin: 8px;
28
+ position: relative;
29
+ animation: 2s ${bulge} infinite ease-out;
30
+ background-color: ${props => props.backgroundColor};
31
+ `
32
+
33
+ export const Dot = styled.span`
34
+ height: 6px;
35
+ width: 6px;
36
+ margin: 0 1px;
37
+ background-color: #9e9ea1;
38
+ display: inline-block;
39
+ border-radius: 50%;
40
+ opacity: 0.4;
41
+ &:nth-of-type(1) {
42
+ animation: 1s ${blink} infinite 0.3333s;
43
+ }
44
+ &:nth-of-type(2) {
45
+ animation: 1s ${blink} infinite 0.6666s;
46
+ }
47
+ &:nth-of-type(3) {
48
+ animation: 1s ${blink} infinite 1s;
49
+ }
50
+ `
@@ -0,0 +1,35 @@
1
+ import React, { useContext, useEffect, useState } from 'react'
2
+
3
+ import { WebchatContext } from '../../contexts'
4
+ import { BotonicContainerId } from '../constants'
5
+ import { useWebchatDimensions } from '../hooks'
6
+ import { WebchatMessageList } from '../message-list'
7
+ import { WebchatReplies } from '../replies'
8
+ import { StyledWebchatChatArea } from './styles'
9
+
10
+ export const WebchatChatArea = () => {
11
+ const {
12
+ webchatState: { replies },
13
+ chatAreaRef,
14
+ } = useContext(WebchatContext)
15
+
16
+ const { calculateResizedPxChatAreaHeight } = useWebchatDimensions()
17
+ const [chatAreaHeight, setChatAreaHeight] = useState(0)
18
+
19
+ useEffect(() => {
20
+ setChatAreaHeight(calculateResizedPxChatAreaHeight())
21
+ }, [])
22
+
23
+ return (
24
+ <StyledWebchatChatArea
25
+ id={BotonicContainerId.ChatArea}
26
+ ref={chatAreaRef}
27
+ height={chatAreaHeight}
28
+ >
29
+ <WebchatMessageList />
30
+ {replies && Object.keys(replies).length > 0 && (
31
+ <WebchatReplies replies={replies} />
32
+ )}
33
+ </StyledWebchatChatArea>
34
+ )
35
+ }
@@ -0,0 +1,9 @@
1
+ import styled from 'styled-components'
2
+
3
+ export const StyledWebchatChatArea = styled.div<{ height: number }>`
4
+ display: inherit;
5
+ flex-direction: inherit;
6
+ height: ${props => props.height}px;
7
+ width: inherit;
8
+ overflow: inherit;
9
+ `
@@ -5,7 +5,7 @@ import { v4 as uuidv4 } from 'uuid'
5
5
  import { WEBCHAT } from '../../constants'
6
6
  import { WebchatContext } from '../../contexts'
7
7
  import { getFullMimeWhitelist } from '../../message-utils'
8
- import { DeviceAdapter } from '../devices/device-adapter'
8
+ import { BotonicContainerId } from '../constants'
9
9
  import { Attachment } from './attachment'
10
10
  import { EmojiPicker } from './emoji-picker'
11
11
  import { OpenedEmojiPicker } from './opened-emoji-picker'
@@ -20,7 +20,7 @@ interface WebchatInputPanelProps {
20
20
  enableAttachments: boolean
21
21
  handleAttachment: (event: any) => void
22
22
  textareaRef: React.MutableRefObject<HTMLTextAreaElement>
23
- deviceAdapter: DeviceAdapter
23
+ host: HTMLElement
24
24
  onUserInput?: (event: any) => Promise<void>
25
25
  }
26
26
 
@@ -30,7 +30,7 @@ export const WebchatInputPanel = ({
30
30
  enableAttachments,
31
31
  handleAttachment,
32
32
  textareaRef,
33
- deviceAdapter,
33
+ host,
34
34
  onUserInput,
35
35
  }: WebchatInputPanelProps) => {
36
36
  const {
@@ -39,6 +39,7 @@ export const WebchatInputPanel = ({
39
39
  togglePersistentMenu,
40
40
  toggleEmojiPicker,
41
41
  webchatState,
42
+ inputPanelRef,
42
43
  } = useContext(WebchatContext)
43
44
 
44
45
  const handleSelectedEmoji = event => {
@@ -77,6 +78,8 @@ export const WebchatInputPanel = ({
77
78
 
78
79
  return (
79
80
  <UserInputContainer
81
+ id={BotonicContainerId.InputPanel}
82
+ ref={inputPanelRef}
80
83
  style={{
81
84
  ...getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.userInputStyle),
82
85
  }}
@@ -92,7 +95,7 @@ export const WebchatInputPanel = ({
92
95
  <PersistentMenu onClick={handleMenu} persistentMenu={persistentMenu} />
93
96
 
94
97
  <Textarea
95
- deviceAdapter={deviceAdapter}
98
+ host={host}
96
99
  persistentMenu={persistentMenu}
97
100
  textareaRef={textareaRef}
98
101
  sendChatEvent={sendChatEvent}
@@ -5,11 +5,11 @@ import { PersistentMenuTheme } from '../../components/index-types'
5
5
  import { WEBCHAT } from '../../constants'
6
6
  import { WebchatContext } from '../../contexts'
7
7
  import { Typing } from '../../index-types'
8
- import { DeviceAdapter } from '../devices/device-adapter'
8
+ import { useDeviceAdapter } from '../hooks'
9
9
  import { TextAreaContainer } from './styles'
10
10
 
11
11
  interface TextareaProps {
12
- deviceAdapter: DeviceAdapter
12
+ host: HTMLElement
13
13
  persistentMenu: PersistentMenuTheme
14
14
  textareaRef: React.MutableRefObject<HTMLTextAreaElement>
15
15
  sendChatEvent: (event: string) => Promise<void>
@@ -17,13 +17,15 @@ interface TextareaProps {
17
17
  }
18
18
 
19
19
  export const Textarea = ({
20
- deviceAdapter,
20
+ host,
21
21
  persistentMenu,
22
22
  textareaRef,
23
23
  sendChatEvent,
24
24
  sendTextAreaText,
25
25
  }: TextareaProps) => {
26
- const { getThemeProperty } = useContext(WebchatContext)
26
+ const { getThemeProperty, webchatState } = useContext(WebchatContext)
27
+
28
+ useDeviceAdapter(host, webchatState.isWebchatOpen)
27
29
 
28
30
  let isTyping = false
29
31
  let typingTimeout
@@ -74,12 +76,6 @@ export const Textarea = ({
74
76
  <TextareaAutosize
75
77
  ref={(ref: HTMLTextAreaElement) => (textareaRef.current = ref)}
76
78
  name='text'
77
- onFocus={() => {
78
- deviceAdapter.onFocus()
79
- }}
80
- onBlur={() => {
81
- deviceAdapter.onBlur()
82
- }}
83
79
  maxRows={4}
84
80
  wrap='soft'
85
81
  maxLength={1000}
@@ -92,7 +88,7 @@ export const Textarea = ({
92
88
  onKeyUp={onKeyUp}
93
89
  style={{
94
90
  display: 'flex',
95
- fontSize: deviceAdapter.fontSize(14),
91
+ fontSize: 16,
96
92
  width: '100%',
97
93
  border: 'none',
98
94
  resize: 'none',
@@ -48,8 +48,6 @@ export function webchatReducer(
48
48
  return { ...state, lastRoutePath: action.payload }
49
49
  case WebchatAction.SET_CURRENT_ATTACHMENT:
50
50
  return { ...state, currentAttachment: action.payload }
51
- case WebchatAction.UPDATE_JWT:
52
- return { ...state, jwt: action.payload }
53
51
  default:
54
52
  return messagesReducer(state, action)
55
53
  }