@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.
- package/dist/components/Composer.d.ts +1 -1
- package/dist/components/Composer.js +12 -2
- package/dist/components/Container.d.ts +1 -1
- package/dist/components/Container.js +0 -2
- package/dist/components/ContextMenu.js +0 -9
- package/dist/components/Header.d.ts +1 -1
- package/dist/components/Header.js +10 -27
- package/dist/components/VoiceRecorder.js +6 -2
- package/dist/components/common/{Avatar.d.ts → Avatar/index.d.ts} +0 -0
- package/dist/components/common/Avatar/index.js +13 -0
- package/dist/components/common/{BotInfo.d.ts → BotInfo/index.d.ts} +2 -2
- package/dist/components/common/BotInfo/index.js +112 -0
- package/dist/components/common/ConfirmDialog/index.d.ts +11 -0
- package/dist/components/common/ConfirmDialog/index.js +78 -0
- package/dist/components/common/Dialog/index.d.ts +17 -0
- package/dist/components/common/Dialog/index.js +57 -0
- package/dist/components/common/MoreOptions/index.d.ts +21 -0
- package/dist/components/common/MoreOptions/index.js +60 -0
- package/dist/components/common/Overlay/index.d.ts +7 -0
- package/dist/components/common/{Avatar.js → Overlay/index.js} +15 -8
- package/dist/components/common/ToolTip/index.d.ts +10 -0
- package/dist/components/common/ToolTip/index.js +163 -0
- package/dist/components/common/ToolTip/utils.d.ts +15 -0
- package/dist/components/common/ToolTip/utils.js +78 -0
- package/dist/components/messages/Message.js +1 -20
- package/dist/components/messages/MessageGroup.d.ts +1 -9
- package/dist/components/messages/MessageGroup.js +4 -35
- package/dist/components/messages/MessageList.d.ts +1 -1
- package/dist/components/messages/MessageList.js +1 -2
- package/dist/core/api.d.ts +4 -13
- package/dist/core/api.js +29 -130
- package/dist/core/socket.d.ts +0 -5
- package/dist/core/socket.js +2 -45
- package/dist/icons/Cancel.d.ts +5 -0
- package/dist/icons/Cancel.js +10 -0
- package/dist/icons/Microphone.d.ts +5 -0
- package/dist/icons/Microphone.js +12 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -0
- package/dist/main.d.ts +1 -1
- package/dist/main.js +20 -37
- package/dist/store/composer.js +3 -6
- package/dist/store/index.d.ts +6 -12
- package/dist/store/index.js +74 -89
- package/dist/store/view.d.ts +0 -2
- package/dist/store/view.js +0 -10
- package/dist/translations/index.d.ts +2 -1
- package/dist/translations/index.js +9 -4
- package/dist/typings.d.ts +6 -18
- package/dist/utils/storage.d.ts +17 -0
- package/dist/utils/storage.js +117 -0
- package/dist/utils.js +1 -1
- package/package.json +4 -2
- package/dist/components/common/BotInfo.js +0 -110
package/dist/store/index.d.ts
CHANGED
|
@@ -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,
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
package/dist/store/index.js
CHANGED
|
@@ -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
|
-
|
|
42
|
-
|
|
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.
|
|
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
|
|
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
|
|
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.
|
|
107
|
-
yield this.api.
|
|
108
|
-
this.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
|
163
|
+
console.error('Error while fetching data, creating new conversation...', err);
|
|
171
164
|
yield this.createConversation();
|
|
172
165
|
}
|
|
173
|
-
|
|
166
|
+
this.fetchLanguage();
|
|
174
167
|
});
|
|
175
168
|
}
|
|
176
169
|
fetchBotInfo() {
|
|
177
170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
-
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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.
|
|
280
|
-
|
|
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
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
382
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
(
|
|
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, "
|
|
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);
|
package/dist/store/view.d.ts
CHANGED
|
@@ -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;
|
package/dist/store/view.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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 = () =>
|
|
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 = '
|
|
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:
|
|
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;
|