@botpress/webchat 0.2.3 → 0.3.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 (70) hide show
  1. package/README.md +31 -0
  2. package/dist/components/Composer.d.ts +4 -5
  3. package/dist/components/Composer.js +13 -23
  4. package/dist/components/Container.d.ts +1 -1
  5. package/dist/components/Container.js +1 -6
  6. package/dist/components/ConversationList.d.ts +1 -1
  7. package/dist/components/ConversationList.js +5 -46
  8. package/dist/components/Header.d.ts +1 -3
  9. package/dist/components/Header.js +17 -64
  10. package/dist/components/VoiceRecorder.js +6 -2
  11. package/dist/components/common/{Avatar.d.ts → Avatar/index.d.ts} +0 -0
  12. package/dist/components/common/Avatar/index.js +13 -0
  13. package/dist/components/common/{BotInfo.d.ts → BotInfo/index.d.ts} +3 -3
  14. package/dist/components/common/BotInfo/index.js +102 -0
  15. package/dist/components/common/ConfirmDialog/index.d.ts +11 -0
  16. package/dist/components/common/ConfirmDialog/index.js +78 -0
  17. package/dist/components/common/Dialog/index.d.ts +17 -0
  18. package/dist/components/common/Dialog/index.js +57 -0
  19. package/dist/components/common/ToolTip/index.d.ts +10 -0
  20. package/dist/components/common/ToolTip/index.js +163 -0
  21. package/dist/components/common/ToolTip/utils.d.ts +15 -0
  22. package/dist/components/common/ToolTip/utils.js +78 -0
  23. package/dist/components/messages/InlineFeedback.d.ts +2 -1
  24. package/dist/components/messages/Message.js +2 -25
  25. package/dist/components/messages/MessageGroup.d.ts +1 -13
  26. package/dist/components/messages/MessageGroup.js +6 -40
  27. package/dist/components/messages/MessageList.d.ts +1 -1
  28. package/dist/components/messages/MessageList.js +8 -31
  29. package/dist/core/api.d.ts +4 -18
  30. package/dist/core/api.js +25 -150
  31. package/dist/core/constants.d.ts +4 -32
  32. package/dist/core/constants.js +18 -32
  33. package/dist/core/socket.d.ts +1 -12
  34. package/dist/core/socket.js +7 -73
  35. package/dist/{components/Stylesheet.d.ts → icons/Cancel.d.ts} +2 -2
  36. package/dist/icons/Cancel.js +10 -0
  37. package/dist/icons/Microphone.d.ts +5 -0
  38. package/dist/icons/Microphone.js +12 -0
  39. package/dist/index.d.ts +2 -8
  40. package/dist/index.js +9 -29
  41. package/dist/main.d.ts +2 -2
  42. package/dist/main.js +100 -168
  43. package/dist/store/composer.js +3 -6
  44. package/dist/store/index.d.ts +8 -18
  45. package/dist/store/index.js +98 -136
  46. package/dist/store/view.d.ts +3 -6
  47. package/dist/store/view.js +6 -23
  48. package/dist/translations/index.d.ts +3 -1
  49. package/dist/translations/index.js +44 -4
  50. package/dist/typings.d.ts +121 -71
  51. package/dist/utils/analytics.d.ts +5 -0
  52. package/dist/utils/analytics.js +37 -0
  53. package/dist/utils/index.d.ts +3 -0
  54. package/dist/utils/index.js +27 -0
  55. package/dist/utils/storage.d.ts +16 -0
  56. package/dist/utils/storage.js +129 -0
  57. package/package.json +4 -3
  58. package/dist/components/ContextMenu.d.ts +0 -2
  59. package/dist/components/ContextMenu.js +0 -33
  60. package/dist/components/OverridableComponent.d.ts +0 -24
  61. package/dist/components/OverridableComponent.js +0 -50
  62. package/dist/components/Stylesheet.js +0 -7
  63. package/dist/components/common/Avatar.js +0 -29
  64. package/dist/components/common/BotInfo.js +0 -110
  65. package/dist/icons/CloseChat.d.ts +0 -6
  66. package/dist/icons/CloseChat.js +0 -9
  67. package/dist/icons/Send.d.ts +0 -6
  68. package/dist/icons/Send.js +0 -8
  69. package/dist/utils.d.ts +0 -8
  70. package/dist/utils.js +0 -111
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Webchat
2
+
3
+ ### Sending
4
+
5
+ | Channels | Webchat | Details |
6
+ | -------- | :-----: | :------ |
7
+ | Text | ✅ | |
8
+ | Image | ✅ | |
9
+ | Choice | ✅ | |
10
+ | Dropdown | ✅ | |
11
+ | Card | ✅ | |
12
+ | Carousel | ✅ | |
13
+ | File | ✅ | |
14
+ | Audio | ✅ | |
15
+ | Video | ✅ | |
16
+ | Location | ❌ | |
17
+
18
+ ### Receiving
19
+
20
+ | Channels | Webchat | Details |
21
+ | ------------- | :-----: | :------ |
22
+ | Text | ✅ | |
23
+ | Quick Reply | ✅ | |
24
+ | Postback | ✅ | |
25
+ | Say Something | ✅ | |
26
+ | Voice | ❌ | |
27
+ | Image | ❌ | |
28
+ | File | ❌ | |
29
+ | Audio | ❌ | |
30
+ | Video | ❌ | |
31
+ | Location | ❌ | |
@@ -8,8 +8,7 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
8
8
  } & import("mobx-react").IWrappedComponent<unknown>;
9
9
  export default _default;
10
10
  declare type ComposerProps = {
11
- focused: boolean;
12
- composerPlaceholder: string;
13
- composerLocked: boolean;
14
- composerHidden: boolean;
15
- } & WrappedComponentProps & Pick<StoreDef, 'botName' | 'composerPlaceholder' | 'intl' | 'focusedArea' | 'sendMessage' | 'sendVoiceMessage' | 'focusPrevious' | 'focusNext' | 'recallHistory' | 'setFocus' | 'updateMessage' | 'message' | 'enableArrowNavigation' | 'resetSession' | 'isEmulator' | 'enableResetSessionShortcut' | 'enableVoiceComposer' | 'currentConversation' | 'preferredLanguage'>;
11
+ composerPlaceholder?: string;
12
+ composerLocked?: boolean;
13
+ composerHidden?: boolean;
14
+ } & WrappedComponentProps & Pick<StoreDef, 'botName' | 'composerPlaceholder' | 'intl' | 'focusedArea' | 'sendMessage' | 'sendVoiceMessage' | 'focusPrevious' | 'focusNext' | 'recallHistory' | 'setFocus' | 'updateMessage' | 'message' | 'enableVoiceComposer' | 'currentConversation' | 'preferredLanguage'>;
@@ -16,35 +16,19 @@ const mobx_1 = require("mobx");
16
16
  const mobx_react_1 = require("mobx-react");
17
17
  const react_1 = __importDefault(require("react"));
18
18
  const react_intl_1 = require("react-intl");
19
+ const ToolTip_1 = __importDefault(require("./common/ToolTip"));
19
20
  const VoiceRecorder_1 = __importDefault(require("./VoiceRecorder"));
20
21
  class Composer extends react_1.default.Component {
21
22
  constructor(props) {
22
23
  super(props);
23
24
  this.handleKeyPress = (e) => __awaiter(this, void 0, void 0, function* () {
24
- if (this.props.enableResetSessionShortcut && e.ctrlKey && e.key === 'Enter') {
25
- e.preventDefault();
26
- yield this.props.resetSession();
27
- yield this.props.sendMessage();
28
- return;
29
- }
30
25
  if (e.key === 'Enter') {
31
26
  e.preventDefault();
32
27
  yield this.props.sendMessage();
33
28
  }
34
29
  });
35
30
  this.handleKeyDown = (e) => {
36
- if (this.props.enableArrowNavigation) {
37
- const shouldFocusPrevious = e.target.selectionStart === 0 && (e.key === 'ArrowUp' || e.key === 'ArrowLeft');
38
- if (shouldFocusPrevious) {
39
- this.props.focusPrevious();
40
- }
41
- const shouldFocusNext = e.target.selectionStart === this.textInput.current.value.length &&
42
- (e.key === 'ArrowDown' || e.key === 'ArrowRight');
43
- if (shouldFocusNext) {
44
- this.props.focusNext();
45
- }
46
- }
47
- else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
31
+ if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
48
32
  this.props.recallHistory(e.key);
49
33
  }
50
34
  };
@@ -89,7 +73,17 @@ class Composer extends react_1.default.Component {
89
73
  defaultMessage: 'Message to send'
90
74
  }), disabled: this.props.composerLocked }),
91
75
  react_1.default.createElement("label", { htmlFor: "input-message", style: { display: 'none' } }, placeholder),
92
- react_1.default.createElement("div", { className: 'bpw-send-buttons' }, this.props.enableVoiceComposer && (react_1.default.createElement(VoiceRecorder_1.default, { onStart: this.onVoiceStart, onDone: this.onVoiceEnd, onNotAvailable: this.onVoiceNotAvailable }))))));
76
+ react_1.default.createElement("div", { className: 'bpw-send-buttons' },
77
+ this.props.enableVoiceComposer && (react_1.default.createElement(VoiceRecorder_1.default, { onStart: this.onVoiceStart, onDone: this.onVoiceEnd, onNotAvailable: this.onVoiceNotAvailable })),
78
+ react_1.default.createElement(ToolTip_1.default, { childId: "btn-send", content: this.props.intl.formatMessage({
79
+ id: 'composer.sendMessage',
80
+ defaultMessage: 'Send Message'
81
+ }) },
82
+ react_1.default.createElement("button", { className: 'bpw-send-button', disabled: !this.props.message.length || this.props.composerLocked || this.state.isRecording, onClick: this.props.sendMessage.bind(this, undefined), "aria-label": this.props.intl.formatMessage({
83
+ id: 'composer.send',
84
+ defaultMessage: 'Send'
85
+ }), id: "btn-send" },
86
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'composer.send' })))))));
93
87
  }
94
88
  }
95
89
  exports.default = (0, mobx_react_1.inject)(({ store }) => ({
@@ -108,10 +102,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
108
102
  focusedArea: store.view.focusedArea,
109
103
  focusPrevious: store.view.focusPrevious,
110
104
  focusNext: store.view.focusNext,
111
- enableArrowNavigation: store.config.enableArrowNavigation,
112
- enableResetSessionShortcut: store.config.enableResetSessionShortcut,
113
- resetSession: store.resetSession,
114
105
  currentConversation: store.currentConversation,
115
- isEmulator: store.isEmulator,
116
106
  preferredLanguage: store.preferredLanguage
117
107
  }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(Composer)));
@@ -9,4 +9,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
9
9
  export default _default;
10
10
  declare type ContainerProps = {
11
11
  store?: RootStore;
12
- } & WrappedComponentProps & Pick<StoreDef, 'config' | 'botName' | 'isFullscreen' | 'isConversationsDisplayed' | 'isBotInfoDisplayed' | 'sideTransition' | 'isInitialized' | 'dimensions' | 'isEmulator' | 'isPoweredByDisplayed' | 'rtl'>;
12
+ } & WrappedComponentProps & Pick<StoreDef, 'config' | 'botName' | 'isFullscreen' | 'isConversationsDisplayed' | 'isBotInfoDisplayed' | 'sideTransition' | 'isInitialized' | 'dimensions' | 'isPoweredByDisplayed' | 'rtl'>;
@@ -14,7 +14,6 @@ const ConversationList_1 = __importDefault(require("./ConversationList"));
14
14
  const Footer_1 = __importDefault(require("./Footer"));
15
15
  const Header_1 = __importDefault(require("./Header"));
16
16
  const MessageList_1 = __importDefault(require("./messages/MessageList"));
17
- const OverridableComponent_1 = __importDefault(require("./OverridableComponent"));
18
17
  class Container extends react_1.default.Component {
19
18
  renderBody() {
20
19
  if (!this.props.isInitialized) {
@@ -29,12 +28,11 @@ class Container extends react_1.default.Component {
29
28
  }
30
29
  else {
31
30
  return (react_1.default.createElement("div", { className: (0, classnames_1.default)('bpw-msg-list-container', {
32
- 'bpw-emulator': this.props.isEmulator,
33
31
  'bpw-rtl': this.props.rtl
34
32
  }) },
35
33
  react_1.default.createElement(MessageList_1.default, null),
36
34
  react_1.default.createElement(messaging_components_1.Keyboard, null,
37
- react_1.default.createElement(OverridableComponent_1.default, { name: 'composer', original: Composer_1.default }))));
35
+ react_1.default.createElement(Composer_1.default, null))));
38
36
  }
39
37
  }
40
38
  render() {
@@ -43,11 +41,9 @@ class Container extends react_1.default.Component {
43
41
  [`bpw-anim-${this.props.sideTransition}`]: true
44
42
  });
45
43
  return (react_1.default.createElement(react_1.default.Fragment, null,
46
- react_1.default.createElement(OverridableComponent_1.default, { name: 'before_container', original: null }),
47
44
  react_1.default.createElement("div", { className: classNames, style: { width: this.props.dimensions.layout } },
48
45
  react_1.default.createElement(Header_1.default, null),
49
46
  this.renderBody(),
50
- react_1.default.createElement(OverridableComponent_1.default, { name: 'below_conversation', original: null }),
51
47
  this.props.isPoweredByDisplayed && react_1.default.createElement(Footer_1.default, null))));
52
48
  }
53
49
  }
@@ -58,7 +54,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
58
54
  isFullscreen: store.view.isFullscreen,
59
55
  sideTransition: store.view.sideTransition,
60
56
  dimensions: store.view.dimensions,
61
- isEmulator: store.isEmulator,
62
57
  isInitialized: store.isInitialized,
63
58
  isPoweredByDisplayed: store.view.isPoweredByDisplayed,
64
59
  config: store.config,
@@ -7,4 +7,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
7
7
  WrappedComponent: React.ComponentType<ConversationListProps>;
8
8
  } & import("mobx-react").IWrappedComponent<unknown>;
9
9
  export default _default;
10
- declare type ConversationListProps = WrappedComponentProps & Pick<StoreDef, 'conversations' | 'fetchConversation' | 'createConversation' | 'enableArrowNavigation'>;
10
+ declare type ConversationListProps = WrappedComponentProps & Pick<StoreDef, 'conversations' | 'fetchConversation' | 'createConversation'>;
@@ -8,7 +8,7 @@ const mobx_react_1 = require("mobx-react");
8
8
  const react_1 = __importDefault(require("react"));
9
9
  const react_intl_1 = require("react-intl");
10
10
  const Add_1 = __importDefault(require("../icons/Add"));
11
- const ConversationListItem = (0, react_intl_1.injectIntl)(({ conversation, onClick, hasFocus, intl }) => {
11
+ const ConversationListItem = (0, react_intl_1.injectIntl)(({ conversation, onClick, intl }) => {
12
12
  var _a, _b, _c;
13
13
  const title = intl.formatMessage({ id: 'conversationList.title' }, { id: conversation.id });
14
14
  const { value, unit } = (0, intl_utils_1.selectUnit)(new Date(((_a = conversation.lastMessage) === null || _a === void 0 ? void 0 : _a.sentOn) || conversation.createdOn));
@@ -23,60 +23,19 @@ const ConversationListItem = (0, react_intl_1.injectIntl)(({ conversation, onCli
23
23
  react_1.default.createElement("div", { className: 'bpw-convo-preview' }, message))));
24
24
  });
25
25
  class ConversationList extends react_1.default.Component {
26
- constructor() {
27
- super(...arguments);
28
- this.state = {
29
- focusIdx: undefined
30
- };
31
- this.changeFocus = (step) => {
32
- let focusIdx = this.state.focusIdx || 0;
33
- focusIdx += step;
34
- if (focusIdx > this.props.conversations.length) {
35
- focusIdx = 0;
36
- }
37
- else if (focusIdx < 0) {
38
- focusIdx = this.props.conversations.length;
39
- }
40
- this.setState({ focusIdx });
41
- };
42
- this.handleKeyDown = (e) => {
43
- if (!this.props.enableArrowNavigation) {
44
- return;
45
- }
46
- if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
47
- this.changeFocus(1);
48
- }
49
- else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
50
- this.changeFocus(-1);
51
- }
52
- else if (e.key === 'Enter' && this.state.focusIdx && this.state.focusIdx < this.props.conversations.length) {
53
- const convoId = this.props.conversations[this.state.focusIdx].id;
54
- this.props.fetchConversation.bind(this, convoId);
55
- }
56
- };
57
- }
58
26
  componentDidMount() {
59
27
  this.main.focus();
60
28
  }
61
- componentDidUpdate(_, prevState) {
62
- if (this.state.focusIdx === this.props.conversations.length) {
63
- this.btn.focus();
64
- }
65
- else if (prevState.focusIdx === this.props.conversations.length) {
66
- this.main.focus();
67
- }
68
- }
69
29
  render() {
70
30
  const { conversations, createConversation, fetchConversation } = this.props;
71
- return (react_1.default.createElement("div", { tabIndex: 0, ref: (el) => (this.main = el), className: 'bpw-convo-list', onKeyDown: this.handleKeyDown },
72
- conversations.map((convo, idx) => (react_1.default.createElement(ConversationListItem, { key: convo.id, hasFocus: this.state.focusIdx === idx, conversation: convo, onClick: fetchConversation.bind(this, convo.id) }))),
73
- react_1.default.createElement("button", { ref: (el) => (this.btn = el), id: "btn-convo-add", className: 'bpw-convo-add-btn', onClick: createConversation.bind(this, undefined) },
31
+ return (react_1.default.createElement("div", { tabIndex: 0, ref: (el) => (this.main = el), className: 'bpw-convo-list' },
32
+ conversations.map((conversation, idx) => (react_1.default.createElement(ConversationListItem, { key: conversation.id, conversation: conversation, onClick: fetchConversation.bind(this, conversation.id) }))),
33
+ react_1.default.createElement("button", { id: "btn-convo-add", className: 'bpw-convo-add-btn', onClick: createConversation.bind(this, undefined) },
74
34
  react_1.default.createElement(Add_1.default, { width: 15, height: 15 }))));
75
35
  }
76
36
  }
77
37
  exports.default = (0, mobx_react_1.inject)(({ store }) => ({
78
38
  conversations: store.conversations,
79
39
  createConversation: store.createConversation,
80
- fetchConversation: store.fetchConversation,
81
- enableArrowNavigation: store.config.enableArrowNavigation
40
+ fetchConversation: store.fetchConversation
82
41
  }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(ConversationList)));
@@ -13,16 +13,14 @@ declare class Header extends React.Component<HeaderProps> {
13
13
  renderTitle: () => JSX.Element;
14
14
  handleDeleteConversation: () => Promise<void>;
15
15
  renderDeleteConversationButton(): JSX.Element;
16
- renderResetButton(): JSX.Element;
17
16
  renderDownloadButton(): JSX.Element;
18
17
  renderConvoButton(): JSX.Element;
19
18
  renderBotInfoButton(): JSX.Element;
20
19
  renderCloseButton(): JSX.Element;
21
20
  renderCustomButtons(): JSX.Element[];
22
- handleKeyDown: (action: any, e: any) => void;
23
21
  setShowingOption: (val: any) => void;
24
22
  render(): JSX.Element;
25
23
  }
26
24
  declare const _default: typeof Header & import("mobx-react").IWrappedComponent<unknown>;
27
25
  export default _default;
28
- declare type HeaderProps = Pick<StoreDef, 'intl' | 'sendMessage' | 'focusPrevious' | 'focusNext' | 'focusedArea' | 'isConversationsDisplayed' | 'botName' | 'isEmulator' | 'hasUnreadMessages' | 'unreadCount' | 'hasBotInfoDescription' | 'deleteConversation' | 'resetSession' | 'downloadConversation' | 'toggleConversations' | 'hideChat' | 'toggleBotInfo' | 'botAvatarUrl' | 'showResetButton' | 'showDeleteConversationButton' | 'showDownloadButton' | 'showConversationsButton' | 'showBotInfoButton' | 'showCloseButton' | 'enableArrowNavigation' | 'botConvoDescription' | 'customButtons'>;
26
+ declare type HeaderProps = Pick<StoreDef, 'intl' | 'sendMessage' | 'focusPrevious' | 'focusNext' | 'focusedArea' | 'isConversationsDisplayed' | 'botName' | 'hasUnreadMessages' | 'unreadCount' | 'hasBotInfoDescription' | 'deleteConversation' | 'downloadConversation' | 'toggleConversations' | 'hideChat' | 'toggleBotInfo' | 'botAvatarUrl' | 'showDeleteConversationButton' | 'showDownloadButton' | 'showConversationsButton' | 'showBotInfoButton' | 'showCloseButton' | 'botConversationDescription' | 'customButtons'>;
@@ -15,16 +15,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const mobx_1 = require("mobx");
16
16
  const mobx_react_1 = require("mobx-react");
17
17
  const react_1 = __importDefault(require("react"));
18
- // TODO: put this back
19
- // import confirmDialog from '../../../../../../packages/ui-shared-lite/ConfirmDialog'
20
- // import MoreOptions from '../../../../../../packages/ui-shared-lite/MoreOptions'
21
18
  const Close_1 = __importDefault(require("../icons/Close"));
22
19
  const Delete_1 = __importDefault(require("../icons/Delete"));
23
20
  const Download_1 = __importDefault(require("../icons/Download"));
24
21
  const Information_1 = __importDefault(require("../icons/Information"));
25
22
  const List_1 = __importDefault(require("../icons/List"));
26
- const Reload_1 = __importDefault(require("../icons/Reload"));
27
23
  const Avatar_1 = __importDefault(require("./common/Avatar"));
24
+ const ConfirmDialog_1 = __importDefault(require("./common/ConfirmDialog"));
28
25
  class Header extends react_1.default.Component {
29
26
  constructor() {
30
27
  super(...arguments);
@@ -65,51 +62,22 @@ class Header extends react_1.default.Component {
65
62
  react_1.default.createElement("div", { className: 'bpw-header-name' },
66
63
  title,
67
64
  this.props.hasUnreadMessages && react_1.default.createElement("span", { className: 'bpw-header-unread' }, this.props.unreadCount)),
68
- this.props.hasBotInfoDescription && (react_1.default.createElement("div", { className: 'bpw-header-subtitle' }, this.props.botConvoDescription))));
65
+ this.props.hasBotInfoDescription && (react_1.default.createElement("div", { className: 'bpw-header-subtitle' }, this.props.botConversationDescription))));
69
66
  };
70
67
  this.handleDeleteConversation = () => __awaiter(this, void 0, void 0, function* () {
71
- // TODO: put this back
72
- /*
73
- if (
74
- await confirmDialog(
75
- this.props.intl!.formatMessage({
76
- id: 'header.deleteConversation'
77
- }),
78
- {
79
- acceptLabel: this.props.intl!.formatMessage({
68
+ if (yield (0, ConfirmDialog_1.default)(this.props.intl.formatMessage({
69
+ id: 'header.deleteConversation'
70
+ }), {
71
+ acceptLabel: this.props.intl.formatMessage({
80
72
  id: 'header.deleteConversationYes'
81
- }),
82
- declineLabel: this.props.intl!.formatMessage({
73
+ }),
74
+ declineLabel: this.props.intl.formatMessage({
83
75
  id: 'header.deleteConversationNo'
84
- })
85
- }
86
- )
87
- ) {
88
- await this.props.deleteConversation!()
76
+ })
77
+ })) {
78
+ yield this.props.deleteConversation();
89
79
  }
90
- */
91
80
  });
92
- this.handleKeyDown = (action, e) => {
93
- if (!this.props.enableArrowNavigation) {
94
- return;
95
- }
96
- if (e.key === 'ArrowUp') {
97
- this.props.focusPrevious();
98
- }
99
- else if (e.key === 'ArrowDown') {
100
- this.props.focusNext();
101
- }
102
- else if (e.key === 'ArrowLeft') {
103
- this.changeButtonFocus(-1);
104
- }
105
- else if (e.key === 'ArrowRight') {
106
- this.changeButtonFocus(1);
107
- }
108
- else if (e.key === 'Enter') {
109
- e.preventDefault();
110
- action();
111
- }
112
- };
113
81
  this.setShowingOption = (val) => {
114
82
  this.setState({ showingOption: val });
115
83
  };
@@ -120,30 +88,26 @@ class Header extends react_1.default.Component {
120
88
  });
121
89
  }
122
90
  renderDeleteConversationButton() {
123
- return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-delete", ref: (el) => (this.btnEls[0] = el), className: 'bpw-header-icon bpw-header-icon-delete', onClick: this.handleDeleteConversation, onKeyDown: this.handleKeyDown.bind(this, this.handleDeleteConversation), onBlur: this.onBlur },
91
+ return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-delete", ref: (el) => (this.btnEls[0] = el), className: 'bpw-header-icon bpw-header-icon-delete', onClick: this.handleDeleteConversation, onBlur: this.onBlur },
124
92
  react_1.default.createElement(Delete_1.default, null)));
125
93
  }
126
- renderResetButton() {
127
- return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-reset", ref: (el) => (this.btnEls[1] = el), className: 'bpw-header-icon bpw-header-icon-reset', onClick: this.props.resetSession, onKeyDown: this.handleKeyDown.bind(this, this.props.resetSession), onBlur: this.onBlur },
128
- react_1.default.createElement(Reload_1.default, null)));
129
- }
130
94
  renderDownloadButton() {
131
- return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-download", ref: (el) => (this.btnEls[2] = el), className: 'bpw-header-icon bpw-header-icon-download', onClick: this.props.downloadConversation, onKeyDown: this.handleKeyDown.bind(this, this.props.downloadConversation), onBlur: this.onBlur },
95
+ return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-download", ref: (el) => (this.btnEls[2] = el), className: 'bpw-header-icon bpw-header-icon-download', onClick: this.props.downloadConversation, onBlur: this.onBlur },
132
96
  react_1.default.createElement(Download_1.default, null)));
133
97
  }
134
98
  renderConvoButton() {
135
- return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-conversations", ref: (el) => (this.btnEls[3] = el), className: 'bpw-header-icon bpw-header-icon-convo', onClick: this.props.toggleConversations, onKeyDown: this.handleKeyDown.bind(this, this.props.toggleConversations), onBlur: this.onBlur },
99
+ return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-conversations", ref: (el) => (this.btnEls[3] = el), className: 'bpw-header-icon bpw-header-icon-convo', onClick: this.props.toggleConversations, onBlur: this.onBlur },
136
100
  react_1.default.createElement(List_1.default, null)));
137
101
  }
138
102
  renderBotInfoButton() {
139
- return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-botinfo", ref: (el) => (this.btnEls[4] = el), className: 'bpw-header-icon bpw-header-icon-botinfo', onClick: this.props.toggleBotInfo, onKeyDown: this.handleKeyDown.bind(this, this.props.toggleBotInfo), onBlur: this.onBlur },
103
+ return (react_1.default.createElement("button", { type: "button", tabIndex: -1, id: "btn-botinfo", ref: (el) => (this.btnEls[4] = el), className: 'bpw-header-icon bpw-header-icon-botinfo', onClick: this.props.toggleBotInfo, onBlur: this.onBlur },
140
104
  react_1.default.createElement(Information_1.default, null)));
141
105
  }
142
106
  renderCloseButton() {
143
107
  return (react_1.default.createElement("button", { type: "button", id: "btn-close", "aria-label": this.props.intl.formatMessage({
144
108
  id: 'header.hideChatWindow',
145
109
  defaultMessage: 'Hide the chat window'
146
- }), ref: (el) => (this.btnEls[5] = el), className: 'bpw-header-icon bpw-header-icon-close', onClick: this.props.hideChat, onKeyDown: this.handleKeyDown.bind(this, this.props.hideChat), onBlur: this.onBlur },
110
+ }), ref: (el) => (this.btnEls[5] = el), className: 'bpw-header-icon bpw-header-icon-close', onClick: this.props.hideChat, onBlur: this.onBlur },
147
111
  react_1.default.createElement(Close_1.default, null)));
148
112
  }
149
113
  renderCustomButtons() {
@@ -178,12 +142,6 @@ class Header extends react_1.default.Component {
178
142
  action: this.props.deleteConversation
179
143
  });
180
144
  }
181
- if (this.props.isEmulator) {
182
- return (react_1.default.createElement("div", { className: "bpw-emulator-header" },
183
- react_1.default.createElement("span", { className: "bpw-emulator-header-tab" }, "Emulator"),
184
- react_1.default.createElement("div", null,
185
- react_1.default.createElement("span", { className: "bpw-emulator-buttons" }, this.props.showResetButton && this.renderResetButton()))));
186
- }
187
145
  return (react_1.default.createElement("div", { className: 'bpw-header-container' },
188
146
  react_1.default.createElement("div", { className: 'bpw-header-title-flexbox' },
189
147
  react_1.default.createElement("div", { className: 'bpw-header-title-container' },
@@ -191,7 +149,6 @@ class Header extends react_1.default.Component {
191
149
  this.renderTitle())),
192
150
  !!this.props.customButtons.length && this.renderCustomButtons(),
193
151
  this.props.showDeleteConversationButton && this.renderDeleteConversationButton(),
194
- this.props.showResetButton && this.renderResetButton(),
195
152
  this.props.showDownloadButton && this.renderDownloadButton(),
196
153
  this.props.showConversationsButton && this.renderConvoButton(),
197
154
  this.props.showBotInfoButton && this.renderBotInfoButton(),
@@ -205,7 +162,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
205
162
  showDownloadButton: store.view.showDownloadButton,
206
163
  showBotInfoButton: store.view.showBotInfoButton,
207
164
  showConversationsButton: store.view.showConversationsButton,
208
- showResetButton: store.view.showResetButton,
209
165
  showCloseButton: store.view.showCloseButton,
210
166
  hasUnreadMessages: store.view.hasUnreadMessages,
211
167
  unreadCount: store.view.unreadCount,
@@ -217,12 +173,9 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
217
173
  toggleBotInfo: store.view.toggleBotInfo,
218
174
  customButtons: store.view.customButtons,
219
175
  deleteConversation: store.deleteConversation,
220
- resetSession: store.resetSession,
221
176
  downloadConversation: store.downloadConversation,
222
177
  botName: store.botName,
223
178
  botAvatarUrl: store.botAvatarUrl,
224
179
  hasBotInfoDescription: store.hasBotInfoDescription,
225
- isEmulator: store.isEmulator,
226
- botConvoDescription: store.config.botConvoDescription,
227
- enableArrowNavigation: store.config.enableArrowNavigation
180
+ botConversationDescription: store.config.botConversationDescription
228
181
  }))((0, mobx_react_1.observer)(Header));
@@ -34,6 +34,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
34
34
  const classnames_1 = __importDefault(require("classnames"));
35
35
  const lite_1 = __importDefault(require("mime/lite"));
36
36
  const react_1 = __importStar(require("react"));
37
+ const Cancel_1 = __importDefault(require("../icons/Cancel"));
38
+ const Microphone_1 = __importDefault(require("../icons/Microphone"));
37
39
  const VoiceRecorder = (props) => {
38
40
  var _a;
39
41
  const [isRecording, setIsRecording] = (0, react_1.useState)(false);
@@ -127,7 +129,9 @@ const VoiceRecorder = (props) => {
127
129
  return null;
128
130
  }
129
131
  return (react_1.default.createElement(react_1.Fragment, null,
130
- isRecording && (react_1.default.createElement("button", { className: (0, classnames_1.default)('bpw-send-button', props.className), onClick: cancelRecording })),
131
- react_1.default.createElement("button", { className: (0, classnames_1.default)('bpw-send-button', props.className), onClick: isRecording ? stopRecording : startRecording })));
132
+ isRecording && (react_1.default.createElement("button", { className: (0, classnames_1.default)('bpw-send-button', props.className), onClick: cancelRecording },
133
+ react_1.default.createElement(Cancel_1.default, { fill: "#ff0000" }))),
134
+ react_1.default.createElement("button", { className: (0, classnames_1.default)('bpw-send-button', props.className), onClick: isRecording ? stopRecording : startRecording },
135
+ react_1.default.createElement(Microphone_1.default, { fill: isRecording ? '#f1f1f1' : 'black' }))));
132
136
  };
133
137
  exports.default = VoiceRecorder;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const Avatar = ({ name, avatarUrl, height, width }) => {
8
+ return (react_1.default.createElement("div", { className: 'bpw-bot-avatar' },
9
+ avatarUrl && react_1.default.createElement("img", { height: height, width: width, src: avatarUrl }),
10
+ !avatarUrl && (react_1.default.createElement("svg", { width: width, height: width },
11
+ react_1.default.createElement("text", { textAnchor: 'middle', x: '50%', y: '50%', dy: '0.35em', fill: '#ffffff', fontSize: 15 }, name && name[0])))));
12
+ };
13
+ exports.default = Avatar;
@@ -1,10 +1,10 @@
1
- import * as React from 'react';
1
+ import React from 'react';
2
2
  import { WrappedComponentProps } from 'react-intl';
3
- import { StoreDef } from '../../store';
3
+ import { StoreDef } from '../../../store';
4
4
  declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omit<BotInfoProps, "intl"> & {
5
5
  forwardedRef?: React.Ref<any> | undefined;
6
6
  } & React.RefAttributes<any>> & {
7
7
  WrappedComponent: React.ComponentType<BotInfoProps>;
8
8
  } & import("mobx-react").IWrappedComponent<unknown>;
9
9
  export default _default;
10
- declare type BotInfoProps = WrappedComponentProps & Pick<StoreDef, 'botInfo' | 'botName' | 'avatarUrl' | 'toggleBotInfo' | 'startConversation' | 'isConversationStarted' | 'enableArrowNavigation' | 'updatePreferredLanguage' | 'preferredLanguage' | 'escapeHTML' | 'rtl'>;
10
+ declare type BotInfoProps = WrappedComponentProps & Pick<StoreDef, 'botInfo' | 'botName' | 'avatarUrl' | 'toggleBotInfo' | 'startConversation' | 'isConversationStarted' | 'updatePreferredLanguage' | 'preferredLanguage' | 'escapeHTML' | 'rtl'>;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ const classnames_1 = __importDefault(require("classnames"));
26
+ const mobx_react_1 = require("mobx-react");
27
+ const react_1 = __importStar(require("react"));
28
+ const react_intl_1 = require("react-intl");
29
+ const Email_1 = __importDefault(require("../../../icons/Email"));
30
+ const Phone_1 = __importDefault(require("../../../icons/Phone"));
31
+ const Website_1 = __importDefault(require("../../../icons/Website"));
32
+ const utils_1 = require("../../../utils");
33
+ const Avatar_1 = __importDefault(require("../Avatar"));
34
+ const CoverPicture = ({ botInfo }) => (react_1.default.createElement("div", { className: 'bpw-botinfo-cover-picture-wrapper' },
35
+ react_1.default.createElement("img", { className: 'bpw-botinfo-cover-picture', src: (botInfo === null || botInfo === void 0 ? void 0 : botInfo.details.coverPictureUrl) || `https://via.placeholder.com/400x175?text=${(botInfo === null || botInfo === void 0 ? void 0 : botInfo.name) || ''}` })));
36
+ class BotInfoPage extends react_1.default.Component {
37
+ constructor() {
38
+ super(...arguments);
39
+ this.changeLanguage = (e) => {
40
+ const lang = e.target.value;
41
+ this.props.updatePreferredLanguage(lang);
42
+ };
43
+ }
44
+ componentDidMount() {
45
+ var _a;
46
+ (_a = this.btnEl) === null || _a === void 0 ? void 0 : _a.focus();
47
+ }
48
+ renderDescription(text) {
49
+ const html = (0, utils_1.renderUnsafeHTML)(text, this.props.escapeHTML);
50
+ return react_1.default.createElement("div", { className: 'bpw-botinfo-description', dangerouslySetInnerHTML: { __html: html } });
51
+ }
52
+ render() {
53
+ const { botInfo, botName, avatarUrl } = this.props;
54
+ const onDismiss = this.props.isConversationStarted ? this.props.toggleBotInfo : this.props.startConversation;
55
+ return (react_1.default.createElement(react_1.Fragment, null,
56
+ react_1.default.createElement("link", { rel: "stylesheet", href: "style.scss" }),
57
+ react_1.default.createElement("div", { className: (0, classnames_1.default)('bpw-botinfo-container', {
58
+ 'bpw-rtl': this.props.rtl
59
+ }) },
60
+ react_1.default.createElement(CoverPicture, { botInfo: botInfo }),
61
+ react_1.default.createElement("div", { className: 'bpw-botinfo-summary' },
62
+ react_1.default.createElement(Avatar_1.default, { name: botName, avatarUrl: avatarUrl, height: 64, width: 64 }),
63
+ react_1.default.createElement("h3", null, botName),
64
+ this.renderDescription(botInfo.description)),
65
+ botInfo.details && (react_1.default.createElement(react_1.default.Fragment, null,
66
+ react_1.default.createElement("div", { className: 'bpw-botinfo-links' },
67
+ botInfo.details.phoneNumber && (react_1.default.createElement("div", { className: 'bpw-botinfo-link' },
68
+ react_1.default.createElement("i", null,
69
+ react_1.default.createElement(Phone_1.default, null)),
70
+ react_1.default.createElement("a", { target: '_blank', href: `tel:${botInfo.details.phoneNumber}` }, botInfo.details.phoneNumber))),
71
+ botInfo.details.website && (react_1.default.createElement("div", { className: 'bpw-botinfo-link' },
72
+ react_1.default.createElement("i", null,
73
+ react_1.default.createElement(Website_1.default, null)),
74
+ react_1.default.createElement("a", { target: '_blank', href: botInfo.details.website }, botInfo.details.website))),
75
+ botInfo.details.emailAddress && (react_1.default.createElement("div", { className: 'bpw-botinfo-link' },
76
+ react_1.default.createElement("i", null,
77
+ react_1.default.createElement(Email_1.default, null)),
78
+ react_1.default.createElement("a", { target: '_blank', href: `mailto:${botInfo.details.emailAddress}` }, botInfo.details.emailAddress)))),
79
+ botInfo.details.termsConditions && (react_1.default.createElement("div", { className: 'bpw-botinfo-terms' },
80
+ react_1.default.createElement("a", { target: '_blank', href: botInfo.details.termsConditions },
81
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.termsAndConditions' })))),
82
+ botInfo.details.privacyPolicy && (react_1.default.createElement("div", { className: 'bpw-botinfo-terms' },
83
+ react_1.default.createElement("a", { target: '_blank', href: botInfo.details.privacyPolicy },
84
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.privacyPolicy' })))))),
85
+ botInfo.languages.length > 1 && (react_1.default.createElement("div", { className: 'bpw-botinfo-preferred-language' },
86
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.preferredLanguage' }),
87
+ react_1.default.createElement("select", { value: this.props.preferredLanguage, onChange: this.changeLanguage }, botInfo.languages.map((lang) => (react_1.default.createElement("option", { key: lang, value: lang }, lang.toUpperCase())))))),
88
+ react_1.default.createElement("button", { tabIndex: 1, ref: (el) => (this.btnEl = el), className: 'bpw-botinfo-start-button', onClick: onDismiss.bind(this, undefined) }, this.props.isConversationStarted ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.backToConversation' })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.startConversation' }))))));
89
+ }
90
+ }
91
+ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
92
+ botName: store.botName,
93
+ botInfo: store.botInfo,
94
+ avatarUrl: store.botAvatarUrl,
95
+ startConversation: store.startConversation,
96
+ toggleBotInfo: store.view.toggleBotInfo,
97
+ isConversationStarted: store.isConversationStarted,
98
+ updatePreferredLanguage: store.updatePreferredLanguage,
99
+ preferredLanguage: store.preferredLanguage,
100
+ escapeHTML: store.escapeHTML,
101
+ rtl: store.rtl
102
+ }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(BotInfoPage)));
@@ -0,0 +1,11 @@
1
+ /// <reference types="react" />
2
+ export interface ConfirmDialogOptions {
3
+ title?: string;
4
+ accept?: () => void;
5
+ decline?: () => void;
6
+ acceptLabel: string;
7
+ declineLabel: string;
8
+ body?: JSX.Element;
9
+ }
10
+ declare const confirmDialog: (message: string, options: ConfirmDialogOptions) => Promise<boolean>;
11
+ export default confirmDialog;