@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/dist/main.js CHANGED
@@ -41,19 +41,18 @@ const query_string_1 = __importDefault(require("query-string"));
41
41
  const react_1 = __importDefault(require("react"));
42
42
  const react_intl_1 = require("react-intl");
43
43
  const Container_1 = __importDefault(require("./components/Container"));
44
- const Stylesheet_1 = __importDefault(require("./components/Stylesheet"));
45
44
  const constants_1 = __importDefault(require("./core/constants"));
46
45
  const socket_1 = __importDefault(require("./core/socket"));
47
46
  const Chat_1 = __importDefault(require("./icons/Chat"));
48
47
  const utils_1 = require("./utils");
48
+ const analytics_1 = require("./utils/analytics");
49
49
  exports.DEFAULT_TYPING_DELAY = 1000;
50
50
  class Web extends react_1.default.Component {
51
51
  constructor(props) {
52
52
  super(props);
53
53
  this.hasBeenInitialized = false;
54
54
  this.isCurrentConversation = (event) => {
55
- var _a, _b;
56
- return !((_a = this.props.config) === null || _a === void 0 ? void 0 : _a.conversationId) || ((_b = this.props.config) === null || _b === void 0 ? void 0 : _b.conversationId) === event.conversationId;
55
+ return this.props.currentConversationId === event.conversationId;
57
56
  };
58
57
  this.handleKeyDown = (e) => __awaiter(this, void 0, void 0, function* () {
59
58
  var _a;
@@ -64,52 +63,51 @@ class Web extends react_1.default.Component {
64
63
  this.props.hideChat();
65
64
  }
66
65
  });
67
- this.handleIframeApi = ({ data: { action, payload } }) => __awaiter(this, void 0, void 0, function* () {
68
- if (action === 'configure') {
69
- this.props.updateConfig(Object.assign({}, constants_1.default.DEFAULT_CONFIG, payload));
70
- }
71
- else if (action === 'mergeConfig') {
72
- this.props.mergeConfig(payload);
73
- }
74
- else if (action === 'sendPayload') {
75
- yield this.props.sendData(payload);
76
- }
77
- else if (action === 'event') {
78
- const { type, text } = payload;
79
- if (type === 'show') {
80
- this.props.showChat();
81
- (0, utils_1.trackWebchatState)('show');
82
- }
83
- else if (type === 'hide') {
84
- this.props.hideChat();
85
- (0, utils_1.trackWebchatState)('hide');
86
- }
87
- else if (type === 'toggle') {
88
- this.props.displayWidgetView ? this.props.showChat() : this.props.hideChat();
89
- (0, utils_1.trackWebchatState)('toggle');
90
- }
91
- else if (type === 'message') {
92
- (0, utils_1.trackMessage)('sent');
93
- yield this.props.sendMessage(text);
94
- }
95
- else if (type === 'loadConversation') {
96
- yield this.props.store.fetchConversation(payload.conversationId);
97
- }
98
- else if (type === 'toggleBotInfo') {
99
- this.props.toggleBotInfo();
100
- }
101
- else {
102
- yield this.props.sendData({ type, payload });
103
- }
66
+ this.handleIframeApi = ({ data }) => __awaiter(this, void 0, void 0, function* () {
67
+ switch (data.action) {
68
+ case 'configure':
69
+ return this.props.updateConfig(Object.assign({}, constants_1.default.DEFAULT_CONFIG, data.payload));
70
+ case 'mergeConfig':
71
+ return this.props.mergeConfig(data.payload);
72
+ case 'sendPayload':
73
+ return this.props.sendData(data.payload);
74
+ case 'event':
75
+ const { type, text, conversationId } = data.payload;
76
+ if (type === 'show') {
77
+ this.props.showChat();
78
+ (0, analytics_1.trackWebchatState)('show');
79
+ }
80
+ else if (type === 'hide') {
81
+ this.props.hideChat();
82
+ (0, analytics_1.trackWebchatState)('hide');
83
+ }
84
+ else if (type === 'toggle') {
85
+ this.props.displayWidgetView ? this.props.showChat() : this.props.hideChat();
86
+ (0, analytics_1.trackWebchatState)('toggle');
87
+ }
88
+ else if (type === 'message') {
89
+ (0, analytics_1.trackMessage)('sent');
90
+ yield this.props.sendMessage(text);
91
+ }
92
+ else if (type === 'loadConversation') {
93
+ yield this.props.fetchConversation(conversationId);
94
+ }
95
+ else if (type === 'toggleBotInfo') {
96
+ this.props.toggleBotInfo();
97
+ }
98
+ else {
99
+ yield this.props.sendData({ type, payload: data.payload });
100
+ }
101
+ default:
102
+ break;
104
103
  }
105
104
  });
106
- this.handleClearMessages = (event) => {
107
- if (this.isCurrentConversation(event)) {
108
- this.props.clearMessages();
109
- }
110
- };
111
105
  this.handleNewMessage = (event) => __awaiter(this, void 0, void 0, function* () {
112
106
  var _b;
107
+ if (!this.isCurrentConversation(event)) {
108
+ // don't do anything, it's a message from another conversation
109
+ return;
110
+ }
113
111
  if (event.authorId === undefined) {
114
112
  const value = (event.payload.type === 'typing' ? event.payload.value : undefined) || exports.DEFAULT_TYPING_DELAY;
115
113
  yield this.handleTyping(Object.assign(Object.assign({}, event), { timeInMs: value }));
@@ -118,11 +116,7 @@ class Web extends react_1.default.Component {
118
116
  // don't do anything, it's the system message
119
117
  return;
120
118
  }
121
- if (!this.isCurrentConversation(event)) {
122
- // don't do anything, it's a message from another conversation
123
- return;
124
- }
125
- (0, utils_1.trackMessage)('received');
119
+ (0, analytics_1.trackMessage)('received');
126
120
  this.props.updateLastMessage(event.conversationId, event);
127
121
  yield this.props.addEventToConversation(event);
128
122
  // there's no focus on the actual conversation
@@ -133,27 +127,11 @@ class Web extends react_1.default.Component {
133
127
  this.handleResetUnreadCount();
134
128
  });
135
129
  this.handleTyping = (event) => __awaiter(this, void 0, void 0, function* () {
136
- if (!this.isCurrentConversation(event)) {
137
- // don't do anything, it's a message from another conversation
138
- return;
139
- }
140
130
  yield this.props.updateTyping(event);
141
131
  });
142
- this.handleDataMessage = (event) => {
143
- if (!event || !event.payload) {
144
- return;
145
- }
146
- const { language } = event.payload;
147
- if (!language) {
148
- return;
149
- }
150
- this.props.updateBotUILanguage(language);
151
- };
152
132
  this.playSound = (0, debounce_1.default)(() => __awaiter(this, void 0, void 0, function* () {
153
- // Preference for config object
154
- const disableNotificationSound = this.config.disableNotificationSound === undefined
155
- ? this.props.config.disableNotificationSound
156
- : this.config.disableNotificationSound;
133
+ var _c;
134
+ const disableNotificationSound = this.config.disableNotificationSound || ((_c = this.props.config) === null || _c === void 0 ? void 0 : _c.disableNotificationSound);
157
135
  if (disableNotificationSound || this.audio.readyState < 2) {
158
136
  return;
159
137
  }
@@ -164,17 +142,16 @@ class Web extends react_1.default.Component {
164
142
  this.props.resetUnread();
165
143
  }
166
144
  };
167
- (0, utils_1.checkLocationOrigin)();
168
- (0, utils_1.initializeAnalytics)();
145
+ (0, analytics_1.initializeAnalytics)();
169
146
  }
170
147
  componentDidMount() {
171
148
  return __awaiter(this, void 0, void 0, function* () {
172
149
  this.audio = new Audio(require('url:../assets/notification.mp3'));
173
- this.props.store.setIntlProvider(this.props.intl);
150
+ this.props.setIntlProvider(this.props.intl);
174
151
  window.store = this.props.store;
175
152
  window.addEventListener('message', this.handleIframeApi);
176
153
  window.addEventListener('keydown', this.handleKeyDown);
177
- yield this.load();
154
+ yield this.loadConfig();
178
155
  yield this.initializeIfChatDisplayed();
179
156
  this.props.setLoadingCompleted();
180
157
  });
@@ -198,27 +175,24 @@ class Web extends react_1.default.Component {
198
175
  if (this.isLazySocket() || !this.socket) {
199
176
  yield this.initializeSocket();
200
177
  }
201
- yield this.socket.waitForUserId();
202
- this.props.store.setSocket(this.socket);
178
+ yield this.socket.connect();
179
+ this.props.setSocket(this.socket);
203
180
  yield this.props.initializeChat();
204
181
  }
205
182
  });
206
183
  }
207
- load() {
184
+ loadConfig() {
208
185
  return __awaiter(this, void 0, void 0, function* () {
209
186
  this.config = this.extractConfig();
187
+ this.props.updateConfig(this.config);
210
188
  if (this.config.exposeStore) {
211
189
  const storePath = this.config.chatId ? `${this.config.chatId}.webchat_store` : 'webchat_store';
212
190
  (0, set_1.default)(window.parent, storePath, this.props.store);
213
191
  }
214
- if (this.config.overrides) {
215
- this.loadOverrides(this.config.overrides);
216
- }
217
192
  if (this.config.containerWidth) {
218
193
  this.postMessageToParent('setWidth', this.config.containerWidth);
219
194
  }
220
- // TODO: replace this by frontend configuration
221
- // await this.props.fetchBotInfo!()
195
+ yield this.props.fetchBotInfo();
222
196
  if (!this.isLazySocket()) {
223
197
  yield this.initializeSocket();
224
198
  }
@@ -226,68 +200,38 @@ class Web extends react_1.default.Component {
226
200
  });
227
201
  }
228
202
  postMessageToParent(type, value) {
229
- var _a, _b;
230
- (_a = window.parent) === null || _a === void 0 ? void 0 : _a.postMessage({ type, value, chatId: (_b = this.config) === null || _b === void 0 ? void 0 : _b.chatId }, '*');
203
+ var _a;
204
+ (_a = window.parent) === null || _a === void 0 ? void 0 : _a.postMessage({ type, value, chatId: this.config.chatId }, '*');
231
205
  }
232
206
  extractConfig() {
233
- const decodeIfRequired = (options) => {
234
- try {
235
- return decodeURIComponent(options);
236
- }
237
- catch (_a) {
238
- return options;
239
- }
240
- };
207
+ let userConfig = Object.assign({}, constants_1.default.DEFAULT_CONFIG, this.props.config);
241
208
  const { options } = query_string_1.default.parse(location.search);
242
- const { config } = JSON.parse(decodeIfRequired(options || '{}'));
243
- const userConfig = Object.assign({}, constants_1.default.DEFAULT_CONFIG, this.props.config, config);
244
- this.props.updateConfig(userConfig);
245
- return userConfig;
209
+ if (!options || typeof options !== 'string') {
210
+ console.warn(`Cannot decode option. Invalid format: ${typeof options}, expecting 'string'.`);
211
+ return userConfig;
212
+ }
213
+ try {
214
+ const parsedOptions = JSON.parse(decodeURIComponent(options));
215
+ userConfig = Object.assign(userConfig, parsedOptions.config);
216
+ return userConfig;
217
+ }
218
+ catch (err) {
219
+ // TODO: Handle those errors so they don't directly bubble up to the users
220
+ throw new Error(`An error occurred while extracting the configurations ${err}`);
221
+ }
246
222
  }
247
223
  initializeSocket() {
248
224
  return __awaiter(this, void 0, void 0, function* () {
249
225
  this.socket = new socket_1.default(this.config);
250
- this.socket.onClear = this.handleClearMessages;
251
226
  this.socket.onMessage = this.handleNewMessage;
252
- this.socket.onTyping = this.handleTyping;
253
- this.socket.onData = this.handleDataMessage;
254
- this.socket.onUserIdChanged = this.props.setUserId;
255
- // TODO: Can't do that
256
- // this.config.userId && this.socket.changeUserId(this.config.userId)
257
227
  this.socket.setup();
258
- yield this.socket.waitForUserId();
259
- this.props.store.setSocket(this.socket);
228
+ yield this.socket.connect();
229
+ this.props.setSocket(this.socket);
260
230
  });
261
231
  }
262
- loadOverrides(overrides) {
263
- try {
264
- for (const override of Object.values(overrides)) {
265
- // TODO: load module view this can't work
266
- // override.map(({ module }) => this.props.bp!.loadModuleView(module, true))
267
- }
268
- }
269
- catch (err) {
270
- console.error('Error while loading overrides', err.message);
271
- }
272
- }
273
232
  setupObserver() {
274
- (0, mobx_1.observe)(this.props.config, 'userId', (data) => __awaiter(this, void 0, void 0, function* () {
275
- if (!data.oldValue || data.oldValue === data.newValue) {
276
- return;
277
- }
278
- // TODO: Can't work right now
279
- // this.socket.changeUserId(data.newValue)
280
- this.socket.setup();
281
- yield this.socket.waitForUserId();
282
- yield this.props.initializeChat();
283
- }));
284
- (0, mobx_1.observe)(this.props.config, 'overrides', (data) => {
285
- if (data.newValue && window.parent) {
286
- this.loadOverrides(data.newValue);
287
- }
288
- });
289
233
  (0, mobx_1.observe)(this.props.dimensions, 'container', (data) => {
290
- if (data.newValue && window.parent) {
234
+ if (data.newValue) {
291
235
  this.postMessageToParent('setWidth', data.newValue);
292
236
  }
293
237
  });
@@ -310,20 +254,22 @@ class Web extends react_1.default.Component {
310
254
  this.props.hasUnreadMessages && react_1.default.createElement("span", { className: 'bpw-floating-button-unread' }, this.props.unreadCount)));
311
255
  }
312
256
  applyAndRenderStyle() {
257
+ var _a, _b, _c;
313
258
  const parentClass = (0, classnames_1.default)(`bp-widget-web bp-widget-${this.props.activeView}`, {
314
259
  'bp-widget-hidden': !this.props.showWidgetButton && this.props.displayWidgetView,
315
- [this.props.config.className]: !!this.props.config.className
260
+ [(_a = this.props.config) === null || _a === void 0 ? void 0 : _a.className]: !!((_b = this.props.config) === null || _b === void 0 ? void 0 : _b.className)
316
261
  });
317
262
  if (this.parentClass !== parentClass) {
318
263
  this.postMessageToParent('setClass', parentClass);
319
264
  this.parentClass = parentClass;
320
265
  }
321
- const { stylesheet, extraStylesheet } = this.props.config;
266
+ const stylesheet = this.props.config.stylesheet;
267
+ const extraStylesheet = (_c = this.props.botInfo) === null || _c === void 0 ? void 0 : _c.extraStylesheet;
322
268
  const RobotoFont = react_1.default.lazy(() => Promise.resolve().then(() => __importStar(require('./fonts/roboto'))));
323
269
  return (react_1.default.createElement(react_1.default.Fragment, null,
324
- !!(stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.length) && react_1.default.createElement(Stylesheet_1.default, { href: stylesheet }),
270
+ !!(stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.length) && react_1.default.createElement("link", { rel: "stylesheet", type: "text/css", href: stylesheet }),
325
271
  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)),
326
- !!(extraStylesheet === null || extraStylesheet === void 0 ? void 0 : extraStylesheet.length) && react_1.default.createElement(Stylesheet_1.default, { href: extraStylesheet })));
272
+ !!(extraStylesheet === null || extraStylesheet === void 0 ? void 0 : extraStylesheet.length) && react_1.default.createElement("link", { rel: "stylesheet", type: "text/css", href: extraStylesheet })));
327
273
  }
328
274
  render() {
329
275
  if (!this.props.isWebchatReady) {
@@ -349,7 +295,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
349
295
  mergeConfig: store.mergeConfig,
350
296
  addEventToConversation: store.addEventToConversation,
351
297
  clearMessages: store.clearMessages,
352
- setUserId: store.setUserId,
353
298
  updateTyping: store.updateTyping,
354
299
  sendMessage: store.sendMessage,
355
300
  updateBotUILanguage: store.updateBotUILanguage,
@@ -369,5 +314,9 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
369
314
  displayWidgetView: store.view.displayWidgetView,
370
315
  setLoadingCompleted: store.view.setLoadingCompleted,
371
316
  sendFeedback: store.sendFeedback,
372
- updateLastMessage: store.updateLastMessage
317
+ updateLastMessage: store.updateLastMessage,
318
+ fetchConversation: store.fetchConversation,
319
+ setIntlProvider: store.setIntlProvider,
320
+ setSocket: store.setSocket,
321
+ currentConversationId: store.currentConversationId
373
322
  }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(Web)));
@@ -1,10 +1,10 @@
1
1
  /// <reference types="node" />
2
2
  import { IntlShape } from 'react-intl';
3
3
  import BpSocket from '../core/socket';
4
- import { BotInfo, Config, CurrentConversation, EventFeedback, Message, QueuedMessage, RecentConversation, StudioConnector, uuid } from '../typings';
4
+ import { BotInfo, Config, CurrentConversation, EventFeedback, Message, QueuedMessage, RecentConversation, uuid } from '../typings';
5
5
  import ComposerStore from './composer';
6
6
  import ViewStore from './view';
7
- /** Includes the partial definitions of all classes */
7
+ /** Includes the definitions of all store classes */
8
8
  export declare type StoreDef = Partial<RootStore> & Partial<ViewStore> & Partial<ComposerStore> & Partial<Config>;
9
9
  declare class RootStore {
10
10
  composer: ComposerStore;
@@ -57,22 +57,18 @@ declare class RootStore {
57
57
  /** Creates a new conversation and switches to it */
58
58
  createConversation(): Promise<uuid>;
59
59
  resetConversation(): void;
60
- resetSession(): Promise<void>;
61
60
  extractFeedback(messages: Message[]): Promise<void>;
62
61
  sendFeedback(feedback: number, messageId: string): Promise<void>;
63
62
  downloadConversation(): Promise<void>;
64
63
  /** Sends an event or a message, depending on how the backend manages those types */
65
64
  sendData(data: any): Promise<void>;
66
- uploadFile(title: string, payload: string, file: File): Promise<void>;
67
65
  /** Sends a message of type voice */
68
66
  sendVoiceMessage(voice: Buffer, ext: string): Promise<void>;
69
67
  /** Use this method to replace a value or add a new config */
70
68
  mergeConfig(config: Partial<Config>): void;
71
69
  /** This replaces all the configurations by this object */
72
- updateConfig(config: Config, bp?: StudioConnector): void;
70
+ updateConfig(config: Config): void;
73
71
  private _applyConfig;
74
- /** When this method is used, the user ID is changed in the configuration, then the socket is updated */
75
- setUserId(userId: string): void;
76
72
  publishConfigChanged(): void;
77
73
  updatePreferredLanguage(lang: string): void;
78
74
  /** Starts a timer to remove the typing animation when it's completed */
@@ -80,7 +76,7 @@ declare class RootStore {
80
76
  private _expireTyping;
81
77
  updateBotUILanguage(lang: string): void;
82
78
  private emptyDelayedMessagesQueue;
83
- /** Returns the current conversation ID, or the last one if it didn't expired. Otherwise, returns nothing. */
79
+ /** Returns the current conversation ID, or the last one. */
84
80
  private _getCurrentConvoId;
85
81
  }
86
82
  export { RootStore };
@@ -19,6 +19,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.RootStore = void 0;
22
+ const axios_1 = __importDefault(require("axios"));
22
23
  const is_before_1 = __importDefault(require("date-fns/is_before"));
23
24
  const is_valid_1 = __importDefault(require("date-fns/is_valid"));
24
25
  const merge_1 = __importDefault(require("lodash/merge"));
@@ -28,6 +29,7 @@ const api_1 = __importDefault(require("../core/api"));
28
29
  const main_1 = require("../main");
29
30
  const translations_1 = require("../translations");
30
31
  const utils_1 = require("../utils");
32
+ const analytics_1 = require("../utils/analytics");
31
33
  const composer_1 = __importDefault(require("./composer"));
32
34
  const view_1 = __importDefault(require("./view"));
33
35
  class RootStore {
@@ -58,14 +60,14 @@ class RootStore {
58
60
  }
59
61
  get hasBotInfoDescription() {
60
62
  var _a;
61
- return !!((_a = this.config.botConvoDescription) === null || _a === void 0 ? void 0 : _a.length);
63
+ return !!((_a = this.config.botConversationDescription) === null || _a === void 0 ? void 0 : _a.length);
62
64
  }
63
65
  get botAvatarUrl() {
64
66
  var _a, _b, _c;
65
67
  return ((_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.avatarUrl) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.avatarUrl) || undefined;
66
68
  }
67
69
  get rtl() {
68
- return (0, utils_1.isRTLLocale)(this.preferredLanguage);
70
+ return (0, translations_1.isRTLLocale)(this.preferredLanguage);
69
71
  }
70
72
  get escapeHTML() {
71
73
  var _a, _b;
@@ -155,7 +157,7 @@ class RootStore {
155
157
  return __awaiter(this, void 0, void 0, function* () {
156
158
  try {
157
159
  yield this.fetchConversations();
158
- yield this.fetchConversation(this.config.conversationId);
160
+ yield this.fetchConversation();
159
161
  (0, mobx_1.runInAction)('-> setInitialized', () => {
160
162
  this.isInitialized = true;
161
163
  this.postMessage('webchatReady');
@@ -173,17 +175,21 @@ class RootStore {
173
175
  if (!this.config.mediaFileServiceUrl) {
174
176
  return;
175
177
  }
176
- const botInfo = yield this.api.fetchBotInfo(this.config.mediaFileServiceUrl);
177
- if (!botInfo) {
178
- return;
178
+ try {
179
+ const { data } = yield axios_1.default.get(this.config.mediaFileServiceUrl);
180
+ if (!data) {
181
+ return;
182
+ }
183
+ (0, mobx_1.runInAction)('-> setBotInfo', () => {
184
+ this.botInfo = data;
185
+ });
186
+ this.mergeConfig({
187
+ disableNotificationSound: data.disableNotificationSound
188
+ });
189
+ }
190
+ catch (err) {
191
+ console.error('Error while loading bot info', err);
179
192
  }
180
- (0, mobx_1.runInAction)('-> setBotInfo', () => {
181
- this.botInfo = botInfo;
182
- });
183
- this.mergeConfig({
184
- extraStylesheet: botInfo.extraStylesheet,
185
- disableNotificationSound: botInfo.disableNotificationSound
186
- });
187
193
  });
188
194
  }
189
195
  fetchLanguage() {
@@ -235,7 +241,7 @@ class RootStore {
235
241
  this.composer.updateMessage('');
236
242
  try {
237
243
  yield this.sendData({ type: 'text', text: userMessage });
238
- (0, utils_1.trackMessage)('sent');
244
+ (0, analytics_1.trackMessage)('sent');
239
245
  this.composer.addMessageToHistory(userMessage);
240
246
  }
241
247
  catch (e) {
@@ -264,18 +270,9 @@ class RootStore {
264
270
  resetConversation() {
265
271
  this.currentConversation = undefined;
266
272
  }
267
- resetSession() {
268
- return __awaiter(this, void 0, void 0, function* () {
269
- if (this.currentConversationId) {
270
- this.composer.setLocked(false);
271
- return this.api.resetSession(this.currentConversationId);
272
- }
273
- });
274
- }
275
273
  extractFeedback(messages) {
276
274
  return __awaiter(this, void 0, void 0, function* () {
277
275
  const feedbackMessageIds = messages.filter((x) => x.payload && x.payload.collectFeedback).map((x) => x.id);
278
- // TODO: store feedback somewhere
279
276
  const feedbackInfo = feedbackMessageIds.map((x) => ({ messageId: x, feedback: 1 }));
280
277
  (0, mobx_1.runInAction)('-> setFeedbackInfo', () => {
281
278
  this.messageFeedbacks = feedbackInfo;
@@ -305,7 +302,7 @@ class RootStore {
305
302
  if (payload.type === 'session_reset') {
306
303
  continue;
307
304
  }
308
- info += `\n[${formatDate(message.sentOn)}] ${message.authorId ? 'User' : this.config.botId || 'Bot'}: Event (${payload.type}): ${payload.text ||
305
+ info += `\n[${formatDate(message.sentOn)}] ${message.authorId ? 'User' : this.config.botName || 'Bot'}: Event (${payload.type}): ${payload.text ||
309
306
  payload.audio ||
310
307
  payload.image ||
311
308
  payload.video ||
@@ -333,13 +330,6 @@ class RootStore {
333
330
  this.updateLastMessage(this.currentConversationId, message);
334
331
  });
335
332
  }
336
- uploadFile(title, payload, file) {
337
- return __awaiter(this, void 0, void 0, function* () {
338
- if (this.currentConversationId) {
339
- yield this.api.uploadFile(file, payload, this.currentConversationId);
340
- }
341
- });
342
- }
343
333
  /** Sends a message of type voice */
344
334
  sendVoiceMessage(voice, ext) {
345
335
  return __awaiter(this, void 0, void 0, function* () {
@@ -354,7 +344,7 @@ class RootStore {
354
344
  this._applyConfig();
355
345
  }
356
346
  /** This replaces all the configurations by this object */
357
- updateConfig(config, bp) {
347
+ updateConfig(config) {
358
348
  this.config = config;
359
349
  this._applyConfig();
360
350
  }
@@ -362,13 +352,11 @@ class RootStore {
362
352
  window.BP_STORAGE.config = this.config;
363
353
  this.config.layoutWidth && this.view.setLayoutWidth(this.config.layoutWidth);
364
354
  this.config.containerWidth && this.view.setContainerWidth(this.config.containerWidth);
365
- this.view.disableAnimations = this.config.disableAnimations;
355
+ this.view.disableAnimations = !!this.config.disableAnimations;
366
356
  this.config.showPoweredBy ? this.view.showPoweredBy() : this.view.hidePoweredBy();
367
357
  document.title = this.config.botName || 'Botpress Webchat';
368
- // TODO: can't work at the moment
369
- // this.api.updateUserId(this.config.userId!)
370
358
  if (!this.isInitialized) {
371
- window.USE_SESSION_STORAGE = this.config.useSessionStorage;
359
+ window.USE_SESSION_STORAGE = !!this.config.useSessionStorage;
372
360
  }
373
361
  else if (window.USE_SESSION_STORAGE !== this.config.useSessionStorage) {
374
362
  console.warn('[WebChat] "useSessionStorage" value cannot be altered once the webchat is initialized');
@@ -378,13 +366,6 @@ class RootStore {
378
366
  document.documentElement.setAttribute('lang', locale);
379
367
  this.publishConfigChanged();
380
368
  }
381
- /** When this method is used, the user ID is changed in the configuration, then the socket is updated */
382
- setUserId(userId) {
383
- this.config.userId = userId;
384
- this.resetConversation();
385
- // this.api.updateUserId(userId)
386
- this.publishConfigChanged();
387
- }
388
369
  publishConfigChanged() {
389
370
  this.postMessage('configChanged', JSON.stringify(this.config, undefined, 2));
390
371
  }
@@ -441,7 +422,7 @@ class RootStore {
441
422
  }
442
423
  }
443
424
  }
444
- /** Returns the current conversation ID, or the last one if it didn't expired. Otherwise, returns nothing. */
425
+ /** Returns the current conversation ID, or the last one. */
445
426
  _getCurrentConvoId() {
446
427
  if (this.currentConversationId) {
447
428
  return this.currentConversationId;
@@ -449,15 +430,6 @@ class RootStore {
449
430
  if (!this.conversations.length) {
450
431
  return;
451
432
  }
452
- // TODO: these settings need to be set in the frontend
453
- /*
454
- const lifeTimeMargin = Date.now() - ms(this.config.recentConversationLifetime)
455
- const isConversationExpired =
456
- new Date(this.conversations[0].lastMessage?.sentOn || this.conversations[0].createdOn).getTime() < lifeTimeMargin
457
- if (isConversationExpired && this.config.startNewConvoOnTimeout) {
458
- return
459
- }
460
- */
461
433
  return this.conversations[0].id;
462
434
  }
463
435
  }
@@ -563,9 +535,6 @@ __decorate([
563
535
  __decorate([
564
536
  mobx_1.action.bound
565
537
  ], RootStore.prototype, "resetConversation", null);
566
- __decorate([
567
- mobx_1.action.bound
568
- ], RootStore.prototype, "resetSession", null);
569
538
  __decorate([
570
539
  mobx_1.action.bound
571
540
  ], RootStore.prototype, "extractFeedback", null);
@@ -578,9 +547,6 @@ __decorate([
578
547
  __decorate([
579
548
  mobx_1.action.bound
580
549
  ], RootStore.prototype, "sendData", null);
581
- __decorate([
582
- mobx_1.action.bound
583
- ], RootStore.prototype, "uploadFile", null);
584
550
  __decorate([
585
551
  mobx_1.action.bound
586
552
  ], RootStore.prototype, "sendVoiceMessage", null);
@@ -590,9 +556,6 @@ __decorate([
590
556
  __decorate([
591
557
  mobx_1.action.bound
592
558
  ], RootStore.prototype, "updateConfig", null);
593
- __decorate([
594
- mobx_1.action.bound
595
- ], RootStore.prototype, "setUserId", null);
596
559
  __decorate([
597
560
  mobx_1.action.bound
598
561
  ], RootStore.prototype, "publishConfigChanged", null);
@@ -18,11 +18,10 @@ declare class ViewStore {
18
18
  customActions: CustomAction[];
19
19
  disableAnimations: boolean;
20
20
  constructor(rootStore: RootStore, fullscreen: boolean);
21
- get showConversationsButton(): boolean;
21
+ get showConversationsButton(): boolean | undefined;
22
22
  get showBotInfoButton(): boolean;
23
- get showDownloadButton(): boolean;
24
- get showDeleteConversationButton(): boolean;
25
- get showResetButton(): boolean;
23
+ get showDownloadButton(): boolean | undefined;
24
+ get showDeleteConversationButton(): boolean | undefined;
26
25
  get showCloseButton(): boolean;
27
26
  get showWidgetButton(): boolean;
28
27
  get hasUnreadMessages(): boolean;