@botpress/webchat 0.2.1 → 0.2.5

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 (53) hide show
  1. package/dist/components/Composer.d.ts +1 -1
  2. package/dist/components/Composer.js +12 -2
  3. package/dist/components/Container.d.ts +1 -1
  4. package/dist/components/Container.js +0 -2
  5. package/dist/components/ContextMenu.js +0 -9
  6. package/dist/components/Header.d.ts +1 -1
  7. package/dist/components/Header.js +10 -27
  8. package/dist/components/VoiceRecorder.js +6 -2
  9. package/dist/components/common/{Avatar.d.ts → Avatar/index.d.ts} +0 -0
  10. package/dist/components/common/Avatar/index.js +13 -0
  11. package/dist/components/common/{BotInfo.d.ts → BotInfo/index.d.ts} +2 -2
  12. package/dist/components/common/BotInfo/index.js +112 -0
  13. package/dist/components/common/ConfirmDialog/index.d.ts +11 -0
  14. package/dist/components/common/ConfirmDialog/index.js +78 -0
  15. package/dist/components/common/Dialog/index.d.ts +17 -0
  16. package/dist/components/common/Dialog/index.js +57 -0
  17. package/dist/components/common/MoreOptions/index.d.ts +21 -0
  18. package/dist/components/common/MoreOptions/index.js +60 -0
  19. package/dist/components/common/Overlay/index.d.ts +7 -0
  20. package/dist/components/common/{Avatar.js → Overlay/index.js} +15 -8
  21. package/dist/components/common/ToolTip/index.d.ts +10 -0
  22. package/dist/components/common/ToolTip/index.js +163 -0
  23. package/dist/components/common/ToolTip/utils.d.ts +15 -0
  24. package/dist/components/common/ToolTip/utils.js +78 -0
  25. package/dist/components/messages/Message.js +1 -20
  26. package/dist/components/messages/MessageGroup.d.ts +1 -9
  27. package/dist/components/messages/MessageGroup.js +4 -35
  28. package/dist/components/messages/MessageList.d.ts +1 -1
  29. package/dist/components/messages/MessageList.js +1 -2
  30. package/dist/core/api.d.ts +5 -15
  31. package/dist/core/api.js +31 -128
  32. package/dist/core/socket.d.ts +0 -3
  33. package/dist/core/socket.js +2 -21
  34. package/dist/icons/Cancel.d.ts +5 -0
  35. package/dist/icons/Cancel.js +10 -0
  36. package/dist/icons/Microphone.d.ts +5 -0
  37. package/dist/icons/Microphone.js +12 -0
  38. package/dist/index.js +4 -3
  39. package/dist/main.d.ts +1 -1
  40. package/dist/main.js +20 -37
  41. package/dist/store/composer.js +3 -6
  42. package/dist/store/index.d.ts +5 -11
  43. package/dist/store/index.js +84 -85
  44. package/dist/store/view.d.ts +0 -2
  45. package/dist/store/view.js +0 -10
  46. package/dist/translations/index.d.ts +2 -1
  47. package/dist/translations/index.js +9 -4
  48. package/dist/typings.d.ts +8 -18
  49. package/dist/utils/storage.d.ts +16 -0
  50. package/dist/utils/storage.js +129 -0
  51. package/dist/utils.js +1 -1
  52. package/package.json +6 -2
  53. package/dist/components/common/BotInfo.js +0 -110
@@ -22,6 +22,7 @@ exports.RootStore = void 0;
22
22
  const is_before_1 = __importDefault(require("date-fns/is_before"));
23
23
  const is_valid_1 = __importDefault(require("date-fns/is_valid"));
24
24
  const merge_1 = __importDefault(require("lodash/merge"));
25
+ const orderBy_1 = __importDefault(require("lodash/orderBy"));
25
26
  const mobx_1 = require("mobx");
26
27
  const api_1 = __importDefault(require("../core/api"));
27
28
  const main_1 = require("../main");
@@ -29,18 +30,17 @@ const translations_1 = require("../translations");
29
30
  const utils_1 = require("../utils");
30
31
  const composer_1 = __importDefault(require("./composer"));
31
32
  const view_1 = __importDefault(require("./view"));
32
- const chosenLocale = (0, translations_1.getUserLocale)();
33
33
  class RootStore {
34
34
  constructor(options, config) {
35
35
  this.conversations = [];
36
36
  this.isBotTyping = mobx_1.observable.box(false);
37
- this.botUILanguage = chosenLocale;
38
37
  this.delayedMessages = [];
39
38
  this.composer = new composer_1.default(this);
40
39
  this.view = new view_1.default(this, options.fullscreen);
41
40
  if (config) {
42
41
  this.updateConfig(config);
43
42
  }
43
+ this.botUILanguage = (0, translations_1.getUserLocale)();
44
44
  }
45
45
  setIntlProvider(provider) {
46
46
  this.intl = provider;
@@ -56,10 +56,6 @@ class RootStore {
56
56
  var _a, _b;
57
57
  return ((_a = this.config) === null || _a === void 0 ? void 0 : _a.botName) || ((_b = this.botInfo) === null || _b === void 0 ? void 0 : _b.name) || 'Bot';
58
58
  }
59
- get isEmulator() {
60
- var _a;
61
- return ((_a = this.config) === null || _a === void 0 ? void 0 : _a.isEmulator) || false;
62
- }
63
59
  get hasBotInfoDescription() {
64
60
  var _a;
65
61
  return !!((_a = this.config.botConvoDescription) === null || _a === void 0 ? void 0 : _a.length);
@@ -77,7 +73,7 @@ class RootStore {
77
73
  }
78
74
  get currentMessages() {
79
75
  var _a;
80
- return (_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.messages;
76
+ return ((_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.messages) || [];
81
77
  }
82
78
  get currentConversationId() {
83
79
  var _a;
@@ -88,7 +84,9 @@ class RootStore {
88
84
  window.parent.postMessage({ name, chatId, payload }, '*');
89
85
  }
90
86
  updateMessages(messages) {
91
- this.currentConversation.messages = messages;
87
+ if (this.currentConversation) {
88
+ this.currentConversation.messages = messages;
89
+ }
92
90
  }
93
91
  updateLastMessage(conversationId, message) {
94
92
  for (const conversation of this.conversations) {
@@ -99,30 +97,27 @@ class RootStore {
99
97
  }
100
98
  }
101
99
  clearMessages() {
102
- this.currentConversation.messages = [];
100
+ if (this.currentConversation) {
101
+ this.currentConversation.messages = [];
102
+ }
103
103
  }
104
104
  deleteConversation() {
105
105
  return __awaiter(this, void 0, void 0, function* () {
106
- if (this.currentConversation !== undefined && this.currentConversation.messages.length > 0) {
107
- yield this.api.deleteMessages(this.currentConversationId);
108
- this.clearMessages();
109
- }
110
- });
111
- }
112
- loadEventInDebugger(messageId, isManual) {
113
- return __awaiter(this, void 0, void 0, function* () {
114
- if (!this.config.isEmulator || !messageId) {
115
- return;
106
+ if (this.currentConversationId) {
107
+ yield this.api.deleteConversation(this.currentConversationId);
108
+ const index = this.conversations.findIndex((c) => c.id === this.currentConversationId);
109
+ if (index > -1) {
110
+ this.conversations.splice(index, 1);
111
+ }
112
+ this.resetConversation();
113
+ yield this.fetchConversation();
116
114
  }
117
- const messages = yield this.api.listByIncomingEvent(messageId);
118
- this.view.setHighlightedMessages(messages);
119
- window.parent.postMessage({ action: 'load-event', payload: { messageId, isManual } }, '*');
120
115
  });
121
116
  }
122
117
  addEventToConversation(event) {
123
118
  var _a;
124
119
  return __awaiter(this, void 0, void 0, function* () {
125
- if (this.isInitialized && this.currentConversationId !== event.conversationId) {
120
+ if (!this.currentConversation || (this.isInitialized && this.currentConversationId !== event.conversationId)) {
126
121
  yield this.fetchConversations();
127
122
  yield this.fetchConversation(event.conversationId);
128
123
  return;
@@ -142,7 +137,7 @@ class RootStore {
142
137
  }
143
138
  updateTyping(event) {
144
139
  return __awaiter(this, void 0, void 0, function* () {
145
- if (this.isInitialized && this.currentConversationId !== event.conversationId) {
140
+ if (!this.currentConversation || (this.isInitialized && this.currentConversationId !== event.conversationId)) {
146
141
  yield this.fetchConversations();
147
142
  yield this.fetchConversation(event.conversationId);
148
143
  return;
@@ -167,15 +162,21 @@ class RootStore {
167
162
  });
168
163
  }
169
164
  catch (err) {
170
- console.error('Error while fetching data, creating new convo...', err);
165
+ console.error('Error while fetching data, creating new conversation...', err);
171
166
  yield this.createConversation();
172
167
  }
173
- yield this.fetchPreferences();
168
+ this.fetchLanguage();
174
169
  });
175
170
  }
176
171
  fetchBotInfo() {
177
172
  return __awaiter(this, void 0, void 0, function* () {
178
- const botInfo = yield this.api.fetchBotInfo();
173
+ if (!this.config.mediaFileServiceUrl) {
174
+ return;
175
+ }
176
+ const botInfo = yield this.api.fetchBotInfo(this.config.mediaFileServiceUrl);
177
+ if (!botInfo) {
178
+ return;
179
+ }
179
180
  (0, mobx_1.runInAction)('-> setBotInfo', () => {
180
181
  this.botInfo = botInfo;
181
182
  });
@@ -185,16 +186,10 @@ class RootStore {
185
186
  });
186
187
  });
187
188
  }
188
- fetchPreferences() {
189
- return __awaiter(this, void 0, void 0, function* () {
190
- // TODO: where to fetch this from? Can this just be set in the frontend?
191
- const preferences = { language: 'en' }; // await this.api.fetchPreferences()
192
- if (!preferences.language) {
193
- return;
194
- }
195
- (0, mobx_1.runInAction)('-> setPreferredLanguage', () => {
196
- this.updateBotUILanguage(preferences.language);
197
- });
189
+ fetchLanguage() {
190
+ const language = (0, translations_1.getUserLocale)(this.config.locale);
191
+ (0, mobx_1.runInAction)('-> setPreferredLanguage', () => {
192
+ this.updateBotUILanguage(language);
198
193
  });
199
194
  }
200
195
  /** Fetches the list of conversation, and update the corresponding config values */
@@ -266,18 +261,15 @@ class RootStore {
266
261
  return newId;
267
262
  });
268
263
  }
269
- setReference() {
270
- return __awaiter(this, void 0, void 0, function* () {
271
- return this.api.setReference(this.config.reference, this.currentConversationId);
272
- });
273
- }
274
264
  resetConversation() {
275
265
  this.currentConversation = undefined;
276
266
  }
277
267
  resetSession() {
278
268
  return __awaiter(this, void 0, void 0, function* () {
279
- this.composer.setLocked(false);
280
- return this.api.resetSession(this.currentConversationId);
269
+ if (this.currentConversationId) {
270
+ this.composer.setLocked(false);
271
+ return this.api.resetSession(this.currentConversationId);
272
+ }
281
273
  });
282
274
  }
283
275
  extractFeedback(messages) {
@@ -298,41 +290,62 @@ class RootStore {
298
290
  downloadConversation() {
299
291
  return __awaiter(this, void 0, void 0, function* () {
300
292
  try {
301
- const { txt, name } = yield this.api.downloadConversation(this.currentConversationId);
302
- const blobFile = new Blob([txt]);
303
- (0, utils_1.downloadFile)(name, blobFile);
293
+ const formatDate = (date) => {
294
+ return new Date(date).toLocaleString();
295
+ };
296
+ const conversation = this.currentConversation;
297
+ if (!conversation) {
298
+ console.warn('Cannot download the current conversation as it is undefined.');
299
+ return;
300
+ }
301
+ let info = `Conversation Id: ${conversation.id}\nCreated on: ${formatDate(conversation.createdOn)}\nUser: ${conversation.userId}\n-----------------`;
302
+ const messages = yield this.api.listCurrentConversationMessages(500);
303
+ for (const message of (0, orderBy_1.default)(messages, 'sentOn', 'desc')) {
304
+ const payload = message.payload;
305
+ if (payload.type === 'session_reset') {
306
+ continue;
307
+ }
308
+ info += `\n[${formatDate(message.sentOn)}] ${message.authorId ? 'User' : this.config.botId || 'Bot'}: Event (${payload.type}): ${payload.text ||
309
+ payload.audio ||
310
+ payload.image ||
311
+ payload.video ||
312
+ payload.file ||
313
+ payload.message ||
314
+ payload.title ||
315
+ ''}`;
316
+ }
317
+ const blobFile = new Blob([info]);
318
+ (0, utils_1.downloadFile)(`conversation-${conversation.id}`, blobFile);
304
319
  }
305
320
  catch (err) {
306
- console.error('Error trying to download conversation');
321
+ console.error('Error trying to download conversation', err);
307
322
  }
308
323
  });
309
324
  }
310
325
  /** Sends an event or a message, depending on how the backend manages those types */
311
326
  sendData(data) {
312
327
  return __awaiter(this, void 0, void 0, function* () {
313
- if (!this.isInitialized) {
328
+ if (!this.isInitialized || !this.currentConversationId) {
314
329
  console.warn('[webchat] Cannot send data until the webchat is ready');
315
330
  return;
316
331
  }
317
- // TODO: this can't work. We can't create events directly
318
- /*
319
- if (!constants.MESSAGE_TYPES.includes(data.type)) {
320
- return this.api.sendEvent(data, this.currentConversationId)
321
- }
322
- */
323
332
  const message = yield this.api.sendMessage(data, this.currentConversationId);
324
333
  this.updateLastMessage(this.currentConversationId, message);
325
334
  });
326
335
  }
327
336
  uploadFile(title, payload, file) {
328
337
  return __awaiter(this, void 0, void 0, function* () {
329
- yield this.api.uploadFile(file, payload, this.currentConversationId);
338
+ if (this.currentConversationId) {
339
+ yield this.api.uploadFile(file, payload, this.currentConversationId);
340
+ }
330
341
  });
331
342
  }
332
343
  /** Sends a message of type voice */
333
344
  sendVoiceMessage(voice, ext) {
334
345
  return __awaiter(this, void 0, void 0, function* () {
335
- return this.api.sendVoiceMessage(voice, ext, this.currentConversationId);
346
+ if (this.currentConversationId) {
347
+ return this.api.sendVoiceMessage(voice, ext, this.currentConversationId);
348
+ }
336
349
  });
337
350
  }
338
351
  /** Use this method to replace a value or add a new config */
@@ -346,6 +359,7 @@ class RootStore {
346
359
  this._applyConfig();
347
360
  }
348
361
  _applyConfig() {
362
+ window.BP_STORAGE.config = this.config;
349
363
  this.config.layoutWidth && this.view.setLayoutWidth(this.config.layoutWidth);
350
364
  this.config.containerWidth && this.view.setContainerWidth(this.config.containerWidth);
351
365
  this.view.disableAnimations = this.config.disableAnimations;
@@ -359,7 +373,7 @@ class RootStore {
359
373
  else if (window.USE_SESSION_STORAGE !== this.config.useSessionStorage) {
360
374
  console.warn('[WebChat] "useSessionStorage" value cannot be altered once the webchat is initialized');
361
375
  }
362
- const locale = this.config.locale ? (0, translations_1.getUserLocale)(this.config.locale) : chosenLocale;
376
+ const locale = (0, translations_1.getUserLocale)(this.config.locale);
363
377
  this.updateBotUILanguage(locale);
364
378
  document.documentElement.setAttribute('lang', locale);
365
379
  this.publishConfigChanged();
@@ -374,14 +388,9 @@ class RootStore {
374
388
  publishConfigChanged() {
375
389
  this.postMessage('configChanged', JSON.stringify(this.config, undefined, 2));
376
390
  }
377
- setMessageWrapper(messageWrapper) {
378
- this.messageWrapper = messageWrapper;
379
- }
380
391
  updatePreferredLanguage(lang) {
381
- return __awaiter(this, void 0, void 0, function* () {
382
- this.preferredLanguage = lang;
383
- yield this.api.updateUserPreferredLanguage(lang);
384
- });
392
+ this.preferredLanguage = lang;
393
+ (0, translations_1.setUserLocale)(lang);
385
394
  }
386
395
  /** Starts a timer to remove the typing animation when it's completed */
387
396
  _startTypingTimer() {
@@ -390,7 +399,8 @@ class RootStore {
390
399
  }
391
400
  this.isBotTyping.set(true);
392
401
  this._typingInterval = setInterval(() => {
393
- const typeUntil = new Date(this.currentConversation && this.currentConversation.typingUntil);
402
+ var _a;
403
+ const typeUntil = new Date((_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.typingUntil);
394
404
  if (!typeUntil || !(0, is_valid_1.default)(typeUntil) || (0, is_before_1.default)(typeUntil, new Date())) {
395
405
  this._expireTyping();
396
406
  }
@@ -402,20 +412,24 @@ class RootStore {
402
412
  _expireTyping() {
403
413
  this.emptyDelayedMessagesQueue(true);
404
414
  this.isBotTyping.set(false);
405
- this.currentConversation.typingUntil = undefined;
415
+ if (this.currentConversation) {
416
+ this.currentConversation.typingUntil = undefined;
417
+ }
406
418
  clearInterval(this._typingInterval);
407
419
  this._typingInterval = undefined;
408
420
  }
409
421
  updateBotUILanguage(lang) {
410
422
  lang = (0, translations_1.getUserLocale)(lang); // Ensure language is supported
411
423
  (0, mobx_1.runInAction)('-> setBotUILanguage', () => {
412
- var _a;
413
424
  this.botUILanguage = lang;
414
425
  this.preferredLanguage = lang;
415
- (_a = window.BP_STORAGE) === null || _a === void 0 ? void 0 : _a.set('bp/channel-web/user-lang', lang);
426
+ (0, translations_1.setUserLocale)(lang);
416
427
  });
417
428
  }
418
429
  emptyDelayedMessagesQueue(removeAll) {
430
+ if (!this.currentConversation) {
431
+ return;
432
+ }
419
433
  while (this.delayedMessages.length) {
420
434
  const message = this.delayedMessages[0];
421
435
  if (removeAll || (0, is_before_1.default)(message.showAt, new Date())) {
@@ -468,9 +482,6 @@ __decorate([
468
482
  __decorate([
469
483
  mobx_1.observable
470
484
  ], RootStore.prototype, "messageFeedbacks", void 0);
471
- __decorate([
472
- mobx_1.observable
473
- ], RootStore.prototype, "messageWrapper", void 0);
474
485
  __decorate([
475
486
  mobx_1.observable
476
487
  ], RootStore.prototype, "botUILanguage", void 0);
@@ -486,9 +497,6 @@ __decorate([
486
497
  __decorate([
487
498
  mobx_1.computed
488
499
  ], RootStore.prototype, "botName", null);
489
- __decorate([
490
- mobx_1.computed
491
- ], RootStore.prototype, "isEmulator", null);
492
500
  __decorate([
493
501
  mobx_1.computed
494
502
  ], RootStore.prototype, "hasBotInfoDescription", null);
@@ -522,9 +530,6 @@ __decorate([
522
530
  __decorate([
523
531
  mobx_1.action.bound
524
532
  ], RootStore.prototype, "deleteConversation", null);
525
- __decorate([
526
- mobx_1.action.bound
527
- ], RootStore.prototype, "loadEventInDebugger", null);
528
533
  __decorate([
529
534
  mobx_1.action.bound
530
535
  ], RootStore.prototype, "addEventToConversation", null);
@@ -539,7 +544,7 @@ __decorate([
539
544
  ], RootStore.prototype, "fetchBotInfo", null);
540
545
  __decorate([
541
546
  mobx_1.action.bound
542
- ], RootStore.prototype, "fetchPreferences", null);
547
+ ], RootStore.prototype, "fetchLanguage", null);
543
548
  __decorate([
544
549
  mobx_1.action.bound
545
550
  ], RootStore.prototype, "fetchConversations", null);
@@ -555,9 +560,6 @@ __decorate([
555
560
  __decorate([
556
561
  mobx_1.action.bound
557
562
  ], RootStore.prototype, "createConversation", null);
558
- __decorate([
559
- mobx_1.action.bound
560
- ], RootStore.prototype, "setReference", null);
561
563
  __decorate([
562
564
  mobx_1.action.bound
563
565
  ], RootStore.prototype, "resetConversation", null);
@@ -594,9 +596,6 @@ __decorate([
594
596
  __decorate([
595
597
  mobx_1.action.bound
596
598
  ], RootStore.prototype, "publishConfigChanged", null);
597
- __decorate([
598
- mobx_1.action.bound
599
- ], RootStore.prototype, "setMessageWrapper", null);
600
599
  __decorate([
601
600
  mobx_1.action.bound
602
601
  ], RootStore.prototype, "updatePreferredLanguage", null);
@@ -17,7 +17,6 @@ declare class ViewStore {
17
17
  customButtons: CustomButton[];
18
18
  customActions: CustomAction[];
19
19
  disableAnimations: boolean;
20
- highlightedMessages: string[];
21
20
  constructor(rootStore: RootStore, fullscreen: boolean);
22
21
  get showConversationsButton(): boolean;
23
22
  get showBotInfoButton(): boolean;
@@ -51,7 +50,6 @@ declare class ViewStore {
51
50
  addCustomAction(newAction: CustomAction): void;
52
51
  removeCustomAction(actionId: string): void;
53
52
  addHeaderButton(newButton: CustomButton): void;
54
- setHighlightedMessages(ids: string[]): void;
55
53
  /** Updates one or multiple properties of a specific button */
56
54
  updateHeaderButton(buttonId: string, newProps: Partial<CustomButton>): void;
57
55
  removeHeaderButton(buttonId: string): void;
@@ -26,7 +26,6 @@ class ViewStore {
26
26
  this.customButtons = [];
27
27
  this.customActions = [];
28
28
  this.disableAnimations = false;
29
- this.highlightedMessages = [];
30
29
  this.rootStore = rootStore;
31
30
  this.isFullscreen = fullscreen;
32
31
  this.activeView = fullscreen ? 'side' : 'widget';
@@ -151,9 +150,6 @@ class ViewStore {
151
150
  }
152
151
  this.customButtons.push(newButton);
153
152
  }
154
- setHighlightedMessages(ids) {
155
- this.highlightedMessages = ids;
156
- }
157
153
  /** Updates one or multiple properties of a specific button */
158
154
  updateHeaderButton(buttonId, newProps) {
159
155
  const button = this.customButtons.find((btn) => btn.id === buttonId);
@@ -260,9 +256,6 @@ __decorate([
260
256
  __decorate([
261
257
  mobx_1.observable
262
258
  ], ViewStore.prototype, "disableAnimations", void 0);
263
- __decorate([
264
- mobx_1.observable
265
- ], ViewStore.prototype, "highlightedMessages", void 0);
266
259
  __decorate([
267
260
  mobx_1.computed
268
261
  ], ViewStore.prototype, "showConversationsButton", null);
@@ -353,9 +346,6 @@ __decorate([
353
346
  __decorate([
354
347
  mobx_1.action.bound
355
348
  ], ViewStore.prototype, "addHeaderButton", null);
356
- __decorate([
357
- mobx_1.action.bound
358
- ], ViewStore.prototype, "setHighlightedMessages", null);
359
349
  __decorate([
360
350
  mobx_1.action.bound
361
351
  ], ViewStore.prototype, "updateHeaderButton", null);
@@ -4,4 +4,5 @@ declare const translations: {
4
4
  [lang: string]: any;
5
5
  };
6
6
  declare const getUserLocale: (manualLocale?: Locale) => string;
7
- export { translations, DEFAULT_LOCALE as defaultLocale, getUserLocale };
7
+ declare const setUserLocale: (locale: Locale) => void;
8
+ export { translations, DEFAULT_LOCALE as defaultLocale, getUserLocale, setUserLocale };
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getUserLocale = exports.defaultLocale = exports.translations = void 0;
6
+ exports.setUserLocale = exports.getUserLocale = exports.defaultLocale = exports.translations = void 0;
7
7
  require('@formatjs/intl-pluralrules/polyfill');
8
8
  require('@formatjs/intl-pluralrules/locale-data/ar');
9
9
  require('@formatjs/intl-pluralrules/locale-data/de');
@@ -25,19 +25,20 @@ const ru_json_1 = __importDefault(require("./ru.json"));
25
25
  const uk_json_1 = __importDefault(require("./uk.json"));
26
26
  const DEFAULT_LOCALE = 'en';
27
27
  exports.defaultLocale = DEFAULT_LOCALE;
28
- const STORAGE_KEY = 'bp/channel-web/user-lang';
28
+ const USER_LANG_STORAGE_KEY = 'user-lang';
29
29
  const translations = { en: en_json_1.default, fr: fr_json_1.default, pt: pt_json_1.default, es: es_json_1.default, ar: ar_json_1.default, ru: ru_json_1.default, uk: uk_json_1.default, de: de_json_1.default, it: it_json_1.default };
30
30
  exports.translations = translations;
31
31
  const cleanLanguageCode = (str) => str.split('-')[0];
32
32
  const getNavigatorLanguage = () => cleanLanguageCode(navigator.language || navigator['userLanguage'] || '');
33
- const getStorageLanguage = () => { var _a; return cleanLanguageCode(((_a = window.BP_STORAGE) === null || _a === void 0 ? void 0 : _a.get(STORAGE_KEY)) || ''); };
33
+ const getStorageLanguage = () => cleanLanguageCode(window.BP_STORAGE.get(USER_LANG_STORAGE_KEY) || '');
34
+ const setStorageLanguage = (locale) => window.BP_STORAGE.set(USER_LANG_STORAGE_KEY, locale);
34
35
  // Desired precedence
35
36
  // 1- manual locale = 'browser' : browser lang
36
37
  // 2- manual locale is supported : manual lang
37
38
  // 3- storage lang is supported : storage lang
38
39
  // 4- browser lang is supported : browser lang
39
40
  // 5- default lang
40
- const getUserLocale = (manualLocale = 'browser') => {
41
+ const getUserLocale = (manualLocale = '') => {
41
42
  const browserLocale = getNavigatorLanguage();
42
43
  if (manualLocale === 'browser' && translations[browserLocale]) {
43
44
  return browserLocale;
@@ -53,3 +54,7 @@ const getUserLocale = (manualLocale = 'browser') => {
53
54
  return translations[browserLocale] ? browserLocale : DEFAULT_LOCALE;
54
55
  };
55
56
  exports.getUserLocale = getUserLocale;
57
+ const setUserLocale = (locale) => {
58
+ setStorageLanguage(locale);
59
+ };
60
+ exports.setUserLocale = setUserLocale;
package/dist/typings.d.ts CHANGED
@@ -1,22 +1,17 @@
1
1
  /// <reference types="react" />
2
2
  import { RootStore } from './store';
3
+ import { BPStorage } from './utils/storage';
3
4
  declare global {
4
5
  interface Window {
5
6
  __BP_VISITOR_SOCKET_ID: string;
6
7
  __BP_VISITOR_ID: string;
7
8
  botpressWebChat: any;
8
9
  store: RootStore;
9
- BOT_API_PATH: string;
10
- API_PATH: string;
11
- BOTPRESS_VERSION: string;
12
- BOT_NAME: string;
13
- ROOT_PATH: string;
14
10
  BOT_ID: string;
15
- BP_BASE_PATH: string;
16
11
  SEND_USAGE_STATS: boolean;
17
12
  SHOW_POWERED_BY: boolean;
18
13
  USE_SESSION_STORAGE: boolean;
19
- BP_STORAGE: any;
14
+ BP_STORAGE: BPStorage;
20
15
  botpress: {
21
16
  [moduleName: string]: any;
22
17
  };
@@ -35,7 +30,6 @@ export declare namespace Renderer {
35
30
  noBubble?: boolean;
36
31
  keyboard?: any;
37
32
  eventId?: string;
38
- isHighlighted?: boolean;
39
33
  isLastGroup?: boolean;
40
34
  isLastOfGroup?: boolean;
41
35
  isBotMessage?: boolean;
@@ -145,6 +139,8 @@ export interface StudioConnector {
145
139
  export interface Config {
146
140
  /** Url of the messaging server */
147
141
  messagingUrl: string;
142
+ /** Url of the Media File Service where we fetch the bot info */
143
+ mediaFileServiceUrl?: string;
148
144
  /** Id of your messaging client */
149
145
  clientId: string;
150
146
  botId?: string;
@@ -155,7 +151,6 @@ export interface Config {
155
151
  userIdScope?: string;
156
152
  enableReset: boolean;
157
153
  stylesheet?: string;
158
- isEmulator?: boolean;
159
154
  extraStylesheet?: string;
160
155
  showConversationsButton: boolean;
161
156
  showUserName: boolean;
@@ -196,8 +191,6 @@ export interface Config {
196
191
  enablePersistHistory: boolean;
197
192
  /** Experimental: expose the store to the parent frame for more control on the webchat's behavior */
198
193
  exposeStore: boolean;
199
- /** Reference ensures that a specific value and its signature are valid */
200
- reference?: string;
201
194
  /** If true, Websocket is created when the Webchat is opened. Bot cannot be proactive. */
202
195
  lazySocket?: boolean;
203
196
  /** If true, chat will no longer play the notification sound for new messages. */
@@ -206,6 +199,8 @@ export interface Config {
206
199
  chatId?: string;
207
200
  /** CSS class to be applied to iframe */
208
201
  className?: string;
202
+ /** Key used to encrypt data in the localStorage */
203
+ encryptionKey?: string;
209
204
  }
210
205
  export declare type OverridableComponents = 'below_conversation' | 'before_container' | 'composer';
211
206
  export interface Overrides {
@@ -234,6 +229,8 @@ export interface BotInfo {
234
229
  escapeHTML: boolean;
235
230
  };
236
231
  lazySocket: boolean;
232
+ extraStylesheet?: string;
233
+ disableNotificationSound?: boolean;
237
234
  }
238
235
  export declare type uuid = string;
239
236
  export interface Conversation {
@@ -296,13 +293,6 @@ export interface CustomAction {
296
293
  /** The event triggered when the action is clicked */
297
294
  onClick: (actionId: string, messageProps: any, event: React.MouseEvent) => void;
298
295
  }
299
- /** When set, this will wrap every messages displayed in the webchat */
300
- export interface MessageWrapper {
301
- /** The name of the module hosting the component */
302
- module: string;
303
- /** Name of the component exposed by the module */
304
- component: string;
305
- }
306
296
  export interface EventFeedback {
307
297
  messageId: uuid;
308
298
  feedback?: number;
@@ -0,0 +1,16 @@
1
+ import { Config } from '../typings';
2
+ export declare class BPStorage {
3
+ private _config?;
4
+ private _storage;
5
+ constructor(config?: Config);
6
+ get config(): Config | undefined;
7
+ set config(config: Config | undefined);
8
+ private serialize;
9
+ private deserialize;
10
+ private getStorageKey;
11
+ private getDriver;
12
+ set<T>(key: string, value: T): void;
13
+ get<T = string>(key: string): T | undefined;
14
+ del(key: string): void;
15
+ }
16
+ export default BPStorage;