@botpress/webchat 0.2.3 → 0.3.0
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/README.md +31 -0
- package/dist/components/Composer.d.ts +4 -5
- package/dist/components/Composer.js +13 -23
- package/dist/components/Container.d.ts +1 -1
- package/dist/components/Container.js +1 -6
- package/dist/components/ConversationList.d.ts +1 -1
- package/dist/components/ConversationList.js +5 -46
- package/dist/components/Header.d.ts +1 -3
- package/dist/components/Header.js +17 -64
- 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} +3 -3
- package/dist/components/common/BotInfo/index.js +102 -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/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/InlineFeedback.d.ts +2 -1
- package/dist/components/messages/Message.js +2 -25
- package/dist/components/messages/MessageGroup.d.ts +1 -13
- package/dist/components/messages/MessageGroup.js +6 -40
- package/dist/components/messages/MessageList.d.ts +1 -1
- package/dist/components/messages/MessageList.js +8 -31
- package/dist/core/api.d.ts +4 -18
- package/dist/core/api.js +25 -150
- package/dist/core/constants.d.ts +4 -32
- package/dist/core/constants.js +18 -32
- package/dist/core/socket.d.ts +1 -12
- package/dist/core/socket.js +7 -73
- package/dist/{components/Stylesheet.d.ts → icons/Cancel.d.ts} +2 -2
- 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 +2 -8
- package/dist/index.js +9 -29
- package/dist/main.d.ts +2 -2
- package/dist/main.js +100 -168
- package/dist/store/composer.js +3 -6
- package/dist/store/index.d.ts +8 -18
- package/dist/store/index.js +98 -136
- package/dist/store/view.d.ts +3 -6
- package/dist/store/view.js +6 -23
- package/dist/translations/index.d.ts +3 -1
- package/dist/translations/index.js +44 -4
- package/dist/typings.d.ts +121 -71
- package/dist/utils/analytics.d.ts +5 -0
- package/dist/utils/analytics.js +37 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +27 -0
- package/dist/utils/storage.d.ts +16 -0
- package/dist/utils/storage.js +129 -0
- package/package.json +4 -3
- package/dist/components/ContextMenu.d.ts +0 -2
- package/dist/components/ContextMenu.js +0 -33
- package/dist/components/OverridableComponent.d.ts +0 -24
- package/dist/components/OverridableComponent.js +0 -50
- package/dist/components/Stylesheet.js +0 -7
- package/dist/components/common/Avatar.js +0 -29
- package/dist/components/common/BotInfo.js +0 -110
- package/dist/icons/CloseChat.d.ts +0 -6
- package/dist/icons/CloseChat.js +0 -9
- package/dist/icons/Send.d.ts +0 -6
- package/dist/icons/Send.js +0 -8
- package/dist/utils.d.ts +0 -8
- package/dist/utils.js +0 -111
|
@@ -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.isRTLLocale = 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,43 @@ 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
|
+
const rtlLocales = [
|
|
32
|
+
'ae' /* Avestan */,
|
|
33
|
+
'ar' /* 'العربية', Arabic */,
|
|
34
|
+
'arc' /* Aramaic */,
|
|
35
|
+
'bcc' /* 'بلوچی مکرانی', Southern Balochi */,
|
|
36
|
+
'bqi' /* 'بختياري', Bakthiari */,
|
|
37
|
+
'ckb' /* 'Soranî / کوردی', Sorani */,
|
|
38
|
+
'dv' /* Dhivehi */,
|
|
39
|
+
'fa' /* 'فارسی', Persian */,
|
|
40
|
+
'glk' /* 'گیلکی', Gilaki */,
|
|
41
|
+
'he' /* 'עברית', Hebrew */,
|
|
42
|
+
'ku' /* 'Kurdî / كوردی', Kurdish */,
|
|
43
|
+
'mzn' /* 'مازِرونی', Mazanderani */,
|
|
44
|
+
'nqo' /* N'Ko */,
|
|
45
|
+
'pnb' /* 'پنجابی', Western Punjabi */,
|
|
46
|
+
'ps' /* 'پښتو', Pashto, */,
|
|
47
|
+
'sd' /* 'سنڌي', Sindhi */,
|
|
48
|
+
'ug' /* 'Uyghurche / ئۇيغۇرچە', Uyghur */,
|
|
49
|
+
'ur' /* 'اردو', Urdu */,
|
|
50
|
+
'yi' /* 'ייִדיש', Yiddish */
|
|
51
|
+
];
|
|
52
|
+
// 'en-US' becomes ['en', '-us'] 'en' becomes ['en']
|
|
53
|
+
const localeRegex = /^([a-zA-Z]{2,3})([_\-a-zA-Z]{3,5})$/;
|
|
31
54
|
const cleanLanguageCode = (str) => str.split('-')[0];
|
|
32
55
|
const getNavigatorLanguage = () => cleanLanguageCode(navigator.language || navigator['userLanguage'] || '');
|
|
33
|
-
const getStorageLanguage = () =>
|
|
56
|
+
const getStorageLanguage = () => cleanLanguageCode(window.BP_STORAGE.get(USER_LANG_STORAGE_KEY) || '');
|
|
57
|
+
const setStorageLanguage = (locale) => window.BP_STORAGE.set(USER_LANG_STORAGE_KEY, locale);
|
|
34
58
|
// Desired precedence
|
|
35
59
|
// 1- manual locale = 'browser' : browser lang
|
|
36
60
|
// 2- manual locale is supported : manual lang
|
|
37
61
|
// 3- storage lang is supported : storage lang
|
|
38
62
|
// 4- browser lang is supported : browser lang
|
|
39
63
|
// 5- default lang
|
|
40
|
-
const getUserLocale = (manualLocale = '
|
|
64
|
+
const getUserLocale = (manualLocale = '') => {
|
|
41
65
|
const browserLocale = getNavigatorLanguage();
|
|
42
66
|
if (manualLocale === 'browser' && translations[browserLocale]) {
|
|
43
67
|
return browserLocale;
|
|
@@ -53,3 +77,19 @@ const getUserLocale = (manualLocale = 'browser') => {
|
|
|
53
77
|
return translations[browserLocale] ? browserLocale : DEFAULT_LOCALE;
|
|
54
78
|
};
|
|
55
79
|
exports.getUserLocale = getUserLocale;
|
|
80
|
+
const setUserLocale = (locale) => {
|
|
81
|
+
setStorageLanguage(locale);
|
|
82
|
+
};
|
|
83
|
+
exports.setUserLocale = setUserLocale;
|
|
84
|
+
const isRTLLocale = (locale) => {
|
|
85
|
+
if (!locale) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
locale = locale.toLowerCase();
|
|
89
|
+
const matches = localeRegex.exec(locale);
|
|
90
|
+
if (!matches || matches.length < 2) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
return rtlLocales.includes(matches[1]);
|
|
94
|
+
};
|
|
95
|
+
exports.isRTLLocale = isRTLLocale;
|
package/dist/typings.d.ts
CHANGED
|
@@ -1,22 +1,16 @@
|
|
|
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
|
-
SHOW_POWERED_BY: boolean;
|
|
18
12
|
USE_SESSION_STORAGE: boolean;
|
|
19
|
-
BP_STORAGE:
|
|
13
|
+
BP_STORAGE: BPStorage;
|
|
20
14
|
botpress: {
|
|
21
15
|
[moduleName: string]: any;
|
|
22
16
|
};
|
|
@@ -35,7 +29,6 @@ export declare namespace Renderer {
|
|
|
35
29
|
noBubble?: boolean;
|
|
36
30
|
keyboard?: any;
|
|
37
31
|
eventId?: string;
|
|
38
|
-
isHighlighted?: boolean;
|
|
39
32
|
isLastGroup?: boolean;
|
|
40
33
|
isLastOfGroup?: boolean;
|
|
41
34
|
isBotMessage?: boolean;
|
|
@@ -147,76 +140,137 @@ export interface Config {
|
|
|
147
140
|
messagingUrl: string;
|
|
148
141
|
/** Id of your messaging client */
|
|
149
142
|
clientId: string;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Url of the Media File Service where we fetch the bot info
|
|
145
|
+
* @default ''
|
|
146
|
+
*/
|
|
147
|
+
mediaFileServiceUrl?: string;
|
|
148
|
+
/**
|
|
149
|
+
* Key used to encrypt data in the localStorage
|
|
150
|
+
* @default '''
|
|
151
|
+
*/
|
|
152
|
+
encryptionKey?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Provide a path to a stylesheet to customize the webchat
|
|
155
|
+
* @default '''
|
|
156
|
+
*/
|
|
157
157
|
stylesheet?: string;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
158
|
+
/**
|
|
159
|
+
* If false, will hide the conversation list pane
|
|
160
|
+
* @default true
|
|
161
|
+
*/
|
|
162
|
+
showConversationsButton?: boolean;
|
|
163
|
+
/**
|
|
164
|
+
* If true, will display a timestamp under each messages
|
|
165
|
+
* @default false
|
|
166
|
+
*/
|
|
167
|
+
showTimestamp?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Allows the user to download the conversation history
|
|
170
|
+
* @default true
|
|
171
|
+
*/
|
|
172
|
+
enableTranscriptDownload?: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* Allows the user to delete its conversation history
|
|
175
|
+
* @default false
|
|
176
|
+
*/
|
|
177
|
+
enableConversationDeletion?: boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Close the webchat when pressing the Esc key
|
|
180
|
+
* @default true
|
|
181
|
+
*/
|
|
182
|
+
closeOnEscape?: boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Displays the bot name to the right of its avatar
|
|
185
|
+
* @default ''
|
|
186
|
+
*/
|
|
168
187
|
botName?: string;
|
|
188
|
+
/**
|
|
189
|
+
* Allows to set a custom composer placeholder
|
|
190
|
+
* @default 'Reply to {name}'
|
|
191
|
+
*/
|
|
169
192
|
composerPlaceholder?: string;
|
|
193
|
+
/**
|
|
194
|
+
* Allow to specify a custom URL for the bot's avatar
|
|
195
|
+
* @default '''
|
|
196
|
+
*/
|
|
170
197
|
avatarUrl?: string;
|
|
171
198
|
/** Force the display language of the webchat (en, fr, ar, ru, etc..)
|
|
172
199
|
* Defaults to the user's browser language if not set
|
|
173
200
|
* Set to 'browser' to force use the browser's language
|
|
201
|
+
* @default 'browser'
|
|
174
202
|
*/
|
|
175
203
|
locale?: 'browser' | string;
|
|
176
|
-
/**
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
204
|
+
/**
|
|
205
|
+
* Small description written under the bot's name
|
|
206
|
+
* @default ''
|
|
207
|
+
*/
|
|
208
|
+
botConversationDescription?: string;
|
|
209
|
+
/**
|
|
210
|
+
* When true, the widget button to open the chat is hidden
|
|
211
|
+
* @default false
|
|
212
|
+
*/
|
|
213
|
+
hideWidget?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Disable the slide in / out animations of the webchat
|
|
216
|
+
* @default false
|
|
217
|
+
*/
|
|
218
|
+
disableAnimations?: boolean;
|
|
219
|
+
/**
|
|
220
|
+
* When true, webchat displays a voice icon in the composer to send voice messages (must use Google Speech integration)
|
|
221
|
+
* @default false
|
|
222
|
+
*/
|
|
223
|
+
enableVoiceComposer?: boolean;
|
|
224
|
+
/**
|
|
225
|
+
* Use sessionStorage instead of localStorage, which means the session expires when tab is closed
|
|
226
|
+
* @default false
|
|
227
|
+
*/
|
|
228
|
+
useSessionStorage?: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Sends an event to the parent container with the width provided
|
|
231
|
+
* @default 360
|
|
232
|
+
*/
|
|
192
233
|
containerWidth?: string | number;
|
|
234
|
+
/**
|
|
235
|
+
* Sets the width of the webchat
|
|
236
|
+
* @default 360
|
|
237
|
+
*/
|
|
193
238
|
layoutWidth?: string | number;
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
|
|
201
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Show Powered By Botpress in the footer
|
|
241
|
+
* @default false
|
|
242
|
+
*/
|
|
243
|
+
showPoweredBy?: boolean;
|
|
244
|
+
/**
|
|
245
|
+
* When enabled, sent messages are persisted to local storage (recall previous messages)
|
|
246
|
+
* @default true
|
|
247
|
+
*/
|
|
248
|
+
enablePersistHistory?: boolean;
|
|
249
|
+
/**
|
|
250
|
+
* Experimental: expose the store to the parent frame for more control on the webchat's behavior
|
|
251
|
+
* @default false
|
|
252
|
+
*/
|
|
253
|
+
exposeStore?: boolean;
|
|
254
|
+
/**
|
|
255
|
+
* If true, Websocket is created when the Webchat is opened. Bot cannot be proactive.
|
|
256
|
+
* @default false
|
|
257
|
+
*/
|
|
202
258
|
lazySocket?: boolean;
|
|
203
|
-
/**
|
|
259
|
+
/**
|
|
260
|
+
* If true, chat will no longer play the notification sound for new messages.
|
|
261
|
+
* @default false
|
|
262
|
+
*/
|
|
204
263
|
disableNotificationSound?: boolean;
|
|
205
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* Refers to a specific webchat reference in parent window. Useful when using multiple chat window
|
|
266
|
+
* @default ''
|
|
267
|
+
*/
|
|
206
268
|
chatId?: string;
|
|
207
|
-
/**
|
|
269
|
+
/**
|
|
270
|
+
* CSS class to be applied to iframe
|
|
271
|
+
* @default '''
|
|
272
|
+
*/
|
|
208
273
|
className?: string;
|
|
209
|
-
/** Key used to encrypt data in the localStorage */
|
|
210
|
-
encryptionKey?: string;
|
|
211
|
-
}
|
|
212
|
-
export declare type OverridableComponents = 'below_conversation' | 'before_container' | 'composer';
|
|
213
|
-
export interface Overrides {
|
|
214
|
-
[componentToOverride: string]: [
|
|
215
|
-
{
|
|
216
|
-
module: string;
|
|
217
|
-
component: string;
|
|
218
|
-
}
|
|
219
|
-
];
|
|
220
274
|
}
|
|
221
275
|
export interface BotDetails {
|
|
222
276
|
website?: string;
|
|
@@ -225,6 +279,7 @@ export interface BotDetails {
|
|
|
225
279
|
privacyPolicy?: string;
|
|
226
280
|
emailAddress?: string;
|
|
227
281
|
avatarUrl?: string;
|
|
282
|
+
coverPictureUrl?: string;
|
|
228
283
|
}
|
|
229
284
|
export interface BotInfo {
|
|
230
285
|
name: string;
|
|
@@ -236,6 +291,8 @@ export interface BotInfo {
|
|
|
236
291
|
escapeHTML: boolean;
|
|
237
292
|
};
|
|
238
293
|
lazySocket: boolean;
|
|
294
|
+
extraStylesheet?: string;
|
|
295
|
+
disableNotificationSound?: boolean;
|
|
239
296
|
}
|
|
240
297
|
export declare type uuid = string;
|
|
241
298
|
export interface Conversation {
|
|
@@ -298,13 +355,6 @@ export interface CustomAction {
|
|
|
298
355
|
/** The event triggered when the action is clicked */
|
|
299
356
|
onClick: (actionId: string, messageProps: any, event: React.MouseEvent) => void;
|
|
300
357
|
}
|
|
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
358
|
export interface EventFeedback {
|
|
309
359
|
messageId: uuid;
|
|
310
360
|
feedback?: number;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const initializeAnalytics: () => void;
|
|
2
|
+
export declare type MessageDirection = 'sent' | 'received';
|
|
3
|
+
export declare const trackMessage: (direction: MessageDirection) => void;
|
|
4
|
+
export declare type WebchatState = 'show' | 'hide' | 'toggle';
|
|
5
|
+
export declare const trackWebchatState: (state: WebchatState) => void;
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
exports.trackWebchatState = exports.trackMessage = exports.initializeAnalytics = void 0;
|
|
7
|
+
const react_ga_1 = __importDefault(require("react-ga"));
|
|
8
|
+
const initializeAnalytics = () => {
|
|
9
|
+
if (window.SEND_USAGE_STATS) {
|
|
10
|
+
try {
|
|
11
|
+
react_ga_1.default.initialize('UA-90044826-2');
|
|
12
|
+
react_ga_1.default.pageview(`${window.location.pathname}${window.location.search}`);
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.error('Error initializing analytics', err);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
exports.initializeAnalytics = initializeAnalytics;
|
|
20
|
+
const trackMessage = (direction) => {
|
|
21
|
+
if (window.SEND_USAGE_STATS) {
|
|
22
|
+
try {
|
|
23
|
+
react_ga_1.default.event({ category: 'Interactions', action: `message ${direction}` });
|
|
24
|
+
}
|
|
25
|
+
catch (_a) { }
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.trackMessage = trackMessage;
|
|
29
|
+
const trackWebchatState = (state) => {
|
|
30
|
+
if (window.SEND_USAGE_STATS) {
|
|
31
|
+
try {
|
|
32
|
+
react_ga_1.default.event({ category: 'Display', action: state });
|
|
33
|
+
}
|
|
34
|
+
catch (_a) { }
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
exports.trackWebchatState = trackWebchatState;
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
exports.renderUnsafeHTML = exports.downloadFile = exports.isIE = void 0;
|
|
7
|
+
const snarkdown_1 = __importDefault(require("snarkdown"));
|
|
8
|
+
exports.isIE = window.navigator.userAgent.match(/MSIE|Trident/) !== null;
|
|
9
|
+
const downloadFile = (name, blob) => {
|
|
10
|
+
const url = window.URL.createObjectURL(blob);
|
|
11
|
+
const link = document.createElement('a');
|
|
12
|
+
link.href = url;
|
|
13
|
+
link.setAttribute('download', name);
|
|
14
|
+
document.body.appendChild(link);
|
|
15
|
+
link.click();
|
|
16
|
+
document.body.removeChild(link);
|
|
17
|
+
window.URL.revokeObjectURL(url);
|
|
18
|
+
};
|
|
19
|
+
exports.downloadFile = downloadFile;
|
|
20
|
+
const renderUnsafeHTML = (message = '', escaped) => {
|
|
21
|
+
if (escaped) {
|
|
22
|
+
message = message.replace(/</g, '<').replace(/>/g, '>');
|
|
23
|
+
}
|
|
24
|
+
const html = (0, snarkdown_1.default)(message);
|
|
25
|
+
return html.replace(/<a href/gi, '<a target="_blank" href');
|
|
26
|
+
};
|
|
27
|
+
exports.renderUnsafeHTML = renderUnsafeHTML;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Config } from '../typings';
|
|
2
|
+
export declare class BPStorage {
|
|
3
|
+
private _config?;
|
|
4
|
+
private _storage;
|
|
5
|
+
constructor(config?: Config);
|
|
6
|
+
get config(): Config | undefined;
|
|
7
|
+
set config(config: Config | undefined);
|
|
8
|
+
private serialize;
|
|
9
|
+
private deserialize;
|
|
10
|
+
private getStorageKey;
|
|
11
|
+
private getDriver;
|
|
12
|
+
set<T>(key: string, value: T): void;
|
|
13
|
+
get<T = string>(key: string): T | undefined;
|
|
14
|
+
del(key: string): void;
|
|
15
|
+
}
|
|
16
|
+
export default BPStorage;
|
|
@@ -0,0 +1,129 @@
|
|
|
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
|
+
exports.BPStorage = void 0;
|
|
7
|
+
const aes_1 = __importDefault(require("crypto-js/aes"));
|
|
8
|
+
const enc_utf8_1 = __importDefault(require("crypto-js/enc-utf8"));
|
|
9
|
+
const sha256_1 = __importDefault(require("crypto-js/sha256"));
|
|
10
|
+
const js_cookie_1 = __importDefault(require("js-cookie"));
|
|
11
|
+
class BPStorage {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.serialize = (value) => {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
if (value === null || value === undefined) {
|
|
16
|
+
throw new Error('[Storage] Cannot store null or undefined values');
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
let str = '';
|
|
20
|
+
if (typeof value === 'string') {
|
|
21
|
+
str = value;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
str = JSON.stringify(value);
|
|
25
|
+
}
|
|
26
|
+
if ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.encryptionKey) === null || _b === void 0 ? void 0 : _b.length) {
|
|
27
|
+
str = aes_1.default.encrypt(str, this.config.encryptionKey).toString();
|
|
28
|
+
}
|
|
29
|
+
return str;
|
|
30
|
+
}
|
|
31
|
+
catch (_c) {
|
|
32
|
+
console.error('[Storage] Error parsing value', value);
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
this.deserialize = (strValue) => {
|
|
37
|
+
var _a, _b;
|
|
38
|
+
if (strValue === null || strValue === undefined) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
if ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.encryptionKey) === null || _b === void 0 ? void 0 : _b.length) {
|
|
43
|
+
strValue = aes_1.default.decrypt(strValue, this.config.encryptionKey).toString(enc_utf8_1.default);
|
|
44
|
+
}
|
|
45
|
+
return JSON.parse(strValue);
|
|
46
|
+
}
|
|
47
|
+
catch (_c) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
this.getStorageKey = (key) => {
|
|
52
|
+
var _a, _b, _c;
|
|
53
|
+
const rawKey = `bp-chat-${key}`;
|
|
54
|
+
if ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.encryptionKey) === null || _b === void 0 ? void 0 : _b.length) {
|
|
55
|
+
return `${rawKey}-${(0, sha256_1.default)(`${this.config.clientId}-${this.config.encryptionKey}`).toString()}`;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return `${rawKey}-${(_c = this.config) === null || _c === void 0 ? void 0 : _c.clientId}`;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
this.getDriver = () => {
|
|
62
|
+
var _a;
|
|
63
|
+
if (this._storage) {
|
|
64
|
+
return this._storage;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const storage = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.useSessionStorage) === true && typeof sessionStorage !== 'undefined' ? sessionStorage : localStorage;
|
|
68
|
+
const tempKey = '__storage_test__';
|
|
69
|
+
storage.setItem(tempKey, tempKey);
|
|
70
|
+
storage.removeItem(tempKey);
|
|
71
|
+
return (this._storage = storage);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
return (this._storage = 'cookie');
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
if (config) {
|
|
78
|
+
this._config = config;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
get config() {
|
|
82
|
+
return this._config;
|
|
83
|
+
}
|
|
84
|
+
set config(config) {
|
|
85
|
+
this._config = config;
|
|
86
|
+
}
|
|
87
|
+
set(key, value) {
|
|
88
|
+
if (!this.config) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const driver = this.getDriver();
|
|
93
|
+
driver !== 'cookie'
|
|
94
|
+
? driver.setItem(this.getStorageKey(key), this.serialize(value))
|
|
95
|
+
: js_cookie_1.default.set(this.getStorageKey(key), this.serialize(value));
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
console.error('Error while setting data into storage.', err.message);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
get(key) {
|
|
102
|
+
if (!this.config) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const driver = this.getDriver();
|
|
107
|
+
return driver !== 'cookie'
|
|
108
|
+
? this.deserialize(driver.getItem(this.getStorageKey(key)))
|
|
109
|
+
: this.deserialize(js_cookie_1.default.get(this.getStorageKey(key)));
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
console.error('Error while getting data from storage.', err.message);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
del(key) {
|
|
116
|
+
if (!this.config) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
const driver = this.getDriver();
|
|
121
|
+
driver !== 'cookie' ? driver.removeItem(this.getStorageKey(key)) : js_cookie_1.default.remove(this.getStorageKey(key));
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
console.error('Error while deleting data from storage.', err.message);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.BPStorage = BPStorage;
|
|
129
|
+
exports.default = BPStorage;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botpress/webchat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"source": "src/index.tsx",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"@types/crypto-js": "^4.1.1",
|
|
18
|
+
"@types/js-cookie": "^3.0.1",
|
|
18
19
|
"@types/lodash": "^4.14.178",
|
|
19
20
|
"@types/mime": "^2.0.3",
|
|
20
21
|
"@types/node": "^16.11.13",
|
|
@@ -25,7 +26,7 @@
|
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
27
28
|
"@blueprintjs/core": "^3.23.1",
|
|
28
|
-
"@botpress/messaging-components": "0.
|
|
29
|
+
"@botpress/messaging-components": "0.3.0",
|
|
29
30
|
"@botpress/messaging-socket": "1.1.0",
|
|
30
31
|
"@formatjs/intl-pluralrules": "^4.1.6",
|
|
31
32
|
"@formatjs/intl-utils": "^3.8.4",
|
|
@@ -34,11 +35,11 @@
|
|
|
34
35
|
"classnames": "^2.3.1",
|
|
35
36
|
"crypto-js": "^4.1.1",
|
|
36
37
|
"date-fns": "^1.30.1",
|
|
38
|
+
"js-cookie": "^3.0.1",
|
|
37
39
|
"lodash": "^4.17.21",
|
|
38
40
|
"mime": "^3.0.0",
|
|
39
41
|
"mobx": "5.15.7",
|
|
40
42
|
"mobx-react": "^6.2.1",
|
|
41
|
-
"mobx-react-lite": "2.0.0",
|
|
42
43
|
"query-string": "^7.1.0",
|
|
43
44
|
"react": "^17.0.2",
|
|
44
45
|
"react-dom": "^17.0.2",
|
|
@@ -1,33 +0,0 @@
|
|
|
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
|
-
exports.showContextMenu = void 0;
|
|
7
|
-
const core_1 = require("@blueprintjs/core");
|
|
8
|
-
const react_1 = __importDefault(require("react"));
|
|
9
|
-
function MessageMenu(props) {
|
|
10
|
-
return (react_1.default.createElement(core_1.Menu, null, props.customActions.map((action) => {
|
|
11
|
-
return (react_1.default.createElement(core_1.MenuItem, { key: action.id, text: action.label,
|
|
12
|
-
// TODO: undefined is supposed to be "this". Does that make sense??
|
|
13
|
-
onClick: action.onClick.bind(undefined, action.id, props.element) }));
|
|
14
|
-
})));
|
|
15
|
-
}
|
|
16
|
-
const showContextMenu = (e, props) => {
|
|
17
|
-
const customActions = props.store.view.customActions;
|
|
18
|
-
if (props.store.config.isEmulator) {
|
|
19
|
-
customActions.push({
|
|
20
|
-
id: 'actionDebug',
|
|
21
|
-
label: 'Inspect in Debugger',
|
|
22
|
-
onClick: (_actionId, props) => {
|
|
23
|
-
props.store.loadEventInDebugger(props.incomingEventId, true);
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
if (customActions && props.incomingEventId) {
|
|
28
|
-
e.preventDefault();
|
|
29
|
-
const menu = react_1.default.createElement(MessageMenu, { element: props, customActions: customActions });
|
|
30
|
-
core_1.ContextMenu.show(menu, { left: e.clientX, top: e.clientY });
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
exports.showContextMenu = showContextMenu;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Overrides } from '../typings';
|
|
3
|
-
declare class OverridableComponent extends React.Component<Props, State> {
|
|
4
|
-
state: State;
|
|
5
|
-
componentDidMount(): void;
|
|
6
|
-
componentDidUpdate(prevProps: Props): void;
|
|
7
|
-
componentDidCatch(error: any, info: any): void;
|
|
8
|
-
loadComponents(): void;
|
|
9
|
-
resolveComponents: () => {
|
|
10
|
-
key: string;
|
|
11
|
-
element: any;
|
|
12
|
-
}[] | undefined;
|
|
13
|
-
render(): any;
|
|
14
|
-
}
|
|
15
|
-
declare const _default: typeof OverridableComponent & import("mobx-react").IWrappedComponent<unknown>;
|
|
16
|
-
export default _default;
|
|
17
|
-
interface Props {
|
|
18
|
-
name: string;
|
|
19
|
-
overrides?: Overrides;
|
|
20
|
-
original?: any;
|
|
21
|
-
}
|
|
22
|
-
interface State {
|
|
23
|
-
components: any;
|
|
24
|
-
}
|