@botpress/webchat 0.2.3 → 0.2.4

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/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 +4 -13
  31. package/dist/core/api.js +29 -130
  32. package/dist/core/socket.d.ts +0 -5
  33. package/dist/core/socket.js +2 -45
  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.d.ts +1 -1
  39. package/dist/index.js +7 -0
  40. package/dist/main.d.ts +1 -1
  41. package/dist/main.js +20 -37
  42. package/dist/store/composer.js +3 -6
  43. package/dist/store/index.d.ts +6 -12
  44. package/dist/store/index.js +74 -89
  45. package/dist/store/view.d.ts +0 -2
  46. package/dist/store/view.js +0 -10
  47. package/dist/translations/index.d.ts +2 -1
  48. package/dist/translations/index.js +9 -4
  49. package/dist/typings.d.ts +6 -18
  50. package/dist/utils/storage.d.ts +17 -0
  51. package/dist/utils/storage.js +117 -0
  52. package/dist/utils.js +1 -1
  53. package/package.json +4 -2
  54. package/dist/components/common/BotInfo.js +0 -110
@@ -1,7 +1,7 @@
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, MessageWrapper, QueuedMessage, RecentConversation, StudioConnector, uuid } from '../typings';
4
+ import { BotInfo, Config, CurrentConversation, EventFeedback, Message, QueuedMessage, RecentConversation, StudioConnector, uuid } from '../typings';
5
5
  import ComposerStore from './composer';
6
6
  import ViewStore from './view';
7
7
  /** Includes the partial definitions of all classes */
@@ -12,7 +12,7 @@ declare class RootStore {
12
12
  private _typingInterval;
13
13
  private api;
14
14
  conversations: RecentConversation[];
15
- currentConversation: CurrentConversation;
15
+ currentConversation?: CurrentConversation;
16
16
  botInfo: BotInfo;
17
17
  config: Config;
18
18
  preferredLanguage: string;
@@ -20,36 +20,32 @@ declare class RootStore {
20
20
  messageFeedbacks: EventFeedback[];
21
21
  intl: IntlShape;
22
22
  isBotTyping: import("mobx").IObservableValue<boolean>;
23
- /** When a wrapper is defined, every messages are wrapped by the specified component */
24
- messageWrapper: MessageWrapper | undefined;
25
23
  botUILanguage: string;
26
24
  delayedMessages: QueuedMessage[];
27
25
  constructor(options: {
28
26
  fullscreen: boolean;
29
- }, config?: Config);
27
+ }, config: Config);
30
28
  setIntlProvider(provider: IntlShape): void;
31
29
  setSocket(socket: BpSocket): void;
32
30
  get isConversationStarted(): boolean;
33
31
  get botName(): string;
34
- get isEmulator(): boolean;
35
32
  get hasBotInfoDescription(): boolean;
36
33
  get botAvatarUrl(): string | undefined;
37
34
  get rtl(): boolean;
38
35
  get escapeHTML(): boolean;
39
36
  get currentMessages(): Message[];
40
- get currentConversationId(): uuid;
37
+ get currentConversationId(): uuid | undefined;
41
38
  postMessage(name: string, payload?: any): void;
42
39
  updateMessages(messages: Message[]): void;
43
40
  updateLastMessage(conversationId: string, message?: Message): void;
44
41
  clearMessages(): void;
45
42
  deleteConversation(): Promise<void>;
46
- loadEventInDebugger(messageId: uuid, isManual?: boolean): Promise<void>;
47
43
  addEventToConversation(event: Message): Promise<void>;
48
44
  updateTyping(event: Message): Promise<void>;
49
45
  /** Loads the initial state, for the first time or when the user ID is changed. */
50
46
  initializeChat(): Promise<void>;
51
47
  fetchBotInfo(): Promise<void>;
52
- fetchPreferences(): Promise<void>;
48
+ fetchLanguage(): void;
53
49
  /** Fetches the list of conversation, and update the corresponding config values */
54
50
  fetchConversations(): Promise<void>;
55
51
  /** Fetch the specified conversation ID, or try to fetch a valid one from the list */
@@ -60,7 +56,6 @@ declare class RootStore {
60
56
  startConversation(): Promise<void>;
61
57
  /** Creates a new conversation and switches to it */
62
58
  createConversation(): Promise<uuid>;
63
- setReference(): Promise<void>;
64
59
  resetConversation(): void;
65
60
  resetSession(): Promise<void>;
66
61
  extractFeedback(messages: Message[]): Promise<void>;
@@ -79,8 +74,7 @@ declare class RootStore {
79
74
  /** When this method is used, the user ID is changed in the configuration, then the socket is updated */
80
75
  setUserId(userId: string): void;
81
76
  publishConfigChanged(): void;
82
- setMessageWrapper(messageWrapper: MessageWrapper): void;
83
- updatePreferredLanguage(lang: string): Promise<void>;
77
+ updatePreferredLanguage(lang: string): void;
84
78
  /** Starts a timer to remove the typing animation when it's completed */
85
79
  private _startTypingTimer;
86
80
  private _expireTyping;
@@ -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,15 @@ 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
- if (config) {
42
- this.updateConfig(config);
43
- }
40
+ this.updateConfig(config);
41
+ this.botUILanguage = (0, translations_1.getUserLocale)();
44
42
  }
45
43
  setIntlProvider(provider) {
46
44
  this.intl = provider;
@@ -53,12 +51,8 @@ class RootStore {
53
51
  return !!((_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.messages.length);
54
52
  }
55
53
  get botName() {
56
- var _a, _b;
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
- }
59
- get isEmulator() {
60
54
  var _a;
61
- return ((_a = this.config) === null || _a === void 0 ? void 0 : _a.isEmulator) || false;
55
+ return this.config.botName || ((_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.name) || 'Bot';
62
56
  }
63
57
  get hasBotInfoDescription() {
64
58
  var _a;
@@ -77,7 +71,7 @@ class RootStore {
77
71
  }
78
72
  get currentMessages() {
79
73
  var _a;
80
- return (_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.messages;
74
+ return ((_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.messages) || [];
81
75
  }
82
76
  get currentConversationId() {
83
77
  var _a;
@@ -88,7 +82,9 @@ class RootStore {
88
82
  window.parent.postMessage({ name, chatId, payload }, '*');
89
83
  }
90
84
  updateMessages(messages) {
91
- this.currentConversation.messages = messages;
85
+ if (this.currentConversation) {
86
+ this.currentConversation.messages = messages;
87
+ }
92
88
  }
93
89
  updateLastMessage(conversationId, message) {
94
90
  for (const conversation of this.conversations) {
@@ -99,30 +95,27 @@ class RootStore {
99
95
  }
100
96
  }
101
97
  clearMessages() {
102
- this.currentConversation.messages = [];
98
+ if (this.currentConversation) {
99
+ this.currentConversation.messages = [];
100
+ }
103
101
  }
104
102
  deleteConversation() {
105
103
  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;
104
+ if (this.currentConversationId) {
105
+ yield this.api.deleteConversation(this.currentConversationId);
106
+ const index = this.conversations.findIndex((c) => c.id === this.currentConversationId);
107
+ if (index > -1) {
108
+ this.conversations.splice(index, 1);
109
+ }
110
+ this.resetConversation();
111
+ yield this.fetchConversation();
116
112
  }
117
- const messages = yield this.api.listByIncomingEvent(messageId);
118
- this.view.setHighlightedMessages(messages);
119
- window.parent.postMessage({ action: 'load-event', payload: { messageId, isManual } }, '*');
120
113
  });
121
114
  }
122
115
  addEventToConversation(event) {
123
116
  var _a;
124
117
  return __awaiter(this, void 0, void 0, function* () {
125
- if (this.isInitialized && this.currentConversationId !== event.conversationId) {
118
+ if (!this.currentConversation || (this.isInitialized && this.currentConversationId !== event.conversationId)) {
126
119
  yield this.fetchConversations();
127
120
  yield this.fetchConversation(event.conversationId);
128
121
  return;
@@ -142,7 +135,7 @@ class RootStore {
142
135
  }
143
136
  updateTyping(event) {
144
137
  return __awaiter(this, void 0, void 0, function* () {
145
- if (this.isInitialized && this.currentConversationId !== event.conversationId) {
138
+ if (!this.currentConversation || (this.isInitialized && this.currentConversationId !== event.conversationId)) {
146
139
  yield this.fetchConversations();
147
140
  yield this.fetchConversation(event.conversationId);
148
141
  return;
@@ -167,15 +160,21 @@ class RootStore {
167
160
  });
168
161
  }
169
162
  catch (err) {
170
- console.error('Error while fetching data, creating new convo...', err);
163
+ console.error('Error while fetching data, creating new conversation...', err);
171
164
  yield this.createConversation();
172
165
  }
173
- yield this.fetchPreferences();
166
+ this.fetchLanguage();
174
167
  });
175
168
  }
176
169
  fetchBotInfo() {
177
170
  return __awaiter(this, void 0, void 0, function* () {
178
- const botInfo = yield this.api.fetchBotInfo();
171
+ if (!this.config.mediaFileServiceUrl) {
172
+ return;
173
+ }
174
+ const botInfo = yield this.api.fetchBotInfo(this.config.mediaFileServiceUrl);
175
+ if (!botInfo) {
176
+ return;
177
+ }
179
178
  (0, mobx_1.runInAction)('-> setBotInfo', () => {
180
179
  this.botInfo = botInfo;
181
180
  });
@@ -185,16 +184,10 @@ class RootStore {
185
184
  });
186
185
  });
187
186
  }
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
- });
187
+ fetchLanguage() {
188
+ const language = (0, translations_1.getUserLocale)(this.config.locale);
189
+ (0, mobx_1.runInAction)('-> setPreferredLanguage', () => {
190
+ this.updateBotUILanguage(language);
198
191
  });
199
192
  }
200
193
  /** Fetches the list of conversation, and update the corresponding config values */
@@ -266,18 +259,15 @@ class RootStore {
266
259
  return newId;
267
260
  });
268
261
  }
269
- setReference() {
270
- return __awaiter(this, void 0, void 0, function* () {
271
- return this.api.setReference(this.config.reference, this.currentConversationId);
272
- });
273
- }
274
262
  resetConversation() {
275
263
  this.currentConversation = undefined;
276
264
  }
277
265
  resetSession() {
278
266
  return __awaiter(this, void 0, void 0, function* () {
279
- this.composer.setLocked(false);
280
- return this.api.resetSession(this.currentConversationId);
267
+ if (this.currentConversationId) {
268
+ this.composer.setLocked(false);
269
+ return this.api.resetSession(this.currentConversationId);
270
+ }
281
271
  });
282
272
  }
283
273
  extractFeedback(messages) {
@@ -298,41 +288,50 @@ class RootStore {
298
288
  downloadConversation() {
299
289
  return __awaiter(this, void 0, void 0, function* () {
300
290
  try {
301
- const { txt, name } = yield this.api.downloadConversation(this.currentConversationId);
302
- const blobFile = new Blob([txt]);
303
- (0, utils_1.downloadFile)(name, blobFile);
291
+ const formatDate = (date) => {
292
+ return new Date(date).toLocaleString();
293
+ };
294
+ const conversation = this.currentConversation;
295
+ if (!conversation) {
296
+ console.warn('Cannot download the current conversation as it is undefined.');
297
+ return;
298
+ }
299
+ let info = `Conversation Id: ${conversation.id}\nCreated on: ${formatDate(conversation.createdOn)}\nUser: ${conversation.userId}\n-----------------`;
300
+ for (const message of (0, orderBy_1.default)(conversation.messages, 'sentOn', 'desc')) {
301
+ info += `\n[${formatDate(message.sentOn)}] ${message.authorId ? 'User' : this.config.botId || 'Bot'}: ${message.payload.text}`;
302
+ }
303
+ const blobFile = new Blob([info]);
304
+ (0, utils_1.downloadFile)(`conversation-${conversation.id}`, blobFile);
304
305
  }
305
306
  catch (err) {
306
- console.error('Error trying to download conversation');
307
+ console.error('Error trying to download conversation', err);
307
308
  }
308
309
  });
309
310
  }
310
311
  /** Sends an event or a message, depending on how the backend manages those types */
311
312
  sendData(data) {
312
313
  return __awaiter(this, void 0, void 0, function* () {
313
- if (!this.isInitialized) {
314
+ if (!this.isInitialized || !this.currentConversationId) {
314
315
  console.warn('[webchat] Cannot send data until the webchat is ready');
315
316
  return;
316
317
  }
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
318
  const message = yield this.api.sendMessage(data, this.currentConversationId);
324
319
  this.updateLastMessage(this.currentConversationId, message);
325
320
  });
326
321
  }
327
322
  uploadFile(title, payload, file) {
328
323
  return __awaiter(this, void 0, void 0, function* () {
329
- yield this.api.uploadFile(file, payload, this.currentConversationId);
324
+ if (this.currentConversationId) {
325
+ yield this.api.uploadFile(file, payload, this.currentConversationId);
326
+ }
330
327
  });
331
328
  }
332
329
  /** Sends a message of type voice */
333
330
  sendVoiceMessage(voice, ext) {
334
331
  return __awaiter(this, void 0, void 0, function* () {
335
- return this.api.sendVoiceMessage(voice, ext, this.currentConversationId);
332
+ if (this.currentConversationId) {
333
+ return this.api.sendVoiceMessage(voice, ext, this.currentConversationId);
334
+ }
336
335
  });
337
336
  }
338
337
  /** Use this method to replace a value or add a new config */
@@ -346,6 +345,7 @@ class RootStore {
346
345
  this._applyConfig();
347
346
  }
348
347
  _applyConfig() {
348
+ window.BP_STORAGE.config = this.config;
349
349
  this.config.layoutWidth && this.view.setLayoutWidth(this.config.layoutWidth);
350
350
  this.config.containerWidth && this.view.setContainerWidth(this.config.containerWidth);
351
351
  this.view.disableAnimations = this.config.disableAnimations;
@@ -359,7 +359,7 @@ class RootStore {
359
359
  else if (window.USE_SESSION_STORAGE !== this.config.useSessionStorage) {
360
360
  console.warn('[WebChat] "useSessionStorage" value cannot be altered once the webchat is initialized');
361
361
  }
362
- const locale = this.config.locale ? (0, translations_1.getUserLocale)(this.config.locale) : chosenLocale;
362
+ const locale = (0, translations_1.getUserLocale)(this.config.locale);
363
363
  this.updateBotUILanguage(locale);
364
364
  document.documentElement.setAttribute('lang', locale);
365
365
  this.publishConfigChanged();
@@ -374,14 +374,9 @@ class RootStore {
374
374
  publishConfigChanged() {
375
375
  this.postMessage('configChanged', JSON.stringify(this.config, undefined, 2));
376
376
  }
377
- setMessageWrapper(messageWrapper) {
378
- this.messageWrapper = messageWrapper;
379
- }
380
377
  updatePreferredLanguage(lang) {
381
- return __awaiter(this, void 0, void 0, function* () {
382
- this.preferredLanguage = lang;
383
- yield this.api.updateUserPreferredLanguage(lang);
384
- });
378
+ this.preferredLanguage = lang;
379
+ (0, translations_1.setUserLocale)(lang);
385
380
  }
386
381
  /** Starts a timer to remove the typing animation when it's completed */
387
382
  _startTypingTimer() {
@@ -390,7 +385,8 @@ class RootStore {
390
385
  }
391
386
  this.isBotTyping.set(true);
392
387
  this._typingInterval = setInterval(() => {
393
- const typeUntil = new Date(this.currentConversation && this.currentConversation.typingUntil);
388
+ var _a;
389
+ const typeUntil = new Date((_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.typingUntil);
394
390
  if (!typeUntil || !(0, is_valid_1.default)(typeUntil) || (0, is_before_1.default)(typeUntil, new Date())) {
395
391
  this._expireTyping();
396
392
  }
@@ -402,20 +398,24 @@ class RootStore {
402
398
  _expireTyping() {
403
399
  this.emptyDelayedMessagesQueue(true);
404
400
  this.isBotTyping.set(false);
405
- this.currentConversation.typingUntil = undefined;
401
+ if (this.currentConversation) {
402
+ this.currentConversation.typingUntil = undefined;
403
+ }
406
404
  clearInterval(this._typingInterval);
407
405
  this._typingInterval = undefined;
408
406
  }
409
407
  updateBotUILanguage(lang) {
410
408
  lang = (0, translations_1.getUserLocale)(lang); // Ensure language is supported
411
409
  (0, mobx_1.runInAction)('-> setBotUILanguage', () => {
412
- var _a;
413
410
  this.botUILanguage = lang;
414
411
  this.preferredLanguage = lang;
415
- (_a = window.BP_STORAGE) === null || _a === void 0 ? void 0 : _a.set('bp/channel-web/user-lang', lang);
412
+ (0, translations_1.setUserLocale)(lang);
416
413
  });
417
414
  }
418
415
  emptyDelayedMessagesQueue(removeAll) {
416
+ if (!this.currentConversation) {
417
+ return;
418
+ }
419
419
  while (this.delayedMessages.length) {
420
420
  const message = this.delayedMessages[0];
421
421
  if (removeAll || (0, is_before_1.default)(message.showAt, new Date())) {
@@ -468,9 +468,6 @@ __decorate([
468
468
  __decorate([
469
469
  mobx_1.observable
470
470
  ], RootStore.prototype, "messageFeedbacks", void 0);
471
- __decorate([
472
- mobx_1.observable
473
- ], RootStore.prototype, "messageWrapper", void 0);
474
471
  __decorate([
475
472
  mobx_1.observable
476
473
  ], RootStore.prototype, "botUILanguage", void 0);
@@ -486,9 +483,6 @@ __decorate([
486
483
  __decorate([
487
484
  mobx_1.computed
488
485
  ], RootStore.prototype, "botName", null);
489
- __decorate([
490
- mobx_1.computed
491
- ], RootStore.prototype, "isEmulator", null);
492
486
  __decorate([
493
487
  mobx_1.computed
494
488
  ], RootStore.prototype, "hasBotInfoDescription", null);
@@ -522,9 +516,6 @@ __decorate([
522
516
  __decorate([
523
517
  mobx_1.action.bound
524
518
  ], RootStore.prototype, "deleteConversation", null);
525
- __decorate([
526
- mobx_1.action.bound
527
- ], RootStore.prototype, "loadEventInDebugger", null);
528
519
  __decorate([
529
520
  mobx_1.action.bound
530
521
  ], RootStore.prototype, "addEventToConversation", null);
@@ -539,7 +530,7 @@ __decorate([
539
530
  ], RootStore.prototype, "fetchBotInfo", null);
540
531
  __decorate([
541
532
  mobx_1.action.bound
542
- ], RootStore.prototype, "fetchPreferences", null);
533
+ ], RootStore.prototype, "fetchLanguage", null);
543
534
  __decorate([
544
535
  mobx_1.action.bound
545
536
  ], RootStore.prototype, "fetchConversations", null);
@@ -555,9 +546,6 @@ __decorate([
555
546
  __decorate([
556
547
  mobx_1.action.bound
557
548
  ], RootStore.prototype, "createConversation", null);
558
- __decorate([
559
- mobx_1.action.bound
560
- ], RootStore.prototype, "setReference", null);
561
549
  __decorate([
562
550
  mobx_1.action.bound
563
551
  ], RootStore.prototype, "resetConversation", null);
@@ -594,9 +582,6 @@ __decorate([
594
582
  __decorate([
595
583
  mobx_1.action.bound
596
584
  ], RootStore.prototype, "publishConfigChanged", null);
597
- __decorate([
598
- mobx_1.action.bound
599
- ], RootStore.prototype, "setMessageWrapper", null);
600
585
  __decorate([
601
586
  mobx_1.action.bound
602
587
  ], 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. */
@@ -236,6 +229,8 @@ export interface BotInfo {
236
229
  escapeHTML: boolean;
237
230
  };
238
231
  lazySocket: boolean;
232
+ extraStylesheet?: string;
233
+ disableNotificationSound?: boolean;
239
234
  }
240
235
  export declare type uuid = string;
241
236
  export interface Conversation {
@@ -298,13 +293,6 @@ export interface CustomAction {
298
293
  /** The event triggered when the action is clicked */
299
294
  onClick: (actionId: string, messageProps: any, event: React.MouseEvent) => void;
300
295
  }
301
- /** When set, this will wrap every messages displayed in the webchat */
302
- export interface MessageWrapper {
303
- /** The name of the module hosting the component */
304
- module: string;
305
- /** Name of the component exposed by the module */
306
- component: string;
307
- }
308
296
  export interface EventFeedback {
309
297
  messageId: uuid;
310
298
  feedback?: number;
@@ -0,0 +1,17 @@
1
+ import { Config } from '../typings';
2
+ export declare type StorageConfig = Pick<Config, 'clientId' | 'encryptionKey' | 'useSessionStorage'>;
3
+ export declare class BPStorage {
4
+ private _config;
5
+ private _storage;
6
+ constructor(config: StorageConfig);
7
+ get config(): Partial<StorageConfig>;
8
+ set config(config: Partial<StorageConfig>);
9
+ private serialize;
10
+ private deserialize;
11
+ private getStorageKey;
12
+ private getDriver;
13
+ set<T>(key: string, value: T): void;
14
+ get<T = string>(key: string): T | undefined;
15
+ del(key: string): void;
16
+ }
17
+ export default BPStorage;