@botpress/webchat 0.0.1 → 0.2.3

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 (58) hide show
  1. package/dist/components/Composer.d.ts +9 -11
  2. package/dist/components/Composer.js +3 -3
  3. package/dist/components/Container.d.ts +8 -7
  4. package/dist/components/Container.js +6 -25
  5. package/dist/components/ConversationList.d.ts +6 -3
  6. package/dist/components/ConversationList.js +6 -4
  7. package/dist/components/Header.js +3 -3
  8. package/dist/components/OverridableComponent.js +1 -1
  9. package/dist/components/VoiceRecorder.js +9 -9
  10. package/dist/components/common/BotInfo.d.ts +6 -3
  11. package/dist/components/common/BotInfo.js +4 -4
  12. package/dist/components/messages/InlineFeedback.js +2 -2
  13. package/dist/components/messages/Message.d.ts +6 -3
  14. package/dist/components/messages/Message.js +23 -98
  15. package/dist/components/messages/MessageGroup.js +4 -12
  16. package/dist/components/messages/MessageList.d.ts +6 -3
  17. package/dist/components/messages/MessageList.js +8 -8
  18. package/dist/core/api.d.ts +1 -0
  19. package/dist/core/api.js +26 -6
  20. package/dist/core/socket.d.ts +2 -0
  21. package/dist/core/socket.js +29 -6
  22. package/dist/fonts/roboto.d.ts +4 -0
  23. package/dist/fonts/roboto.js +9 -0
  24. package/dist/index.d.ts +0 -1
  25. package/dist/index.js +15 -11
  26. package/dist/main.d.ts +9 -7
  27. package/dist/main.js +46 -27
  28. package/dist/store/composer.js +2 -2
  29. package/dist/store/index.d.ts +4 -4
  30. package/dist/store/index.js +36 -40
  31. package/dist/store/view.js +2 -2
  32. package/dist/translations/index.d.ts +1 -2
  33. package/dist/translations/index.js +11 -25
  34. package/dist/typings.d.ts +3 -1
  35. package/dist/utils.js +1 -1
  36. package/package.json +34 -13
  37. package/dist/components/Keyboard.d.ts +0 -22
  38. package/dist/components/Keyboard.js +0 -86
  39. package/dist/components/messages/renderer/Button.d.ts +0 -16
  40. package/dist/components/messages/renderer/Button.js +0 -66
  41. package/dist/components/messages/renderer/Carousel.d.ts +0 -21
  42. package/dist/components/messages/renderer/Carousel.js +0 -72
  43. package/dist/components/messages/renderer/Dropdown.d.ts +0 -3
  44. package/dist/components/messages/renderer/Dropdown.js +0 -76
  45. package/dist/components/messages/renderer/FileInput.d.ts +0 -9
  46. package/dist/components/messages/renderer/FileInput.js +0 -32
  47. package/dist/components/messages/renderer/FileMessage.d.ts +0 -3
  48. package/dist/components/messages/renderer/FileMessage.js +0 -53
  49. package/dist/components/messages/renderer/LoginPrompt.d.ts +0 -6
  50. package/dist/components/messages/renderer/LoginPrompt.js +0 -98
  51. package/dist/components/messages/renderer/QuickReplies.d.ts +0 -18
  52. package/dist/components/messages/renderer/QuickReplies.js +0 -73
  53. package/dist/components/messages/renderer/Text.d.ts +0 -11
  54. package/dist/components/messages/renderer/Text.js +0 -71
  55. package/dist/components/messages/renderer/VoiceMessage.d.ts +0 -5
  56. package/dist/components/messages/renderer/VoiceMessage.js +0 -50
  57. package/dist/components/messages/renderer/index.d.ts +0 -8
  58. package/dist/components/messages/renderer/index.js +0 -19
@@ -36,7 +36,7 @@ class MessageList extends react_1.default.Component {
36
36
  this.shouldDisplayMessage = (m) => {
37
37
  return m.payload.type !== 'postback';
38
38
  };
39
- this.handleScroll = debounce_1.default((e) => {
39
+ this.handleScroll = (0, debounce_1.default)((e) => {
40
40
  const scroll = this.messagesDiv.scrollHeight - this.messagesDiv.scrollTop - this.messagesDiv.clientHeight;
41
41
  const manualScroll = scroll >= 150;
42
42
  const showNewMessageIndicator = this.state.showNewMessageIndicator && manualScroll;
@@ -45,11 +45,11 @@ class MessageList extends react_1.default.Component {
45
45
  }
46
46
  componentDidMount() {
47
47
  this.tryScrollToBottom(true);
48
- mobx_1.observe(this.props.focusedArea, (focus) => {
48
+ (0, mobx_1.observe)(this.props.focusedArea, (focus) => {
49
49
  focus.newValue === 'convo' && this.messagesDiv.focus();
50
50
  });
51
51
  if (this.props.currentMessages) {
52
- mobx_1.observe(this.props.currentMessages, (messages) => {
52
+ (0, mobx_1.observe)(this.props.currentMessages, (messages) => {
53
53
  if (this.state.manualScroll) {
54
54
  if (!this.state.showNewMessageIndicator) {
55
55
  this.setState({ showNewMessageIndicator: true });
@@ -60,7 +60,7 @@ class MessageList extends react_1.default.Component {
60
60
  });
61
61
  }
62
62
  // this should account for keyboard rendering as it triggers a resize of the messagesDiv
63
- this.divSizeObserver = new resize_observer_1.ResizeObserver(debounce_1.default(([divResizeEntry]) => {
63
+ this.divSizeObserver = new resize_observer_1.ResizeObserver((0, debounce_1.default)(([divResizeEntry]) => {
64
64
  // we don't need to do anything with the resize entry
65
65
  this.tryScrollToBottom();
66
66
  }, 200, { trailing: true }));
@@ -112,7 +112,7 @@ class MessageList extends react_1.default.Component {
112
112
  // Create a new group if messages are separated by more than X minutes or if different speaker
113
113
  if (speaker !== lastSpeaker ||
114
114
  !currentGroup ||
115
- difference_in_minutes_1.default(new Date(date), new Date(lastDate)) >= constants_1.default.TIME_BETWEEN_DATES) {
115
+ (0, difference_in_minutes_1.default)(new Date(date), new Date(lastDate)) >= constants_1.default.TIME_BETWEEN_DATES) {
116
116
  currentGroup = [];
117
117
  groups.push(currentGroup);
118
118
  }
@@ -139,7 +139,7 @@ class MessageList extends react_1.default.Component {
139
139
  const lastDate = (_a = lastGroup === null || lastGroup === void 0 ? void 0 : lastGroup[lastGroup.length - 1]) === null || _a === void 0 ? void 0 : _a.sentOn;
140
140
  const groupDate = group === null || group === void 0 ? void 0 : group[0].sentOn;
141
141
  const isDateNeeded = !groups[i - 1] ||
142
- difference_in_minutes_1.default(new Date(groupDate), new Date(lastDate)) > constants_1.default.TIME_BETWEEN_DATES;
142
+ (0, difference_in_minutes_1.default)(new Date(groupDate), new Date(lastDate)) > constants_1.default.TIME_BETWEEN_DATES;
143
143
  const [{ authorId, payload }] = group;
144
144
  const avatar = authorId
145
145
  ? this.props.showUserAvatar &&
@@ -161,7 +161,7 @@ class MessageList extends react_1.default.Component {
161
161
  this.renderMessageGroups()));
162
162
  }
163
163
  }
164
- exports.default = mobx_react_1.inject(({ store }) => ({
164
+ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
165
165
  intl: store.intl,
166
166
  isEmulator: store.isEmulator,
167
167
  botName: store.botName,
@@ -174,4 +174,4 @@ exports.default = mobx_react_1.inject(({ store }) => ({
174
174
  showUserAvatar: store.config.showUserAvatar,
175
175
  enableArrowNavigation: store.config.enableArrowNavigation,
176
176
  preferredLanguage: store.preferredLanguage
177
- }))(react_intl_1.injectIntl(mobx_react_1.observer(MessageList)));
177
+ }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(MessageList)));
@@ -23,6 +23,7 @@ export default class WebchatApi {
23
23
  } | undefined>;
24
24
  resetSession(conversationId: uuid): Promise<void>;
25
25
  createConversation(): Promise<uuid | undefined>;
26
+ startConversation(): Promise<void>;
26
27
  downloadConversation(conversationId: uuid): Promise<any>;
27
28
  sendMessage(payload: any, conversationId: uuid): Promise<Message | undefined>;
28
29
  deleteMessages(conversationId: uuid): Promise<void>;
package/dist/core/api.js CHANGED
@@ -13,16 +13,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const get_1 = __importDefault(require("lodash/get"));
16
- const uuid_1 = __importDefault(require("uuid"));
16
+ const uuid_1 = require("uuid");
17
17
  class WebchatApi {
18
18
  constructor(socket) {
19
19
  this.socket = socket;
20
20
  this.handleApiError = (error) => __awaiter(this, void 0, void 0, function* () {
21
21
  // @deprecated 11.9 (replace with proper error management)
22
- const data = get_1.default(error, 'response.data', {});
22
+ const data = (0, get_1.default)(error, 'response.data', {});
23
23
  if (data && typeof data === 'string' && data.includes('BP_CONV_NOT_FOUND')) {
24
24
  console.error('Conversation not found, starting a new one...');
25
25
  yield this.createConversation();
26
+ yield this.startConversation();
26
27
  }
27
28
  });
28
29
  }
@@ -66,7 +67,16 @@ class WebchatApi {
66
67
  fetchConversations() {
67
68
  return __awaiter(this, void 0, void 0, function* () {
68
69
  try {
69
- const convos = yield this.socket.socket.listConversations();
70
+ const convos = (yield this.socket.socket.listConversations());
71
+ // Add the last message of each conversation
72
+ for (const convo of convos) {
73
+ const limit = 1;
74
+ yield this.socket.socket.switchConversation(convo.id);
75
+ const lastMessages = yield this.socket.socket.listMessages(limit);
76
+ if (lastMessages.length >= limit) {
77
+ convo.lastMessage = lastMessages[0];
78
+ }
79
+ }
70
80
  return convos;
71
81
  }
72
82
  catch (err) {
@@ -79,7 +89,7 @@ class WebchatApi {
79
89
  try {
80
90
  const conversation = yield this.socket.socket.getConversation(conversationId);
81
91
  this.socket.socket.switchConversation(conversation.id);
82
- const messages = yield this.socket.socket.listMessages();
92
+ const messages = (yield this.socket.socket.listMessages()).filter((x) => x.payload.type !== 'visit');
83
93
  return Object.assign(Object.assign({}, conversation), { messages });
84
94
  }
85
95
  catch (err) {
@@ -108,6 +118,16 @@ class WebchatApi {
108
118
  }
109
119
  });
110
120
  }
121
+ startConversation() {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ try {
124
+ yield this.socket.socket.startConversation();
125
+ }
126
+ catch (err) {
127
+ console.error('Error in start conversation', err);
128
+ }
129
+ });
130
+ }
111
131
  downloadConversation(conversationId) {
112
132
  return __awaiter(this, void 0, void 0, function* () {
113
133
  try {
@@ -152,7 +172,7 @@ class WebchatApi {
152
172
  sendFeedback(feedback, messageId) {
153
173
  return __awaiter(this, void 0, void 0, function* () {
154
174
  try {
155
- return this.axios.post('/saveFeedback', { messageId, target: this.userId, feedback }, this.axiosConfig);
175
+ return this.socket.socket.sendFeedback(messageId, feedback);
156
176
  }
157
177
  catch (err) {
158
178
  yield this.handleApiError(err);
@@ -190,7 +210,7 @@ class WebchatApi {
190
210
  try {
191
211
  const audio = {
192
212
  buffer: voice.toString('base64'),
193
- title: `${uuid_1.default.v4()}.${ext}`
213
+ title: `${(0, uuid_1.v4)()}.${ext}`
194
214
  };
195
215
  return this.axios.post('/messages/voice', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId, audio }), this.axiosConfig);
196
216
  }
@@ -3,6 +3,8 @@ import { Config } from '../typings';
3
3
  export default class BpSocket {
4
4
  socket: MessagingSocket;
5
5
  private chatId;
6
+ private encryptionKey;
7
+ private clientId;
6
8
  private waitingForUser?;
7
9
  onClear: (event: any) => void;
8
10
  onMessage: (event: any) => void;
@@ -8,8 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  const messaging_socket_1 = require("@botpress/messaging-socket");
16
+ const aes_1 = __importDefault(require("crypto-js/aes"));
17
+ const enc_utf8_1 = __importDefault(require("crypto-js/enc-utf8"));
18
+ const sha256_1 = __importDefault(require("crypto-js/sha256"));
13
19
  class BpSocket {
14
20
  constructor(config) {
15
21
  this.postToParent = (_type, payload) => {
@@ -18,6 +24,8 @@ class BpSocket {
18
24
  (_a = window.parent) === null || _a === void 0 ? void 0 : _a.postMessage(Object.assign(Object.assign({}, payload), { chatId: this.chatId }), '*');
19
25
  };
20
26
  this.chatId = config.chatId;
27
+ this.encryptionKey = config.encryptionKey;
28
+ this.clientId = config.clientId;
21
29
  this.socket = new messaging_socket_1.MessagingSocket({ url: config.messagingUrl, clientId: config.clientId });
22
30
  }
23
31
  setup() {
@@ -47,8 +55,7 @@ class BpSocket {
47
55
  }
48
56
  this.waitingForUser = new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
49
57
  const creds = this.getStorage('creds');
50
- yield this.socket.connect({ autoLogin: false });
51
- yield this.socket.login(creds);
58
+ yield this.socket.connect(creds);
52
59
  if (this.socket.userId) {
53
60
  const userId = this.socket.userId;
54
61
  this.setStorage('creds', this.socket.creds);
@@ -65,23 +72,39 @@ class BpSocket {
65
72
  });
66
73
  }
67
74
  getStorage(key) {
68
- const stored = localStorage.getItem(this.getStorageKey(key));
75
+ var _a;
76
+ let stored = localStorage.getItem(this.getStorageKey(key));
69
77
  if (!stored) {
70
78
  return undefined;
71
79
  }
80
+ if ((_a = this.encryptionKey) === null || _a === void 0 ? void 0 : _a.length) {
81
+ stored = aes_1.default.decrypt(stored, this.encryptionKey).toString(enc_utf8_1.default);
82
+ }
72
83
  try {
73
84
  const val = JSON.parse(stored);
74
85
  return val;
75
86
  }
76
- catch (_a) {
87
+ catch (_b) {
77
88
  return undefined;
78
89
  }
79
90
  }
80
91
  setStorage(key, object) {
81
- localStorage.setItem(this.getStorageKey(key), JSON.stringify(object));
92
+ var _a;
93
+ let string = JSON.stringify(object);
94
+ if ((_a = this.encryptionKey) === null || _a === void 0 ? void 0 : _a.length) {
95
+ string = aes_1.default.encrypt(string, this.encryptionKey).toString();
96
+ }
97
+ localStorage.setItem(this.getStorageKey(key), string);
82
98
  }
83
99
  getStorageKey(key) {
84
- return `bp-chat-${key}`;
100
+ var _a;
101
+ const rawKey = `bp-chat-${key}`;
102
+ if ((_a = this.encryptionKey) === null || _a === void 0 ? void 0 : _a.length) {
103
+ return `${rawKey}-${(0, sha256_1.default)(`${this.clientId}-${this.encryptionKey}`).toString()}`;
104
+ }
105
+ else {
106
+ return `${rawKey}-${this.clientId}`;
107
+ }
85
108
  }
86
109
  }
87
110
  exports.default = BpSocket;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import '../../assets/fonts/roboto.css';
3
+ declare const Font: () => JSX.Element;
4
+ export default Font;
@@ -0,0 +1,9 @@
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
+ require("../../assets/fonts/roboto.css");
8
+ const Font = () => react_1.default.createElement(react_1.default.Fragment, null);
9
+ exports.default = Font;
package/dist/index.d.ts CHANGED
@@ -21,4 +21,3 @@ export declare class ExposedWebChat extends React.Component<Props, State> {
21
21
  export { Embedded as embedded } from '.';
22
22
  export { Fullscreen as fullscreen } from '.';
23
23
  export * from './typings';
24
- export { Carousel, QuickReplies, LoginPrompt, Text, FileMessage, FileInput, Button } from './components/messages/renderer';
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  return (mod && mod.__esModule) ? mod : { "default": mod };
14
14
  };
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.Button = exports.FileInput = exports.FileMessage = exports.Text = exports.LoginPrompt = exports.QuickReplies = exports.Carousel = exports.fullscreen = exports.embedded = exports.ExposedWebChat = exports.Fullscreen = exports.Embedded = void 0;
16
+ exports.fullscreen = exports.embedded = exports.ExposedWebChat = exports.Fullscreen = exports.Embedded = void 0;
17
17
  const mobx_1 = require("mobx");
18
18
  const mobx_react_1 = require("mobx-react");
19
19
  const react_1 = __importDefault(require("react"));
@@ -21,7 +21,7 @@ const react_intl_1 = require("react-intl");
21
21
  const main_1 = __importDefault(require("./main"));
22
22
  const store_1 = require("./store");
23
23
  const translations_1 = require("./translations");
24
- mobx_1.configure({ enforceActions: 'observed' });
24
+ (0, mobx_1.configure)({ enforceActions: 'observed' });
25
25
  const Embedded = (props) => new Wrapper(Object.assign(Object.assign({}, props), { fullscreen: false }));
26
26
  exports.Embedded = Embedded;
27
27
  const Fullscreen = (props) => new Wrapper(Object.assign(Object.assign({}, props), { fullscreen: true }));
@@ -44,7 +44,7 @@ class ExposedWebChat extends react_1.default.Component {
44
44
  }
45
45
  exports.ExposedWebChat = ExposedWebChat;
46
46
  // TODO: what does this observer do?
47
- const Wrapper = mobx_react_1.observer(ExposedWebChat);
47
+ const Wrapper = (0, mobx_react_1.observer)(ExposedWebChat);
48
48
  /**
49
49
  * @deprecated Since the way views are handled has changed, we're also exporting views in lowercase.
50
50
  * https://botpress.com/docs/developers/migrate/
@@ -54,11 +54,15 @@ Object.defineProperty(exports, "embedded", { enumerable: true, get: function ()
54
54
  var _2 = require(".");
55
55
  Object.defineProperty(exports, "fullscreen", { enumerable: true, get: function () { return _2.Fullscreen; } });
56
56
  __exportStar(require("./typings"), exports);
57
- var renderer_1 = require("./components/messages/renderer");
58
- Object.defineProperty(exports, "Carousel", { enumerable: true, get: function () { return renderer_1.Carousel; } });
59
- Object.defineProperty(exports, "QuickReplies", { enumerable: true, get: function () { return renderer_1.QuickReplies; } });
60
- Object.defineProperty(exports, "LoginPrompt", { enumerable: true, get: function () { return renderer_1.LoginPrompt; } });
61
- Object.defineProperty(exports, "Text", { enumerable: true, get: function () { return renderer_1.Text; } });
62
- Object.defineProperty(exports, "FileMessage", { enumerable: true, get: function () { return renderer_1.FileMessage; } });
63
- Object.defineProperty(exports, "FileInput", { enumerable: true, get: function () { return renderer_1.FileInput; } });
64
- Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return renderer_1.Button; } });
57
+ // TODO: export this
58
+ /*
59
+ export {
60
+ Carousel,
61
+ QuickReplies,
62
+ LoginPrompt,
63
+ Text,
64
+ FileMessage,
65
+ FileInput,
66
+ Button
67
+ } from './components/messages/renderer'
68
+ */
package/dist/main.d.ts CHANGED
@@ -1,11 +1,13 @@
1
- /// <reference types="react-intl" />
2
1
  import React from 'react';
2
+ import { WrappedComponentProps } from 'react-intl';
3
3
  import { RootStore, StoreDef } from './store';
4
- declare const _default: React.ComponentClass<Pick<{
5
- store: RootStore;
6
- } & Pick<StoreDef, "intl" | "isFullscreen" | "unreadCount" | "dimensions" | "activeView" | "showWidgetButton" | "hasUnreadMessages" | "isWebchatReady" | "widgetTransition" | "displayWidgetView" | "incrementUnread" | "resetUnread" | "toggleBotInfo" | "setLoadingCompleted" | "showChat" | "hideChat" | "botInfo" | "config" | "isEmulator" | "clearMessages" | "addEventToConversation" | "updateTyping" | "initializeChat" | "fetchBotInfo" | "sendMessage" | "setReference" | "sendData" | "mergeConfig" | "updateConfig" | "setUserId" | "updateBotUILanguage">, "store" | "isFullscreen" | "unreadCount" | "dimensions" | "activeView" | "showWidgetButton" | "hasUnreadMessages" | "isWebchatReady" | "widgetTransition" | "displayWidgetView" | "incrementUnread" | "resetUnread" | "toggleBotInfo" | "setLoadingCompleted" | "showChat" | "hideChat" | "botInfo" | "config" | "isEmulator" | "clearMessages" | "addEventToConversation" | "updateTyping" | "initializeChat" | "fetchBotInfo" | "sendMessage" | "setReference" | "sendData" | "mergeConfig" | "updateConfig" | "setUserId" | "updateBotUILanguage">, any> & {
7
- WrappedComponent: React.ComponentType<{
8
- store: RootStore;
9
- } & Pick<StoreDef, "intl" | "isFullscreen" | "unreadCount" | "dimensions" | "activeView" | "showWidgetButton" | "hasUnreadMessages" | "isWebchatReady" | "widgetTransition" | "displayWidgetView" | "incrementUnread" | "resetUnread" | "toggleBotInfo" | "setLoadingCompleted" | "showChat" | "hideChat" | "botInfo" | "config" | "isEmulator" | "clearMessages" | "addEventToConversation" | "updateTyping" | "initializeChat" | "fetchBotInfo" | "sendMessage" | "setReference" | "sendData" | "mergeConfig" | "updateConfig" | "setUserId" | "updateBotUILanguage"> & ReactIntl.InjectedIntlProps>;
4
+ export declare const DEFAULT_TYPING_DELAY = 1000;
5
+ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omit<MainProps, "intl"> & {
6
+ forwardedRef?: React.Ref<any> | undefined;
7
+ } & React.RefAttributes<any>> & {
8
+ WrappedComponent: React.ComponentType<MainProps>;
10
9
  } & import("mobx-react").IWrappedComponent<unknown>;
11
10
  export default _default;
11
+ declare type MainProps = {
12
+ store: RootStore;
13
+ } & WrappedComponentProps & Pick<StoreDef, 'config' | 'initializeChat' | 'botInfo' | 'fetchBotInfo' | 'sendMessage' | 'setUserId' | 'sendData' | 'intl' | 'isEmulator' | 'updateTyping' | 'setReference' | 'updateBotUILanguage' | 'hideChat' | 'showChat' | 'toggleBotInfo' | 'widgetTransition' | 'activeView' | 'isFullscreen' | 'unreadCount' | 'hasUnreadMessages' | 'showWidgetButton' | 'addEventToConversation' | 'clearMessages' | 'updateConfig' | 'mergeConfig' | 'isWebchatReady' | 'incrementUnread' | 'displayWidgetView' | 'resetUnread' | 'setLoadingCompleted' | 'dimensions' | 'updateLastMessage'>;
package/dist/main.js CHANGED
@@ -1,4 +1,23 @@
1
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
+ };
2
21
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
22
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
23
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -12,6 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
32
  };
14
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.DEFAULT_TYPING_DELAY = void 0;
15
35
  const classnames_1 = __importDefault(require("classnames"));
16
36
  const debounce_1 = __importDefault(require("lodash/debounce"));
17
37
  const set_1 = __importDefault(require("lodash/set"));
@@ -26,8 +46,7 @@ const constants_1 = __importDefault(require("./core/constants"));
26
46
  const socket_1 = __importDefault(require("./core/socket"));
27
47
  const Chat_1 = __importDefault(require("./icons/Chat"));
28
48
  const utils_1 = require("./utils");
29
- const _values = (obj) => Object.keys(obj).map((x) => obj[x]);
30
- const DEFAULT_TYPING_DELAY = 500;
49
+ exports.DEFAULT_TYPING_DELAY = 1000;
31
50
  class Web extends react_1.default.Component {
32
51
  constructor(props) {
33
52
  super(props);
@@ -53,18 +72,18 @@ class Web extends react_1.default.Component {
53
72
  const { type, text } = payload;
54
73
  if (type === 'show') {
55
74
  this.props.showChat();
56
- utils_1.trackWebchatState('show');
75
+ (0, utils_1.trackWebchatState)('show');
57
76
  }
58
77
  else if (type === 'hide') {
59
78
  this.props.hideChat();
60
- utils_1.trackWebchatState('hide');
79
+ (0, utils_1.trackWebchatState)('hide');
61
80
  }
62
81
  else if (type === 'toggle') {
63
82
  this.props.displayWidgetView ? this.props.showChat() : this.props.hideChat();
64
- utils_1.trackWebchatState('toggle');
83
+ (0, utils_1.trackWebchatState)('toggle');
65
84
  }
66
85
  else if (type === 'message') {
67
- utils_1.trackMessage('sent');
86
+ (0, utils_1.trackMessage)('sent');
68
87
  yield this.props.sendMessage(text);
69
88
  }
70
89
  else if (type === 'loadConversation') {
@@ -86,7 +105,7 @@ class Web extends react_1.default.Component {
86
105
  this.handleNewMessage = (event) => __awaiter(this, void 0, void 0, function* () {
87
106
  var _a;
88
107
  if (event.authorId === undefined) {
89
- const value = (event.payload.type === 'typing' ? event.payload.value : undefined) || DEFAULT_TYPING_DELAY;
108
+ const value = (event.payload.type === 'typing' ? event.payload.value : undefined) || exports.DEFAULT_TYPING_DELAY;
90
109
  yield this.handleTyping(Object.assign(Object.assign({}, event), { timeInMs: value }));
91
110
  }
92
111
  if (((_a = event.payload) === null || _a === void 0 ? void 0 : _a.type) === 'visit') {
@@ -97,7 +116,8 @@ class Web extends react_1.default.Component {
97
116
  // don't do anything, it's a message from another conversation
98
117
  return;
99
118
  }
100
- utils_1.trackMessage('received');
119
+ (0, utils_1.trackMessage)('received');
120
+ this.props.updateLastMessage(event.conversationId, event);
101
121
  yield this.props.addEventToConversation(event);
102
122
  // there's no focus on the actual conversation
103
123
  if ((document.hasFocus && !document.hasFocus()) || this.props.activeView !== 'side') {
@@ -127,7 +147,7 @@ class Web extends react_1.default.Component {
127
147
  }
128
148
  this.props.updateBotUILanguage(language);
129
149
  };
130
- this.playSound = debounce_1.default(() => __awaiter(this, void 0, void 0, function* () {
150
+ this.playSound = (0, debounce_1.default)(() => __awaiter(this, void 0, void 0, function* () {
131
151
  // Preference for config object
132
152
  const disableNotificationSound = this.config.disableNotificationSound === undefined
133
153
  ? this.props.config.disableNotificationSound
@@ -143,13 +163,12 @@ class Web extends react_1.default.Component {
143
163
  this.props.resetUnread();
144
164
  }
145
165
  };
146
- utils_1.checkLocationOrigin();
147
- utils_1.initializeAnalytics();
166
+ (0, utils_1.checkLocationOrigin)();
167
+ (0, utils_1.initializeAnalytics)();
148
168
  }
149
169
  componentDidMount() {
150
170
  return __awaiter(this, void 0, void 0, function* () {
151
- // TODO: serve this from cdn
152
- this.audio = new Audio(`${window.ROOT_PATH}/assets/modules/channel-web/notification.mp3`);
171
+ this.audio = new Audio(require('url:../assets/notification.mp3'));
153
172
  this.props.store.setIntlProvider(this.props.intl);
154
173
  window.store = this.props.store;
155
174
  window.addEventListener('message', this.handleIframeApi);
@@ -200,7 +219,7 @@ class Web extends react_1.default.Component {
200
219
  this.config = this.extractConfig();
201
220
  if (this.config.exposeStore) {
202
221
  const storePath = this.config.chatId ? `${this.config.chatId}.webchat_store` : 'webchat_store';
203
- set_1.default(window.parent, storePath, this.props.store);
222
+ (0, set_1.default)(window.parent, storePath, this.props.store);
204
223
  }
205
224
  if (this.config.overrides) {
206
225
  this.loadOverrides(this.config.overrides);
@@ -256,7 +275,7 @@ class Web extends react_1.default.Component {
256
275
  }
257
276
  loadOverrides(overrides) {
258
277
  try {
259
- for (const override of _values(overrides)) {
278
+ for (const override of Object.values(overrides)) {
260
279
  // TODO: load module view this can't work
261
280
  // override.map(({ module }) => this.props.bp!.loadModuleView(module, true))
262
281
  }
@@ -266,7 +285,7 @@ class Web extends react_1.default.Component {
266
285
  }
267
286
  }
268
287
  setupObserver() {
269
- mobx_1.observe(this.props.config, 'userId', (data) => __awaiter(this, void 0, void 0, function* () {
288
+ (0, mobx_1.observe)(this.props.config, 'userId', (data) => __awaiter(this, void 0, void 0, function* () {
270
289
  if (!data.oldValue || data.oldValue === data.newValue) {
271
290
  return;
272
291
  }
@@ -276,12 +295,12 @@ class Web extends react_1.default.Component {
276
295
  yield this.socket.waitForUserId();
277
296
  yield this.props.initializeChat();
278
297
  }));
279
- mobx_1.observe(this.props.config, 'overrides', (data) => {
298
+ (0, mobx_1.observe)(this.props.config, 'overrides', (data) => {
280
299
  if (data.newValue && window.parent) {
281
300
  this.loadOverrides(data.newValue);
282
301
  }
283
302
  });
284
- mobx_1.observe(this.props.dimensions, 'container', (data) => {
303
+ (0, mobx_1.observe)(this.props.dimensions, 'container', (data) => {
285
304
  if (data.newValue && window.parent) {
286
305
  this.postMessageToParent('setWidth', data.newValue);
287
306
  }
@@ -298,7 +317,7 @@ class Web extends react_1.default.Component {
298
317
  if (!this.props.showWidgetButton) {
299
318
  return null;
300
319
  }
301
- return (react_1.default.createElement("button", { className: classnames_1.default('bpw-widget-btn', 'bpw-floating-button', {
320
+ return (react_1.default.createElement("button", { className: (0, classnames_1.default)('bpw-widget-btn', 'bpw-floating-button', {
302
321
  [`bpw-anim-${this.props.widgetTransition}` || 'none']: true
303
322
  }), "aria-label": this.props.intl.formatMessage({ id: 'widget.toggle' }), onClick: this.props.showChat.bind(this) },
304
323
  react_1.default.createElement(Chat_1.default, null),
@@ -306,7 +325,7 @@ class Web extends react_1.default.Component {
306
325
  }
307
326
  applyAndRenderStyle() {
308
327
  const emulatorClass = this.props.isEmulator ? ' emulator' : '';
309
- const parentClass = classnames_1.default(`bp-widget-web bp-widget-${this.props.activeView}${emulatorClass}`, {
328
+ const parentClass = (0, classnames_1.default)(`bp-widget-web bp-widget-${this.props.activeView}${emulatorClass}`, {
310
329
  'bp-widget-hidden': !this.props.showWidgetButton && this.props.displayWidgetView,
311
330
  [this.props.config.className]: !!this.props.config.className
312
331
  });
@@ -314,11 +333,11 @@ class Web extends react_1.default.Component {
314
333
  this.postMessageToParent('setClass', parentClass);
315
334
  this.parentClass = parentClass;
316
335
  }
317
- const { isEmulator, stylesheet, extraStylesheet } = this.props.config;
336
+ const { stylesheet, extraStylesheet } = this.props.config;
337
+ const RobotoFont = react_1.default.lazy(() => Promise.resolve().then(() => __importStar(require('./fonts/roboto'))));
318
338
  return (react_1.default.createElement(react_1.default.Fragment, null,
319
339
  !!(stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.length) && react_1.default.createElement(Stylesheet_1.default, { href: stylesheet }),
320
- !stylesheet && react_1.default.createElement(Stylesheet_1.default, { href: `assets/modules/channel-web/default${isEmulator ? '-emulator' : ''}.css` }),
321
- !utils_1.isIE && react_1.default.createElement(Stylesheet_1.default, { href: 'assets/modules/channel-web/font.css' }),
340
+ react_1.default.createElement(react_1.default.Suspense, { fallback: react_1.default.createElement(react_1.default.Fragment, null) }, !utils_1.isIE && react_1.default.createElement(RobotoFont, null)),
322
341
  !!(extraStylesheet === null || extraStylesheet === void 0 ? void 0 : extraStylesheet.length) && react_1.default.createElement(Stylesheet_1.default, { href: extraStylesheet })));
323
342
  }
324
343
  render() {
@@ -334,7 +353,7 @@ class Web extends react_1.default.Component {
334
353
  this.props.displayWidgetView ? this.renderWidget() : react_1.default.createElement(Container_1.default, null)));
335
354
  }
336
355
  }
337
- exports.default = mobx_react_1.inject(({ store }) => ({
356
+ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
338
357
  store,
339
358
  config: store.config,
340
359
  sendData: store.sendData,
@@ -366,6 +385,6 @@ exports.default = mobx_react_1.inject(({ store }) => ({
366
385
  widgetTransition: store.view.widgetTransition,
367
386
  displayWidgetView: store.view.displayWidgetView,
368
387
  setLoadingCompleted: store.view.setLoadingCompleted,
369
- sendFeedback: store.sendFeedback
370
- // @ts-ignore
371
- }))(react_intl_1.injectIntl(mobx_react_1.observer(Web)));
388
+ sendFeedback: store.sendFeedback,
389
+ updateLastMessage: store.updateLastMessage
390
+ }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(Web)));
@@ -36,11 +36,11 @@ class ComposerStore {
36
36
  }
37
37
  addMessageToHistory(text) {
38
38
  var _a;
39
- if (last_1.default(this._sentHistory) !== text) {
39
+ if ((0, last_1.default)(this._sentHistory) !== text) {
40
40
  this._sentHistory.push(text);
41
41
  this._sentHistoryIndex = 0;
42
42
  if (this.rootStore.config.enablePersistHistory) {
43
- (_a = window.BP_STORAGE) === null || _a === void 0 ? void 0 : _a.set(SENT_HISTORY_KEY, takeRight_1.default(this._sentHistory, constants_1.default.SENT_HISTORY_SIZE));
43
+ (_a = window.BP_STORAGE) === null || _a === void 0 ? void 0 : _a.set(SENT_HISTORY_KEY, (0, takeRight_1.default)(this._sentHistory, constants_1.default.SENT_HISTORY_SIZE));
44
44
  }
45
45
  }
46
46
  }
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { InjectedIntl } from 'react-intl';
2
+ import { IntlShape } from 'react-intl';
3
3
  import BpSocket from '../core/socket';
4
4
  import { BotInfo, Config, CurrentConversation, EventFeedback, Message, MessageWrapper, QueuedMessage, RecentConversation, StudioConnector, uuid } from '../typings';
5
5
  import ComposerStore from './composer';
@@ -18,7 +18,7 @@ declare class RootStore {
18
18
  preferredLanguage: string;
19
19
  isInitialized: boolean;
20
20
  messageFeedbacks: EventFeedback[];
21
- intl: InjectedIntl;
21
+ intl: IntlShape;
22
22
  isBotTyping: import("mobx").IObservableValue<boolean>;
23
23
  /** When a wrapper is defined, every messages are wrapped by the specified component */
24
24
  messageWrapper: MessageWrapper | undefined;
@@ -27,7 +27,7 @@ declare class RootStore {
27
27
  constructor(options: {
28
28
  fullscreen: boolean;
29
29
  }, config?: Config);
30
- setIntlProvider(provider: InjectedIntl): void;
30
+ setIntlProvider(provider: IntlShape): void;
31
31
  setSocket(socket: BpSocket): void;
32
32
  get isConversationStarted(): boolean;
33
33
  get botName(): string;
@@ -40,6 +40,7 @@ declare class RootStore {
40
40
  get currentConversationId(): uuid;
41
41
  postMessage(name: string, payload?: any): void;
42
42
  updateMessages(messages: Message[]): void;
43
+ updateLastMessage(conversationId: string, message?: Message): void;
43
44
  clearMessages(): void;
44
45
  deleteConversation(): Promise<void>;
45
46
  loadEventInDebugger(messageId: uuid, isManual?: boolean): Promise<void>;
@@ -62,7 +63,6 @@ declare class RootStore {
62
63
  setReference(): Promise<void>;
63
64
  resetConversation(): void;
64
65
  resetSession(): Promise<void>;
65
- sendUserVisit(): Promise<void>;
66
66
  extractFeedback(messages: Message[]): Promise<void>;
67
67
  sendFeedback(feedback: number, messageId: string): Promise<void>;
68
68
  downloadConversation(): Promise<void>;