@botonic/react 0.31.1-alpha.1 → 0.31.1
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/webchat/context/index.js +4 -1
- package/lib/cjs/webchat/context/index.js.map +1 -1
- package/lib/cjs/webchat/context/types.d.ts +3 -1
- package/lib/cjs/webchat/context/use-webchat.d.ts +1 -1
- package/lib/cjs/webchat/context/use-webchat.js +2 -2
- package/lib/cjs/webchat/context/use-webchat.js.map +1 -1
- package/lib/cjs/webchat/hooks/use-scrollbar-controller.js +14 -14
- package/lib/cjs/webchat/hooks/use-scrollbar-controller.js.map +1 -1
- package/lib/cjs/webchat/hooks/use-webchat-dimensions.js +3 -3
- package/lib/cjs/webchat/hooks/use-webchat-dimensions.js.map +1 -1
- package/lib/cjs/webchat/hooks/use-webchat-resizer.js +5 -5
- package/lib/cjs/webchat/hooks/use-webchat-resizer.js.map +1 -1
- package/lib/cjs/webchat/webchat.js +9 -14
- package/lib/cjs/webchat/webchat.js.map +1 -1
- package/lib/cjs/webchat/webview/header.d.ts +1 -0
- package/lib/cjs/webchat/webview/header.js +16 -0
- package/lib/cjs/webchat/webview/header.js.map +1 -0
- package/lib/cjs/webchat/webview/index.d.ts +1 -0
- package/lib/cjs/webchat/webview/index.js +49 -0
- package/lib/cjs/webchat/webview/index.js.map +1 -0
- package/lib/cjs/webchat/webview/styles.d.ts +7 -0
- package/lib/cjs/webchat/webview/styles.js +46 -0
- package/lib/cjs/webchat/webview/styles.js.map +1 -0
- package/lib/esm/webchat/context/index.js +4 -1
- package/lib/esm/webchat/context/index.js.map +1 -1
- package/lib/esm/webchat/context/types.d.ts +3 -1
- package/lib/esm/webchat/context/use-webchat.d.ts +1 -1
- package/lib/esm/webchat/context/use-webchat.js +2 -2
- package/lib/esm/webchat/context/use-webchat.js.map +1 -1
- package/lib/esm/webchat/hooks/use-scrollbar-controller.js +14 -14
- package/lib/esm/webchat/hooks/use-scrollbar-controller.js.map +1 -1
- package/lib/esm/webchat/hooks/use-webchat-dimensions.js +3 -3
- package/lib/esm/webchat/hooks/use-webchat-dimensions.js.map +1 -1
- package/lib/esm/webchat/hooks/use-webchat-resizer.js +5 -5
- package/lib/esm/webchat/hooks/use-webchat-resizer.js.map +1 -1
- package/lib/esm/webchat/webchat.js +9 -14
- package/lib/esm/webchat/webchat.js.map +1 -1
- package/lib/esm/webchat/webview/header.d.ts +1 -0
- package/lib/esm/webchat/webview/header.js +12 -0
- package/lib/esm/webchat/webview/header.js.map +1 -0
- package/lib/esm/webchat/webview/index.d.ts +1 -0
- package/lib/esm/webchat/webview/index.js +45 -0
- package/lib/esm/webchat/webview/index.js.map +1 -0
- package/lib/esm/webchat/webview/styles.d.ts +7 -0
- package/lib/esm/webchat/webview/styles.js +42 -0
- package/lib/esm/webchat/webview/styles.js.map +1 -0
- package/package.json +2 -2
- package/src/webchat/context/index.tsx +4 -1
- package/src/webchat/context/types.ts +3 -1
- package/src/webchat/context/use-webchat.ts +3 -3
- package/src/webchat/hooks/use-scrollbar-controller.ts +20 -15
- package/src/webchat/hooks/use-webchat-dimensions.ts +3 -3
- package/src/webchat/hooks/use-webchat-resizer.ts +5 -5
- package/src/webchat/webchat.tsx +10 -29
- package/src/webchat/webview/header.tsx +22 -0
- package/src/webchat/webview/index.tsx +80 -0
- package/src/webchat/webview/styles.ts +48 -0
- package/lib/cjs/webchat/webview.d.ts +0 -2
- package/lib/cjs/webchat/webview.js +0 -76
- package/lib/cjs/webchat/webview.js.map +0 -1
- package/lib/esm/webchat/webview.d.ts +0 -2
- package/lib/esm/webchat/webview.js +0 -71
- package/lib/esm/webchat/webview.js.map +0 -1
- package/src/webchat/webview.jsx +0 -106
|
@@ -13,6 +13,9 @@ export const WebchatContext = createContext<WebchatContextProps>({
|
|
|
13
13
|
getThemeProperty: () => {
|
|
14
14
|
return
|
|
15
15
|
}, // used to retrieve a specific property of the theme defined by the developer in his 'webchat/index.js'
|
|
16
|
+
closeWebview: async () => {
|
|
17
|
+
return
|
|
18
|
+
},
|
|
16
19
|
openWebview: () => {
|
|
17
20
|
return
|
|
18
21
|
},
|
|
@@ -72,7 +75,7 @@ export const WebchatContext = createContext<WebchatContextProps>({
|
|
|
72
75
|
trackEvent: async () => {
|
|
73
76
|
return
|
|
74
77
|
},
|
|
75
|
-
|
|
78
|
+
webchatContainerRef: { current: null },
|
|
76
79
|
chatAreaRef: { current: null },
|
|
77
80
|
inputPanelRef: { current: null },
|
|
78
81
|
headerRef: { current: null },
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from '@botonic/core'
|
|
6
6
|
|
|
7
7
|
import { Reply, WebchatSettingsProps, Webview } from '../../components'
|
|
8
|
+
import { CloseWebviewOptions } from '../../contexts'
|
|
8
9
|
import { TrackEventFunction, WebchatMessage } from '../../index-types'
|
|
9
10
|
import { WebchatStateTheme } from '../index-types'
|
|
10
11
|
import { ThemeProps } from '../theme/types'
|
|
@@ -54,6 +55,7 @@ export type ClientInput = Omit<CoreInput, 'message_id' | 'bot_interaction_id'>
|
|
|
54
55
|
export interface WebchatContextProps {
|
|
55
56
|
addMessage: (message: WebchatMessage) => void
|
|
56
57
|
getThemeProperty: (property: string, defaultValue?: any) => any
|
|
58
|
+
closeWebview: (options?: CloseWebviewOptions) => Promise<void>
|
|
57
59
|
openWebview: (webviewComponent: Webview, params?: any) => void
|
|
58
60
|
resetUnreadMessages: () => void
|
|
59
61
|
resolveCase: () => void
|
|
@@ -75,7 +77,7 @@ export interface WebchatContextProps {
|
|
|
75
77
|
updateWebchatDevSettings: (settings: WebchatSettingsProps) => void
|
|
76
78
|
trackEvent?: TrackEventFunction
|
|
77
79
|
webchatState: WebchatState
|
|
78
|
-
|
|
80
|
+
webchatContainerRef: React.MutableRefObject<HTMLDivElement | null>
|
|
79
81
|
chatAreaRef: React.MutableRefObject<HTMLDivElement | null>
|
|
80
82
|
inputPanelRef: React.MutableRefObject<HTMLDivElement | null>
|
|
81
83
|
headerRef: React.MutableRefObject<HTMLDivElement | null>
|
|
@@ -79,7 +79,7 @@ export interface UseWebchat {
|
|
|
79
79
|
removeReplies: () => void
|
|
80
80
|
removeWebview: () => void
|
|
81
81
|
webchatState: WebchatState
|
|
82
|
-
|
|
82
|
+
webchatContainerRef: React.MutableRefObject<HTMLDivElement | null>
|
|
83
83
|
headerRef: React.MutableRefObject<HTMLDivElement | null>
|
|
84
84
|
chatAreaRef: React.MutableRefObject<HTMLDivElement | null>
|
|
85
85
|
scrollableMessagesListRef: React.MutableRefObject<HTMLDivElement | null>
|
|
@@ -93,7 +93,7 @@ export function useWebchat(): UseWebchat {
|
|
|
93
93
|
webchatInitialState
|
|
94
94
|
)
|
|
95
95
|
|
|
96
|
-
const
|
|
96
|
+
const webchatContainerRef = useRef<HTMLDivElement | null>(null)
|
|
97
97
|
const chatAreaRef = useRef<HTMLDivElement | null>(null)
|
|
98
98
|
const inputPanelRef = useRef<HTMLDivElement | null>(null)
|
|
99
99
|
const headerRef = useRef<HTMLDivElement | null>(null)
|
|
@@ -281,7 +281,7 @@ export function useWebchat(): UseWebchat {
|
|
|
281
281
|
removeReplies,
|
|
282
282
|
removeWebview,
|
|
283
283
|
webchatState,
|
|
284
|
-
|
|
284
|
+
webchatContainerRef,
|
|
285
285
|
headerRef,
|
|
286
286
|
chatAreaRef,
|
|
287
287
|
scrollableMessagesListRef,
|
|
@@ -25,8 +25,12 @@ const stopAtScrollLimit = element => {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export const useScrollbarController = (currentDevice, host) => {
|
|
28
|
-
const {
|
|
29
|
-
|
|
28
|
+
const {
|
|
29
|
+
webchatContainerRef,
|
|
30
|
+
chatAreaRef,
|
|
31
|
+
repliesRef,
|
|
32
|
+
scrollableMessagesListRef,
|
|
33
|
+
} = useContext(WebchatContext)
|
|
30
34
|
|
|
31
35
|
const hasScrollbar = () => {
|
|
32
36
|
if (chatAreaRef.current && scrollableMessagesListRef.current) {
|
|
@@ -70,25 +74,25 @@ export const useScrollbarController = (currentDevice, host) => {
|
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
const toggleOnTouchMoveEvents = () => {
|
|
73
|
-
if (
|
|
77
|
+
if (webchatContainerRef.current && scrollableMessagesListRef.current) {
|
|
74
78
|
if (hasScrollbar()) {
|
|
75
79
|
scrollableMessagesListRef.current.style.touchAction = 'auto'
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
webchatContainerRef.current.style.touchAction = 'auto'
|
|
81
|
+
webchatContainerRef.current.ontouchmove = null
|
|
82
|
+
webchatContainerRef.current.ontouchstart = null
|
|
79
83
|
return
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
scrollableMessagesListRef.current.style.touchAction = 'none'
|
|
83
|
-
|
|
87
|
+
webchatContainerRef.current.style.touchAction = 'none'
|
|
84
88
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
89
|
+
if (webchatContainerRef.current) {
|
|
90
|
+
webchatContainerRef.current.ontouchstart = e => {
|
|
87
91
|
if (e.target === e.currentTarget) {
|
|
88
92
|
e.preventDefault()
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
|
-
|
|
95
|
+
webchatContainerRef.current.ontouchmove = e => {
|
|
92
96
|
if (e.target === e.currentTarget) {
|
|
93
97
|
e.preventDefault()
|
|
94
98
|
}
|
|
@@ -122,22 +126,23 @@ export const useScrollbarController = (currentDevice, host) => {
|
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
const handleScrollEvents = () => {
|
|
125
|
-
if (
|
|
129
|
+
if (webchatContainerRef.current) {
|
|
126
130
|
if (isMobileDevice()) {
|
|
127
131
|
if (currentDevice !== DEVICES.MOBILE.IPHONE) return
|
|
128
132
|
|
|
129
133
|
limitScrollBoundaries()
|
|
130
134
|
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
webchatContainerRef.current.ontouchstart = handleOnTouchMoveEvents
|
|
136
|
+
webchatContainerRef.current.ontouchmove = handleOnTouchMoveEvents
|
|
133
137
|
} else {
|
|
134
|
-
|
|
138
|
+
webchatContainerRef.current.onmouseover = e =>
|
|
139
|
+
handleOnMouseOverEvents(e)
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
useEffect(() => {
|
|
140
|
-
const webchat =
|
|
145
|
+
const webchat = webchatContainerRef.current
|
|
141
146
|
|
|
142
147
|
handleScrollEvents()
|
|
143
148
|
|
|
@@ -4,14 +4,14 @@ import { WebchatContext } from '../../webchat/context'
|
|
|
4
4
|
|
|
5
5
|
export const useWebchatDimensions = () => {
|
|
6
6
|
const {
|
|
7
|
-
|
|
7
|
+
webchatContainerRef,
|
|
8
8
|
headerRef,
|
|
9
9
|
inputPanelRef,
|
|
10
10
|
webchatState: { isWebchatOpen },
|
|
11
11
|
} = useContext(WebchatContext)
|
|
12
12
|
|
|
13
13
|
const calculateResizedPercentualWebchatHeight = useCallback(() => {
|
|
14
|
-
const webchatElement =
|
|
14
|
+
const webchatElement = webchatContainerRef.current
|
|
15
15
|
if (!isWebchatOpen || !webchatElement) return 0
|
|
16
16
|
const webchatHeight = webchatElement.clientHeight || 0
|
|
17
17
|
const keyboardOffset =
|
|
@@ -24,7 +24,7 @@ export const useWebchatDimensions = () => {
|
|
|
24
24
|
}, [isWebchatOpen])
|
|
25
25
|
|
|
26
26
|
const calculateResizedPxChatAreaHeight = useCallback(() => {
|
|
27
|
-
const webchatElement =
|
|
27
|
+
const webchatElement = webchatContainerRef.current
|
|
28
28
|
const headerElement = headerRef.current
|
|
29
29
|
const inputPanelElement = inputPanelRef.current
|
|
30
30
|
|
|
@@ -4,7 +4,7 @@ import { WebchatContext } from '../../webchat/context'
|
|
|
4
4
|
import { useWebchatDimensions } from './use-webchat-dimensions'
|
|
5
5
|
|
|
6
6
|
export const useWebchatResizer = () => {
|
|
7
|
-
const {
|
|
7
|
+
const { webchatContainerRef, chatAreaRef, inputPanelRef, headerRef } =
|
|
8
8
|
useContext(WebchatContext)
|
|
9
9
|
|
|
10
10
|
const {
|
|
@@ -14,24 +14,24 @@ export const useWebchatResizer = () => {
|
|
|
14
14
|
|
|
15
15
|
const handleKeyboardShown = () => {
|
|
16
16
|
if (
|
|
17
|
-
|
|
17
|
+
webchatContainerRef.current &&
|
|
18
18
|
chatAreaRef.current &&
|
|
19
19
|
headerRef.current &&
|
|
20
20
|
inputPanelRef.current
|
|
21
21
|
) {
|
|
22
|
-
|
|
22
|
+
webchatContainerRef.current.style.height = `${calculateResizedPercentualWebchatHeight()}%`
|
|
23
23
|
chatAreaRef.current.style.height = `${calculateResizedPxChatAreaHeight()}px`
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const handleKeyboardHidden = () => {
|
|
28
28
|
if (
|
|
29
|
-
|
|
29
|
+
webchatContainerRef.current &&
|
|
30
30
|
chatAreaRef.current &&
|
|
31
31
|
inputPanelRef.current &&
|
|
32
32
|
headerRef.current
|
|
33
33
|
) {
|
|
34
|
-
|
|
34
|
+
webchatContainerRef.current.style.height = '100%'
|
|
35
35
|
chatAreaRef.current.style.height = `${calculateResizedPxChatAreaHeight()}px`
|
|
36
36
|
}
|
|
37
37
|
}
|
package/src/webchat/webchat.tsx
CHANGED
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
INPUT,
|
|
4
4
|
isMobile,
|
|
5
5
|
params2queryString,
|
|
6
|
-
Session as CoreSession,
|
|
7
6
|
} from '@botonic/core'
|
|
8
7
|
import merge from 'lodash.merge'
|
|
9
8
|
import React, {
|
|
@@ -27,7 +26,7 @@ import {
|
|
|
27
26
|
WebchatSettingsProps,
|
|
28
27
|
} from '../components'
|
|
29
28
|
import { COLORS, MAX_ALLOWED_SIZE_MB, ROLES, WEBCHAT } from '../constants'
|
|
30
|
-
import { CloseWebviewOptions
|
|
29
|
+
import { CloseWebviewOptions } from '../contexts'
|
|
31
30
|
import { SENDERS, WebchatProps, WebchatRef } from '../index-types'
|
|
32
31
|
import {
|
|
33
32
|
getMediaType,
|
|
@@ -71,7 +70,7 @@ import {
|
|
|
71
70
|
import { TriggerButton } from './trigger-button'
|
|
72
71
|
import { useStorageState } from './use-storage-state-hook'
|
|
73
72
|
import { getParsedAction } from './utils'
|
|
74
|
-
import { WebviewContainer } from './webview'
|
|
73
|
+
import { WebviewContainer } from './webview/index'
|
|
75
74
|
|
|
76
75
|
// eslint-disable-next-line complexity, react/display-name
|
|
77
76
|
const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
@@ -104,7 +103,7 @@ const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
|
104
103
|
removeWebview,
|
|
105
104
|
removeReplies,
|
|
106
105
|
webchatState,
|
|
107
|
-
|
|
106
|
+
webchatContainerRef,
|
|
108
107
|
chatAreaRef,
|
|
109
108
|
inputPanelRef,
|
|
110
109
|
headerRef,
|
|
@@ -319,8 +318,7 @@ const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
|
319
318
|
)
|
|
320
319
|
|
|
321
320
|
const darkBackgroundMenu = getThemeProperty(
|
|
322
|
-
WEBCHAT.CUSTOM_PROPERTIES.darkBackgroundMenu
|
|
323
|
-
false
|
|
321
|
+
WEBCHAT.CUSTOM_PROPERTIES.darkBackgroundMenu
|
|
324
322
|
)
|
|
325
323
|
|
|
326
324
|
const getBlockInputs = (rule, inputData) => {
|
|
@@ -577,13 +575,6 @@ const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
|
577
575
|
}
|
|
578
576
|
}
|
|
579
577
|
|
|
580
|
-
const webviewRequestContext = {
|
|
581
|
-
closeWebview: async (options?: CloseWebviewOptions) =>
|
|
582
|
-
await closeWebview(options),
|
|
583
|
-
params: webchatState.webviewParams || ({} as Record<string, any>),
|
|
584
|
-
session: webchatState.session || ({} as Partial<CoreSession>),
|
|
585
|
-
}
|
|
586
|
-
|
|
587
578
|
useEffect(() => {
|
|
588
579
|
if (firstUpdate.current) {
|
|
589
580
|
firstUpdate.current = false
|
|
@@ -609,18 +600,7 @@ const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
|
609
600
|
|
|
610
601
|
const userInputEnabled = isUserInputEnabled()
|
|
611
602
|
|
|
612
|
-
|
|
613
|
-
<WebviewRequestContext.Provider value={webviewRequestContext}>
|
|
614
|
-
<WebviewContainer
|
|
615
|
-
style={{
|
|
616
|
-
...getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.webviewStyle),
|
|
617
|
-
...mobileStyle,
|
|
618
|
-
}}
|
|
619
|
-
webview={webchatState.webview}
|
|
620
|
-
/>
|
|
621
|
-
</WebviewRequestContext.Provider>
|
|
622
|
-
)
|
|
623
|
-
|
|
603
|
+
// TODO: Create a default theme that include mobileStyle
|
|
624
604
|
let mobileStyle = {}
|
|
625
605
|
if (isMobile(getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.mobileBreakpoint))) {
|
|
626
606
|
mobileStyle = getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.mobileStyle) || {
|
|
@@ -671,6 +651,7 @@ const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
|
671
651
|
value={{
|
|
672
652
|
addMessage,
|
|
673
653
|
getThemeProperty,
|
|
654
|
+
closeWebview,
|
|
674
655
|
openWebview,
|
|
675
656
|
resolveCase,
|
|
676
657
|
resetUnreadMessages,
|
|
@@ -691,9 +672,9 @@ const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
|
691
672
|
updateWebchatDevSettings: updateWebchatDevSettings,
|
|
692
673
|
trackEvent: props.onTrackEvent,
|
|
693
674
|
webchatState,
|
|
694
|
-
// TODO: Review if need theme inside Context, already exist
|
|
675
|
+
// TODO: Review if need theme inside Context, already exist inside webchatState
|
|
695
676
|
theme,
|
|
696
|
-
|
|
677
|
+
webchatContainerRef,
|
|
697
678
|
chatAreaRef,
|
|
698
679
|
inputPanelRef,
|
|
699
680
|
headerRef,
|
|
@@ -706,7 +687,7 @@ const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
|
706
687
|
{webchatState.isWebchatOpen && (
|
|
707
688
|
<StyledWebchat
|
|
708
689
|
id={BotonicContainerId.Webchat}
|
|
709
|
-
ref={
|
|
690
|
+
ref={webchatContainerRef}
|
|
710
691
|
// TODO: Distinguish between multiple instances of webchat, e.g. `${uniqueId}-botonic-webchat`
|
|
711
692
|
role={ROLES.WEBCHAT}
|
|
712
693
|
width={webchatState.width}
|
|
@@ -749,7 +730,7 @@ const Webchat = forwardRef<WebchatRef | null, WebchatProps>((props, ref) => {
|
|
|
749
730
|
/>
|
|
750
731
|
)}
|
|
751
732
|
|
|
752
|
-
{webchatState.webview &&
|
|
733
|
+
{webchatState.webview && <WebviewContainer />}
|
|
753
734
|
|
|
754
735
|
{webchatState.isCustomComponentRendered &&
|
|
755
736
|
customComponent &&
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { useContext } from 'react'
|
|
2
|
+
|
|
3
|
+
import { ROLES, WEBCHAT } from '../../constants'
|
|
4
|
+
import { WebviewRequestContext } from '../../contexts'
|
|
5
|
+
import { WebchatContext } from '../context'
|
|
6
|
+
import { StyledCloseHeader, StyledWebviewHeader } from './styles'
|
|
7
|
+
|
|
8
|
+
export const WebviewHeader = () => {
|
|
9
|
+
const { closeWebview } = useContext(WebviewRequestContext)
|
|
10
|
+
const { getThemeProperty } = useContext(WebchatContext)
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<StyledWebviewHeader
|
|
14
|
+
role={ROLES.WEBVIEW_HEADER}
|
|
15
|
+
style={{
|
|
16
|
+
...getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.webviewHeaderStyle),
|
|
17
|
+
}}
|
|
18
|
+
>
|
|
19
|
+
<StyledCloseHeader onClick={() => closeWebview()}>✕</StyledCloseHeader>
|
|
20
|
+
</StyledWebviewHeader>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { isMobile, Session as CoreSession } from '@botonic/core'
|
|
2
|
+
import React, { useContext, useEffect } from 'react'
|
|
3
|
+
|
|
4
|
+
import { ROLES, WEBCHAT } from '../../constants'
|
|
5
|
+
import { CloseWebviewOptions, WebviewRequestContext } from '../../contexts'
|
|
6
|
+
import { WebchatContext } from '../context'
|
|
7
|
+
import { WebviewHeader } from './header'
|
|
8
|
+
import {
|
|
9
|
+
StyledFrame,
|
|
10
|
+
StyledFrameAsDiv,
|
|
11
|
+
StyledWebview,
|
|
12
|
+
StyledWebviewContent,
|
|
13
|
+
} from './styles'
|
|
14
|
+
|
|
15
|
+
export const WebviewContainer = () => {
|
|
16
|
+
const { closeWebview, getThemeProperty, webchatState } =
|
|
17
|
+
useContext(WebchatContext)
|
|
18
|
+
|
|
19
|
+
const webviewRequestContext = {
|
|
20
|
+
closeWebview: async (options?: CloseWebviewOptions) =>
|
|
21
|
+
await closeWebview(options),
|
|
22
|
+
params: webchatState.webviewParams || ({} as Record<string, any>),
|
|
23
|
+
session: webchatState.session || ({} as Partial<CoreSession>),
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// TODO: Remove this code and use theme or webchatState.theme from the context,
|
|
27
|
+
// this code is duplicated from webchat.tsx
|
|
28
|
+
let mobileStyle = {}
|
|
29
|
+
if (isMobile(getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.mobileBreakpoint))) {
|
|
30
|
+
mobileStyle = getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.mobileStyle) || {
|
|
31
|
+
width: '100%',
|
|
32
|
+
height: '100%',
|
|
33
|
+
right: 0,
|
|
34
|
+
bottom: 0,
|
|
35
|
+
borderRadius: 0,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const Webview = webchatState.webview as string | React.ComponentType
|
|
40
|
+
|
|
41
|
+
const close = async (e: any) => {
|
|
42
|
+
if (e.data === 'botonicCloseWebview') {
|
|
43
|
+
console.log('Received close message from webview')
|
|
44
|
+
await closeWebview()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
window.addEventListener('message', close, false)
|
|
50
|
+
|
|
51
|
+
return () => window.removeEventListener('message', close, false)
|
|
52
|
+
}, [])
|
|
53
|
+
|
|
54
|
+
// TODO: Review how to split the logic of rendering a webview in local development and production
|
|
55
|
+
// In local development, Webview is a component. In production it is the URL of the webview
|
|
56
|
+
const isUrlToWebview = typeof Webview === 'string'
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<StyledWebview
|
|
60
|
+
role={ROLES.WEBVIEW}
|
|
61
|
+
style={{
|
|
62
|
+
...getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.webviewStyle),
|
|
63
|
+
...mobileStyle,
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<WebviewHeader />
|
|
67
|
+
<StyledWebviewContent>
|
|
68
|
+
{isUrlToWebview ? (
|
|
69
|
+
<StyledFrame src={Webview} />
|
|
70
|
+
) : (
|
|
71
|
+
<WebviewRequestContext.Provider value={webviewRequestContext}>
|
|
72
|
+
<StyledFrameAsDiv>
|
|
73
|
+
<Webview />
|
|
74
|
+
</StyledFrameAsDiv>
|
|
75
|
+
</WebviewRequestContext.Provider>
|
|
76
|
+
)}
|
|
77
|
+
</StyledWebviewContent>
|
|
78
|
+
</StyledWebview>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import styled from 'styled-components'
|
|
2
|
+
|
|
3
|
+
import { COLORS, WEBCHAT } from '../../constants'
|
|
4
|
+
|
|
5
|
+
export const StyledWebview = styled.div`
|
|
6
|
+
position: absolute;
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
bottom: 0;
|
|
10
|
+
width: 100%;
|
|
11
|
+
height: 100%;
|
|
12
|
+
background-color: ${COLORS.SOLID_WHITE};
|
|
13
|
+
z-index: 2;
|
|
14
|
+
border-radius: ${WEBCHAT.DEFAULTS.BORDER_RADIUS_TOP_CORNERS};
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
export const StyledWebviewHeader = styled.div`
|
|
18
|
+
flex: none;
|
|
19
|
+
text-align: right;
|
|
20
|
+
background-color: ${COLORS.WILD_SAND_WHITE};
|
|
21
|
+
border-top: 1px solid ${COLORS.SOLID_BLACK_ALPHA_0_2};
|
|
22
|
+
border-bottom: 1px solid ${COLORS.SOLID_BLACK_ALPHA_0_2};
|
|
23
|
+
border-radius: ${WEBCHAT.DEFAULTS.BORDER_RADIUS_TOP_CORNERS};
|
|
24
|
+
`
|
|
25
|
+
export const StyledCloseHeader = styled.div`
|
|
26
|
+
display: inline-block;
|
|
27
|
+
padding: 8px 12px;
|
|
28
|
+
cursor: pointer;
|
|
29
|
+
`
|
|
30
|
+
|
|
31
|
+
export const StyledWebviewContent = styled.div`
|
|
32
|
+
flex: 1;
|
|
33
|
+
overflow: auto;
|
|
34
|
+
`
|
|
35
|
+
|
|
36
|
+
export const FrameStyles = `
|
|
37
|
+
border-style: none;
|
|
38
|
+
width: 100%;
|
|
39
|
+
height: 100%;
|
|
40
|
+
`
|
|
41
|
+
|
|
42
|
+
export const StyledFrame = styled.iframe`
|
|
43
|
+
${FrameStyles}
|
|
44
|
+
`
|
|
45
|
+
|
|
46
|
+
export const StyledFrameAsDiv = styled.div`
|
|
47
|
+
${FrameStyles}
|
|
48
|
+
`
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WebviewContainer = exports.WebviewHeader = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
-
const react_1 = tslib_1.__importStar(require("react"));
|
|
7
|
-
const styled_components_1 = tslib_1.__importDefault(require("styled-components"));
|
|
8
|
-
const constants_1 = require("../constants");
|
|
9
|
-
const contexts_1 = require("../contexts");
|
|
10
|
-
const context_1 = require("../webchat/context");
|
|
11
|
-
const StyledWebview = styled_components_1.default.div `
|
|
12
|
-
position: absolute;
|
|
13
|
-
display: flex;
|
|
14
|
-
flex-direction: column;
|
|
15
|
-
bottom: 0;
|
|
16
|
-
width: 100%;
|
|
17
|
-
height: 100%;
|
|
18
|
-
background-color: ${constants_1.COLORS.SOLID_WHITE};
|
|
19
|
-
z-index: 2;
|
|
20
|
-
border-radius: ${constants_1.WEBCHAT.DEFAULTS.BORDER_RADIUS_TOP_CORNERS};
|
|
21
|
-
`;
|
|
22
|
-
const StyledWebviewHeader = styled_components_1.default.div `
|
|
23
|
-
text-align: right;
|
|
24
|
-
background-color: ${constants_1.COLORS.WILD_SAND_WHITE};
|
|
25
|
-
border-top: 1px solid ${constants_1.COLORS.SOLID_BLACK_ALPHA_0_2};
|
|
26
|
-
border-bottom: 1px solid ${constants_1.COLORS.SOLID_BLACK_ALPHA_0_2};
|
|
27
|
-
border-radius: ${constants_1.WEBCHAT.DEFAULTS.BORDER_RADIUS_TOP_CORNERS};
|
|
28
|
-
`;
|
|
29
|
-
const StyledCloseHeader = styled_components_1.default.div `
|
|
30
|
-
display: inline-block;
|
|
31
|
-
padding: 8px 12px;
|
|
32
|
-
cursor: pointer;
|
|
33
|
-
`;
|
|
34
|
-
const StyledWebviewContent = styled_components_1.default.div `
|
|
35
|
-
flex: 1;
|
|
36
|
-
overflow: auto;
|
|
37
|
-
`;
|
|
38
|
-
const FrameStyles = `
|
|
39
|
-
border-style: none;
|
|
40
|
-
width: 100%;
|
|
41
|
-
height: 100%;
|
|
42
|
-
`;
|
|
43
|
-
const StyledFrame = styled_components_1.default.iframe `
|
|
44
|
-
${FrameStyles}
|
|
45
|
-
`;
|
|
46
|
-
const StyledFrameAsDiv = styled_components_1.default.div `
|
|
47
|
-
${FrameStyles}
|
|
48
|
-
`;
|
|
49
|
-
const WebviewHeader = () => {
|
|
50
|
-
const { closeWebview } = (0, react_1.useContext)(contexts_1.WebviewRequestContext);
|
|
51
|
-
const { getThemeProperty } = (0, react_1.useContext)(context_1.WebchatContext);
|
|
52
|
-
return ((0, jsx_runtime_1.jsx)(StyledWebviewHeader, Object.assign({ role: constants_1.ROLES.WEBVIEW_HEADER, style: Object.assign({}, getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.webviewHeaderStyle)) }, { children: (0, jsx_runtime_1.jsx)(StyledCloseHeader, Object.assign({ onClick: closeWebview }, { children: "\u2715" })) })));
|
|
53
|
-
};
|
|
54
|
-
exports.WebviewHeader = WebviewHeader;
|
|
55
|
-
const WebviewContainer = props => {
|
|
56
|
-
const { webchatState } = (0, react_1.useContext)(context_1.WebchatContext);
|
|
57
|
-
const { closeWebview } = (0, react_1.useContext)(contexts_1.WebviewRequestContext);
|
|
58
|
-
const Webview = webchatState.webview;
|
|
59
|
-
const close = (e) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
-
if (e.data === 'botonicCloseWebview') {
|
|
61
|
-
yield closeWebview();
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
(0, react_1.useEffect)(() => {
|
|
65
|
-
if (window.addEventListener) {
|
|
66
|
-
window.addEventListener('message', close, false);
|
|
67
|
-
}
|
|
68
|
-
else if (window.attachEvent) {
|
|
69
|
-
// ie8
|
|
70
|
-
window.attachEvent('onmessage', close);
|
|
71
|
-
}
|
|
72
|
-
}, []);
|
|
73
|
-
return ((0, jsx_runtime_1.jsxs)(StyledWebview, Object.assign({ role: constants_1.ROLES.WEBVIEW, style: Object.assign({}, props.style) }, { children: [(0, jsx_runtime_1.jsx)(exports.WebviewHeader, { style: { flex: 'none' } }), (0, jsx_runtime_1.jsx)(StyledWebviewContent, { children: typeof Webview === 'string' ? ((0, jsx_runtime_1.jsx)(StyledFrame, { src: Webview })) : ((0, jsx_runtime_1.jsx)(StyledFrameAsDiv, { children: (0, jsx_runtime_1.jsx)(Webview, {}) })) })] })));
|
|
74
|
-
};
|
|
75
|
-
exports.WebviewContainer = WebviewContainer;
|
|
76
|
-
//# sourceMappingURL=webview.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webview.js","sourceRoot":"","sources":["../../../src/webchat/webview.jsx"],"names":[],"mappings":";;;;;AAAA,uDAAoD;AACpD,kFAAsC;AAEtC,4CAAqD;AACrD,0CAAmD;AACnD,gDAAmD;AAEnD,MAAM,aAAa,GAAG,2BAAM,CAAC,GAAG,CAAA;;;;;;;sBAOV,kBAAM,CAAC,WAAW;;mBAErB,mBAAO,CAAC,QAAQ,CAAC,yBAAyB;CAC5D,CAAA;AAED,MAAM,mBAAmB,GAAG,2BAAM,CAAC,GAAG,CAAA;;sBAEhB,kBAAM,CAAC,eAAe;0BAClB,kBAAM,CAAC,qBAAqB;6BACzB,kBAAM,CAAC,qBAAqB;mBACtC,mBAAO,CAAC,QAAQ,CAAC,yBAAyB;CAC5D,CAAA;AACD,MAAM,iBAAiB,GAAG,2BAAM,CAAC,GAAG,CAAA;;;;CAInC,CAAA;AAED,MAAM,oBAAoB,GAAG,2BAAM,CAAC,GAAG,CAAA;;;CAGtC,CAAA;AAED,MAAM,WAAW,GAAG;;;;CAInB,CAAA;AAED,MAAM,WAAW,GAAG,2BAAM,CAAC,MAAM,CAAA;IAC7B,WAAW;CACd,CAAA;AAED,MAAM,gBAAgB,GAAG,2BAAM,CAAC,GAAG,CAAA;IAC/B,WAAW;CACd,CAAA;AAEM,MAAM,aAAa,GAAG,GAAG,EAAE;IAChC,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,kBAAU,EAAC,gCAAqB,CAAC,CAAA;IAC1D,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAA,kBAAU,EAAC,wBAAc,CAAC,CAAA;IACvD,OAAO,CACL,uBAAC,mBAAmB,kBAClB,IAAI,EAAE,iBAAK,CAAC,cAAc,EAC1B,KAAK,oBACA,gBAAgB,CAAC,mBAAO,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,iBAGnE,uBAAC,iBAAiB,kBAAC,OAAO,EAAE,YAAY,4BAAuB,IAC3C,CACvB,CAAA;AACH,CAAC,CAAA;AAbY,QAAA,aAAa,iBAazB;AAEM,MAAM,gBAAgB,GAAG,KAAK,CAAC,EAAE;IACtC,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,kBAAU,EAAC,wBAAc,CAAC,CAAA;IACnD,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,kBAAU,EAAC,gCAAqB,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAA;IAEpC,MAAM,KAAK,GAAG,CAAM,CAAC,EAAC,EAAE;QACtB,IAAI,CAAC,CAAC,IAAI,KAAK,qBAAqB,EAAE;YACpC,MAAM,YAAY,EAAE,CAAA;SACrB;IACH,CAAC,CAAA,CAAA;IAED,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,MAAM,CAAC,gBAAgB,EAAE;YAC3B,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;SACjD;aAAM,IAAI,MAAM,CAAC,WAAW,EAAE;YAC7B,MAAM;YACN,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;SACvC;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CACL,wBAAC,aAAa,kBACZ,IAAI,EAAE,iBAAK,CAAC,OAAO,EACnB,KAAK,oBACA,KAAK,CAAC,KAAK,kBAGhB,uBAAC,qBAAa,IAAC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAI,EAC1C,uBAAC,oBAAoB,cAClB,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAC7B,uBAAC,WAAW,IAAC,GAAG,EAAE,OAAO,GAAI,CAC9B,CAAC,CAAC,CAAC,CACF,uBAAC,gBAAgB,cACf,uBAAC,OAAO,KAAG,GACM,CACpB,GACoB,KACT,CACjB,CAAA;AACH,CAAC,CAAA;AAvCY,QAAA,gBAAgB,oBAuC5B"}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import React, { useContext, useEffect } from 'react';
|
|
4
|
-
import styled from 'styled-components';
|
|
5
|
-
import { COLORS, ROLES, WEBCHAT } from '../constants';
|
|
6
|
-
import { WebviewRequestContext } from '../contexts';
|
|
7
|
-
import { WebchatContext } from '../webchat/context';
|
|
8
|
-
const StyledWebview = styled.div `
|
|
9
|
-
position: absolute;
|
|
10
|
-
display: flex;
|
|
11
|
-
flex-direction: column;
|
|
12
|
-
bottom: 0;
|
|
13
|
-
width: 100%;
|
|
14
|
-
height: 100%;
|
|
15
|
-
background-color: ${COLORS.SOLID_WHITE};
|
|
16
|
-
z-index: 2;
|
|
17
|
-
border-radius: ${WEBCHAT.DEFAULTS.BORDER_RADIUS_TOP_CORNERS};
|
|
18
|
-
`;
|
|
19
|
-
const StyledWebviewHeader = styled.div `
|
|
20
|
-
text-align: right;
|
|
21
|
-
background-color: ${COLORS.WILD_SAND_WHITE};
|
|
22
|
-
border-top: 1px solid ${COLORS.SOLID_BLACK_ALPHA_0_2};
|
|
23
|
-
border-bottom: 1px solid ${COLORS.SOLID_BLACK_ALPHA_0_2};
|
|
24
|
-
border-radius: ${WEBCHAT.DEFAULTS.BORDER_RADIUS_TOP_CORNERS};
|
|
25
|
-
`;
|
|
26
|
-
const StyledCloseHeader = styled.div `
|
|
27
|
-
display: inline-block;
|
|
28
|
-
padding: 8px 12px;
|
|
29
|
-
cursor: pointer;
|
|
30
|
-
`;
|
|
31
|
-
const StyledWebviewContent = styled.div `
|
|
32
|
-
flex: 1;
|
|
33
|
-
overflow: auto;
|
|
34
|
-
`;
|
|
35
|
-
const FrameStyles = `
|
|
36
|
-
border-style: none;
|
|
37
|
-
width: 100%;
|
|
38
|
-
height: 100%;
|
|
39
|
-
`;
|
|
40
|
-
const StyledFrame = styled.iframe `
|
|
41
|
-
${FrameStyles}
|
|
42
|
-
`;
|
|
43
|
-
const StyledFrameAsDiv = styled.div `
|
|
44
|
-
${FrameStyles}
|
|
45
|
-
`;
|
|
46
|
-
export const WebviewHeader = () => {
|
|
47
|
-
const { closeWebview } = useContext(WebviewRequestContext);
|
|
48
|
-
const { getThemeProperty } = useContext(WebchatContext);
|
|
49
|
-
return (_jsx(StyledWebviewHeader, Object.assign({ role: ROLES.WEBVIEW_HEADER, style: Object.assign({}, getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.webviewHeaderStyle)) }, { children: _jsx(StyledCloseHeader, Object.assign({ onClick: closeWebview }, { children: "\u2715" })) })));
|
|
50
|
-
};
|
|
51
|
-
export const WebviewContainer = props => {
|
|
52
|
-
const { webchatState } = useContext(WebchatContext);
|
|
53
|
-
const { closeWebview } = useContext(WebviewRequestContext);
|
|
54
|
-
const Webview = webchatState.webview;
|
|
55
|
-
const close = (e) => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
-
if (e.data === 'botonicCloseWebview') {
|
|
57
|
-
yield closeWebview();
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
if (window.addEventListener) {
|
|
62
|
-
window.addEventListener('message', close, false);
|
|
63
|
-
}
|
|
64
|
-
else if (window.attachEvent) {
|
|
65
|
-
// ie8
|
|
66
|
-
window.attachEvent('onmessage', close);
|
|
67
|
-
}
|
|
68
|
-
}, []);
|
|
69
|
-
return (_jsxs(StyledWebview, Object.assign({ role: ROLES.WEBVIEW, style: Object.assign({}, props.style) }, { children: [_jsx(WebviewHeader, { style: { flex: 'none' } }), _jsx(StyledWebviewContent, { children: typeof Webview === 'string' ? (_jsx(StyledFrame, { src: Webview })) : (_jsx(StyledFrameAsDiv, { children: _jsx(Webview, {}) })) })] })));
|
|
70
|
-
};
|
|
71
|
-
//# sourceMappingURL=webview.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webview.js","sourceRoot":"","sources":["../../../src/webchat/webview.jsx"],"names":[],"mappings":"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"}
|