@botpress/webchat 0.2.5 → 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 (54) hide show
  1. package/README.md +31 -0
  2. package/dist/components/Composer.d.ts +4 -5
  3. package/dist/components/Composer.js +1 -21
  4. package/dist/components/Container.js +1 -4
  5. package/dist/components/ConversationList.d.ts +1 -1
  6. package/dist/components/ConversationList.js +5 -46
  7. package/dist/components/Header.d.ts +1 -3
  8. package/dist/components/Header.js +7 -37
  9. package/dist/components/common/BotInfo/index.d.ts +1 -1
  10. package/dist/components/common/BotInfo/index.js +4 -14
  11. package/dist/components/messages/InlineFeedback.d.ts +2 -1
  12. package/dist/components/messages/Message.js +1 -5
  13. package/dist/components/messages/MessageGroup.d.ts +1 -5
  14. package/dist/components/messages/MessageGroup.js +4 -7
  15. package/dist/components/messages/MessageList.d.ts +1 -1
  16. package/dist/components/messages/MessageList.js +7 -29
  17. package/dist/core/api.d.ts +2 -6
  18. package/dist/core/api.js +4 -32
  19. package/dist/core/constants.d.ts +4 -32
  20. package/dist/core/constants.js +18 -32
  21. package/dist/core/socket.d.ts +1 -7
  22. package/dist/core/socket.js +7 -30
  23. package/dist/index.d.ts +2 -8
  24. package/dist/index.js +6 -27
  25. package/dist/main.d.ts +2 -2
  26. package/dist/main.js +84 -135
  27. package/dist/store/index.d.ts +4 -8
  28. package/dist/store/index.js +25 -62
  29. package/dist/store/view.d.ts +3 -4
  30. package/dist/store/view.js +6 -13
  31. package/dist/translations/index.d.ts +2 -1
  32. package/dist/translations/index.js +36 -1
  33. package/dist/typings.d.ts +117 -55
  34. package/dist/utils/analytics.d.ts +5 -0
  35. package/dist/utils/analytics.js +37 -0
  36. package/dist/utils/index.d.ts +3 -0
  37. package/dist/utils/index.js +27 -0
  38. package/package.json +2 -3
  39. package/dist/components/ContextMenu.d.ts +0 -2
  40. package/dist/components/ContextMenu.js +0 -24
  41. package/dist/components/OverridableComponent.d.ts +0 -24
  42. package/dist/components/OverridableComponent.js +0 -50
  43. package/dist/components/Stylesheet.d.ts +0 -5
  44. package/dist/components/Stylesheet.js +0 -7
  45. package/dist/components/common/MoreOptions/index.d.ts +0 -21
  46. package/dist/components/common/MoreOptions/index.js +0 -60
  47. package/dist/components/common/Overlay/index.d.ts +0 -7
  48. package/dist/components/common/Overlay/index.js +0 -36
  49. package/dist/icons/CloseChat.d.ts +0 -6
  50. package/dist/icons/CloseChat.js +0 -9
  51. package/dist/icons/Send.d.ts +0 -6
  52. package/dist/icons/Send.js +0 -8
  53. package/dist/utils.d.ts +0 -8
  54. 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' | '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'>;
@@ -22,30 +22,13 @@ class Composer extends react_1.default.Component {
22
22
  constructor(props) {
23
23
  super(props);
24
24
  this.handleKeyPress = (e) => __awaiter(this, void 0, void 0, function* () {
25
- if (this.props.enableResetSessionShortcut && e.ctrlKey && e.key === 'Enter') {
26
- e.preventDefault();
27
- yield this.props.resetSession();
28
- yield this.props.sendMessage();
29
- return;
30
- }
31
25
  if (e.key === 'Enter') {
32
26
  e.preventDefault();
33
27
  yield this.props.sendMessage();
34
28
  }
35
29
  });
36
30
  this.handleKeyDown = (e) => {
37
- if (this.props.enableArrowNavigation) {
38
- const shouldFocusPrevious = e.target.selectionStart === 0 && (e.key === 'ArrowUp' || e.key === 'ArrowLeft');
39
- if (shouldFocusPrevious) {
40
- this.props.focusPrevious();
41
- }
42
- const shouldFocusNext = e.target.selectionStart === this.textInput.current.value.length &&
43
- (e.key === 'ArrowDown' || e.key === 'ArrowRight');
44
- if (shouldFocusNext) {
45
- this.props.focusNext();
46
- }
47
- }
48
- else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
31
+ if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
49
32
  this.props.recallHistory(e.key);
50
33
  }
51
34
  };
@@ -119,9 +102,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
119
102
  focusedArea: store.view.focusedArea,
120
103
  focusPrevious: store.view.focusPrevious,
121
104
  focusNext: store.view.focusNext,
122
- enableArrowNavigation: store.config.enableArrowNavigation,
123
- enableResetSessionShortcut: store.config.enableResetSessionShortcut,
124
- resetSession: store.resetSession,
125
105
  currentConversation: store.currentConversation,
126
106
  preferredLanguage: store.preferredLanguage
127
107
  }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(Composer)));
@@ -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) {
@@ -33,7 +32,7 @@ class Container extends react_1.default.Component {
33
32
  }) },
34
33
  react_1.default.createElement(MessageList_1.default, null),
35
34
  react_1.default.createElement(messaging_components_1.Keyboard, null,
36
- react_1.default.createElement(OverridableComponent_1.default, { name: 'composer', original: Composer_1.default }))));
35
+ react_1.default.createElement(Composer_1.default, null))));
37
36
  }
38
37
  }
39
38
  render() {
@@ -42,11 +41,9 @@ class Container extends react_1.default.Component {
42
41
  [`bpw-anim-${this.props.sideTransition}`]: true
43
42
  });
44
43
  return (react_1.default.createElement(react_1.default.Fragment, null,
45
- react_1.default.createElement(OverridableComponent_1.default, { name: 'before_container', original: null }),
46
44
  react_1.default.createElement("div", { className: classNames, style: { width: this.props.dimensions.layout } },
47
45
  react_1.default.createElement(Header_1.default, null),
48
46
  this.renderBody(),
49
- react_1.default.createElement(OverridableComponent_1.default, { name: 'below_conversation', original: null }),
50
47
  this.props.isPoweredByDisplayed && react_1.default.createElement(Footer_1.default, null))));
51
48
  }
52
49
  }
@@ -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' | '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'>;
@@ -20,7 +20,6 @@ const Delete_1 = __importDefault(require("../icons/Delete"));
20
20
  const Download_1 = __importDefault(require("../icons/Download"));
21
21
  const Information_1 = __importDefault(require("../icons/Information"));
22
22
  const List_1 = __importDefault(require("../icons/List"));
23
- const Reload_1 = __importDefault(require("../icons/Reload"));
24
23
  const Avatar_1 = __importDefault(require("./common/Avatar"));
25
24
  const ConfirmDialog_1 = __importDefault(require("./common/ConfirmDialog"));
26
25
  class Header extends react_1.default.Component {
@@ -63,7 +62,7 @@ class Header extends react_1.default.Component {
63
62
  react_1.default.createElement("div", { className: 'bpw-header-name' },
64
63
  title,
65
64
  this.props.hasUnreadMessages && react_1.default.createElement("span", { className: 'bpw-header-unread' }, this.props.unreadCount)),
66
- 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))));
67
66
  };
68
67
  this.handleDeleteConversation = () => __awaiter(this, void 0, void 0, function* () {
69
68
  if (yield (0, ConfirmDialog_1.default)(this.props.intl.formatMessage({
@@ -79,27 +78,6 @@ class Header extends react_1.default.Component {
79
78
  yield this.props.deleteConversation();
80
79
  }
81
80
  });
82
- this.handleKeyDown = (action, e) => {
83
- if (!this.props.enableArrowNavigation) {
84
- return;
85
- }
86
- if (e.key === 'ArrowUp') {
87
- this.props.focusPrevious();
88
- }
89
- else if (e.key === 'ArrowDown') {
90
- this.props.focusNext();
91
- }
92
- else if (e.key === 'ArrowLeft') {
93
- this.changeButtonFocus(-1);
94
- }
95
- else if (e.key === 'ArrowRight') {
96
- this.changeButtonFocus(1);
97
- }
98
- else if (e.key === 'Enter') {
99
- e.preventDefault();
100
- action();
101
- }
102
- };
103
81
  this.setShowingOption = (val) => {
104
82
  this.setState({ showingOption: val });
105
83
  };
@@ -110,30 +88,26 @@ class Header extends react_1.default.Component {
110
88
  });
111
89
  }
112
90
  renderDeleteConversationButton() {
113
- 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 },
114
92
  react_1.default.createElement(Delete_1.default, null)));
115
93
  }
116
- renderResetButton() {
117
- 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 },
118
- react_1.default.createElement(Reload_1.default, null)));
119
- }
120
94
  renderDownloadButton() {
121
- 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 },
122
96
  react_1.default.createElement(Download_1.default, null)));
123
97
  }
124
98
  renderConvoButton() {
125
- 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 },
126
100
  react_1.default.createElement(List_1.default, null)));
127
101
  }
128
102
  renderBotInfoButton() {
129
- 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 },
130
104
  react_1.default.createElement(Information_1.default, null)));
131
105
  }
132
106
  renderCloseButton() {
133
107
  return (react_1.default.createElement("button", { type: "button", id: "btn-close", "aria-label": this.props.intl.formatMessage({
134
108
  id: 'header.hideChatWindow',
135
109
  defaultMessage: 'Hide the chat window'
136
- }), 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 },
137
111
  react_1.default.createElement(Close_1.default, null)));
138
112
  }
139
113
  renderCustomButtons() {
@@ -175,7 +149,6 @@ class Header extends react_1.default.Component {
175
149
  this.renderTitle())),
176
150
  !!this.props.customButtons.length && this.renderCustomButtons(),
177
151
  this.props.showDeleteConversationButton && this.renderDeleteConversationButton(),
178
- this.props.showResetButton && this.renderResetButton(),
179
152
  this.props.showDownloadButton && this.renderDownloadButton(),
180
153
  this.props.showConversationsButton && this.renderConvoButton(),
181
154
  this.props.showBotInfoButton && this.renderBotInfoButton(),
@@ -189,7 +162,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
189
162
  showDownloadButton: store.view.showDownloadButton,
190
163
  showBotInfoButton: store.view.showBotInfoButton,
191
164
  showConversationsButton: store.view.showConversationsButton,
192
- showResetButton: store.view.showResetButton,
193
165
  showCloseButton: store.view.showCloseButton,
194
166
  hasUnreadMessages: store.view.hasUnreadMessages,
195
167
  unreadCount: store.view.unreadCount,
@@ -201,11 +173,9 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
201
173
  toggleBotInfo: store.view.toggleBotInfo,
202
174
  customButtons: store.view.customButtons,
203
175
  deleteConversation: store.deleteConversation,
204
- resetSession: store.resetSession,
205
176
  downloadConversation: store.downloadConversation,
206
177
  botName: store.botName,
207
178
  botAvatarUrl: store.botAvatarUrl,
208
179
  hasBotInfoDescription: store.hasBotInfoDescription,
209
- botConvoDescription: store.config.botConvoDescription,
210
- enableArrowNavigation: store.config.enableArrowNavigation
180
+ botConversationDescription: store.config.botConversationDescription
211
181
  }))((0, mobx_react_1.observer)(Header));
@@ -7,4 +7,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
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'>;
@@ -18,15 +18,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
21
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
- return new (P || (P = Promise))(function (resolve, reject) {
24
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
- step((generator = generator.apply(thisArg, _arguments || [])).next());
28
- });
29
- };
30
21
  var __importDefault = (this && this.__importDefault) || function (mod) {
31
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
32
23
  };
@@ -41,15 +32,14 @@ const Website_1 = __importDefault(require("../../../icons/Website"));
41
32
  const utils_1 = require("../../../utils");
42
33
  const Avatar_1 = __importDefault(require("../Avatar"));
43
34
  const CoverPicture = ({ botInfo }) => (react_1.default.createElement("div", { className: 'bpw-botinfo-cover-picture-wrapper' },
44
- react_1.default.createElement("img", { className: 'bpw-botinfo-cover-picture', src: (botInfo.details && botInfo.details.coverPictureUrl) ||
45
- `https://via.placeholder.com/400x175?text=${botInfo.name}` })));
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) || ''}` })));
46
36
  class BotInfoPage extends react_1.default.Component {
47
37
  constructor() {
48
38
  super(...arguments);
49
- this.changeLanguage = (e) => __awaiter(this, void 0, void 0, function* () {
39
+ this.changeLanguage = (e) => {
50
40
  const lang = e.target.value;
51
- yield this.props.updatePreferredLanguage(lang);
52
- });
41
+ this.props.updatePreferredLanguage(lang);
42
+ };
53
43
  }
54
44
  componentDidMount() {
55
45
  var _a;
@@ -1,10 +1,11 @@
1
1
  import { FC } from 'react';
2
+ import { IntlShape } from 'react-intl';
2
3
  import { EventFeedback as MessageFeedback } from '../../typings';
3
4
  interface Props {
4
5
  onFeedback: (feedback: number, eventId: string) => void;
5
6
  messageId: string;
6
7
  messageFeedbacks: MessageFeedback[];
7
- intl: any;
8
+ intl: IntlShape;
8
9
  }
9
10
  export declare const InlineFeedback: FC<Props>;
10
11
  export {};
@@ -27,7 +27,6 @@ const classnames_1 = __importDefault(require("classnames"));
27
27
  const mobx_react_1 = require("mobx-react");
28
28
  const react_1 = __importStar(require("react"));
29
29
  const react_intl_1 = require("react-intl");
30
- const ContextMenu_1 = require("../ContextMenu");
31
30
  class Message extends react_1.Component {
32
31
  constructor() {
33
32
  super(...arguments);
@@ -35,9 +34,6 @@ class Message extends react_1.Component {
35
34
  hasError: false,
36
35
  showMore: false
37
36
  };
38
- this.handleContextMenu = (e) => {
39
- (0, ContextMenu_1.showContextMenu)(e, this.props);
40
- };
41
37
  }
42
38
  static getDerivedStateFromError(_error) {
43
39
  return { hasError: true };
@@ -77,7 +73,7 @@ class Message extends react_1.Component {
77
73
  return (react_1.default.createElement("div", { className: (0, classnames_1.default)(this.props.className, wrappedClass), style: additionalStyle }, rendered));
78
74
  }
79
75
  return (react_1.default.createElement("div", { className: (0, classnames_1.default)(this.props.className, wrappedClass, 'bpw-chat-bubble', `bpw-bubble-${type}`), "data-from": this.props.fromLabel, tabIndex: -1, style: additionalStyle },
80
- react_1.default.createElement("div", { tabIndex: -1, className: "bpw-chat-bubble-content", onContextMenu: type !== 'session_reset' ? this.handleContextMenu : () => { } },
76
+ react_1.default.createElement("div", { tabIndex: -1, className: "bpw-chat-bubble-content" },
81
77
  react_1.default.createElement("span", { className: "sr-only" }, this.props.store.intl.formatMessage({
82
78
  id: this.props.isBotMessage ? 'message.botSaid' : 'message.iSaid',
83
79
  defaultMessage: this.props.isBotMessage ? 'Virtual assistant said : ' : 'I said : '
@@ -17,11 +17,7 @@ export default _default;
17
17
  declare type Props = {
18
18
  isBot: boolean;
19
19
  avatar: JSX.Element;
20
- userName: string;
21
20
  messages: MessageDetails[];
22
21
  isLastGroup: boolean;
23
- onFileUpload?: any;
24
- onSendData?: any;
25
- onFeedback?: any;
26
22
  store?: RootStore;
27
- } & Pick<StoreDef, 'showUserName'>;
23
+ } & Pick<StoreDef, 'sendFeedback' | 'sendData'>;
@@ -29,7 +29,7 @@ class MessageGroup extends react_1.default.Component {
29
29
  return { hasError: true };
30
30
  }
31
31
  render() {
32
- const { messages, avatar, isBot, showUserName, userName } = this.props;
32
+ const { messages, avatar, isBot } = this.props;
33
33
  const fromLabel = this.props.store.intl.formatMessage({
34
34
  id: this.props.isBot ? 'message.fromBotLabel' : 'message.fromMeLabel',
35
35
  defaultMessage: 'Me'
@@ -43,21 +43,18 @@ class MessageGroup extends react_1.default.Component {
43
43
  }) },
44
44
  avatar,
45
45
  react_1.default.createElement("div", { role: "region", className: 'bpw-message-container' },
46
- showUserName && react_1.default.createElement("div", { className: 'bpw-message-username' }, userName),
47
46
  react_1.default.createElement("div", { "aria-live": "assertive", role: "log", className: 'bpw-message-group' },
48
47
  react_1.default.createElement("span", { "data-from": fromLabel, className: "from hidden", "aria-hidden": "true" }, fromLabel),
49
48
  (0, sortBy_1.default)(messages, ['sent_on', 'eventId']).map((message, i, messages) => {
50
49
  const isLastMsg = i === messages.length - 1;
51
50
  const payload = message.payload;
52
51
  const showInlineFeedback = isBot && isLastMsg && payload.collectFeedback;
53
- return (react_1.default.createElement(Message_1.default, { key: `${message.id}-${message.payload.type}`, inlineFeedback: showInlineFeedback && (react_1.default.createElement(InlineFeedback_1.InlineFeedback, { intl: this.props.store.intl, messageId: message.id, onFeedback: this.props.onFeedback, messageFeedbacks: this.props.store.messageFeedbacks })), messageId: message.id, noBubble: !!payload.noBubble, fromLabel: fromLabel, isLastOfGroup: i >= this.props.messages.length - 1, isLastGroup: this.props.isLastGroup, isBotMessage: !message.authorId, payload: payload, sentOn: message.sentOn, onSendData: this.props.onSendData, onFileUpload: this.props.onFileUpload, store: this.props.store, onAudioEnded: this.onAudioEnded, shouldPlay: this.state.audioPlayingIndex === i }));
52
+ return (react_1.default.createElement(Message_1.default, { key: `${message.id}-${message.payload.type}`, inlineFeedback: showInlineFeedback && (react_1.default.createElement(InlineFeedback_1.InlineFeedback, { intl: this.props.store.intl, messageId: message.id, onFeedback: this.props.sendFeedback, messageFeedbacks: this.props.store.messageFeedbacks })), messageId: message.id, noBubble: !!payload.noBubble, fromLabel: fromLabel, isLastOfGroup: i >= this.props.messages.length - 1, isLastGroup: this.props.isLastGroup, isBotMessage: !message.authorId, payload: payload, sentOn: message.sentOn, onSendData: this.props.sendData, store: this.props.store, onAudioEnded: this.onAudioEnded, shouldPlay: this.state.audioPlayingIndex === i }));
54
53
  })))));
55
54
  }
56
55
  }
57
56
  exports.default = (0, mobx_react_1.inject)(({ store }) => ({
58
57
  store,
59
- onFeedback: store.sendFeedback,
60
- onSendData: store.sendData,
61
- onFileUpload: store.uploadFile,
62
- showUserName: store.config.showUserName
58
+ sendFeedback: store.sendFeedback,
59
+ sendData: store.sendData
63
60
  }))(MessageGroup);
@@ -7,4 +7,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
7
7
  WrappedComponent: React.ComponentType<MessageListProps>;
8
8
  } & import("mobx-react").IWrappedComponent<unknown>;
9
9
  export default _default;
10
- declare type MessageListProps = WrappedComponentProps & Pick<StoreDef, 'intl' | 'isBotTyping' | 'focusedArea' | 'focusPrevious' | 'focusNext' | 'botAvatarUrl' | 'botName' | 'enableArrowNavigation' | 'showUserAvatar' | 'currentMessages' | 'preferredLanguage'>;
10
+ declare type MessageListProps = WrappedComponentProps & Pick<StoreDef, 'intl' | 'isBotTyping' | 'focusedArea' | 'focusPrevious' | 'focusNext' | 'botAvatarUrl' | 'botName' | 'currentMessages' | 'preferredLanguage'>;
@@ -17,22 +17,6 @@ class MessageList extends react_1.default.Component {
17
17
  constructor() {
18
18
  super(...arguments);
19
19
  this.state = { showNewMessageIndicator: false, manualScroll: false };
20
- this.handleKeyDown = (e) => {
21
- if (!this.props.enableArrowNavigation) {
22
- return;
23
- }
24
- const maxScroll = this.messagesDiv.scrollHeight - this.messagesDiv.clientHeight;
25
- const shouldFocusNext = e.key === 'ArrowRight' || (e.key === 'ArrowDown' && this.messagesDiv.scrollTop === maxScroll);
26
- const shouldFocusPrevious = e.key === 'ArrowLeft' || (e.key === 'ArrowUp' && this.messagesDiv.scrollTop === 0);
27
- if (shouldFocusNext) {
28
- this.messagesDiv.blur();
29
- this.props.focusNext();
30
- }
31
- if (shouldFocusPrevious) {
32
- this.messagesDiv.blur();
33
- this.props.focusPrevious();
34
- }
35
- };
36
20
  this.shouldDisplayMessage = (m) => {
37
21
  return m.payload.type !== 'postback';
38
22
  };
@@ -60,7 +44,7 @@ class MessageList extends react_1.default.Component {
60
44
  });
61
45
  }
62
46
  // this should account for keyboard rendering as it triggers a resize of the messagesDiv
63
- this.divSizeObserver = new resize_observer_1.ResizeObserver((0, debounce_1.default)(([divResizeEntry]) => {
47
+ this.divSizeObserver = new resize_observer_1.ResizeObserver((0, debounce_1.default)((_divResizeEntry) => {
64
48
  // we don't need to do anything with the resize entry
65
49
  this.tryScrollToBottom();
66
50
  }, 200, { trailing: true }));
@@ -106,8 +90,7 @@ class MessageList extends react_1.default.Component {
106
90
  let lastDate = undefined;
107
91
  let currentGroup = undefined;
108
92
  messages.forEach((m) => {
109
- var _a, _b;
110
- const speaker = ((_b = (_a = m.payload.channel) === null || _a === void 0 ? void 0 : _a.web) === null || _b === void 0 ? void 0 : _b.userName) || m.authorId;
93
+ const speaker = m.authorId;
111
94
  const date = m.sentOn;
112
95
  // Create a new group if messages are separated by more than X minutes or if different speaker
113
96
  if (speaker !== lastSpeaker ||
@@ -134,24 +117,21 @@ class MessageList extends react_1.default.Component {
134
117
  });
135
118
  }
136
119
  return (react_1.default.createElement("div", null, groups.map((group, i) => {
137
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
120
+ var _a;
138
121
  const lastGroup = groups[i - 1];
139
122
  const lastDate = (_a = lastGroup === null || lastGroup === void 0 ? void 0 : lastGroup[lastGroup.length - 1]) === null || _a === void 0 ? void 0 : _a.sentOn;
140
123
  const groupDate = group === null || group === void 0 ? void 0 : group[0].sentOn;
141
124
  const isDateNeeded = !groups[i - 1] ||
142
125
  (0, difference_in_minutes_1.default)(new Date(groupDate), new Date(lastDate)) > constants_1.default.TIME_BETWEEN_DATES;
143
- const [{ authorId, payload }] = group;
144
- const avatar = authorId
145
- ? this.props.showUserAvatar &&
146
- this.renderAvatar((_c = (_b = payload.channel) === null || _b === void 0 ? void 0 : _b.web) === null || _c === void 0 ? void 0 : _c.userName, (_e = (_d = payload.channel) === null || _d === void 0 ? void 0 : _d.web) === null || _e === void 0 ? void 0 : _e.avatarUrl)
147
- : this.renderAvatar(this.props.botName, ((_g = (_f = payload.channel) === null || _f === void 0 ? void 0 : _f.web) === null || _g === void 0 ? void 0 : _g.avatarUrl) || this.props.botAvatarUrl);
126
+ const [{ authorId }] = group;
127
+ const avatar = !authorId && this.renderAvatar(this.props.botName, this.props.botAvatarUrl);
148
128
  return (react_1.default.createElement("div", { key: i },
149
129
  isDateNeeded && this.renderDate(group[0].sentOn),
150
- react_1.default.createElement(MessageGroup_1.default, { isBot: !authorId, avatar: avatar, userName: (_j = (_h = payload.channel) === null || _h === void 0 ? void 0 : _h.web) === null || _j === void 0 ? void 0 : _j.userName, key: `msg-group-${i}`, isLastGroup: i >= groups.length - 1, messages: group })));
130
+ react_1.default.createElement(MessageGroup_1.default, { isBot: !authorId, avatar: avatar, key: `msg-group-${i}`, isLastGroup: i >= groups.length - 1, messages: group })));
151
131
  })));
152
132
  }
153
133
  render() {
154
- return (react_1.default.createElement("div", { tabIndex: 0, onKeyDown: this.handleKeyDown, className: 'bpw-msg-list', ref: (m) => {
134
+ return (react_1.default.createElement("div", { tabIndex: 0, className: 'bpw-msg-list', ref: (m) => {
155
135
  this.messagesDiv = m;
156
136
  }, onScroll: this.handleScroll },
157
137
  this.state.showNewMessageIndicator && (react_1.default.createElement("div", { className: "bpw-new-messages-indicator", onClick: (e) => this.tryScrollToBottom() },
@@ -170,7 +150,5 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
170
150
  focusPrevious: store.view.focusPrevious,
171
151
  focusNext: store.view.focusNext,
172
152
  focusedArea: store.view.focusedArea,
173
- showUserAvatar: store.config.showUserAvatar,
174
- enableArrowNavigation: store.config.enableArrowNavigation,
175
153
  preferredLanguage: store.preferredLanguage
176
154
  }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(MessageList)));
@@ -1,13 +1,11 @@
1
1
  /// <reference types="node" />
2
2
  import { Message } from '@botpress/messaging-socket';
3
- import { RecentConversation } from '..';
4
- import { BotInfo, uuid } from '../typings';
3
+ import { uuid, RecentConversation } from '../typings';
5
4
  import BpSocket from './socket';
6
5
  export default class WebchatApi {
7
6
  private socket;
8
7
  constructor(socket: BpSocket);
9
- fetchBotInfo(mediaFileServiceUrl: string): Promise<BotInfo | undefined>;
10
- listCurrentConversationMessages(limit?: number): Promise<Message[]>;
8
+ listCurrentConversationMessages(limit?: number): Promise<Message[] | undefined>;
11
9
  fetchConversations(): Promise<RecentConversation[]>;
12
10
  fetchConversation(conversationId: uuid): Promise<{
13
11
  messages: Message[];
@@ -16,12 +14,10 @@ export default class WebchatApi {
16
14
  userId?: string | undefined;
17
15
  createdOn?: Date | undefined;
18
16
  } | undefined>;
19
- resetSession(conversationId: uuid): Promise<void>;
20
17
  createConversation(): Promise<uuid | undefined>;
21
18
  startConversation(): Promise<void>;
22
19
  sendMessage(payload: any, conversationId: uuid): Promise<Message | undefined>;
23
20
  deleteConversation(conversationId: uuid): Promise<void>;
24
21
  sendFeedback(feedback: number, messageId: uuid): Promise<void>;
25
- uploadFile(file: File, payload: string, conversationId: uuid): Promise<void>;
26
22
  sendVoiceMessage(voice: Buffer, ext: string, conversationId: uuid): Promise<void>;
27
23
  }