@botpress/webchat 0.2.0 → 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 (59) 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 +2 -23
  5. package/dist/components/ContextMenu.js +0 -9
  6. package/dist/components/ConversationList.js +1 -1
  7. package/dist/components/Header.d.ts +1 -1
  8. package/dist/components/Header.js +10 -27
  9. package/dist/components/VoiceRecorder.js +6 -2
  10. package/dist/components/common/{Avatar.d.ts → Avatar/index.d.ts} +0 -0
  11. package/dist/components/common/Avatar/index.js +13 -0
  12. package/dist/components/common/{BotInfo.d.ts → BotInfo/index.d.ts} +2 -2
  13. package/dist/components/common/BotInfo/index.js +112 -0
  14. package/dist/components/common/ConfirmDialog/index.d.ts +11 -0
  15. package/dist/components/common/ConfirmDialog/index.js +78 -0
  16. package/dist/components/common/Dialog/index.d.ts +17 -0
  17. package/dist/components/common/Dialog/index.js +57 -0
  18. package/dist/components/common/MoreOptions/index.d.ts +21 -0
  19. package/dist/components/common/MoreOptions/index.js +60 -0
  20. package/dist/components/common/Overlay/index.d.ts +7 -0
  21. package/dist/components/common/{Avatar.js → Overlay/index.js} +15 -8
  22. package/dist/components/common/ToolTip/index.d.ts +10 -0
  23. package/dist/components/common/ToolTip/index.js +163 -0
  24. package/dist/components/common/ToolTip/utils.d.ts +15 -0
  25. package/dist/components/common/ToolTip/utils.js +78 -0
  26. package/dist/components/messages/Message.js +1 -20
  27. package/dist/components/messages/MessageGroup.d.ts +1 -9
  28. package/dist/components/messages/MessageGroup.js +4 -39
  29. package/dist/components/messages/MessageList.d.ts +1 -1
  30. package/dist/components/messages/MessageList.js +1 -2
  31. package/dist/core/api.d.ts +4 -13
  32. package/dist/core/api.js +35 -127
  33. package/dist/core/socket.d.ts +0 -3
  34. package/dist/core/socket.js +2 -21
  35. package/dist/fonts/roboto.d.ts +4 -0
  36. package/dist/fonts/roboto.js +9 -0
  37. package/dist/icons/Cancel.d.ts +5 -0
  38. package/dist/icons/Cancel.js +10 -0
  39. package/dist/icons/Microphone.d.ts +5 -0
  40. package/dist/icons/Microphone.js +12 -0
  41. package/dist/index.d.ts +1 -1
  42. package/dist/index.js +7 -0
  43. package/dist/main.d.ts +2 -1
  44. package/dist/main.js +50 -47
  45. package/dist/store/composer.js +3 -6
  46. package/dist/store/index.d.ts +7 -12
  47. package/dist/store/index.js +92 -97
  48. package/dist/store/view.d.ts +0 -2
  49. package/dist/store/view.js +0 -10
  50. package/dist/translations/index.d.ts +2 -1
  51. package/dist/translations/index.js +9 -4
  52. package/dist/typings.d.ts +9 -19
  53. package/dist/utils/storage.d.ts +17 -0
  54. package/dist/utils/storage.js +117 -0
  55. package/dist/utils.js +1 -1
  56. package/package.json +6 -2
  57. package/dist/components/Keyboard.d.ts +0 -22
  58. package/dist/components/Keyboard.js +0 -86
  59. 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,35 +29,24 @@ class WebchatApi {
43
29
  }
44
30
  });
45
31
  }
46
- fetchPreferences() {
47
- 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
- }
65
- });
66
- }
67
32
  fetchConversations() {
68
33
  return __awaiter(this, void 0, void 0, function* () {
69
34
  try {
70
- const convos = yield this.socket.socket.listConversations();
71
- return convos;
35
+ const conversations = (yield this.socket.socket.listConversations());
36
+ // Add the last message of each conversation
37
+ for (const conversation of conversations) {
38
+ const limit = 1;
39
+ yield this.socket.socket.switchConversation(conversation.id);
40
+ const lastMessages = yield this.socket.socket.listMessages(limit);
41
+ if (lastMessages.length >= limit) {
42
+ conversation.lastMessage = lastMessages[0];
43
+ }
44
+ }
45
+ return conversations;
72
46
  }
73
47
  catch (err) {
74
- console.error('Error while fetching convos', err);
48
+ console.error('Error while fetching users conversations', err);
49
+ return [];
75
50
  }
76
51
  });
77
52
  }
@@ -84,14 +59,14 @@ class WebchatApi {
84
59
  return Object.assign(Object.assign({}, conversation), { messages });
85
60
  }
86
61
  catch (err) {
87
- yield this.handleApiError(err);
62
+ console.error('Error fetching a conversation', err);
88
63
  }
89
64
  });
90
65
  }
66
+ // TODO: Fis this
91
67
  resetSession(conversationId) {
92
68
  return __awaiter(this, void 0, void 0, function* () {
93
69
  try {
94
- yield this.axios.post('/conversations/reset', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId }), this.axiosConfig);
95
70
  }
96
71
  catch (err) {
97
72
  console.error('Error while resetting conversation', err);
@@ -105,7 +80,7 @@ class WebchatApi {
105
80
  return conversation.id;
106
81
  }
107
82
  catch (err) {
108
- console.error('Error in create conversation', err);
83
+ console.error('Error creating conversation', err);
109
84
  }
110
85
  });
111
86
  }
@@ -115,118 +90,51 @@ class WebchatApi {
115
90
  yield this.socket.socket.startConversation();
116
91
  }
117
92
  catch (err) {
118
- console.error('Error in start conversation', err);
119
- }
120
- });
121
- }
122
- downloadConversation(conversationId) {
123
- return __awaiter(this, void 0, void 0, function* () {
124
- try {
125
- const { data } = yield this.axios.post('/conversations/download/txt', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId }), this.axiosConfig);
126
- return { name: data.name, txt: data.txt };
127
- }
128
- catch (err) {
129
- console.error('Error in download conversation', err);
93
+ console.error('Error starting conversation', err);
130
94
  }
131
95
  });
132
96
  }
133
- // TODO: we don't have a /events route available for this
134
- /*
135
- async sendEvent(payload: any, conversationId: uuid): Promise<void> {
136
- try {
137
- return this.axios.post('/events', { ...this.baseUserPayload, conversationId, payload }, this.axiosConfig)
138
- } catch (err) {
139
- await this.handleApiError(err)
140
- }
141
- }
142
- */
143
97
  sendMessage(payload, conversationId) {
144
98
  return __awaiter(this, void 0, void 0, function* () {
145
99
  try {
146
100
  return this.socket.sendPayload(payload);
147
101
  }
148
102
  catch (err) {
149
- yield this.handleApiError(err);
103
+ console.error('Error sending message', err);
150
104
  }
151
105
  });
152
106
  }
153
- deleteMessages(conversationId) {
107
+ deleteConversation(conversationId) {
154
108
  return __awaiter(this, void 0, void 0, function* () {
155
109
  try {
156
- yield this.axios.post('/conversations/messages/delete', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId }), this.axiosConfig);
110
+ yield this.socket.socket.deleteConversation(conversationId);
157
111
  }
158
112
  catch (err) {
159
- yield this.handleApiError(err);
113
+ console.error('Error deleting conversation', err);
160
114
  }
161
115
  });
162
116
  }
163
117
  sendFeedback(feedback, messageId) {
164
118
  return __awaiter(this, void 0, void 0, function* () {
165
- try {
166
- return this.socket.socket.sendFeedback(messageId, feedback);
167
- }
168
- catch (err) {
169
- yield this.handleApiError(err);
170
- }
171
- });
172
- }
173
- getMessageIdsFeedbackInfo(messageIds) {
174
- return __awaiter(this, void 0, void 0, function* () {
175
- try {
176
- const { data } = yield this.axios.post('/feedbackInfo', { messageIds, target: this.userId }, this.axiosConfig);
177
- return data;
178
- }
179
- catch (err) {
180
- yield this.handleApiError(err);
181
- }
119
+ return this.socket.socket.sendFeedback(messageId, feedback);
182
120
  });
183
121
  }
184
122
  uploadFile(file, payload, conversationId) {
185
123
  return __awaiter(this, void 0, void 0, function* () {
186
- try {
187
- const data = new FormData();
188
- data.append('file', file);
189
- data.append('webSessionId', this.baseUserPayload.webSessionId);
190
- data.append('conversationId', conversationId);
191
- data.append('payload', payload);
192
- return this.axios.post('/messages/files', data, this.axiosConfig);
193
- }
194
- catch (err) {
195
- yield this.handleApiError(err);
196
- }
124
+ const data = new FormData();
125
+ data.append('file', file);
126
+ data.append('conversationId', conversationId);
127
+ data.append('payload', payload);
128
+ return this.axios.post('/messages/files', data, this.axiosConfig);
197
129
  });
198
130
  }
131
+ // TODO: Fix this
199
132
  sendVoiceMessage(voice, ext, conversationId) {
200
133
  return __awaiter(this, void 0, void 0, function* () {
201
- try {
202
- const audio = {
203
- buffer: voice.toString('base64'),
204
- title: `${(0, uuid_1.v4)()}.${ext}`
205
- };
206
- return this.axios.post('/messages/voice', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId, audio }), this.axiosConfig);
207
- }
208
- catch (err) {
209
- yield this.handleApiError(err);
210
- }
211
- });
212
- }
213
- setReference(reference, conversationId) {
214
- return __awaiter(this, void 0, void 0, function* () {
215
- // TODO: this can't work. We don't have a reference route
216
- try {
217
- return this.axios.post('/conversations/reference', Object.assign(Object.assign({}, this.baseUserPayload), { conversationId, reference }), this.axiosConfig);
218
- }
219
- catch (err) {
220
- yield this.handleApiError(err);
221
- }
222
- });
223
- }
224
- listByIncomingEvent(messageId) {
225
- return __awaiter(this, void 0, void 0, function* () {
226
- const { data: messages } = yield this.axios.get(`/messaging/list-by-incoming-event/${messageId}`, {
227
- baseURL: window['BOT_API_PATH']
228
- });
229
- return messages;
134
+ const audio = {
135
+ buffer: voice.toString('base64'),
136
+ title: `${(0, uuid_1.v4)()}.${ext}`
137
+ };
230
138
  });
231
139
  }
232
140
  }
@@ -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,4 @@
1
+ /// <reference types="react" />
2
+ import '../../assets/fonts/roboto.css';
3
+ declare const Font: () => JSX.Element;
4
+ export default Font;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ require("../../assets/fonts/roboto.css");
8
+ const Font = () => react_1.default.createElement(react_1.default.Fragment, null);
9
+ exports.default = Font;
@@ -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.d.ts CHANGED
@@ -7,7 +7,7 @@ interface State {
7
7
  store: RootStore;
8
8
  }
9
9
  interface Props {
10
- config?: Config;
10
+ config: Config;
11
11
  fullscreen?: boolean;
12
12
  }
13
13
  export declare class ExposedWebChat extends React.Component<Props, State> {
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,12 @@ exports.Fullscreen = Fullscreen;
29
30
  class ExposedWebChat extends react_1.default.Component {
30
31
  constructor(props) {
31
32
  super(props);
33
+ const { clientId, encryptionKey, useSessionStorage } = props.config;
34
+ window.BP_STORAGE = new storage_1.default({
35
+ clientId,
36
+ encryptionKey,
37
+ useSessionStorage
38
+ });
32
39
  this.state = {
33
40
  store: new store_1.RootStore({ fullscreen: props.fullscreen }, props.config)
34
41
  };
package/dist/main.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { WrappedComponentProps } from 'react-intl';
3
3
  import { RootStore, StoreDef } from './store';
4
+ export declare const DEFAULT_TYPING_DELAY = 1000;
4
5
  declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omit<MainProps, "intl"> & {
5
6
  forwardedRef?: React.Ref<any> | undefined;
6
7
  } & React.RefAttributes<any>> & {
@@ -9,4 +10,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
9
10
  export default _default;
10
11
  declare type MainProps = {
11
12
  store: RootStore;
12
- } & 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'>;
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
@@ -1,4 +1,23 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
2
21
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
22
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
23
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -12,6 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
32
  };
14
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.DEFAULT_TYPING_DELAY = void 0;
15
35
  const classnames_1 = __importDefault(require("classnames"));
16
36
  const debounce_1 = __importDefault(require("lodash/debounce"));
17
37
  const set_1 = __importDefault(require("lodash/set"));
@@ -26,16 +46,24 @@ const constants_1 = __importDefault(require("./core/constants"));
26
46
  const socket_1 = __importDefault(require("./core/socket"));
27
47
  const Chat_1 = __importDefault(require("./icons/Chat"));
28
48
  const utils_1 = require("./utils");
29
- const _values = (obj) => Object.keys(obj).map((x) => obj[x]);
30
- const DEFAULT_TYPING_DELAY = 1000;
49
+ exports.DEFAULT_TYPING_DELAY = 1000;
31
50
  class Web extends react_1.default.Component {
32
51
  constructor(props) {
33
52
  super(props);
34
53
  this.hasBeenInitialized = false;
35
54
  this.isCurrentConversation = (event) => {
36
- var _a;
37
- 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;
38
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
+ });
39
67
  this.handleIframeApi = ({ data: { action, payload } }) => __awaiter(this, void 0, void 0, function* () {
40
68
  if (action === 'configure') {
41
69
  this.props.updateConfig(Object.assign({}, constants_1.default.DEFAULT_CONFIG, payload));
@@ -46,9 +74,6 @@ class Web extends react_1.default.Component {
46
74
  else if (action === 'sendPayload') {
47
75
  yield this.props.sendData(payload);
48
76
  }
49
- else if (action === 'change-user-id') {
50
- this.props.store.setUserId(payload);
51
- }
52
77
  else if (action === 'event') {
53
78
  const { type, text } = payload;
54
79
  if (type === 'show') {
@@ -84,12 +109,12 @@ class Web extends react_1.default.Component {
84
109
  }
85
110
  };
86
111
  this.handleNewMessage = (event) => __awaiter(this, void 0, void 0, function* () {
87
- var _a;
112
+ var _b;
88
113
  if (event.authorId === undefined) {
89
- const value = (event.payload.type === 'typing' ? event.payload.value : undefined) || DEFAULT_TYPING_DELAY;
114
+ const value = (event.payload.type === 'typing' ? event.payload.value : undefined) || exports.DEFAULT_TYPING_DELAY;
90
115
  yield this.handleTyping(Object.assign(Object.assign({}, event), { timeInMs: value }));
91
116
  }
92
- 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') {
93
118
  // don't do anything, it's the system message
94
119
  return;
95
120
  }
@@ -98,17 +123,14 @@ class Web extends react_1.default.Component {
98
123
  return;
99
124
  }
100
125
  (0, utils_1.trackMessage)('received');
126
+ this.props.updateLastMessage(event.conversationId, event);
101
127
  yield this.props.addEventToConversation(event);
102
128
  // there's no focus on the actual conversation
103
- if ((document.hasFocus && !document.hasFocus()) || this.props.activeView !== 'side') {
129
+ if (!document.hasFocus() || this.props.activeView !== 'side') {
104
130
  yield this.playSound();
105
131
  this.props.incrementUnread();
106
132
  }
107
133
  this.handleResetUnreadCount();
108
- if (!['session_reset'].includes(event.payload.type) && event.id !== this.lastMessageId) {
109
- this.lastMessageId = event.id;
110
- yield this.props.store.loadEventInDebugger(event.id);
111
- }
112
134
  });
113
135
  this.handleTyping = (event) => __awaiter(this, void 0, void 0, function* () {
114
136
  if (!this.isCurrentConversation(event)) {
@@ -138,8 +160,7 @@ class Web extends react_1.default.Component {
138
160
  yield this.audio.play();
139
161
  }), constants_1.default.MIN_TIME_BETWEEN_SOUNDS);
140
162
  this.handleResetUnreadCount = () => {
141
- var _a;
142
- 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') {
143
164
  this.props.resetUnread();
144
165
  }
145
166
  };
@@ -148,23 +169,11 @@ class Web extends react_1.default.Component {
148
169
  }
149
170
  componentDidMount() {
150
171
  return __awaiter(this, void 0, void 0, function* () {
151
- // TODO: serve this from cdn
152
- this.audio = new Audio(`${window.ROOT_PATH}/assets/modules/channel-web/notification.mp3`);
172
+ this.audio = new Audio(require('url:../assets/notification.mp3'));
153
173
  this.props.store.setIntlProvider(this.props.intl);
154
174
  window.store = this.props.store;
155
175
  window.addEventListener('message', this.handleIframeApi);
156
- window.addEventListener('keydown', (e) => {
157
- if (!this.props.config.closeOnEscape) {
158
- return;
159
- }
160
- if (e.key === 'Escape') {
161
- this.props.hideChat();
162
- // TODO: what to do with emulator mode?
163
- if (this.props.config.isEmulator) {
164
- window.parent.document.getElementById('mainLayout').focus();
165
- }
166
- }
167
- });
176
+ window.addEventListener('keydown', this.handleKeyDown);
168
177
  yield this.load();
169
178
  yield this.initializeIfChatDisplayed();
170
179
  this.props.setLoadingCompleted();
@@ -172,11 +181,11 @@ class Web extends react_1.default.Component {
172
181
  }
173
182
  componentWillUnmount() {
174
183
  window.removeEventListener('message', this.handleIframeApi);
184
+ window.removeEventListener('keydown', this.handleKeyDown);
175
185
  }
176
186
  componentDidUpdate() {
177
187
  if (this.config) {
178
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
179
- this.initializeIfChatDisplayed();
188
+ void this.initializeIfChatDisplayed();
180
189
  }
181
190
  }
182
191
  initializeIfChatDisplayed() {
@@ -208,9 +217,6 @@ class Web extends react_1.default.Component {
208
217
  if (this.config.containerWidth) {
209
218
  this.postMessageToParent('setWidth', this.config.containerWidth);
210
219
  }
211
- if (this.config.reference) {
212
- yield this.props.setReference();
213
- }
214
220
  // TODO: replace this by frontend configuration
215
221
  // await this.props.fetchBotInfo!()
216
222
  if (!this.isLazySocket()) {
@@ -232,10 +238,9 @@ class Web extends react_1.default.Component {
232
238
  return options;
233
239
  }
234
240
  };
235
- const { options, ref } = query_string_1.default.parse(location.search);
241
+ const { options } = query_string_1.default.parse(location.search);
236
242
  const { config } = JSON.parse(decodeIfRequired(options || '{}'));
237
243
  const userConfig = Object.assign({}, constants_1.default.DEFAULT_CONFIG, this.props.config, config);
238
- userConfig.reference = (config === null || config === void 0 ? void 0 : config.ref) || ref;
239
244
  this.props.updateConfig(userConfig);
240
245
  return userConfig;
241
246
  }
@@ -256,7 +261,7 @@ class Web extends react_1.default.Component {
256
261
  }
257
262
  loadOverrides(overrides) {
258
263
  try {
259
- for (const override of _values(overrides)) {
264
+ for (const override of Object.values(overrides)) {
260
265
  // TODO: load module view this can't work
261
266
  // override.map(({ module }) => this.props.bp!.loadModuleView(module, true))
262
267
  }
@@ -305,8 +310,7 @@ class Web extends react_1.default.Component {
305
310
  this.props.hasUnreadMessages && react_1.default.createElement("span", { className: 'bpw-floating-button-unread' }, this.props.unreadCount)));
306
311
  }
307
312
  applyAndRenderStyle() {
308
- const emulatorClass = this.props.isEmulator ? ' emulator' : '';
309
- 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}`, {
310
314
  'bp-widget-hidden': !this.props.showWidgetButton && this.props.displayWidgetView,
311
315
  [this.props.config.className]: !!this.props.config.className
312
316
  });
@@ -314,11 +318,11 @@ class Web extends react_1.default.Component {
314
318
  this.postMessageToParent('setClass', parentClass);
315
319
  this.parentClass = parentClass;
316
320
  }
317
- const { isEmulator, stylesheet, extraStylesheet } = this.props.config;
321
+ const { stylesheet, extraStylesheet } = this.props.config;
322
+ const RobotoFont = react_1.default.lazy(() => Promise.resolve().then(() => __importStar(require('./fonts/roboto'))));
318
323
  return (react_1.default.createElement(react_1.default.Fragment, null,
319
324
  !!(stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.length) && react_1.default.createElement(Stylesheet_1.default, { href: stylesheet }),
320
- !stylesheet && react_1.default.createElement(Stylesheet_1.default, { href: `assets/modules/channel-web/default${isEmulator ? '-emulator' : ''}.css` }),
321
- !utils_1.isIE && react_1.default.createElement(Stylesheet_1.default, { href: 'assets/modules/channel-web/font.css' }),
325
+ react_1.default.createElement(react_1.default.Suspense, { fallback: react_1.default.createElement(react_1.default.Fragment, null) }, !utils_1.isIE && react_1.default.createElement(RobotoFont, null)),
322
326
  !!(extraStylesheet === null || extraStylesheet === void 0 ? void 0 : extraStylesheet.length) && react_1.default.createElement(Stylesheet_1.default, { href: extraStylesheet })));
323
327
  }
324
328
  render() {
@@ -348,8 +352,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
348
352
  setUserId: store.setUserId,
349
353
  updateTyping: store.updateTyping,
350
354
  sendMessage: store.sendMessage,
351
- setReference: store.setReference,
352
- isEmulator: store.isEmulator,
353
355
  updateBotUILanguage: store.updateBotUILanguage,
354
356
  isWebchatReady: store.view.isWebchatReady,
355
357
  showWidgetButton: store.view.showWidgetButton,
@@ -366,5 +368,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
366
368
  widgetTransition: store.view.widgetTransition,
367
369
  displayWidgetView: store.view.displayWidgetView,
368
370
  setLoadingCompleted: store.view.setLoadingCompleted,
369
- sendFeedback: store.sendFeedback
371
+ sendFeedback: store.sendFeedback,
372
+ updateLastMessage: store.updateLastMessage
370
373
  }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(Web)));
@@ -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
  }