@botpress/webchat 0.2.5 → 0.3.2
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/assets/fonts/roboto/roboto.woff2 +0 -0
- package/assets/fonts/roboto/roboto500.woff2 +0 -0
- package/assets/fonts/roboto.css +128 -0
- package/assets/notification.mp3 +0 -0
- package/dist/components/Composer.d.ts +4 -5
- package/dist/components/Composer.js +16 -25
- package/dist/components/Container.js +1 -4
- 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 +7 -37
- package/dist/components/common/BotInfo/index.d.ts +1 -1
- package/dist/components/common/BotInfo/index.js +4 -14
- package/dist/components/messages/InlineFeedback.d.ts +2 -1
- package/dist/components/messages/Message.js +3 -6
- package/dist/components/messages/MessageGroup.d.ts +1 -5
- package/dist/components/messages/MessageGroup.js +4 -7
- package/dist/components/messages/MessageList.d.ts +1 -1
- package/dist/components/messages/MessageList.js +7 -29
- package/dist/core/api.d.ts +2 -6
- package/dist/core/api.js +4 -32
- package/dist/core/constants.d.ts +4 -32
- package/dist/core/constants.js +18 -32
- package/dist/core/socket.d.ts +1 -7
- package/dist/core/socket.js +8 -30
- package/dist/index.d.ts +2 -8
- package/dist/index.js +6 -27
- package/dist/main.d.ts +2 -2
- package/dist/main.js +84 -135
- package/dist/store/composer.js +1 -1
- package/dist/store/index.d.ts +4 -8
- package/dist/store/index.js +25 -62
- package/dist/store/view.d.ts +3 -4
- package/dist/store/view.js +6 -13
- package/dist/translations/index.d.ts +2 -1
- package/dist/translations/index.js +36 -1
- package/dist/typings.d.ts +123 -55
- 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/package.json +6 -5
- package/dist/components/ContextMenu.d.ts +0 -2
- package/dist/components/ContextMenu.js +0 -24
- package/dist/components/OverridableComponent.d.ts +0 -24
- package/dist/components/OverridableComponent.js +0 -50
- package/dist/components/Stylesheet.d.ts +0 -5
- package/dist/components/Stylesheet.js +0 -7
- package/dist/components/common/MoreOptions/index.d.ts +0 -21
- package/dist/components/common/MoreOptions/index.js +0 -60
- package/dist/components/common/Overlay/index.d.ts +0 -7
- package/dist/components/common/Overlay/index.js +0 -36
- 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
package/dist/store/view.js
CHANGED
|
@@ -35,8 +35,8 @@ class ViewStore {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
get showConversationsButton() {
|
|
38
|
-
var _a
|
|
39
|
-
return
|
|
38
|
+
var _a;
|
|
39
|
+
return (_a = this.rootStore.config) === null || _a === void 0 ? void 0 : _a.showConversationsButton;
|
|
40
40
|
}
|
|
41
41
|
get showBotInfoButton() {
|
|
42
42
|
return !this.isConversationsDisplayed && this.rootStore.botInfo && this.rootStore.botInfo.showBotInfoPage;
|
|
@@ -47,10 +47,6 @@ class ViewStore {
|
|
|
47
47
|
get showDeleteConversationButton() {
|
|
48
48
|
return (!this.isConversationsDisplayed && !this.isBotInfoDisplayed && this.rootStore.config.enableConversationDeletion);
|
|
49
49
|
}
|
|
50
|
-
get showResetButton() {
|
|
51
|
-
var _a;
|
|
52
|
-
return !this.isConversationsDisplayed && !this.isBotInfoDisplayed && ((_a = this.rootStore.config) === null || _a === void 0 ? void 0 : _a.enableReset);
|
|
53
|
-
}
|
|
54
50
|
get showCloseButton() {
|
|
55
51
|
return !this.isFullscreen;
|
|
56
52
|
}
|
|
@@ -167,7 +163,7 @@ class ViewStore {
|
|
|
167
163
|
this._updateTransitions({ widgetTransition: 'fadeOut' });
|
|
168
164
|
setTimeout(() => {
|
|
169
165
|
this._updateTransitions({ sideTransition: 'fadeIn' });
|
|
170
|
-
}, constants_1.default.
|
|
166
|
+
}, constants_1.default.ANIMATION_DURATION + 10);
|
|
171
167
|
this._endAnimation('side');
|
|
172
168
|
this.rootStore.postMessage('webchatOpened');
|
|
173
169
|
}
|
|
@@ -184,7 +180,7 @@ class ViewStore {
|
|
|
184
180
|
if (!this.activeView || this.activeView === 'side') {
|
|
185
181
|
setTimeout(() => {
|
|
186
182
|
this._updateTransitions({ widgetTransition: 'fadeIn' });
|
|
187
|
-
}, constants_1.default.
|
|
183
|
+
}, constants_1.default.ANIMATION_DURATION + 10);
|
|
188
184
|
}
|
|
189
185
|
this._endAnimation('widget');
|
|
190
186
|
this.rootStore.postMessage('webchatClosed');
|
|
@@ -194,13 +190,13 @@ class ViewStore {
|
|
|
194
190
|
(0, mobx_1.runInAction)(() => {
|
|
195
191
|
this.activeView = finalView;
|
|
196
192
|
});
|
|
197
|
-
}, constants_1.default.
|
|
193
|
+
}, constants_1.default.ANIMATION_DURATION);
|
|
198
194
|
setTimeout(() => {
|
|
199
195
|
this._updateTransitions({
|
|
200
196
|
widgetTransition: undefined,
|
|
201
197
|
sideTransition: this.transitions.sideTransition === 'fadeIn' ? 'fadeIn' : undefined
|
|
202
198
|
});
|
|
203
|
-
}, constants_1.default.
|
|
199
|
+
}, constants_1.default.ANIMATION_DURATION * 2.1);
|
|
204
200
|
}
|
|
205
201
|
_updateTransitions({ widgetTransition, sideTransition }) {
|
|
206
202
|
this.transitions = { widgetTransition, sideTransition };
|
|
@@ -268,9 +264,6 @@ __decorate([
|
|
|
268
264
|
__decorate([
|
|
269
265
|
mobx_1.computed
|
|
270
266
|
], ViewStore.prototype, "showDeleteConversationButton", null);
|
|
271
|
-
__decorate([
|
|
272
|
-
mobx_1.computed
|
|
273
|
-
], ViewStore.prototype, "showResetButton", null);
|
|
274
267
|
__decorate([
|
|
275
268
|
mobx_1.computed
|
|
276
269
|
], ViewStore.prototype, "showCloseButton", null);
|
|
@@ -5,4 +5,5 @@ declare const translations: {
|
|
|
5
5
|
};
|
|
6
6
|
declare const getUserLocale: (manualLocale?: Locale) => string;
|
|
7
7
|
declare const setUserLocale: (locale: Locale) => void;
|
|
8
|
-
|
|
8
|
+
declare const isRTLLocale: (locale?: string | undefined) => boolean;
|
|
9
|
+
export { translations, DEFAULT_LOCALE as defaultLocale, getUserLocale, setUserLocale, isRTLLocale };
|
|
@@ -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.setUserLocale = 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');
|
|
@@ -28,6 +28,29 @@ exports.defaultLocale = DEFAULT_LOCALE;
|
|
|
28
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
56
|
const getStorageLanguage = () => cleanLanguageCode(window.BP_STORAGE.get(USER_LANG_STORAGE_KEY) || '');
|
|
@@ -58,3 +81,15 @@ const setUserLocale = (locale) => {
|
|
|
58
81
|
setStorageLanguage(locale);
|
|
59
82
|
};
|
|
60
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
|
@@ -9,7 +9,6 @@ declare global {
|
|
|
9
9
|
store: RootStore;
|
|
10
10
|
BOT_ID: string;
|
|
11
11
|
SEND_USAGE_STATS: boolean;
|
|
12
|
-
SHOW_POWERED_BY: boolean;
|
|
13
12
|
USE_SESSION_STORAGE: boolean;
|
|
14
13
|
BP_STORAGE: BPStorage;
|
|
15
14
|
botpress: {
|
|
@@ -139,77 +138,145 @@ export interface StudioConnector {
|
|
|
139
138
|
export interface Config {
|
|
140
139
|
/** Url of the messaging server */
|
|
141
140
|
messagingUrl: string;
|
|
142
|
-
/** Url of the Media File Service where we fetch the bot info */
|
|
143
|
-
mediaFileServiceUrl?: string;
|
|
144
141
|
/** Id of your messaging client */
|
|
145
142
|
clientId: string;
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
+
*/
|
|
153
157
|
stylesheet?: string;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
+
*/
|
|
163
187
|
botName?: string;
|
|
188
|
+
/**
|
|
189
|
+
* Allows to set a custom composer placeholder
|
|
190
|
+
* @default 'Reply to {name}'
|
|
191
|
+
*/
|
|
164
192
|
composerPlaceholder?: string;
|
|
193
|
+
/**
|
|
194
|
+
* Allow to specify a custom URL for the bot's avatar
|
|
195
|
+
* @default '''
|
|
196
|
+
*/
|
|
165
197
|
avatarUrl?: string;
|
|
166
198
|
/** Force the display language of the webchat (en, fr, ar, ru, etc..)
|
|
167
199
|
* Defaults to the user's browser language if not set
|
|
168
200
|
* Set to 'browser' to force use the browser's language
|
|
201
|
+
* @default 'browser'
|
|
169
202
|
*/
|
|
170
203
|
locale?: 'browser' | string;
|
|
171
|
-
/**
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
+
*/
|
|
187
233
|
containerWidth?: string | number;
|
|
234
|
+
/**
|
|
235
|
+
* Sets the width of the webchat
|
|
236
|
+
* @default 360
|
|
237
|
+
*/
|
|
188
238
|
layoutWidth?: string | number;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
/**
|
|
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
|
+
*/
|
|
195
258
|
lazySocket?: boolean;
|
|
196
|
-
/**
|
|
259
|
+
/**
|
|
260
|
+
* If true, chat will no longer play the notification sound for new messages.
|
|
261
|
+
* @default false
|
|
262
|
+
*/
|
|
197
263
|
disableNotificationSound?: boolean;
|
|
198
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* Refers to a specific webchat reference in parent window. Useful when using multiple chat window
|
|
266
|
+
* @default ''
|
|
267
|
+
*/
|
|
199
268
|
chatId?: string;
|
|
200
|
-
/**
|
|
269
|
+
/**
|
|
270
|
+
* CSS class to be applied to iframe
|
|
271
|
+
* @default ''
|
|
272
|
+
*/
|
|
201
273
|
className?: string;
|
|
202
|
-
/**
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
{
|
|
209
|
-
module: string;
|
|
210
|
-
component: string;
|
|
211
|
-
}
|
|
212
|
-
];
|
|
274
|
+
/**
|
|
275
|
+
* Google Maps API Key required to display the map.
|
|
276
|
+
* Will display a link to Google Maps otherwise
|
|
277
|
+
* @default ''
|
|
278
|
+
*/
|
|
279
|
+
googleMapsAPIKey?: string;
|
|
213
280
|
}
|
|
214
281
|
export interface BotDetails {
|
|
215
282
|
website?: string;
|
|
@@ -218,6 +285,7 @@ export interface BotDetails {
|
|
|
218
285
|
privacyPolicy?: string;
|
|
219
286
|
emailAddress?: string;
|
|
220
287
|
avatarUrl?: string;
|
|
288
|
+
coverPictureUrl?: string;
|
|
221
289
|
}
|
|
222
290
|
export interface BotInfo {
|
|
223
291
|
name: string;
|
|
@@ -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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botpress/webchat",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"source": "src/index.tsx",
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "yarn && yarn run -T tsc --build",
|
|
10
10
|
"watch": "yarn && yarn run -T tsc --build --watch",
|
|
11
|
+
"dev": "yarn run -T parcel test/index.html",
|
|
11
12
|
"prepublish": "yarn run -T rimraf dist && yarn --immutable && yarn run -T tsc --build && yarn run -T rimraf dist/.tsbuildinfo"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
|
-
"dist"
|
|
15
|
+
"dist",
|
|
16
|
+
"assets"
|
|
15
17
|
],
|
|
16
18
|
"devDependencies": {
|
|
17
19
|
"@types/crypto-js": "^4.1.1",
|
|
@@ -26,8 +28,8 @@
|
|
|
26
28
|
},
|
|
27
29
|
"dependencies": {
|
|
28
30
|
"@blueprintjs/core": "^3.23.1",
|
|
29
|
-
"@botpress/messaging-components": "0.
|
|
30
|
-
"@botpress/messaging-socket": "1.1.
|
|
31
|
+
"@botpress/messaging-components": "0.3.0",
|
|
32
|
+
"@botpress/messaging-socket": "1.1.1",
|
|
31
33
|
"@formatjs/intl-pluralrules": "^4.1.6",
|
|
32
34
|
"@formatjs/intl-utils": "^3.8.4",
|
|
33
35
|
"@juggle/resize-observer": "^3.0.2",
|
|
@@ -40,7 +42,6 @@
|
|
|
40
42
|
"mime": "^3.0.0",
|
|
41
43
|
"mobx": "5.15.7",
|
|
42
44
|
"mobx-react": "^6.2.1",
|
|
43
|
-
"mobx-react-lite": "2.0.0",
|
|
44
45
|
"query-string": "^7.1.0",
|
|
45
46
|
"react": "^17.0.2",
|
|
46
47
|
"react-dom": "^17.0.2",
|
|
@@ -1,24 +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 (customActions && props.incomingEventId) {
|
|
19
|
-
e.preventDefault();
|
|
20
|
-
const menu = react_1.default.createElement(MessageMenu, { element: props, customActions: customActions });
|
|
21
|
-
core_1.ContextMenu.show(menu, { left: e.clientX, top: e.clientY });
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
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
|
-
}
|
|
@@ -1,50 +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
|
-
const mobx_react_1 = require("mobx-react");
|
|
7
|
-
const react_1 = __importDefault(require("react"));
|
|
8
|
-
class OverridableComponent extends react_1.default.Component {
|
|
9
|
-
constructor() {
|
|
10
|
-
super(...arguments);
|
|
11
|
-
this.state = {
|
|
12
|
-
components: undefined
|
|
13
|
-
};
|
|
14
|
-
this.resolveComponents = () => {
|
|
15
|
-
var _a, _b;
|
|
16
|
-
return (_b = (_a = this.props.overrides) === null || _a === void 0 ? void 0 : _a[this.props.name]) === null || _b === void 0 ? void 0 : _b.map(({ module, component }) => {
|
|
17
|
-
var _a;
|
|
18
|
-
return ({
|
|
19
|
-
key: `${module}:${component}`,
|
|
20
|
-
element: (_a = window.botpress[module]) === null || _a === void 0 ? void 0 : _a[component]
|
|
21
|
-
});
|
|
22
|
-
}).filter((x) => x.element);
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
componentDidMount() {
|
|
26
|
-
this.loadComponents();
|
|
27
|
-
}
|
|
28
|
-
componentDidUpdate(prevProps) {
|
|
29
|
-
if (prevProps.overrides !== this.props.overrides) {
|
|
30
|
-
this.loadComponents();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
componentDidCatch(error, info) {
|
|
34
|
-
console.error(`Error in overridable component ${this.props.name}. Loading original component.`, error, info);
|
|
35
|
-
this.setState({ components: [{ key: 'original', element: this.props.original }] });
|
|
36
|
-
}
|
|
37
|
-
loadComponents() {
|
|
38
|
-
this.setState({ components: this.resolveComponents() || [{ key: 'original', element: this.props.original }] });
|
|
39
|
-
}
|
|
40
|
-
render() {
|
|
41
|
-
const { components } = this.state;
|
|
42
|
-
return components
|
|
43
|
-
? components.map(({ element: Element, key }) => Element && react_1.default.createElement(Element, Object.assign({ key: key }, this.props)))
|
|
44
|
-
: null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
exports.default = (0, mobx_react_1.inject)(({ store }) => ({
|
|
48
|
-
store,
|
|
49
|
-
overrides: store.config.overrides
|
|
50
|
-
}))(OverridableComponent);
|
|
@@ -1,7 +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
|
-
const react_1 = __importDefault(require("react"));
|
|
7
|
-
exports.default = ({ href }) => react_1.default.createElement("link", { rel: "stylesheet", type: "text/css", href: href });
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { IconName } from '@blueprintjs/core';
|
|
2
|
-
import { FC } from 'react';
|
|
3
|
-
interface MoreOptionsProps {
|
|
4
|
-
show: boolean;
|
|
5
|
-
onToggle: (value: boolean) => void;
|
|
6
|
-
children?: any;
|
|
7
|
-
className?: string;
|
|
8
|
-
element?: JSX.Element;
|
|
9
|
-
items: MoreOptionsItems[];
|
|
10
|
-
}
|
|
11
|
-
export interface MoreOptionsItems {
|
|
12
|
-
icon?: IconName;
|
|
13
|
-
label: string;
|
|
14
|
-
className?: string;
|
|
15
|
-
selected?: boolean;
|
|
16
|
-
content?: JSX.Element;
|
|
17
|
-
action?: () => void;
|
|
18
|
-
type?: 'delete';
|
|
19
|
-
}
|
|
20
|
-
declare const MoreOptions: FC<MoreOptionsProps>;
|
|
21
|
-
export default MoreOptions;
|