@botonic/react 0.23.0 → 0.23.1-alpha.0
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/image.js +3 -1
- package/lib/cjs/components/image.js.map +1 -1
- package/lib/cjs/components/index-types.d.ts +7 -0
- package/lib/cjs/components/index-types.js.map +1 -1
- package/lib/cjs/components/multichannel/index-types.d.ts +1 -0
- package/lib/cjs/components/multichannel/multichannel-text.js +53 -18
- package/lib/cjs/components/multichannel/multichannel-text.js.map +1 -1
- package/lib/cjs/components/multichannel/multichannel-utils.d.ts +2 -0
- package/lib/cjs/components/multichannel/multichannel-utils.js +3 -1
- package/lib/cjs/components/multichannel/multichannel-utils.js.map +1 -1
- package/lib/cjs/components/webchat-settings.d.ts +3 -10
- package/lib/cjs/components/webchat-settings.js +9 -14
- package/lib/cjs/components/webchat-settings.js.map +1 -1
- package/lib/cjs/components/whatsapp-button-list.d.ts +1 -1
- package/lib/cjs/util/environment.js +1 -1
- package/lib/cjs/util/environment.js.map +1 -1
- package/lib/cjs/webchat/webchat.js +3 -1
- package/lib/cjs/webchat/webchat.js.map +1 -1
- package/lib/esm/components/image.js +3 -1
- package/lib/esm/components/image.js.map +1 -1
- package/lib/esm/components/index-types.d.ts +7 -0
- package/lib/esm/components/index-types.js.map +1 -1
- package/lib/esm/components/multichannel/index-types.d.ts +1 -0
- package/lib/esm/components/multichannel/multichannel-text.js +55 -20
- package/lib/esm/components/multichannel/multichannel-text.js.map +1 -1
- package/lib/esm/components/multichannel/multichannel-utils.d.ts +2 -0
- package/lib/esm/components/multichannel/multichannel-utils.js +2 -0
- package/lib/esm/components/multichannel/multichannel-utils.js.map +1 -1
- package/lib/esm/components/webchat-settings.d.ts +3 -10
- package/lib/esm/components/webchat-settings.js +9 -13
- package/lib/esm/components/webchat-settings.js.map +1 -1
- package/lib/esm/components/whatsapp-button-list.d.ts +1 -1
- package/lib/esm/util/environment.js +1 -1
- package/lib/esm/util/environment.js.map +1 -1
- package/lib/esm/webchat/webchat.js +3 -1
- package/lib/esm/webchat/webchat.js.map +1 -1
- package/package.json +1 -1
- package/src/components/image.jsx +3 -1
- package/src/components/index-types.ts +7 -0
- package/src/components/multichannel/index-types.ts +1 -0
- package/src/components/multichannel/multichannel-text.jsx +99 -25
- package/src/components/multichannel/multichannel-utils.js +2 -0
- package/src/components/{webchat-settings.jsx → webchat-settings.tsx} +8 -8
- package/src/components/whatsapp-button-list.tsx +1 -1
- package/src/util/environment.js +1 -1
- package/src/webchat/webchat.jsx +4 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { INPUT } from '@botonic/core/lib/esm/models/legacy-types'
|
|
1
2
|
import React, { useContext } from 'react'
|
|
2
3
|
|
|
3
4
|
import { RequestContext } from '../../contexts'
|
|
5
|
+
import { WhatsappButtonList } from '..'
|
|
4
6
|
import { Text } from '../text'
|
|
5
7
|
import { MultichannelFacebook } from './facebook/facebook'
|
|
6
8
|
import { MultichannelButton } from './multichannel-button'
|
|
@@ -16,7 +18,9 @@ import {
|
|
|
16
18
|
getMultichannelReplies,
|
|
17
19
|
isFacebook,
|
|
18
20
|
isWhatsapp,
|
|
21
|
+
MENU_BUTOON_WHATSAPP_BUTTON_LIST,
|
|
19
22
|
MULTICHANNEL_WHATSAPP_PROPS,
|
|
23
|
+
WHATSAPP_LIST_MAX_BUTTONS,
|
|
20
24
|
WHATSAPP_MAX_BUTTONS,
|
|
21
25
|
} from './multichannel-utils'
|
|
22
26
|
import { whatsappMarkdown } from './whatsapp/markdown'
|
|
@@ -55,8 +59,8 @@ export const MultichannelText = props => {
|
|
|
55
59
|
const webviewButtons = []
|
|
56
60
|
for (const button of getButtonsAndReplies()) {
|
|
57
61
|
if (elementHasUrl(button)) urlButtons.push(button)
|
|
58
|
-
if (
|
|
59
|
-
if (
|
|
62
|
+
else if (elementHasWebview(button)) webviewButtons.push(button)
|
|
63
|
+
else if (elementHasPostback(button)) postbackButtons.push(button)
|
|
60
64
|
}
|
|
61
65
|
return { postbackButtons, urlButtons, webviewButtons }
|
|
62
66
|
}
|
|
@@ -77,11 +81,14 @@ export const MultichannelText = props => {
|
|
|
77
81
|
const asText =
|
|
78
82
|
type === buttonTypes.POSTBACK ? postbackButtonsAsText : true
|
|
79
83
|
const newline =
|
|
80
|
-
multichannelContext.messageSeparator
|
|
84
|
+
multichannelContext.messageSeparator === null &&
|
|
81
85
|
!newLineFirstButton &&
|
|
82
86
|
i === 0
|
|
83
87
|
? ''
|
|
84
88
|
: '\n'
|
|
89
|
+
if (type !== buttonTypes.POSTBACK && multichannelButton.props.payload) {
|
|
90
|
+
delete multichannelButton.props.payload
|
|
91
|
+
}
|
|
85
92
|
return (
|
|
86
93
|
<MultichannelButton
|
|
87
94
|
key={`${type}${i}`}
|
|
@@ -96,14 +103,19 @@ export const MultichannelText = props => {
|
|
|
96
103
|
return generator
|
|
97
104
|
}
|
|
98
105
|
|
|
99
|
-
const
|
|
106
|
+
const splitInWhatsappListButtons = postbackButtons => {
|
|
100
107
|
const messages = []
|
|
101
|
-
for (
|
|
102
|
-
|
|
108
|
+
for (
|
|
109
|
+
let i = 0;
|
|
110
|
+
i < postbackButtons.length;
|
|
111
|
+
i += WHATSAPP_LIST_MAX_BUTTONS
|
|
112
|
+
) {
|
|
113
|
+
messages.push(postbackButtons.slice(i, i + WHATSAPP_LIST_MAX_BUTTONS))
|
|
103
114
|
}
|
|
104
115
|
return messages
|
|
105
116
|
}
|
|
106
117
|
|
|
118
|
+
// START WHATSAPP LOGIC
|
|
107
119
|
if (isWhatsapp(requestContext)) {
|
|
108
120
|
const texts = getText(props.children)
|
|
109
121
|
const { postbackButtons, urlButtons, webviewButtons } = getWhatsappButtons()
|
|
@@ -120,45 +132,105 @@ export const MultichannelText = props => {
|
|
|
120
132
|
const buttonsTextSeparator =
|
|
121
133
|
props.buttonsTextSeparator || DEFAULT_WHATSAPP_MAX_BUTTON_SEPARATOR
|
|
122
134
|
|
|
135
|
+
//MORE THAN 3 BUTTONS
|
|
123
136
|
if (
|
|
124
137
|
!postbackButtonsAsText &&
|
|
125
138
|
postbackButtons.length > WHATSAPP_MAX_BUTTONS
|
|
126
139
|
) {
|
|
140
|
+
const menuButtonTextWhatsappList =
|
|
141
|
+
props.menuButtonTextWhatsappList || MENU_BUTOON_WHATSAPP_BUTTON_LIST
|
|
142
|
+
|
|
127
143
|
const urlButtonElements = urlButtons.map(
|
|
128
144
|
regenerateMultichannelButtons(!!texts.length)
|
|
129
145
|
)
|
|
130
146
|
const postbackButtonElements = postbackButtons.map(
|
|
131
147
|
regenerateMultichannelButtons(!!texts.length || !!urlButtons.length)
|
|
132
148
|
)
|
|
133
|
-
|
|
149
|
+
|
|
150
|
+
const messagesPostbackButtonList = splitInWhatsappListButtons(
|
|
134
151
|
postbackButtonElements
|
|
135
152
|
)
|
|
136
153
|
|
|
137
|
-
const messages =
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
154
|
+
const messages = messagesPostbackButtonList.map(
|
|
155
|
+
(postbackButtons, index) => {
|
|
156
|
+
if (postbackButtons.length < 4) {
|
|
157
|
+
return {
|
|
158
|
+
type: INPUT.TEXT,
|
|
159
|
+
children: [...buttonsTextSeparator, ...postbackButtons],
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const rows = postbackButtons.map(postbackButton => {
|
|
163
|
+
const row = {
|
|
164
|
+
id: postbackButton.props.path
|
|
165
|
+
? `__PATH_PAYLOAD__${postbackButton.props.path}`
|
|
166
|
+
: postbackButton.props.payload,
|
|
167
|
+
title: postbackButton.props.children,
|
|
168
|
+
}
|
|
169
|
+
console.log({ row })
|
|
170
|
+
return row
|
|
171
|
+
})
|
|
172
|
+
const whatsbuttonlistProps = {
|
|
173
|
+
body: index === 0 ? textElements : buttonsTextSeparator,
|
|
174
|
+
button: menuButtonTextWhatsappList,
|
|
175
|
+
sections: [{ rows }],
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
type: INPUT.WHATSAPP_BUTTON_LIST,
|
|
180
|
+
props: whatsbuttonlistProps,
|
|
181
|
+
}
|
|
146
182
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
const messageWithUrlButtonElements = (
|
|
186
|
+
<Text
|
|
187
|
+
key={`msg-with-url-button`}
|
|
188
|
+
{...MULTICHANNEL_WHATSAPP_PROPS}
|
|
189
|
+
{...props}
|
|
190
|
+
>
|
|
191
|
+
{urlButtonElements}
|
|
192
|
+
</Text>
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
const messageWithWebviewButtonElements = (
|
|
196
|
+
<Text
|
|
197
|
+
key={`msg-with-webview-button`}
|
|
198
|
+
{...MULTICHANNEL_WHATSAPP_PROPS}
|
|
199
|
+
{...props}
|
|
200
|
+
>
|
|
201
|
+
{buttonsTextSeparator}
|
|
202
|
+
{webviewButtonElements}
|
|
203
|
+
</Text>
|
|
204
|
+
)
|
|
151
205
|
|
|
152
206
|
return (
|
|
153
207
|
<>
|
|
154
|
-
{messages.map((message, i) =>
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
208
|
+
{messages.map((message, i) => {
|
|
209
|
+
if (message.type === INPUT.WHATSAPP_BUTTON_LIST)
|
|
210
|
+
return (
|
|
211
|
+
<WhatsappButtonList
|
|
212
|
+
key={`msg-${i}-whatsapp-list`}
|
|
213
|
+
{...message.props}
|
|
214
|
+
/>
|
|
215
|
+
)
|
|
216
|
+
return (
|
|
217
|
+
<Text
|
|
218
|
+
key={`msg-${i}-with-postback-buttons`}
|
|
219
|
+
{...MULTICHANNEL_WHATSAPP_PROPS}
|
|
220
|
+
{...props}
|
|
221
|
+
>
|
|
222
|
+
{message.children}
|
|
223
|
+
</Text>
|
|
224
|
+
)
|
|
225
|
+
})}
|
|
226
|
+
{urlButtonElements.length ? messageWithUrlButtonElements : null}
|
|
227
|
+
{webviewButtonElements.length
|
|
228
|
+
? messageWithWebviewButtonElements
|
|
229
|
+
: null}
|
|
159
230
|
</>
|
|
160
231
|
)
|
|
161
232
|
}
|
|
233
|
+
// END LOGIC WHATSAPP WITH MORE THAN 3 BUTTONS
|
|
162
234
|
|
|
163
235
|
multichannelContext.currentIndex = getDefaultIndex()
|
|
164
236
|
const postbackButtonElements = postbackButtons.map(
|
|
@@ -192,7 +264,9 @@ export const MultichannelText = props => {
|
|
|
192
264
|
|
|
193
265
|
return <>{messages}</>
|
|
194
266
|
}
|
|
267
|
+
// END WHATSAPP LOGIC
|
|
195
268
|
|
|
269
|
+
// START FACEBOOK LOGIC
|
|
196
270
|
if (isFacebook(requestContext)) {
|
|
197
271
|
const text = getText(props.children)
|
|
198
272
|
const multichannelFacebook = new MultichannelFacebook()
|
|
@@ -8,8 +8,10 @@ import { Providers } from '@botonic/core'
|
|
|
8
8
|
export const MULTICHANNEL_WHATSAPP_PROPS = { markdown: false }
|
|
9
9
|
|
|
10
10
|
export const WHATSAPP_MAX_BUTTONS = 3
|
|
11
|
+
export const WHATSAPP_LIST_MAX_BUTTONS = 10
|
|
11
12
|
export const WHATSAPP_MAX_BUTTON_CHARS = 20
|
|
12
13
|
export const DEFAULT_WHATSAPP_MAX_BUTTON_SEPARATOR = 'More options:'
|
|
14
|
+
export const MENU_BUTOON_WHATSAPP_BUTTON_LIST = 'Menu'
|
|
13
15
|
|
|
14
16
|
export function isMultichannelButton(node) {
|
|
15
17
|
return isNodeKind(node, 'MultichannelButton')
|
|
@@ -4,6 +4,7 @@ import React, { useContext } from 'react'
|
|
|
4
4
|
import { WebchatContext } from '../contexts'
|
|
5
5
|
import { renderComponent } from '../util/react'
|
|
6
6
|
import { stringifyWithRegexs } from '../util/regexs'
|
|
7
|
+
import { WebchatSettingsProps } from '.'
|
|
7
8
|
|
|
8
9
|
export const WebchatSettings = ({
|
|
9
10
|
theme,
|
|
@@ -13,7 +14,7 @@ export const WebchatSettings = ({
|
|
|
13
14
|
enableAttachments,
|
|
14
15
|
enableUserInput,
|
|
15
16
|
enableAnimations,
|
|
16
|
-
}) => {
|
|
17
|
+
}: WebchatSettingsProps) => {
|
|
17
18
|
const renderBrowser = () => {
|
|
18
19
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
19
20
|
const { updateWebchatDevSettings } = useContext(WebchatContext)
|
|
@@ -39,16 +40,17 @@ export const WebchatSettings = ({
|
|
|
39
40
|
enableAnimations,
|
|
40
41
|
})
|
|
41
42
|
return (
|
|
43
|
+
//@ts-ignore
|
|
42
44
|
<message
|
|
43
45
|
type={INPUT.WEBCHAT_SETTINGS}
|
|
44
46
|
settings={stringifyWithRegexs({ theme: updatedTheme })}
|
|
45
|
-
|
|
47
|
+
/>
|
|
46
48
|
)
|
|
47
49
|
}
|
|
48
50
|
return renderComponent({ renderBrowser, renderNode })
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
export const normalizeWebchatSettings = settings => {
|
|
53
|
+
export const normalizeWebchatSettings = (settings: WebchatSettingsProps) => {
|
|
52
54
|
let {
|
|
53
55
|
theme,
|
|
54
56
|
blockInputs,
|
|
@@ -60,9 +62,7 @@ export const normalizeWebchatSettings = settings => {
|
|
|
60
62
|
} = settings
|
|
61
63
|
if (!theme) theme = {}
|
|
62
64
|
if (!theme.userInput) theme.userInput = {}
|
|
63
|
-
if (!theme.animations) theme.animations = {}
|
|
64
65
|
if (persistentMenu !== undefined) {
|
|
65
|
-
if (!theme.userInput.persistentMenu) theme.userInput.persistentMenu = {}
|
|
66
66
|
theme.userInput.persistentMenu = persistentMenu
|
|
67
67
|
}
|
|
68
68
|
if (enableEmojiPicker !== undefined) {
|
|
@@ -74,13 +74,13 @@ export const normalizeWebchatSettings = settings => {
|
|
|
74
74
|
theme.userInput.attachments.enable = enableAttachments
|
|
75
75
|
}
|
|
76
76
|
if (enableUserInput !== undefined) {
|
|
77
|
-
if (!theme.userInput.enable) theme.userInput.enable = {}
|
|
78
77
|
theme.userInput.enable = enableUserInput
|
|
79
78
|
}
|
|
79
|
+
if (blockInputs !== undefined) theme.userInput.blockInputs = blockInputs
|
|
80
|
+
|
|
81
|
+
if (!theme.animations) theme.animations = {}
|
|
80
82
|
if (enableAnimations !== undefined) {
|
|
81
|
-
if (!theme.animations.enable) theme.animations.enable = {}
|
|
82
83
|
theme.animations.enable = enableAnimations
|
|
83
84
|
}
|
|
84
|
-
if (blockInputs !== undefined) theme.userInput.blockInputs = blockInputs
|
|
85
85
|
return theme
|
|
86
86
|
}
|
package/src/util/environment.js
CHANGED
|
@@ -24,7 +24,7 @@ export const resolveImage = src => {
|
|
|
24
24
|
|
|
25
25
|
export const isURL = urlPath => {
|
|
26
26
|
// @stephenhay (38 chars) from: https://mathiasbynens.be/demo/url-regex
|
|
27
|
-
const pattern = new RegExp(/^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/)
|
|
27
|
+
const pattern = new RegExp(/^(blob:)?(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/)
|
|
28
28
|
return !!pattern.test(urlPath)
|
|
29
29
|
}
|
|
30
30
|
|
package/src/webchat/webchat.jsx
CHANGED
|
@@ -496,8 +496,10 @@ export const Webchat = forwardRef((props, ref) => {
|
|
|
496
496
|
from: SENDERS.user,
|
|
497
497
|
src: temporaryDisplayUrl,
|
|
498
498
|
}
|
|
499
|
-
if (isImage(input))
|
|
500
|
-
|
|
499
|
+
if (isImage(input)) {
|
|
500
|
+
mediaProps.input = input
|
|
501
|
+
messageComponent = <Image {...mediaProps} />
|
|
502
|
+
} else if (isAudio(input)) messageComponent = <Audio {...mediaProps} />
|
|
501
503
|
else if (isVideo(input)) messageComponent = <Video {...mediaProps} />
|
|
502
504
|
else if (isDocument(input))
|
|
503
505
|
messageComponent = <Document {...mediaProps} />
|