@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.
- package/lib/cjs/components/carousel.js +6 -3
- package/lib/cjs/components/carousel.js.map +1 -1
- package/lib/cjs/constants.d.ts +0 -6
- package/lib/cjs/constants.js +0 -6
- package/lib/cjs/constants.js.map +1 -1
- package/lib/cjs/contexts.d.ts +1 -1
- package/lib/cjs/contexts.js +9 -3
- package/lib/cjs/contexts.js.map +1 -1
- package/lib/cjs/index-types.d.ts +7 -1
- package/lib/cjs/index-types.js +0 -5
- package/lib/cjs/index-types.js.map +1 -1
- package/lib/cjs/node-app.d.ts +0 -5
- package/lib/cjs/node-app.js +0 -5
- package/lib/cjs/node-app.js.map +1 -1
- package/lib/cjs/util/dom.d.ts +0 -10
- package/lib/cjs/util/dom.js +3 -29
- package/lib/cjs/util/dom.js.map +1 -1
- package/lib/cjs/webchat/actions.d.ts +0 -1
- package/lib/cjs/webchat/actions.js +0 -1
- package/lib/cjs/webchat/actions.js.map +1 -1
- package/lib/cjs/webchat/constants.d.ts +8 -0
- package/lib/cjs/webchat/constants.js +13 -0
- package/lib/cjs/webchat/constants.js.map +1 -0
- package/lib/cjs/webchat/header.d.ts +2 -2
- package/lib/cjs/webchat/header.js +14 -13
- package/lib/cjs/webchat/header.js.map +1 -1
- package/lib/cjs/webchat/hooks/index.d.ts +6 -0
- package/lib/cjs/webchat/hooks/index.js +13 -1
- package/lib/cjs/webchat/hooks/index.js.map +1 -1
- package/lib/cjs/webchat/hooks/use-device-adapter.d.ts +3 -0
- package/lib/cjs/webchat/hooks/use-device-adapter.js +46 -0
- package/lib/cjs/webchat/hooks/use-device-adapter.js.map +1 -0
- package/lib/cjs/webchat/hooks/use-scroll-to-bottom.d.ts +7 -0
- package/lib/cjs/webchat/hooks/use-scroll-to-bottom.js +26 -0
- package/lib/cjs/webchat/hooks/use-scroll-to-bottom.js.map +1 -0
- package/lib/cjs/webchat/hooks/use-scrollbar-controller.d.ts +6 -0
- package/lib/cjs/webchat/hooks/use-scrollbar-controller.js +140 -0
- package/lib/cjs/webchat/hooks/use-scrollbar-controller.js.map +1 -0
- package/lib/cjs/webchat/hooks/use-virtual-keyboard-detection.d.ts +3 -0
- package/lib/cjs/webchat/hooks/use-virtual-keyboard-detection.js +28 -0
- package/lib/cjs/webchat/hooks/use-virtual-keyboard-detection.js.map +1 -0
- package/lib/cjs/webchat/hooks/use-webchat-dimensions.d.ts +4 -0
- package/lib/cjs/webchat/hooks/use-webchat-dimensions.js +39 -0
- package/lib/cjs/webchat/hooks/use-webchat-dimensions.js.map +1 -0
- package/lib/cjs/webchat/hooks/use-webchat-resizer.d.ts +4 -0
- package/lib/cjs/webchat/hooks/use-webchat-resizer.js +34 -0
- package/lib/cjs/webchat/hooks/use-webchat-resizer.js.map +1 -0
- package/lib/cjs/webchat/hooks/use-webchat.d.ts +6 -1
- package/lib/cjs/webchat/hooks/use-webchat.js +12 -8
- package/lib/cjs/webchat/hooks/use-webchat.js.map +1 -1
- package/lib/cjs/webchat/index-types.d.ts +0 -1
- package/lib/cjs/webchat/message-list/index.js +4 -9
- package/lib/cjs/webchat/message-list/index.js.map +1 -1
- package/lib/cjs/webchat/message-list/scroll-button.js.map +1 -1
- package/lib/cjs/webchat/message-list/styles.d.ts +1 -0
- package/lib/cjs/webchat/message-list/styles.js +10 -1
- package/lib/cjs/webchat/message-list/styles.js.map +1 -1
- package/lib/cjs/webchat/replies.js +8 -4
- package/lib/cjs/webchat/replies.js.map +1 -1
- package/lib/cjs/webchat/typing-indicator/index.d.ts +1 -0
- package/lib/cjs/webchat/typing-indicator/index.js +9 -0
- package/lib/cjs/webchat/typing-indicator/index.js.map +1 -0
- package/lib/cjs/webchat/typing-indicator/styles.d.ts +6 -0
- package/lib/cjs/webchat/typing-indicator/styles.js +47 -0
- package/lib/cjs/webchat/typing-indicator/styles.js.map +1 -0
- package/lib/cjs/webchat/webchat-chat-area/index.d.ts +1 -0
- package/lib/cjs/webchat/webchat-chat-area/index.js +22 -0
- package/lib/cjs/webchat/webchat-chat-area/index.js.map +1 -0
- package/lib/cjs/webchat/webchat-chat-area/styles.d.ts +3 -0
- package/lib/cjs/webchat/webchat-chat-area/styles.js +13 -0
- package/lib/cjs/webchat/webchat-chat-area/styles.js.map +1 -0
- package/lib/cjs/webchat/webchat-input-panel/index.d.ts +2 -3
- package/lib/cjs/webchat/webchat-input-panel/index.js +4 -3
- package/lib/cjs/webchat/webchat-input-panel/index.js.map +1 -1
- package/lib/cjs/webchat/webchat-input-panel/textarea.d.ts +2 -3
- package/lib/cjs/webchat/webchat-input-panel/textarea.js +5 -7
- package/lib/cjs/webchat/webchat-input-panel/textarea.js.map +1 -1
- package/lib/cjs/webchat/webchat-reducer.js +0 -2
- package/lib/cjs/webchat/webchat-reducer.js.map +1 -1
- package/lib/cjs/webchat/webchat.js +18 -18
- package/lib/cjs/webchat/webchat.js.map +1 -1
- package/lib/cjs/webchat/webview.js +13 -22
- package/lib/cjs/webchat/webview.js.map +1 -1
- package/lib/cjs/webchat-app.d.ts +1 -1
- package/lib/cjs/webchat-app.js +3 -1
- package/lib/cjs/webchat-app.js.map +1 -1
- package/lib/cjs/webview-app.js +11 -11
- package/lib/cjs/webview-app.js.map +1 -1
- package/lib/esm/components/carousel.js +6 -3
- package/lib/esm/components/carousel.js.map +1 -1
- package/lib/esm/constants.d.ts +0 -6
- package/lib/esm/constants.js +0 -6
- package/lib/esm/constants.js.map +1 -1
- package/lib/esm/contexts.d.ts +1 -1
- package/lib/esm/contexts.js +9 -3
- package/lib/esm/contexts.js.map +1 -1
- package/lib/esm/index-types.d.ts +7 -1
- package/lib/esm/index-types.js +0 -5
- package/lib/esm/index-types.js.map +1 -1
- package/lib/esm/node-app.d.ts +0 -5
- package/lib/esm/node-app.js +0 -5
- package/lib/esm/node-app.js.map +1 -1
- package/lib/esm/util/dom.d.ts +0 -10
- package/lib/esm/util/dom.js +2 -25
- package/lib/esm/util/dom.js.map +1 -1
- package/lib/esm/webchat/actions.d.ts +0 -1
- package/lib/esm/webchat/actions.js +0 -1
- package/lib/esm/webchat/actions.js.map +1 -1
- package/lib/esm/webchat/constants.d.ts +8 -0
- package/lib/esm/webchat/constants.js +10 -0
- package/lib/esm/webchat/constants.js.map +1 -0
- package/lib/esm/webchat/header.d.ts +2 -2
- package/lib/esm/webchat/header.js +14 -12
- package/lib/esm/webchat/header.js.map +1 -1
- package/lib/esm/webchat/hooks/index.d.ts +6 -0
- package/lib/esm/webchat/hooks/index.js +6 -0
- package/lib/esm/webchat/hooks/index.js.map +1 -1
- package/lib/esm/webchat/hooks/use-device-adapter.d.ts +3 -0
- package/lib/esm/webchat/hooks/use-device-adapter.js +42 -0
- package/lib/esm/webchat/hooks/use-device-adapter.js.map +1 -0
- package/lib/esm/webchat/hooks/use-scroll-to-bottom.d.ts +7 -0
- package/lib/esm/webchat/hooks/use-scroll-to-bottom.js +22 -0
- package/lib/esm/webchat/hooks/use-scroll-to-bottom.js.map +1 -0
- package/lib/esm/webchat/hooks/use-scrollbar-controller.d.ts +6 -0
- package/lib/esm/webchat/hooks/use-scrollbar-controller.js +136 -0
- package/lib/esm/webchat/hooks/use-scrollbar-controller.js.map +1 -0
- package/lib/esm/webchat/hooks/use-virtual-keyboard-detection.d.ts +3 -0
- package/lib/esm/webchat/hooks/use-virtual-keyboard-detection.js +24 -0
- package/lib/esm/webchat/hooks/use-virtual-keyboard-detection.js.map +1 -0
- package/lib/esm/webchat/hooks/use-webchat-dimensions.d.ts +4 -0
- package/lib/esm/webchat/hooks/use-webchat-dimensions.js +35 -0
- package/lib/esm/webchat/hooks/use-webchat-dimensions.js.map +1 -0
- package/lib/esm/webchat/hooks/use-webchat-resizer.d.ts +4 -0
- package/lib/esm/webchat/hooks/use-webchat-resizer.js +30 -0
- package/lib/esm/webchat/hooks/use-webchat-resizer.js.map +1 -0
- package/lib/esm/webchat/hooks/use-webchat.d.ts +6 -1
- package/lib/esm/webchat/hooks/use-webchat.js +13 -9
- package/lib/esm/webchat/hooks/use-webchat.js.map +1 -1
- package/lib/esm/webchat/index-types.d.ts +0 -1
- package/lib/esm/webchat/message-list/index.js +6 -11
- package/lib/esm/webchat/message-list/index.js.map +1 -1
- package/lib/esm/webchat/message-list/scroll-button.js.map +1 -1
- package/lib/esm/webchat/message-list/styles.d.ts +1 -0
- package/lib/esm/webchat/message-list/styles.js +9 -0
- package/lib/esm/webchat/message-list/styles.js.map +1 -1
- package/lib/esm/webchat/replies.js +8 -4
- package/lib/esm/webchat/replies.js.map +1 -1
- package/lib/esm/webchat/typing-indicator/index.d.ts +1 -0
- package/lib/esm/webchat/typing-indicator/index.js +5 -0
- package/lib/esm/webchat/typing-indicator/index.js.map +1 -0
- package/lib/esm/webchat/typing-indicator/styles.d.ts +6 -0
- package/lib/esm/webchat/typing-indicator/styles.js +43 -0
- package/lib/esm/webchat/typing-indicator/styles.js.map +1 -0
- package/lib/esm/webchat/webchat-chat-area/index.d.ts +1 -0
- package/lib/esm/webchat/webchat-chat-area/index.js +18 -0
- package/lib/esm/webchat/webchat-chat-area/index.js.map +1 -0
- package/lib/esm/webchat/webchat-chat-area/styles.d.ts +3 -0
- package/lib/esm/webchat/webchat-chat-area/styles.js +9 -0
- package/lib/esm/webchat/webchat-chat-area/styles.js.map +1 -0
- package/lib/esm/webchat/webchat-input-panel/index.d.ts +2 -3
- package/lib/esm/webchat/webchat-input-panel/index.js +4 -3
- package/lib/esm/webchat/webchat-input-panel/index.js.map +1 -1
- package/lib/esm/webchat/webchat-input-panel/textarea.d.ts +2 -3
- package/lib/esm/webchat/webchat-input-panel/textarea.js +5 -7
- package/lib/esm/webchat/webchat-input-panel/textarea.js.map +1 -1
- package/lib/esm/webchat/webchat-reducer.js +0 -2
- package/lib/esm/webchat/webchat-reducer.js.map +1 -1
- package/lib/esm/webchat/webchat.js +19 -19
- package/lib/esm/webchat/webchat.js.map +1 -1
- package/lib/esm/webchat/webview.js +14 -22
- package/lib/esm/webchat/webview.js.map +1 -1
- package/lib/esm/webchat-app.d.ts +1 -1
- package/lib/esm/webchat-app.js +3 -1
- package/lib/esm/webchat-app.js.map +1 -1
- package/lib/esm/webview-app.js +11 -11
- package/lib/esm/webview-app.js.map +1 -1
- package/package.json +3 -6
- package/src/components/carousel.jsx +8 -10
- package/src/constants.js +0 -6
- package/src/contexts.tsx +9 -3
- package/src/index-types.ts +7 -52
- package/src/node-app.jsx +0 -6
- package/src/util/dom.js +2 -35
- package/src/webchat/actions.ts +0 -1
- package/src/webchat/constants.ts +9 -0
- package/src/webchat/header.jsx +31 -20
- package/src/webchat/hooks/index.ts +6 -0
- package/src/webchat/hooks/use-device-adapter.ts +50 -0
- package/src/webchat/hooks/use-scroll-to-bottom.ts +29 -0
- package/src/webchat/hooks/use-scrollbar-controller.ts +159 -0
- package/src/webchat/hooks/use-virtual-keyboard-detection.ts +27 -0
- package/src/webchat/hooks/use-webchat-dimensions.ts +50 -0
- package/src/webchat/hooks/use-webchat-resizer.ts +43 -0
- package/src/webchat/hooks/use-webchat.ts +14 -10
- package/src/webchat/index-types.ts +0 -1
- package/src/webchat/message-list/index.tsx +9 -19
- package/src/webchat/message-list/scroll-button.tsx +1 -3
- package/src/webchat/message-list/styles.ts +10 -0
- package/src/webchat/replies.jsx +13 -11
- package/src/webchat/typing-indicator/index.tsx +16 -0
- package/src/webchat/typing-indicator/styles.ts +50 -0
- package/src/webchat/webchat-chat-area/index.tsx +35 -0
- package/src/webchat/webchat-chat-area/styles.ts +9 -0
- package/src/webchat/webchat-input-panel/index.tsx +7 -4
- package/src/webchat/webchat-input-panel/textarea.tsx +7 -11
- package/src/webchat/webchat-reducer.ts +0 -2
- package/src/webchat/webchat.jsx +27 -20
- package/src/webchat/webview.jsx +14 -23
- package/src/webchat-app.jsx +2 -2
- package/src/webview-app.tsx +16 -11
- package/lib/cjs/webchat/components/styled-scrollbar.d.ts +0 -2
- package/lib/cjs/webchat/components/styled-scrollbar.js +0 -54
- package/lib/cjs/webchat/components/styled-scrollbar.js.map +0 -1
- package/lib/cjs/webchat/components/styled-scrollbar.scss +0 -12
- package/lib/cjs/webchat/components/typing-indicator.d.ts +0 -1
- package/lib/cjs/webchat/components/typing-indicator.js +0 -11
- package/lib/cjs/webchat/components/typing-indicator.js.map +0 -1
- package/lib/cjs/webchat/components/typing-indicator.scss +0 -38
- package/lib/cjs/webchat/devices/device-adapter.d.ts +0 -12
- package/lib/cjs/webchat/devices/device-adapter.js +0 -44
- package/lib/cjs/webchat/devices/device-adapter.js.map +0 -1
- package/lib/cjs/webchat/devices/scrollbar-controller.d.ts +0 -12
- package/lib/cjs/webchat/devices/scrollbar-controller.js +0 -103
- package/lib/cjs/webchat/devices/scrollbar-controller.js.map +0 -1
- package/lib/cjs/webchat/devices/webchat-resizer.d.ts +0 -9
- package/lib/cjs/webchat/devices/webchat-resizer.js +0 -47
- package/lib/cjs/webchat/devices/webchat-resizer.js.map +0 -1
- package/lib/esm/webchat/components/styled-scrollbar.d.ts +0 -2
- package/lib/esm/webchat/components/styled-scrollbar.js +0 -50
- package/lib/esm/webchat/components/styled-scrollbar.js.map +0 -1
- package/lib/esm/webchat/components/styled-scrollbar.scss +0 -12
- package/lib/esm/webchat/components/typing-indicator.d.ts +0 -1
- package/lib/esm/webchat/components/typing-indicator.js +0 -6
- package/lib/esm/webchat/components/typing-indicator.js.map +0 -1
- package/lib/esm/webchat/components/typing-indicator.scss +0 -38
- package/lib/esm/webchat/devices/device-adapter.d.ts +0 -12
- package/lib/esm/webchat/devices/device-adapter.js +0 -40
- package/lib/esm/webchat/devices/device-adapter.js.map +0 -1
- package/lib/esm/webchat/devices/scrollbar-controller.d.ts +0 -12
- package/lib/esm/webchat/devices/scrollbar-controller.js +0 -99
- package/lib/esm/webchat/devices/scrollbar-controller.js.map +0 -1
- package/lib/esm/webchat/devices/webchat-resizer.d.ts +0 -9
- package/lib/esm/webchat/devices/webchat-resizer.js +0 -43
- package/lib/esm/webchat/devices/webchat-resizer.js.map +0 -1
- package/src/webchat/components/styled-scrollbar.jsx +0 -60
- package/src/webchat/components/styled-scrollbar.scss +0 -12
- package/src/webchat/components/typing-indicator.jsx +0 -17
- package/src/webchat/components/typing-indicator.scss +0 -38
- package/src/webchat/devices/device-adapter.js +0 -43
- package/src/webchat/devices/scrollbar-controller.js +0 -107
- 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
|
}
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
import React, { useContext, useEffect, useRef, useState } from 'react'
|
|
2
2
|
|
|
3
|
-
import { ROLES
|
|
3
|
+
import { ROLES } from '../../constants'
|
|
4
4
|
import { WebchatContext } from '../../contexts'
|
|
5
|
-
import {
|
|
6
|
-
import { TypingIndicator } from '../
|
|
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
|
-
<
|
|
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
|
-
</
|
|
129
|
+
</ScrollableMessageList>
|
|
140
130
|
{showScrollButton && <ScrollButton handleClick={handleScrollToBottom} />}
|
|
141
131
|
</>
|
|
142
132
|
)
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import 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
|
+
`
|
package/src/webchat/replies.jsx
CHANGED
|
@@ -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 {
|
|
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 } =
|
|
32
|
-
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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
|
+
}
|
|
@@ -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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
8
|
+
import { useDeviceAdapter } from '../hooks'
|
|
9
9
|
import { TextAreaContainer } from './styles'
|
|
10
10
|
|
|
11
11
|
interface TextareaProps {
|
|
12
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
}
|