@botonic/react 0.21.0 → 0.21.2-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/components/index.d.ts +2 -2
- package/lib/constants.js +2 -0
- package/lib/constants.js.map +1 -1
- package/lib/webchat/components/attachment.js +30 -5
- package/lib/webchat/components/attachment.js.map +1 -1
- package/lib/webchat/components/common.js +2 -6
- package/lib/webchat/components/common.js.map +1 -1
- package/lib/webchat/components/conditional-animation.js +42 -0
- package/lib/webchat/components/conditional-animation.js.map +1 -0
- package/lib/webchat/components/emoji-picker.js +36 -10
- package/lib/webchat/components/emoji-picker.js.map +1 -1
- package/lib/webchat/components/persistent-menu.js +15 -7
- package/lib/webchat/components/persistent-menu.js.map +1 -1
- package/lib/webchat/components/send-button.js +23 -5
- package/lib/webchat/components/send-button.js.map +1 -1
- package/lib/webchat/devices/scrollbar-controller.js.map +1 -1
- package/lib/webchat/webchat.js +18 -37
- package/lib/webchat/webchat.js.map +1 -1
- package/lib/webview.js +3 -2
- package/lib/webview.js.map +1 -1
- package/package.json +3 -2
- package/src/components/index.d.ts +2 -2
- package/src/constants.js +2 -0
- package/src/webchat/components/attachment.jsx +50 -18
- package/src/webchat/components/common.jsx +0 -6
- package/src/webchat/components/conditional-animation.jsx +25 -0
- package/src/webchat/components/emoji-picker.jsx +40 -12
- package/src/webchat/components/persistent-menu.jsx +25 -11
- package/src/webchat/components/send-button.jsx +35 -9
- package/src/webchat/devices/scrollbar-controller.js +1 -2
- package/src/webchat/webchat.jsx +26 -75
- package/src/webview.jsx +2 -1
|
@@ -1,21 +1,53 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useContext } from 'react'
|
|
2
2
|
|
|
3
3
|
import AttachmentIcon from '../../assets/attachment-icon.svg'
|
|
4
|
-
import { ROLES } from '../../constants'
|
|
5
|
-
import {
|
|
4
|
+
import { ROLES, WEBCHAT } from '../../constants'
|
|
5
|
+
import { WebchatContext } from '../../contexts'
|
|
6
|
+
import { ConditionalAnimation } from '../components/conditional-animation'
|
|
7
|
+
import { Icon } from './common'
|
|
6
8
|
|
|
7
|
-
export const Attachment = ({ onChange, accept }) =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
)
|
|
9
|
+
export const Attachment = ({ onChange, accept, enableAttachments }) => {
|
|
10
|
+
const { getThemeProperty } = useContext(WebchatContext)
|
|
11
|
+
|
|
12
|
+
const CustomAttachments = getThemeProperty(
|
|
13
|
+
WEBCHAT.CUSTOM_PROPERTIES.customAttachments,
|
|
14
|
+
undefined
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
const isAttachmentsEnabled = () => {
|
|
18
|
+
const hasCustomAttachments = !!CustomAttachments
|
|
19
|
+
return (
|
|
20
|
+
getThemeProperty(
|
|
21
|
+
WEBCHAT.CUSTOM_PROPERTIES.enableAttachments,
|
|
22
|
+
enableAttachments
|
|
23
|
+
) ?? hasCustomAttachments
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
const attachmentsEnabled = isAttachmentsEnabled()
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<>
|
|
30
|
+
{attachmentsEnabled ? (
|
|
31
|
+
<ConditionalAnimation>
|
|
32
|
+
<div role={ROLES.ATTACHMENT_ICON}>
|
|
33
|
+
<label htmlFor='attachment' style={{ marginTop: 4 }}>
|
|
34
|
+
{CustomAttachments ? (
|
|
35
|
+
<CustomAttachments />
|
|
36
|
+
) : (
|
|
37
|
+
<Icon src={AttachmentIcon} />
|
|
38
|
+
)}
|
|
39
|
+
</label>
|
|
40
|
+
<input
|
|
41
|
+
type='file'
|
|
42
|
+
name='file'
|
|
43
|
+
id='attachment'
|
|
44
|
+
style={{ display: 'none' }}
|
|
45
|
+
onChange={onChange}
|
|
46
|
+
accept={accept}
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
49
|
+
</ConditionalAnimation>
|
|
50
|
+
) : null}
|
|
51
|
+
</>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { motion } from 'framer-motion'
|
|
2
|
+
import React, { useContext } from 'react'
|
|
3
|
+
|
|
4
|
+
import { WEBCHAT } from '../../constants'
|
|
5
|
+
import { WebchatContext } from '../../contexts'
|
|
6
|
+
import { ConditionalWrapper } from '../../util/react'
|
|
7
|
+
|
|
8
|
+
export const ConditionalAnimation = props => {
|
|
9
|
+
const { getThemeProperty } = useContext(WebchatContext)
|
|
10
|
+
|
|
11
|
+
const animationsEnabled = getThemeProperty(
|
|
12
|
+
WEBCHAT.CUSTOM_PROPERTIES.enableAnimations,
|
|
13
|
+
props.enableAnimations !== undefined ? props.enableAnimations : true
|
|
14
|
+
)
|
|
15
|
+
return (
|
|
16
|
+
<ConditionalWrapper
|
|
17
|
+
condition={animationsEnabled}
|
|
18
|
+
wrapper={children => (
|
|
19
|
+
<motion.div whileHover={{ scale: 1.2 }}>{children}</motion.div>
|
|
20
|
+
)}
|
|
21
|
+
>
|
|
22
|
+
{props.children}
|
|
23
|
+
</ConditionalWrapper>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
@@ -1,26 +1,54 @@
|
|
|
1
1
|
import Picker from 'emoji-picker-react'
|
|
2
|
-
import React from 'react'
|
|
2
|
+
import React, { useContext } from 'react'
|
|
3
3
|
import styled from 'styled-components'
|
|
4
4
|
|
|
5
5
|
import LogoEmoji from '../../assets/emojiButton.svg'
|
|
6
|
-
import { ROLES } from '../../constants'
|
|
6
|
+
import { ROLES, WEBCHAT } from '../../constants'
|
|
7
|
+
import { WebchatContext } from '../../contexts'
|
|
8
|
+
import { ConditionalAnimation } from '../components/conditional-animation'
|
|
7
9
|
import { useComponentVisible } from '../hooks'
|
|
8
|
-
import { Icon
|
|
10
|
+
import { Icon } from './common'
|
|
9
11
|
|
|
10
|
-
export const EmojiPicker =
|
|
11
|
-
const
|
|
12
|
-
|
|
12
|
+
export const EmojiPicker = ({ enableEmojiPicker, onClick }) => {
|
|
13
|
+
const { getThemeProperty } = useContext(WebchatContext)
|
|
14
|
+
|
|
15
|
+
const CustomEmojiPicker = getThemeProperty(
|
|
16
|
+
WEBCHAT.CUSTOM_PROPERTIES.customEmojiPicker,
|
|
17
|
+
undefined
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const isEmojiPickerEnabled = () => {
|
|
21
|
+
const hasCustomEmojiPicker = !!CustomEmojiPicker
|
|
22
|
+
return (
|
|
23
|
+
getThemeProperty(
|
|
24
|
+
WEBCHAT.CUSTOM_PROPERTIES.enableEmojiPicker,
|
|
25
|
+
enableEmojiPicker
|
|
26
|
+
) ?? hasCustomEmojiPicker
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
const emojiPickerEnabled = isEmojiPickerEnabled()
|
|
30
|
+
|
|
31
|
+
const handleClick = event => {
|
|
32
|
+
onClick()
|
|
13
33
|
event.stopPropagation()
|
|
14
34
|
}
|
|
15
35
|
|
|
16
36
|
return (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
37
|
+
<>
|
|
38
|
+
{emojiPickerEnabled ? (
|
|
39
|
+
<ConditionalAnimation>
|
|
40
|
+
<div role={ROLES.EMOJI_PICKER_ICON} onClick={handleClick}>
|
|
41
|
+
{CustomEmojiPicker ? (
|
|
42
|
+
<CustomEmojiPicker />
|
|
43
|
+
) : (
|
|
44
|
+
<Icon src={LogoEmoji} />
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
</ConditionalAnimation>
|
|
48
|
+
) : null}
|
|
49
|
+
</>
|
|
22
50
|
)
|
|
23
|
-
}
|
|
51
|
+
}
|
|
24
52
|
|
|
25
53
|
const Container = styled.div`
|
|
26
54
|
display: flex;
|
|
@@ -5,6 +5,7 @@ import LogoMenu from '../../assets/menuButton.svg'
|
|
|
5
5
|
import { Button } from '../../components/button'
|
|
6
6
|
import { ROLES, WEBCHAT } from '../../constants'
|
|
7
7
|
import { WebchatContext } from '../../contexts'
|
|
8
|
+
import { ConditionalAnimation } from '../components/conditional-animation'
|
|
8
9
|
import { useComponentVisible } from '../hooks'
|
|
9
10
|
import { Icon } from './common'
|
|
10
11
|
|
|
@@ -59,17 +60,30 @@ export const OpenedPersistentMenu = ({ onClick, options, borderRadius }) => {
|
|
|
59
60
|
)
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
export const PersistentMenu = ({ onClick, persistentMenu }) => {
|
|
64
|
+
const { getThemeProperty } = useContext(WebchatContext)
|
|
65
|
+
|
|
66
|
+
const persistentMenuOptions = getThemeProperty(
|
|
67
|
+
WEBCHAT.CUSTOM_PROPERTIES.persistentMenu,
|
|
68
|
+
persistentMenu
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
const CustomMenuButton = getThemeProperty(
|
|
72
|
+
WEBCHAT.CUSTOM_PROPERTIES.customMenuButton,
|
|
73
|
+
undefined
|
|
74
|
+
)
|
|
68
75
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
{persistentMenuOptions ? (
|
|
79
|
+
<ConditionalAnimation>
|
|
80
|
+
<div role={ROLES.PERSISTENT_MENU_ICON} onClick={onClick}>
|
|
81
|
+
{CustomMenuButton ? <CustomMenuButton /> : <Icon src={LogoMenu} />}
|
|
82
|
+
</div>
|
|
83
|
+
</ConditionalAnimation>
|
|
84
|
+
) : null}
|
|
85
|
+
</>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
74
88
|
|
|
75
89
|
export default OpenedPersistentMenu
|
|
@@ -1,11 +1,37 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useContext } from 'react'
|
|
2
2
|
|
|
3
3
|
import SendButtonIcon from '../../assets/send-button.svg'
|
|
4
|
-
import { ROLES } from '../../constants'
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
import { ROLES, WEBCHAT } from '../../constants'
|
|
5
|
+
import { WebchatContext } from '../../contexts'
|
|
6
|
+
import { ConditionalAnimation } from '../components/conditional-animation'
|
|
7
|
+
import { Icon } from './common'
|
|
8
|
+
|
|
9
|
+
export const SendButton = ({ onClick }) => {
|
|
10
|
+
const { getThemeProperty } = useContext(WebchatContext)
|
|
11
|
+
|
|
12
|
+
const sendButtonEnabled = getThemeProperty(
|
|
13
|
+
WEBCHAT.CUSTOM_PROPERTIES.enableSendButton,
|
|
14
|
+
true
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
const CustomSendButton = getThemeProperty(
|
|
18
|
+
WEBCHAT.CUSTOM_PROPERTIES.customSendButton,
|
|
19
|
+
undefined
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<>
|
|
24
|
+
{sendButtonEnabled || CustomSendButton ? (
|
|
25
|
+
<ConditionalAnimation>
|
|
26
|
+
<div onClick={onClick} role={ROLES.SEND_BUTTON_ICON}>
|
|
27
|
+
{CustomSendButton ? (
|
|
28
|
+
<CustomSendButton />
|
|
29
|
+
) : (
|
|
30
|
+
<Icon src={SendButtonIcon} />
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
</ConditionalAnimation>
|
|
34
|
+
) : null}
|
|
35
|
+
</>
|
|
36
|
+
)
|
|
37
|
+
}
|
package/src/webchat/webchat.jsx
CHANGED
|
@@ -39,7 +39,6 @@ import {
|
|
|
39
39
|
import { msgToBotonic } from '../msg-to-botonic'
|
|
40
40
|
import { scrollToBottom } from '../util/dom'
|
|
41
41
|
import { isDev, resolveImage } from '../util/environment'
|
|
42
|
-
import { ConditionalWrapper } from '../util/react'
|
|
43
42
|
import { deserializeRegex, stringifyWithRegexs } from '../util/regexs'
|
|
44
43
|
import {
|
|
45
44
|
_getThemeProperty,
|
|
@@ -106,8 +105,13 @@ const StyledTriggerButton = styled.div`
|
|
|
106
105
|
|
|
107
106
|
const UserInputContainer = styled.div`
|
|
108
107
|
min-height: 52px;
|
|
109
|
-
display: flex;
|
|
110
108
|
position: relative;
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
justify-content: flex-start;
|
|
112
|
+
gap: 16px;
|
|
113
|
+
padding: 0px 16px;
|
|
114
|
+
z-index: 1;
|
|
111
115
|
border-top: 1px solid ${COLORS.SOLID_BLACK_ALPHA_0_5};
|
|
112
116
|
`
|
|
113
117
|
|
|
@@ -117,13 +121,6 @@ const TextAreaContainer = styled.div`
|
|
|
117
121
|
align-items: center;
|
|
118
122
|
`
|
|
119
123
|
|
|
120
|
-
const FeaturesWrapper = styled.div`
|
|
121
|
-
display: flex;
|
|
122
|
-
align-items: center;
|
|
123
|
-
justify-content: center;
|
|
124
|
-
z-index: 1;
|
|
125
|
-
`
|
|
126
|
-
|
|
127
124
|
const TriggerImage = styled.img`
|
|
128
125
|
max-width: 100%;
|
|
129
126
|
max-height: 100%;
|
|
@@ -402,10 +399,6 @@ export const Webchat = forwardRef((props, ref) => {
|
|
|
402
399
|
toggleEmojiPicker(!webchatState.isEmojiPickerOpen)
|
|
403
400
|
}
|
|
404
401
|
|
|
405
|
-
const animationsEnabled = getThemeProperty(
|
|
406
|
-
WEBCHAT.CUSTOM_PROPERTIES.enableAnimations,
|
|
407
|
-
props.enableAnimations !== undefined ? props.enableAnimations : true
|
|
408
|
-
)
|
|
409
402
|
const persistentMenuOptions = getThemeProperty(
|
|
410
403
|
WEBCHAT.CUSTOM_PROPERTIES.persistentMenu,
|
|
411
404
|
props.persistentMenu
|
|
@@ -774,37 +767,6 @@ export const Webchat = forwardRef((props, ref) => {
|
|
|
774
767
|
}
|
|
775
768
|
|
|
776
769
|
const userInputEnabled = isUserInputEnabled()
|
|
777
|
-
const emojiPickerEnabled = getThemeProperty(
|
|
778
|
-
WEBCHAT.CUSTOM_PROPERTIES.enableEmojiPicker,
|
|
779
|
-
props.enableEmojiPicker
|
|
780
|
-
)
|
|
781
|
-
const attachmentsEnabled = getThemeProperty(
|
|
782
|
-
WEBCHAT.CUSTOM_PROPERTIES.enableAttachments,
|
|
783
|
-
props.enableAttachments
|
|
784
|
-
)
|
|
785
|
-
const sendButtonEnabled = getThemeProperty(
|
|
786
|
-
WEBCHAT.CUSTOM_PROPERTIES.enableSendButton,
|
|
787
|
-
true
|
|
788
|
-
)
|
|
789
|
-
const CustomSendButton = getThemeProperty(
|
|
790
|
-
WEBCHAT.CUSTOM_PROPERTIES.customSendButton,
|
|
791
|
-
undefined
|
|
792
|
-
)
|
|
793
|
-
const CustomMenuButton = getThemeProperty(
|
|
794
|
-
WEBCHAT.CUSTOM_PROPERTIES.customMenuButton,
|
|
795
|
-
undefined
|
|
796
|
-
)
|
|
797
|
-
|
|
798
|
-
const ConditionalAnimation = props => (
|
|
799
|
-
<ConditionalWrapper
|
|
800
|
-
condition={animationsEnabled}
|
|
801
|
-
wrapper={children => (
|
|
802
|
-
<motion.div whileHover={{ scale: 1.2 }}>{children}</motion.div>
|
|
803
|
-
)}
|
|
804
|
-
>
|
|
805
|
-
{props.children}
|
|
806
|
-
</ConditionalWrapper>
|
|
807
|
-
)
|
|
808
770
|
|
|
809
771
|
const userInputArea = () => {
|
|
810
772
|
return (
|
|
@@ -813,6 +775,7 @@ export const Webchat = forwardRef((props, ref) => {
|
|
|
813
775
|
style={{
|
|
814
776
|
...getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.userInputStyle),
|
|
815
777
|
}}
|
|
778
|
+
className='user-input-container'
|
|
816
779
|
>
|
|
817
780
|
{webchatState.isEmojiPickerOpen && (
|
|
818
781
|
<OpenedEmojiPicker
|
|
@@ -821,15 +784,12 @@ export const Webchat = forwardRef((props, ref) => {
|
|
|
821
784
|
onClick={handleEmojiClick}
|
|
822
785
|
/>
|
|
823
786
|
)}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
</ConditionalAnimation>
|
|
831
|
-
</FeaturesWrapper>
|
|
832
|
-
)}
|
|
787
|
+
|
|
788
|
+
<PersistentMenu
|
|
789
|
+
onClick={handleMenu}
|
|
790
|
+
persistentMenu={props.persistentMenu}
|
|
791
|
+
/>
|
|
792
|
+
|
|
833
793
|
<TextAreaContainer>
|
|
834
794
|
<Textarea
|
|
835
795
|
name='text'
|
|
@@ -864,28 +824,19 @@ export const Webchat = forwardRef((props, ref) => {
|
|
|
864
824
|
}}
|
|
865
825
|
/>
|
|
866
826
|
</TextAreaContainer>
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
)}
|
|
881
|
-
{(sendButtonEnabled || CustomSendButton) && (
|
|
882
|
-
<ConditionalAnimation>
|
|
883
|
-
<div onClick={sendTextAreaText}>
|
|
884
|
-
{CustomSendButton ? <CustomSendButton /> : <SendButton />}
|
|
885
|
-
</div>
|
|
886
|
-
</ConditionalAnimation>
|
|
887
|
-
)}
|
|
888
|
-
</FeaturesWrapper>
|
|
827
|
+
|
|
828
|
+
<EmojiPicker
|
|
829
|
+
enableEmojiPicker={props.enableEmojiPicker}
|
|
830
|
+
onClick={handleEmojiClick}
|
|
831
|
+
/>
|
|
832
|
+
|
|
833
|
+
<Attachment
|
|
834
|
+
enableAttachments={props.enableAttachments}
|
|
835
|
+
onChange={handleAttachment}
|
|
836
|
+
accept={getFullMimeWhitelist().join(',')}
|
|
837
|
+
/>
|
|
838
|
+
|
|
839
|
+
<SendButton onClick={sendTextAreaText} />
|
|
889
840
|
</UserInputContainer>
|
|
890
841
|
)
|
|
891
842
|
)
|
package/src/webview.jsx
CHANGED
|
@@ -43,7 +43,8 @@ class App extends React.Component {
|
|
|
43
43
|
const provider = this.state.session.user.provider
|
|
44
44
|
const impId = this.state.session.user.imp_id
|
|
45
45
|
if (provider === PROVIDER.WHATSAPP) {
|
|
46
|
-
|
|
46
|
+
const phone_number = this.state.session.user.unformatted_phone_number
|
|
47
|
+
location.href = 'https://wa.me/' + phone_number
|
|
47
48
|
}
|
|
48
49
|
if (provider === PROVIDER.TELEGRAM) {
|
|
49
50
|
location.href = 'https://t.me/' + impId
|