@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.
Files changed (32) hide show
  1. package/lib/components/index.d.ts +2 -2
  2. package/lib/constants.js +2 -0
  3. package/lib/constants.js.map +1 -1
  4. package/lib/webchat/components/attachment.js +30 -5
  5. package/lib/webchat/components/attachment.js.map +1 -1
  6. package/lib/webchat/components/common.js +2 -6
  7. package/lib/webchat/components/common.js.map +1 -1
  8. package/lib/webchat/components/conditional-animation.js +42 -0
  9. package/lib/webchat/components/conditional-animation.js.map +1 -0
  10. package/lib/webchat/components/emoji-picker.js +36 -10
  11. package/lib/webchat/components/emoji-picker.js.map +1 -1
  12. package/lib/webchat/components/persistent-menu.js +15 -7
  13. package/lib/webchat/components/persistent-menu.js.map +1 -1
  14. package/lib/webchat/components/send-button.js +23 -5
  15. package/lib/webchat/components/send-button.js.map +1 -1
  16. package/lib/webchat/devices/scrollbar-controller.js.map +1 -1
  17. package/lib/webchat/webchat.js +18 -37
  18. package/lib/webchat/webchat.js.map +1 -1
  19. package/lib/webview.js +3 -2
  20. package/lib/webview.js.map +1 -1
  21. package/package.json +3 -2
  22. package/src/components/index.d.ts +2 -2
  23. package/src/constants.js +2 -0
  24. package/src/webchat/components/attachment.jsx +50 -18
  25. package/src/webchat/components/common.jsx +0 -6
  26. package/src/webchat/components/conditional-animation.jsx +25 -0
  27. package/src/webchat/components/emoji-picker.jsx +40 -12
  28. package/src/webchat/components/persistent-menu.jsx +25 -11
  29. package/src/webchat/components/send-button.jsx +35 -9
  30. package/src/webchat/devices/scrollbar-controller.js +1 -2
  31. package/src/webchat/webchat.jsx +26 -75
  32. 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 { Icon, IconContainer } from './common'
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
- <IconContainer role={ROLES.ATTACHMENT_ICON}>
9
- <label htmlFor='attachment' style={{ marginTop: 4 }}>
10
- <Icon src={AttachmentIcon} />
11
- </label>
12
- <input
13
- type='file'
14
- name='file'
15
- id='attachment'
16
- style={{ display: 'none' }}
17
- onChange={onChange}
18
- accept={accept}
19
- ></input>
20
- </IconContainer>
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
+ }
@@ -7,9 +7,3 @@ const PointerImage = styled.img`
7
7
  cursor: pointer;
8
8
  `
9
9
  export const Icon = props => <PointerImage src={resolveImage(props.src)} />
10
-
11
- export const IconContainer = styled.div`
12
- display: flex;
13
- align-items: center;
14
- padding-right: 15px;
15
- `
@@ -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, IconContainer } from './common'
10
+ import { Icon } from './common'
9
11
 
10
- export const EmojiPicker = props =>{
11
- const onClick = event =>{
12
- props.onClick()
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
- <IconContainer role={ROLES.EMOJI_PICKER_ICON}>
18
- <div onClick={onClick}>
19
- <Icon src={LogoEmoji} />
20
- </div>
21
- </IconContainer>
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 IconContainer = styled.div`
63
- display: flex;
64
- align-items: center;
65
- cursor: pointer;
66
- padding: 18px;
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
- export const PersistentMenu = props => (
70
- <IconContainer role={ROLES.PERSISTENT_MENU_ICON} onClick={props.onClick}>
71
- <Icon src={LogoMenu} />
72
- </IconContainer>
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 { Icon, IconContainer } from './common'
6
-
7
- export const SendButton = () => (
8
- <IconContainer role={ROLES.SEND_BUTTON_ICON}>
9
- <Icon src={SendButtonIcon} />
10
- </IconContainer>
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
+ }
@@ -84,8 +84,7 @@ export class ScrollbarController {
84
84
  return
85
85
  }
86
86
  this.webchat.ontouchmove = e => {
87
- if(e.target === e.currentTarget)
88
- e.preventDefault()
87
+ if (e.target === e.currentTarget) e.preventDefault()
89
88
  }
90
89
  }
91
90
 
@@ -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
- {persistentMenuOptions && (
825
- <FeaturesWrapper>
826
- <ConditionalAnimation>
827
- <div onClick={handleMenu}>
828
- {CustomMenuButton ? <CustomMenuButton /> : <PersistentMenu />}
829
- </div>
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
- <FeaturesWrapper>
868
- {emojiPickerEnabled && (
869
- <ConditionalAnimation>
870
- <EmojiPicker onClick={handleEmojiClick} />
871
- </ConditionalAnimation>
872
- )}
873
- {attachmentsEnabled && (
874
- <ConditionalAnimation>
875
- <Attachment
876
- onChange={handleAttachment}
877
- accept={getFullMimeWhitelist().join(',')}
878
- />
879
- </ConditionalAnimation>
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
- location.href = 'https://wa.me/' + impId
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