@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
package/dist/core/api.js CHANGED
@@ -12,30 +12,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- const get_1 = __importDefault(require("lodash/get"));
15
+ const axios_1 = __importDefault(require("axios"));
16
16
  const uuid_1 = require("uuid");
17
17
  class WebchatApi {
18
18
  constructor(socket) {
19
19
  this.socket = socket;
20
- this.handleApiError = (error) => __awaiter(this, void 0, void 0, function* () {
21
- // @deprecated 11.9 (replace with proper error management)
22
- const data = (0, get_1.default)(error, 'response.data', {});
23
- if (data && typeof data === 'string' && data.includes('BP_CONV_NOT_FOUND')) {
24
- console.error('Conversation not found, starting a new one...');
25
- yield this.createConversation();
26
- yield this.startConversation();
27
- }
28
- });
29
20
  }
30
- get baseUserPayload() {
31
- return {
32
- webSessionId: window.__BP_VISITOR_SOCKET_ID
33
- };
34
- }
35
- fetchBotInfo() {
21
+ fetchBotInfo(mediaFileServiceUrl) {
36
22
  return __awaiter(this, void 0, void 0, function* () {
37
23
  try {
38
- const { data } = yield this.axios.get('/botInfo', this.axiosConfig);
24
+ const { data } = yield axios_1.default.get(mediaFileServiceUrl);
39
25
  return data;
40
26
  }
41
27
  catch (err) {
@@ -43,44 +29,29 @@ class WebchatApi {
43
29
  }
44
30
  });
45
31
  }
46
- fetchPreferences() {
32
+ listCurrentConversationMessages(limit) {
47
33
  return __awaiter(this, void 0, void 0, function* () {
48
- try {
49
- const { data } = yield this.axios.post('/preferences/get', this.baseUserPayload, this.axiosConfig);
50
- return data;
51
- }
52
- catch (err) {
53
- console.error('Error while fetching preferences', err);
54
- }
55
- });
56
- }
57
- updateUserPreferredLanguage(language) {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- try {
60
- yield this.axios.post('/preferences', Object.assign(Object.assign({}, this.baseUserPayload), { language }), this.axiosConfig);
61
- }
62
- catch (err) {
63
- console.error('Error in updating user preferred language', err);
64
- }
34
+ return this.socket.socket.listMessages(limit);
65
35
  });
66
36
  }
67
37
  fetchConversations() {
68
38
  return __awaiter(this, void 0, void 0, function* () {
69
39
  try {
70
- const convos = (yield this.socket.socket.listConversations());
40
+ const conversations = (yield this.socket.socket.listConversations());
71
41
  // Add the last message of each conversation
72
- for (const convo of convos) {
42
+ for (const conversation of conversations) {
73
43
  const limit = 1;
74
- yield this.socket.socket.switchConversation(convo.id);
75
- const lastMessages = yield this.socket.socket.listMessages(limit);
44
+ yield this.socket.socket.switchConversation(conversation.id);
45
+ const lastMessages = yield this.listCurrentConversationMessages(limit);
76
46
  if (lastMessages.length >= limit) {
77
- convo.lastMessage = lastMessages[0];
47
+ conversation.lastMessage = lastMessages[0];
78
48
  }
79
49
  }
80
- return convos;
50
+ return conversations;
81
51
  }
82
52
  catch (err) {
83
- console.error('Error while fetching convos', err);
53
+ console.error('Error while fetching users conversations', err);
54
+ return [];
84
55
  }
85
56
  });
86
57
  }
@@ -93,14 +64,14 @@ class WebchatApi {
93
64
  return Object.assign(Object.assign({}, conversation), { messages });
94
65
  }
95
66
  catch (err) {
96
- yield this.handleApiError(err);
67
+ console.error('Error fetching a conversation', err);
97
68
  }
98
69
  });
99
70
  }
71
+ // TODO: Fis this
100
72
  resetSession(conversationId) {
101
73
  return __awaiter(this, void 0, void 0, function* () {
102
74
  try {
103
- yield this.axios.post('/conversations/reset', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId }), this.axiosConfig);
104
75
  }
105
76
  catch (err) {
106
77
  console.error('Error while resetting conversation', err);
@@ -114,7 +85,7 @@ class WebchatApi {
114
85
  return conversation.id;
115
86
  }
116
87
  catch (err) {
117
- console.error('Error in create conversation', err);
88
+ console.error('Error creating conversation', err);
118
89
  }
119
90
  });
120
91
  }
@@ -124,118 +95,50 @@ class WebchatApi {
124
95
  yield this.socket.socket.startConversation();
125
96
  }
126
97
  catch (err) {
127
- console.error('Error in start conversation', err);
98
+ console.error('Error starting conversation', err);
128
99
  }
129
100
  });
130
101
  }
131
- downloadConversation(conversationId) {
132
- return __awaiter(this, void 0, void 0, function* () {
133
- try {
134
- const { data } = yield this.axios.post('/conversations/download/txt', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId }), this.axiosConfig);
135
- return { name: data.name, txt: data.txt };
136
- }
137
- catch (err) {
138
- console.error('Error in download conversation', err);
139
- }
140
- });
141
- }
142
- // TODO: we don't have a /events route available for this
143
- /*
144
- async sendEvent(payload: any, conversationId: uuid): Promise<void> {
145
- try {
146
- return this.axios.post('/events', { ...this.baseUserPayload, conversationId, payload }, this.axiosConfig)
147
- } catch (err) {
148
- await this.handleApiError(err)
149
- }
150
- }
151
- */
152
102
  sendMessage(payload, conversationId) {
153
103
  return __awaiter(this, void 0, void 0, function* () {
154
104
  try {
155
105
  return this.socket.sendPayload(payload);
156
106
  }
157
107
  catch (err) {
158
- yield this.handleApiError(err);
108
+ console.error('Error sending message', err);
159
109
  }
160
110
  });
161
111
  }
162
- deleteMessages(conversationId) {
112
+ deleteConversation(conversationId) {
163
113
  return __awaiter(this, void 0, void 0, function* () {
164
114
  try {
165
- yield this.axios.post('/conversations/messages/delete', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId }), this.axiosConfig);
115
+ yield this.socket.socket.deleteConversation(conversationId);
166
116
  }
167
117
  catch (err) {
168
- yield this.handleApiError(err);
118
+ console.error('Error deleting conversation', err);
169
119
  }
170
120
  });
171
121
  }
172
122
  sendFeedback(feedback, messageId) {
173
123
  return __awaiter(this, void 0, void 0, function* () {
174
- try {
175
- return this.socket.socket.sendFeedback(messageId, feedback);
176
- }
177
- catch (err) {
178
- yield this.handleApiError(err);
179
- }
180
- });
181
- }
182
- getMessageIdsFeedbackInfo(messageIds) {
183
- return __awaiter(this, void 0, void 0, function* () {
184
- try {
185
- const { data } = yield this.axios.post('/feedbackInfo', { messageIds, target: this.userId }, this.axiosConfig);
186
- return data;
187
- }
188
- catch (err) {
189
- yield this.handleApiError(err);
190
- }
124
+ return this.socket.socket.sendFeedback(messageId, feedback);
191
125
  });
192
126
  }
193
127
  uploadFile(file, payload, conversationId) {
194
128
  return __awaiter(this, void 0, void 0, function* () {
195
- try {
196
- const data = new FormData();
197
- data.append('file', file);
198
- data.append('webSessionId', this.baseUserPayload.webSessionId);
199
- data.append('conversationId', conversationId);
200
- data.append('payload', payload);
201
- return this.axios.post('/messages/files', data, this.axiosConfig);
202
- }
203
- catch (err) {
204
- yield this.handleApiError(err);
205
- }
129
+ const data = new FormData();
130
+ data.append('file', file);
131
+ data.append('conversationId', conversationId);
132
+ data.append('payload', payload);
206
133
  });
207
134
  }
135
+ // TODO: Fix this
208
136
  sendVoiceMessage(voice, ext, conversationId) {
209
137
  return __awaiter(this, void 0, void 0, function* () {
210
- try {
211
- const audio = {
212
- buffer: voice.toString('base64'),
213
- title: `${(0, uuid_1.v4)()}.${ext}`
214
- };
215
- return this.axios.post('/messages/voice', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId, audio }), this.axiosConfig);
216
- }
217
- catch (err) {
218
- yield this.handleApiError(err);
219
- }
220
- });
221
- }
222
- setReference(reference, conversationId) {
223
- return __awaiter(this, void 0, void 0, function* () {
224
- // TODO: this can't work. We don't have a reference route
225
- try {
226
- return this.axios.post('/conversations/reference', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId, reference }), this.axiosConfig);
227
- }
228
- catch (err) {
229
- yield this.handleApiError(err);
230
- }
231
- });
232
- }
233
- listByIncomingEvent(messageId) {
234
- return __awaiter(this, void 0, void 0, function* () {
235
- const { data: messages } = yield this.axios.get(`/messaging/list-by-incoming-event/${messageId}`, {
236
- baseURL: window['BOT_API_PATH']
237
- });
238
- return messages;
138
+ const audio = {
139
+ buffer: voice.toString('base64'),
140
+ title: `${(0, uuid_1.v4)()}.${ext}`
141
+ };
239
142
  });
240
143
  }
241
144
  }
@@ -15,7 +15,4 @@ export default class BpSocket {
15
15
  postToParent: (_type: string, payload: any) => void;
16
16
  /** Waits until the VISITOR ID and VISITOR SOCKET ID is set */
17
17
  waitForUserId(): Promise<void>;
18
- getStorage<T>(key: string): T | undefined;
19
- setStorage<T>(key: string, object: T): void;
20
- private getStorageKey;
21
18
  }
@@ -46,11 +46,11 @@ class BpSocket {
46
46
  return this.waitingForUser;
47
47
  }
48
48
  this.waitingForUser = new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
49
- const creds = this.getStorage('creds');
49
+ const creds = window.BP_STORAGE.get('creds');
50
50
  yield this.socket.connect(creds);
51
51
  if (this.socket.userId) {
52
52
  const userId = this.socket.userId;
53
- this.setStorage('creds', this.socket.creds);
53
+ window.BP_STORAGE.set('creds', this.socket.creds);
54
54
  this.onUserIdChanged(userId);
55
55
  this.postToParent('', { userId });
56
56
  resolve();
@@ -63,24 +63,5 @@ class BpSocket {
63
63
  return this.waitingForUser;
64
64
  });
65
65
  }
66
- getStorage(key) {
67
- const stored = localStorage.getItem(this.getStorageKey(key));
68
- if (!stored) {
69
- return undefined;
70
- }
71
- try {
72
- const val = JSON.parse(stored);
73
- return val;
74
- }
75
- catch (_a) {
76
- return undefined;
77
- }
78
- }
79
- setStorage(key, object) {
80
- localStorage.setItem(this.getStorageKey(key), JSON.stringify(object));
81
- }
82
- getStorageKey(key) {
83
- return `bp-chat-${key}`;
84
- }
85
66
  }
86
67
  exports.default = BpSocket;
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ declare const _default: ({ fill }: {
3
+ fill?: string | undefined;
4
+ }) => JSX.Element;
5
+ export default _default;
@@ -0,0 +1,10 @@
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
+ exports.default = ({ fill = 'black' }) => (react_1.default.createElement("i", null,
8
+ react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", version: "1.1", x: "0px", y: "0px", width: "16px", height: "16px", viewBox: "0 0 492 492", fill: `${fill}` },
9
+ react_1.default.createElement("g", null,
10
+ react_1.default.createElement("path", { d: "M300.188,246L484.14,62.04c5.06-5.064,7.852-11.82,7.86-19.024c0-7.208-2.792-13.972-7.86-19.028L468.02,7.872 c-5.068-5.076-11.824-7.856-19.036-7.856c-7.2,0-13.956,2.78-19.024,7.856L246.008,191.82L62.048,7.872 c-5.06-5.076-11.82-7.856-19.028-7.856c-7.2,0-13.96,2.78-19.02,7.856L7.872,23.988c-10.496,10.496-10.496,27.568,0,38.052 L191.828,246L7.872,429.952c-5.064,5.072-7.852,11.828-7.852,19.032c0,7.204,2.788,13.96,7.852,19.028l16.124,16.116 c5.06,5.072,11.824,7.856,19.02,7.856c7.208,0,13.968-2.784,19.028-7.856l183.96-183.952l183.952,183.952 c5.068,5.072,11.824,7.856,19.024,7.856h0.008c7.204,0,13.96-2.784,19.028-7.856l16.12-16.116 c5.06-5.064,7.852-11.824,7.852-19.028c0-7.204-2.792-13.96-7.852-19.028L300.188,246z" })))));
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ declare const _default: ({ fill }: {
3
+ fill?: string | undefined;
4
+ }) => JSX.Element;
5
+ export default _default;
@@ -0,0 +1,12 @@
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
+ exports.default = ({ fill = 'black' }) => (react_1.default.createElement("i", null,
8
+ react_1.default.createElement("svg", { version: "1.1", xmlns: "http://www.w3.org/2000/svg", x: "0px", y: "0px", width: "16px", height: "16px", viewBox: "0 0 475.085 475.085", fill: `${fill}` },
9
+ react_1.default.createElement("g", null,
10
+ react_1.default.createElement("g", null,
11
+ react_1.default.createElement("path", { d: "M237.541,328.897c25.128,0,46.632-8.946,64.523-26.83c17.888-17.884,26.833-39.399,26.833-64.525V91.365\n c0-25.126-8.938-46.632-26.833-64.525C284.173,8.951,262.669,0,237.541,0c-25.125,0-46.632,8.951-64.524,26.84\n c-17.893,17.89-26.838,39.399-26.838,64.525v146.177c0,25.125,8.949,46.641,26.838,64.525\n C190.906,319.951,212.416,328.897,237.541,328.897z" }),
12
+ react_1.default.createElement("path", { d: "M396.563,188.15c-3.606-3.617-7.898-5.426-12.847-5.426c-4.944,0-9.226,1.809-12.847,5.426\n c-3.613,3.616-5.421,7.898-5.421,12.845v36.547c0,35.214-12.518,65.333-37.548,90.362c-25.022,25.03-55.145,37.545-90.36,37.545\n c-35.214,0-65.334-12.515-90.365-37.545c-25.028-25.022-37.541-55.147-37.541-90.362v-36.547c0-4.947-1.809-9.229-5.424-12.845\n c-3.617-3.617-7.895-5.426-12.847-5.426c-4.952,0-9.235,1.809-12.85,5.426c-3.618,3.616-5.426,7.898-5.426,12.845v36.547\n c0,42.065,14.04,78.659,42.112,109.776c28.073,31.118,62.762,48.961,104.068,53.526v37.691h-73.089\n c-4.949,0-9.231,1.811-12.847,5.428c-3.617,3.614-5.426,7.898-5.426,12.847c0,4.941,1.809,9.233,5.426,12.847\n c3.616,3.614,7.898,5.428,12.847,5.428h182.719c4.948,0,9.236-1.813,12.847-5.428c3.621-3.613,5.431-7.905,5.431-12.847\n c0-4.948-1.81-9.232-5.431-12.847c-3.61-3.617-7.898-5.428-12.847-5.428h-73.08v-37.691\n c41.299-4.565,75.985-22.408,104.061-53.526c28.076-31.117,42.12-67.711,42.12-109.776v-36.547\n C401.998,196.049,400.185,191.77,396.563,188.15z" }))))));
package/dist/index.js CHANGED
@@ -21,6 +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
+ const storage_1 = __importDefault(require("./utils/storage"));
24
25
  (0, mobx_1.configure)({ enforceActions: 'observed' });
25
26
  const Embedded = (props) => new Wrapper(Object.assign(Object.assign({}, props), { fullscreen: false }));
26
27
  exports.Embedded = Embedded;
@@ -29,6 +30,7 @@ exports.Fullscreen = Fullscreen;
29
30
  class ExposedWebChat extends react_1.default.Component {
30
31
  constructor(props) {
31
32
  super(props);
33
+ window.BP_STORAGE = new storage_1.default(props.config);
32
34
  this.state = {
33
35
  store: new store_1.RootStore({ fullscreen: props.fullscreen }, props.config)
34
36
  };
@@ -37,9 +39,8 @@ class ExposedWebChat extends react_1.default.Component {
37
39
  const store = this.state.store;
38
40
  const { botUILanguage: locale } = store;
39
41
  return (react_1.default.createElement(mobx_react_1.Provider, { store: store },
40
- react_1.default.createElement(react_intl_1.IntlProvider, { locale: locale, messages: translations_1.translations[locale], defaultLocale: translations_1.defaultLocale },
41
- react_1.default.createElement(react_1.default.Fragment, null,
42
- react_1.default.createElement(main_1.default, Object.assign({ store: store }, this.props))))));
42
+ react_1.default.createElement(react_intl_1.IntlProvider, { locale: locale, messages: translations_1.translations[locale || translations_1.defaultLocale], defaultLocale: translations_1.defaultLocale },
43
+ react_1.default.createElement(main_1.default, Object.assign({ store: store }, this.props)))));
43
44
  }
44
45
  }
45
46
  exports.ExposedWebChat = ExposedWebChat;
package/dist/main.d.ts CHANGED
@@ -10,4 +10,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
10
10
  export default _default;
11
11
  declare type MainProps = {
12
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'>;
13
+ } & WrappedComponentProps & Pick<StoreDef, 'config' | 'initializeChat' | 'botInfo' | 'fetchBotInfo' | 'sendMessage' | 'setUserId' | 'sendData' | 'intl' | 'updateTyping' | '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
@@ -52,9 +52,18 @@ class Web extends react_1.default.Component {
52
52
  super(props);
53
53
  this.hasBeenInitialized = false;
54
54
  this.isCurrentConversation = (event) => {
55
- var _a;
56
- return !((_a = this.props.config) === null || _a === void 0 ? void 0 : _a.conversationId) || this.props.config.conversationId === event.conversationId;
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;
57
57
  };
58
+ this.handleKeyDown = (e) => __awaiter(this, void 0, void 0, function* () {
59
+ var _a;
60
+ if (!((_a = this.props.config) === null || _a === void 0 ? void 0 : _a.closeOnEscape)) {
61
+ return;
62
+ }
63
+ if (e.key === 'Escape') {
64
+ this.props.hideChat();
65
+ }
66
+ });
58
67
  this.handleIframeApi = ({ data: { action, payload } }) => __awaiter(this, void 0, void 0, function* () {
59
68
  if (action === 'configure') {
60
69
  this.props.updateConfig(Object.assign({}, constants_1.default.DEFAULT_CONFIG, payload));
@@ -65,9 +74,6 @@ class Web extends react_1.default.Component {
65
74
  else if (action === 'sendPayload') {
66
75
  yield this.props.sendData(payload);
67
76
  }
68
- else if (action === 'change-user-id') {
69
- this.props.store.setUserId(payload);
70
- }
71
77
  else if (action === 'event') {
72
78
  const { type, text } = payload;
73
79
  if (type === 'show') {
@@ -103,12 +109,12 @@ class Web extends react_1.default.Component {
103
109
  }
104
110
  };
105
111
  this.handleNewMessage = (event) => __awaiter(this, void 0, void 0, function* () {
106
- var _a;
112
+ var _b;
107
113
  if (event.authorId === undefined) {
108
114
  const value = (event.payload.type === 'typing' ? event.payload.value : undefined) || exports.DEFAULT_TYPING_DELAY;
109
115
  yield this.handleTyping(Object.assign(Object.assign({}, event), { timeInMs: value }));
110
116
  }
111
- if (((_a = event.payload) === null || _a === void 0 ? void 0 : _a.type) === 'visit') {
117
+ if (((_b = event.payload) === null || _b === void 0 ? void 0 : _b.type) === 'visit') {
112
118
  // don't do anything, it's the system message
113
119
  return;
114
120
  }
@@ -120,15 +126,11 @@ class Web extends react_1.default.Component {
120
126
  this.props.updateLastMessage(event.conversationId, event);
121
127
  yield this.props.addEventToConversation(event);
122
128
  // there's no focus on the actual conversation
123
- if ((document.hasFocus && !document.hasFocus()) || this.props.activeView !== 'side') {
129
+ if (!document.hasFocus() || this.props.activeView !== 'side') {
124
130
  yield this.playSound();
125
131
  this.props.incrementUnread();
126
132
  }
127
133
  this.handleResetUnreadCount();
128
- if (!['session_reset'].includes(event.payload.type) && event.id !== this.lastMessageId) {
129
- this.lastMessageId = event.id;
130
- yield this.props.store.loadEventInDebugger(event.id);
131
- }
132
134
  });
133
135
  this.handleTyping = (event) => __awaiter(this, void 0, void 0, function* () {
134
136
  if (!this.isCurrentConversation(event)) {
@@ -158,8 +160,7 @@ class Web extends react_1.default.Component {
158
160
  yield this.audio.play();
159
161
  }), constants_1.default.MIN_TIME_BETWEEN_SOUNDS);
160
162
  this.handleResetUnreadCount = () => {
161
- var _a;
162
- if (((_a = document.hasFocus) === null || _a === void 0 ? void 0 : _a.call(document)) && this.props.activeView === 'side') {
163
+ if (document.hasFocus() && this.props.activeView === 'side') {
163
164
  this.props.resetUnread();
164
165
  }
165
166
  };
@@ -172,18 +173,7 @@ class Web extends react_1.default.Component {
172
173
  this.props.store.setIntlProvider(this.props.intl);
173
174
  window.store = this.props.store;
174
175
  window.addEventListener('message', this.handleIframeApi);
175
- window.addEventListener('keydown', (e) => {
176
- if (!this.props.config.closeOnEscape) {
177
- return;
178
- }
179
- if (e.key === 'Escape') {
180
- this.props.hideChat();
181
- // TODO: what to do with emulator mode?
182
- if (this.props.config.isEmulator) {
183
- window.parent.document.getElementById('mainLayout').focus();
184
- }
185
- }
186
- });
176
+ window.addEventListener('keydown', this.handleKeyDown);
187
177
  yield this.load();
188
178
  yield this.initializeIfChatDisplayed();
189
179
  this.props.setLoadingCompleted();
@@ -191,11 +181,11 @@ class Web extends react_1.default.Component {
191
181
  }
192
182
  componentWillUnmount() {
193
183
  window.removeEventListener('message', this.handleIframeApi);
184
+ window.removeEventListener('keydown', this.handleKeyDown);
194
185
  }
195
186
  componentDidUpdate() {
196
187
  if (this.config) {
197
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
198
- this.initializeIfChatDisplayed();
188
+ void this.initializeIfChatDisplayed();
199
189
  }
200
190
  }
201
191
  initializeIfChatDisplayed() {
@@ -227,9 +217,6 @@ class Web extends react_1.default.Component {
227
217
  if (this.config.containerWidth) {
228
218
  this.postMessageToParent('setWidth', this.config.containerWidth);
229
219
  }
230
- if (this.config.reference) {
231
- yield this.props.setReference();
232
- }
233
220
  // TODO: replace this by frontend configuration
234
221
  // await this.props.fetchBotInfo!()
235
222
  if (!this.isLazySocket()) {
@@ -251,10 +238,9 @@ class Web extends react_1.default.Component {
251
238
  return options;
252
239
  }
253
240
  };
254
- const { options, ref } = query_string_1.default.parse(location.search);
241
+ const { options } = query_string_1.default.parse(location.search);
255
242
  const { config } = JSON.parse(decodeIfRequired(options || '{}'));
256
243
  const userConfig = Object.assign({}, constants_1.default.DEFAULT_CONFIG, this.props.config, config);
257
- userConfig.reference = (config === null || config === void 0 ? void 0 : config.ref) || ref;
258
244
  this.props.updateConfig(userConfig);
259
245
  return userConfig;
260
246
  }
@@ -324,8 +310,7 @@ class Web extends react_1.default.Component {
324
310
  this.props.hasUnreadMessages && react_1.default.createElement("span", { className: 'bpw-floating-button-unread' }, this.props.unreadCount)));
325
311
  }
326
312
  applyAndRenderStyle() {
327
- const emulatorClass = this.props.isEmulator ? ' emulator' : '';
328
- const parentClass = (0, classnames_1.default)(`bp-widget-web bp-widget-${this.props.activeView}${emulatorClass}`, {
313
+ const parentClass = (0, classnames_1.default)(`bp-widget-web bp-widget-${this.props.activeView}`, {
329
314
  'bp-widget-hidden': !this.props.showWidgetButton && this.props.displayWidgetView,
330
315
  [this.props.config.className]: !!this.props.config.className
331
316
  });
@@ -367,8 +352,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
367
352
  setUserId: store.setUserId,
368
353
  updateTyping: store.updateTyping,
369
354
  sendMessage: store.sendMessage,
370
- setReference: store.setReference,
371
- isEmulator: store.isEmulator,
372
355
  updateBotUILanguage: store.updateBotUILanguage,
373
356
  isWebchatReady: store.view.isWebchatReady,
374
357
  showWidgetButton: store.view.showWidgetButton,
@@ -14,7 +14,7 @@ const takeRight_1 = __importDefault(require("lodash/takeRight"));
14
14
  const mobx_1 = require("mobx");
15
15
  const constants_1 = __importDefault(require("../core/constants"));
16
16
  const HISTORY_UP = 'ArrowUp';
17
- const SENT_HISTORY_KEY = `bp::${window.BOT_ID}::sentHistory`;
17
+ const SENT_HISTORY_KEY = 'sent-history';
18
18
  class ComposerStore {
19
19
  constructor(rootStore) {
20
20
  this.message = '';
@@ -23,9 +23,7 @@ class ComposerStore {
23
23
  this._sentHistory = [];
24
24
  this._sentHistoryIndex = 0;
25
25
  this.rootStore = rootStore;
26
- if (window.BP_STORAGE) {
27
- this._sentHistory = window.BP_STORAGE.get(SENT_HISTORY_KEY) || [];
28
- }
26
+ this._sentHistory = window.BP_STORAGE.get(SENT_HISTORY_KEY) || [];
29
27
  }
30
28
  get composerPlaceholder() {
31
29
  var _a;
@@ -35,12 +33,11 @@ class ComposerStore {
35
33
  this.message = msg;
36
34
  }
37
35
  addMessageToHistory(text) {
38
- var _a;
39
36
  if ((0, last_1.default)(this._sentHistory) !== text) {
40
37
  this._sentHistory.push(text);
41
38
  this._sentHistoryIndex = 0;
42
39
  if (this.rootStore.config.enablePersistHistory) {
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));
40
+ window.BP_STORAGE.set(SENT_HISTORY_KEY, (0, takeRight_1.default)(this._sentHistory, constants_1.default.SENT_HISTORY_SIZE));
44
41
  }
45
42
  }
46
43
  }
@@ -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,8 +20,6 @@ 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: {
@@ -31,25 +29,23 @@ declare class RootStore {
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;