@botpress/webchat 0.5.0 → 0.5.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 +12 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/components/Composer.js +6 -5
- package/dist/components/ConditionalWrap.d.ts +6 -0
- package/dist/components/ConditionalWrap.js +5 -0
- package/dist/components/common/Avatar/index.d.ts +2 -2
- package/dist/components/common/Avatar/index.js +1 -1
- package/dist/components/common/BotInfo/index.d.ts +1 -1
- package/dist/components/common/BotInfo/index.js +28 -23
- package/dist/components/messages/Message.js +4 -4
- package/dist/components/messages/MessageList.js +70 -75
- package/dist/core/api.js +1 -1
- package/dist/core/socket.d.ts +1 -0
- package/dist/core/socket.js +5 -1
- package/dist/declaration.d.ts +1 -0
- package/dist/main.js +60 -18
- package/dist/store/index.d.ts +10 -1
- package/dist/store/index.js +34 -3
- package/dist/store/view.js +7 -3
- package/dist/typings.d.ts +61 -3
- package/package.json +7 -4
- package/dist/components/common/BotInfo/style.scss +0 -88
- package/dist/components/common/ConfirmDialog/style.module.scss +0 -48
- package/dist/components/common/Dialog/style.module.scss +0 -29
- package/dist/components/common/ToolTip/style.module.scss +0 -108
- package/dist/components/common/variables.scss +0 -38
|
@@ -1,90 +1,89 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
23
|
};
|
|
5
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const resize_observer_1 = require("@juggle/resize-observer");
|
|
7
25
|
const difference_in_minutes_1 = __importDefault(require("date-fns/difference_in_minutes"));
|
|
8
|
-
const
|
|
26
|
+
const last_1 = __importDefault(require("lodash/last"));
|
|
9
27
|
const mobx_1 = require("mobx");
|
|
10
28
|
const mobx_react_1 = require("mobx-react");
|
|
11
|
-
const react_1 =
|
|
29
|
+
const react_1 = __importStar(require("react"));
|
|
12
30
|
const react_intl_1 = require("react-intl");
|
|
31
|
+
const react_scroll_to_bottom_1 = __importStar(require("react-scroll-to-bottom"));
|
|
13
32
|
const constants_1 = __importDefault(require("../../core/constants"));
|
|
14
33
|
const Avatar_1 = __importDefault(require("../common/Avatar"));
|
|
15
34
|
const MessageGroup_1 = __importDefault(require("./MessageGroup"));
|
|
16
35
|
class MessageList extends react_1.default.Component {
|
|
17
|
-
constructor() {
|
|
18
|
-
super(...arguments);
|
|
19
|
-
this.state = { showNewMessageIndicator: false, manualScroll: false };
|
|
20
|
-
this.shouldDisplayMessage = (m) => {
|
|
21
|
-
return m.payload.type !== 'postback';
|
|
22
|
-
};
|
|
23
|
-
this.handleScroll = (0, debounce_1.default)((e) => {
|
|
24
|
-
const scroll = this.messagesDiv.scrollHeight - this.messagesDiv.scrollTop - this.messagesDiv.clientHeight;
|
|
25
|
-
const manualScroll = scroll >= 150;
|
|
26
|
-
const showNewMessageIndicator = this.state.showNewMessageIndicator && manualScroll;
|
|
27
|
-
this.setState({ manualScroll, showNewMessageIndicator });
|
|
28
|
-
}, 50);
|
|
29
|
-
}
|
|
30
36
|
componentDidMount() {
|
|
31
|
-
this.tryScrollToBottom(true);
|
|
32
37
|
(0, mobx_1.observe)(this.props.focusedArea, (focus) => {
|
|
33
|
-
|
|
38
|
+
var _a;
|
|
39
|
+
focus.newValue === 'convo' && ((_a = this.messagesDiv) === null || _a === void 0 ? void 0 : _a.focus());
|
|
34
40
|
});
|
|
35
|
-
if (this.props.currentMessages) {
|
|
36
|
-
(0, mobx_1.observe)(this.props.currentMessages, (messages) => {
|
|
37
|
-
if (this.state.manualScroll) {
|
|
38
|
-
if (!this.state.showNewMessageIndicator) {
|
|
39
|
-
this.setState({ showNewMessageIndicator: true });
|
|
40
|
-
}
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
this.tryScrollToBottom();
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
// this should account for keyboard rendering as it triggers a resize of the messagesDiv
|
|
47
|
-
this.divSizeObserver = new resize_observer_1.ResizeObserver((0, debounce_1.default)((_divResizeEntry) => {
|
|
48
|
-
// we don't need to do anything with the resize entry
|
|
49
|
-
this.tryScrollToBottom();
|
|
50
|
-
}, 200, { trailing: true }));
|
|
51
|
-
this.divSizeObserver.observe(this.messagesDiv);
|
|
52
41
|
}
|
|
53
|
-
|
|
54
|
-
|
|
42
|
+
render() {
|
|
43
|
+
return (react_1.default.createElement(react_scroll_to_bottom_1.default, { mode: 'bottom', initialScrollBehavior: 'auto', tabIndex: 0, className: 'bpw-msg-list-scroll-container', scrollViewClassName: 'bpw-msg-list', ref: (m) => {
|
|
44
|
+
this.messagesDiv = m;
|
|
45
|
+
}, followButtonClassName: 'bpw-msg-list-follow' },
|
|
46
|
+
react_1.default.createElement(Content, Object.assign({}, this.props))));
|
|
55
47
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
}
|
|
49
|
+
const Content = (0, mobx_react_1.observer)((props) => {
|
|
50
|
+
var _a, _b;
|
|
51
|
+
const [state, setState] = (0, react_1.useState)({
|
|
52
|
+
showNewMessageIndicator: false,
|
|
53
|
+
messagesLength: undefined
|
|
54
|
+
});
|
|
55
|
+
const scrollToBottom = (0, react_scroll_to_bottom_1.useScrollToBottom)();
|
|
56
|
+
const [sticky] = (0, react_scroll_to_bottom_1.useSticky)();
|
|
57
|
+
(0, react_1.useEffect)(() => {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
const stateUpdate = Object.assign(Object.assign({}, state), { messagesLength: (_a = props === null || props === void 0 ? void 0 : props.currentMessages) === null || _a === void 0 ? void 0 : _a.length });
|
|
60
|
+
if (!sticky && state.messagesLength !== ((_b = props === null || props === void 0 ? void 0 : props.currentMessages) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
61
|
+
setState(Object.assign(Object.assign({}, stateUpdate), { showNewMessageIndicator: true }));
|
|
59
62
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Discard the error
|
|
69
|
-
}
|
|
70
|
-
}, delayed ? 250 : 0);
|
|
71
|
-
}
|
|
72
|
-
renderDate(date) {
|
|
63
|
+
else {
|
|
64
|
+
setState(Object.assign(Object.assign({}, stateUpdate), { showNewMessageIndicator: false }));
|
|
65
|
+
}
|
|
66
|
+
}, [(_a = props === null || props === void 0 ? void 0 : props.currentMessages) === null || _a === void 0 ? void 0 : _a.length, sticky]);
|
|
67
|
+
const shouldDisplayMessage = (m) => {
|
|
68
|
+
return m.payload.type !== 'postback';
|
|
69
|
+
};
|
|
70
|
+
const renderDate = (date) => {
|
|
73
71
|
return (react_1.default.createElement("div", { className: 'bpw-date-container' },
|
|
74
|
-
new Intl.DateTimeFormat(
|
|
72
|
+
new Intl.DateTimeFormat(props.intl.locale || 'en', {
|
|
75
73
|
month: 'short',
|
|
76
74
|
day: 'numeric',
|
|
77
75
|
hour: 'numeric',
|
|
78
76
|
minute: 'numeric'
|
|
79
77
|
}).format(new Date(date)),
|
|
80
78
|
react_1.default.createElement("div", { className: 'bpw-small-line' })));
|
|
81
|
-
}
|
|
82
|
-
renderAvatar(name, url) {
|
|
79
|
+
};
|
|
80
|
+
const renderAvatar = (name, url) => {
|
|
83
81
|
const avatarSize = 40;
|
|
84
82
|
return react_1.default.createElement(Avatar_1.default, { name: name, avatarUrl: url, height: avatarSize, width: avatarSize });
|
|
85
|
-
}
|
|
86
|
-
renderMessageGroups() {
|
|
87
|
-
|
|
83
|
+
};
|
|
84
|
+
const renderMessageGroups = () => {
|
|
85
|
+
var _a;
|
|
86
|
+
const messages = (props.currentMessages || []).filter((m) => shouldDisplayMessage(m));
|
|
88
87
|
const groups = [];
|
|
89
88
|
let lastSpeaker = undefined;
|
|
90
89
|
let lastDate = undefined;
|
|
@@ -106,7 +105,7 @@ class MessageList extends react_1.default.Component {
|
|
|
106
105
|
lastSpeaker = speaker;
|
|
107
106
|
lastDate = date;
|
|
108
107
|
});
|
|
109
|
-
if (
|
|
108
|
+
if ((_a = props === null || props === void 0 ? void 0 : props.isBotTyping) === null || _a === void 0 ? void 0 : _a.get()) {
|
|
110
109
|
if (lastSpeaker !== 'bot') {
|
|
111
110
|
currentGroup = [];
|
|
112
111
|
groups.push(currentGroup);
|
|
@@ -123,24 +122,20 @@ class MessageList extends react_1.default.Component {
|
|
|
123
122
|
const groupDate = group === null || group === void 0 ? void 0 : group[0].sentOn;
|
|
124
123
|
const isDateNeeded = !groups[i - 1] ||
|
|
125
124
|
(0, difference_in_minutes_1.default)(new Date(groupDate), new Date(lastDate)) > constants_1.default.TIME_BETWEEN_DATES;
|
|
126
|
-
const
|
|
127
|
-
const avatar = !authorId &&
|
|
125
|
+
const { authorId } = (0, last_1.default)(group);
|
|
126
|
+
const avatar = !authorId && renderAvatar(props.botName, props.botAvatarUrl);
|
|
128
127
|
return (react_1.default.createElement("div", { key: i },
|
|
129
|
-
isDateNeeded &&
|
|
128
|
+
isDateNeeded && renderDate(group[0].sentOn),
|
|
130
129
|
react_1.default.createElement(MessageGroup_1.default, { isBot: !authorId, avatar: avatar, key: `msg-group-${i}`, isLastGroup: i >= groups.length - 1, messages: group })));
|
|
131
130
|
})));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
})))),
|
|
141
|
-
this.renderMessageGroups()));
|
|
142
|
-
}
|
|
143
|
-
}
|
|
131
|
+
};
|
|
132
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
133
|
+
state.showNewMessageIndicator && (react_1.default.createElement("div", { className: "bpw-new-messages-indicator", onClick: (e) => scrollToBottom() },
|
|
134
|
+
react_1.default.createElement("span", null, props.intl.formatMessage({
|
|
135
|
+
id: `messages.newMessage${((_b = props === null || props === void 0 ? void 0 : props.currentMessages) === null || _b === void 0 ? void 0 : _b.length) === 1 ? '' : 's'}`
|
|
136
|
+
})))),
|
|
137
|
+
renderMessageGroups()));
|
|
138
|
+
});
|
|
144
139
|
exports.default = (0, mobx_react_1.inject)(({ store }) => ({
|
|
145
140
|
intl: store.intl,
|
|
146
141
|
botName: store.botName,
|
package/dist/core/api.js
CHANGED
|
@@ -50,7 +50,7 @@ class WebchatApi {
|
|
|
50
50
|
try {
|
|
51
51
|
const conversation = yield this.socket.socket.getConversation(conversationId);
|
|
52
52
|
this.socket.socket.switchConversation(conversation.id);
|
|
53
|
-
const messages = (yield this.socket.socket.listMessages()).filter((x) => x.payload.type !== 'visit');
|
|
53
|
+
const messages = (yield this.socket.socket.listMessages(500)).filter((x) => x.payload.type !== 'visit');
|
|
54
54
|
return Object.assign(Object.assign({}, conversation), { messages });
|
|
55
55
|
}
|
|
56
56
|
catch (err) {
|
package/dist/core/socket.d.ts
CHANGED
package/dist/core/socket.js
CHANGED
|
@@ -31,7 +31,8 @@ class BpSocket {
|
|
|
31
31
|
connect() {
|
|
32
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
33
33
|
const creds = this.getCreds();
|
|
34
|
-
|
|
34
|
+
const userData = this.getUserData();
|
|
35
|
+
yield this.socket.connect(creds, userData);
|
|
35
36
|
if (this.socket.userId) {
|
|
36
37
|
const userId = this.socket.userId;
|
|
37
38
|
window.BP_STORAGE.set('creds', this.socket.creds);
|
|
@@ -53,5 +54,8 @@ class BpSocket {
|
|
|
53
54
|
getCreds() {
|
|
54
55
|
return this.config.customUser || window.BP_STORAGE.get('creds');
|
|
55
56
|
}
|
|
57
|
+
getUserData() {
|
|
58
|
+
return this.config.userData;
|
|
59
|
+
}
|
|
56
60
|
}
|
|
57
61
|
exports.default = BpSocket;
|
package/dist/declaration.d.ts
CHANGED
package/dist/main.js
CHANGED
|
@@ -80,6 +80,7 @@ class Web extends react_1.default.Component {
|
|
|
80
80
|
return this.props.sendData(data.payload);
|
|
81
81
|
case 'event':
|
|
82
82
|
const { type, text, conversationId } = data.payload;
|
|
83
|
+
yield this.initialize();
|
|
83
84
|
if (type === 'show') {
|
|
84
85
|
this.props.showChat();
|
|
85
86
|
(0, analytics_1.trackWebchatState)('show');
|
|
@@ -112,7 +113,7 @@ class Web extends react_1.default.Component {
|
|
|
112
113
|
}
|
|
113
114
|
});
|
|
114
115
|
this.handleNewMessage = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
115
|
-
var _b, _c, _d;
|
|
116
|
+
var _b, _c, _d, _e, _f;
|
|
116
117
|
if (!this.isCurrentConversation(event)) {
|
|
117
118
|
// don't do anything, it's a message from another conversation
|
|
118
119
|
return;
|
|
@@ -125,34 +126,70 @@ class Web extends react_1.default.Component {
|
|
|
125
126
|
// don't do anything, it's the system message
|
|
126
127
|
return;
|
|
127
128
|
}
|
|
128
|
-
if (((_c =
|
|
129
|
+
if (((_c = event.payload) === null || _c === void 0 ? void 0 : _c.type) === 'trigger') {
|
|
130
|
+
//
|
|
131
|
+
const { trigger } = event.payload;
|
|
132
|
+
if (typeof (trigger === null || trigger === void 0 ? void 0 : trigger.type) === 'string') {
|
|
133
|
+
yield this.handleTrigger(trigger);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (((_d = this.props.currentConversation) === null || _d === void 0 ? void 0 : _d.userId) !== event.authorId) {
|
|
129
138
|
(0, analytics_1.trackMessage)('received');
|
|
130
|
-
(0, webchatEvents_1.postMessageToParent)('MESSAGE.RECEIVED', event, this.
|
|
139
|
+
(0, webchatEvents_1.postMessageToParent)('MESSAGE.RECEIVED', event, this.config.chatId);
|
|
131
140
|
// This is to handle a special case for the emulator, setting the selected css class to the last message group
|
|
132
141
|
// This needs a rethinking
|
|
133
142
|
if (event.id) {
|
|
134
|
-
(
|
|
143
|
+
(_e = this.props.store) === null || _e === void 0 ? void 0 : _e.setSelectedMessage(event.id);
|
|
135
144
|
}
|
|
136
145
|
}
|
|
137
146
|
this.props.updateLastMessage(event.conversationId, event);
|
|
138
147
|
yield this.props.addEventToConversation(event);
|
|
139
148
|
// there's no focus on the actual conversation
|
|
140
149
|
if (!document.hasFocus() || this.props.activeView !== 'side') {
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
if (((_f = this.props.currentConversation) === null || _f === void 0 ? void 0 : _f.userId) !== event.authorId) {
|
|
151
|
+
// only increment unread if the message comes from the bot
|
|
152
|
+
yield this.playSound();
|
|
153
|
+
this.props.incrementUnread();
|
|
154
|
+
}
|
|
143
155
|
}
|
|
144
156
|
this.handleResetUnreadCount();
|
|
145
157
|
});
|
|
146
158
|
this.handleTyping = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
147
159
|
yield this.props.updateTyping(event);
|
|
148
160
|
});
|
|
161
|
+
this.handleTrigger = (trigger) => __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
var _g;
|
|
163
|
+
if (trigger.type === 'webchat-visibility') {
|
|
164
|
+
if (trigger.visibility === 'hide') {
|
|
165
|
+
this.props.hideChat();
|
|
166
|
+
}
|
|
167
|
+
else if (trigger.visibility === 'show') {
|
|
168
|
+
this.props.showChat();
|
|
169
|
+
}
|
|
170
|
+
else if (trigger.visibility === 'toggle') {
|
|
171
|
+
this.props.displayWidgetView ? this.props.showChat() : this.props.hideChat();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (trigger.type === 'webchat-config') {
|
|
175
|
+
yield this.handleIframeApi({
|
|
176
|
+
data: { action: 'mergeConfig', payload: Object.assign(Object.assign({}, this.config), ((_g = trigger.config) !== null && _g !== void 0 ? _g : {})) }
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (trigger.type === 'custom-event') {
|
|
180
|
+
(0, webchatEvents_1.postMessageToParent)('TRIGGER', trigger.event, this.props.config.chatId);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
149
183
|
this.playSound = (0, debounce_1.default)(() => __awaiter(this, void 0, void 0, function* () {
|
|
150
|
-
var
|
|
151
|
-
const disableNotificationSound = this.config.disableNotificationSound || ((
|
|
184
|
+
var _h;
|
|
185
|
+
const disableNotificationSound = this.config.disableNotificationSound || ((_h = this.props.config) === null || _h === void 0 ? void 0 : _h.disableNotificationSound);
|
|
152
186
|
if (disableNotificationSound || this.audio.readyState < 2) {
|
|
153
187
|
return;
|
|
154
188
|
}
|
|
155
|
-
|
|
189
|
+
try {
|
|
190
|
+
yield this.audio.play();
|
|
191
|
+
}
|
|
192
|
+
catch (_j) { }
|
|
156
193
|
}), constants_1.default.MIN_TIME_BETWEEN_SOUNDS);
|
|
157
194
|
this.handleResetUnreadCount = () => {
|
|
158
195
|
if (document.hasFocus() && this.props.activeView === 'side') {
|
|
@@ -182,19 +219,24 @@ class Web extends react_1.default.Component {
|
|
|
182
219
|
void this.initializeIfChatDisplayed();
|
|
183
220
|
}
|
|
184
221
|
}
|
|
185
|
-
|
|
222
|
+
initialize() {
|
|
186
223
|
return __awaiter(this, void 0, void 0, function* () {
|
|
187
224
|
if (this.hasBeenInitialized) {
|
|
188
225
|
return;
|
|
189
226
|
}
|
|
227
|
+
this.hasBeenInitialized = true;
|
|
228
|
+
if (this.isLazySocket() || !this.socket) {
|
|
229
|
+
yield this.initializeSocket();
|
|
230
|
+
}
|
|
231
|
+
yield this.socket.connect();
|
|
232
|
+
this.props.setSocket(this.socket);
|
|
233
|
+
yield this.props.initializeChat();
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
initializeIfChatDisplayed() {
|
|
237
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
190
238
|
if (this.props.activeView === 'side' || this.props.isFullscreen) {
|
|
191
|
-
this.
|
|
192
|
-
if (this.isLazySocket() || !this.socket) {
|
|
193
|
-
yield this.initializeSocket();
|
|
194
|
-
}
|
|
195
|
-
yield this.socket.connect();
|
|
196
|
-
this.props.setSocket(this.socket);
|
|
197
|
-
yield this.props.initializeChat();
|
|
239
|
+
this.initialize();
|
|
198
240
|
}
|
|
199
241
|
});
|
|
200
242
|
}
|
|
@@ -252,7 +294,7 @@ class Web extends react_1.default.Component {
|
|
|
252
294
|
if (this.config.lazySocket !== undefined) {
|
|
253
295
|
return this.config.lazySocket;
|
|
254
296
|
}
|
|
255
|
-
return (_a = this.props.botInfo) === null || _a === void 0 ? void 0 : _a.lazySocket;
|
|
297
|
+
return ((_a = this.props.botInfo) === null || _a === void 0 ? void 0 : _a.lazySocket) !== false;
|
|
256
298
|
}
|
|
257
299
|
renderWidget() {
|
|
258
300
|
if (!this.props.showWidgetButton) {
|
package/dist/store/index.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ declare class RootStore {
|
|
|
33
33
|
get botName(): string;
|
|
34
34
|
get hasBotInfoDescription(): boolean;
|
|
35
35
|
get botAvatarUrl(): string | undefined;
|
|
36
|
+
get coverPictureUrl(): string | undefined;
|
|
37
|
+
get description(): string | undefined;
|
|
38
|
+
get website(): string | undefined;
|
|
39
|
+
get phoneNumber(): string | undefined;
|
|
40
|
+
get termsConditions(): string | undefined;
|
|
41
|
+
get privacyPolicy(): string | undefined;
|
|
42
|
+
get emailAddress(): string | undefined;
|
|
36
43
|
get rtl(): boolean;
|
|
37
44
|
get escapeHTML(): boolean;
|
|
38
45
|
get currentMessages(): Message[];
|
|
@@ -62,7 +69,9 @@ declare class RootStore {
|
|
|
62
69
|
sendFeedback(feedback: number, messageId: string): Promise<void>;
|
|
63
70
|
downloadConversation(): Promise<void>;
|
|
64
71
|
/** Sends an event or a message, depending on how the backend manages those types */
|
|
65
|
-
sendData(data: any
|
|
72
|
+
sendData(data: any, options?: {
|
|
73
|
+
showBotTyping?: boolean;
|
|
74
|
+
}): Promise<Message | void>;
|
|
66
75
|
/** Sends a message of type voice */
|
|
67
76
|
sendVoiceMessage(voice: Buffer, ext: string): Promise<void>;
|
|
68
77
|
/** Use this method to replace a value or add a new config */
|
package/dist/store/index.js
CHANGED
|
@@ -70,6 +70,34 @@ class RootStore {
|
|
|
70
70
|
var _a, _b, _c;
|
|
71
71
|
return ((_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.avatarUrl) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.avatarUrl) || undefined;
|
|
72
72
|
}
|
|
73
|
+
get coverPictureUrl() {
|
|
74
|
+
var _a, _b, _c, _d;
|
|
75
|
+
return (_c = (_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.coverPictureUrl) !== null && _c !== void 0 ? _c : (_d = this.config) === null || _d === void 0 ? void 0 : _d.coverPictureUrl;
|
|
76
|
+
}
|
|
77
|
+
get description() {
|
|
78
|
+
var _a;
|
|
79
|
+
return (_a = this.config) === null || _a === void 0 ? void 0 : _a.botConversationDescription;
|
|
80
|
+
}
|
|
81
|
+
get website() {
|
|
82
|
+
var _a, _b, _c, _d;
|
|
83
|
+
return (_c = (_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.website) !== null && _c !== void 0 ? _c : (_d = this.config) === null || _d === void 0 ? void 0 : _d.website;
|
|
84
|
+
}
|
|
85
|
+
get phoneNumber() {
|
|
86
|
+
var _a, _b, _c, _d;
|
|
87
|
+
return (_c = (_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.phoneNumber) !== null && _c !== void 0 ? _c : (_d = this.config) === null || _d === void 0 ? void 0 : _d.phoneNumber;
|
|
88
|
+
}
|
|
89
|
+
get termsConditions() {
|
|
90
|
+
var _a, _b, _c, _d;
|
|
91
|
+
return (_c = (_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.termsConditions) !== null && _c !== void 0 ? _c : (_d = this.config) === null || _d === void 0 ? void 0 : _d.termsConditions;
|
|
92
|
+
}
|
|
93
|
+
get privacyPolicy() {
|
|
94
|
+
var _a, _b, _c, _d;
|
|
95
|
+
return (_c = (_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.privacyPolicy) !== null && _c !== void 0 ? _c : (_d = this.config) === null || _d === void 0 ? void 0 : _d.privacyPolicy;
|
|
96
|
+
}
|
|
97
|
+
get emailAddress() {
|
|
98
|
+
var _a, _b, _c, _d;
|
|
99
|
+
return (_c = (_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.emailAddress) !== null && _c !== void 0 ? _c : (_d = this.config) === null || _d === void 0 ? void 0 : _d.emailAddress;
|
|
100
|
+
}
|
|
73
101
|
get rtl() {
|
|
74
102
|
return (0, translations_1.isRTLLocale)(this.preferredLanguage);
|
|
75
103
|
}
|
|
@@ -79,7 +107,7 @@ class RootStore {
|
|
|
79
107
|
}
|
|
80
108
|
get currentMessages() {
|
|
81
109
|
var _a;
|
|
82
|
-
return ((_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.messages) || [];
|
|
110
|
+
return (((_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.messages) || []).filter((x) => { var _a; return ((_a = x.payload) === null || _a === void 0 ? void 0 : _a.type) !== 'trigger'; });
|
|
83
111
|
}
|
|
84
112
|
get currentConversationId() {
|
|
85
113
|
var _a;
|
|
@@ -237,7 +265,7 @@ class RootStore {
|
|
|
237
265
|
}
|
|
238
266
|
this.composer.updateMessage('');
|
|
239
267
|
try {
|
|
240
|
-
const message = yield this.sendData({ type: 'text', text: textMessage });
|
|
268
|
+
const message = yield this.sendData({ type: 'text', text: textMessage }, { showBotTyping: true });
|
|
241
269
|
(0, analytics_1.trackMessage)('sent');
|
|
242
270
|
if (message) {
|
|
243
271
|
(0, webchatEvents_1.postMessageToParent)('MESSAGE.SENT', message, this.config.chatId);
|
|
@@ -321,12 +349,15 @@ class RootStore {
|
|
|
321
349
|
});
|
|
322
350
|
}
|
|
323
351
|
/** Sends an event or a message, depending on how the backend manages those types */
|
|
324
|
-
sendData(data) {
|
|
352
|
+
sendData(data, options) {
|
|
325
353
|
return __awaiter(this, void 0, void 0, function* () {
|
|
326
354
|
if (!this.isInitialized || !this.currentConversationId) {
|
|
327
355
|
console.warn('[webchat] Cannot send data until the webchat is ready');
|
|
328
356
|
return;
|
|
329
357
|
}
|
|
358
|
+
if (options === null || options === void 0 ? void 0 : options.showBotTyping) {
|
|
359
|
+
this.isBotTyping.set(true);
|
|
360
|
+
}
|
|
330
361
|
const message = yield this.api.sendMessage(data, this.currentConversationId);
|
|
331
362
|
this.updateLastMessage(this.currentConversationId, message);
|
|
332
363
|
return message;
|
package/dist/store/view.js
CHANGED
|
@@ -40,7 +40,9 @@ class ViewStore {
|
|
|
40
40
|
return (_a = this.rootStore.config) === null || _a === void 0 ? void 0 : _a.showConversationsButton;
|
|
41
41
|
}
|
|
42
42
|
get showBotInfoButton() {
|
|
43
|
-
|
|
43
|
+
var _a;
|
|
44
|
+
return (!this.isConversationsDisplayed &&
|
|
45
|
+
(((_a = this.rootStore.botInfo) === null || _a === void 0 ? void 0 : _a.showBotInfoPage) || !!this.rootStore.config.showBotInfoPage));
|
|
44
46
|
}
|
|
45
47
|
get showDownloadButton() {
|
|
46
48
|
return !this.isConversationsDisplayed && !this.isBotInfoDisplayed && this.rootStore.config.enableTranscriptDownload;
|
|
@@ -49,7 +51,8 @@ class ViewStore {
|
|
|
49
51
|
return (!this.isConversationsDisplayed && !this.isBotInfoDisplayed && this.rootStore.config.enableConversationDeletion);
|
|
50
52
|
}
|
|
51
53
|
get showCloseButton() {
|
|
52
|
-
|
|
54
|
+
var _a, _b;
|
|
55
|
+
return (_b = (!this.isFullscreen && ((_a = this.rootStore.config) === null || _a === void 0 ? void 0 : _a.showCloseButton))) !== null && _b !== void 0 ? _b : true;
|
|
53
56
|
}
|
|
54
57
|
get showWidgetButton() {
|
|
55
58
|
var _a;
|
|
@@ -62,7 +65,8 @@ class ViewStore {
|
|
|
62
65
|
return !this._isLoading && this.activeView;
|
|
63
66
|
}
|
|
64
67
|
get isBotInfoDisplayed() {
|
|
65
|
-
|
|
68
|
+
var _a;
|
|
69
|
+
return this._showBotInfo && (((_a = this.rootStore.botInfo) === null || _a === void 0 ? void 0 : _a.showBotInfoPage) || !!this.rootStore.config.showBotInfoPage);
|
|
66
70
|
}
|
|
67
71
|
/** Returns the active transition for the side panel, like fade in or out */
|
|
68
72
|
get sideTransition() {
|
package/dist/typings.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { UserCredentials } from '@botpress/messaging-socket';
|
|
2
|
+
import { UserCredentials, UserData } from '@botpress/messaging-socket';
|
|
3
3
|
import { RootStore } from './store';
|
|
4
4
|
import { BPStorage } from './utils/storage';
|
|
5
5
|
declare global {
|
|
@@ -17,6 +17,20 @@ declare global {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
+
export declare namespace Trigger {
|
|
21
|
+
interface WebchatVisibility {
|
|
22
|
+
type: 'webchat-visibility';
|
|
23
|
+
visibility: 'show' | 'hide' | 'toggle';
|
|
24
|
+
}
|
|
25
|
+
interface WebchatConfig {
|
|
26
|
+
type: 'webchat-config';
|
|
27
|
+
config: Partial<Config>;
|
|
28
|
+
}
|
|
29
|
+
interface CustomEvent {
|
|
30
|
+
type: 'custom-event';
|
|
31
|
+
event: any;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
20
34
|
export declare namespace Renderer {
|
|
21
35
|
interface Message {
|
|
22
36
|
type?: string;
|
|
@@ -36,7 +50,9 @@ export declare namespace Renderer {
|
|
|
36
50
|
isLastMessage?: boolean;
|
|
37
51
|
sentOn?: Date;
|
|
38
52
|
inlineFeedback?: any;
|
|
39
|
-
onSendData?: (data: any
|
|
53
|
+
onSendData?: (data: any, options?: {
|
|
54
|
+
showBotTyping?: boolean;
|
|
55
|
+
}) => Promise<Message | void>;
|
|
40
56
|
onFileUpload?: (label: string, payload: any, file: File) => Promise<void>;
|
|
41
57
|
/** Allows to autoplay voice messages coming from the bot */
|
|
42
58
|
onAudioEnded?: () => void;
|
|
@@ -136,7 +152,7 @@ export interface StudioConnector {
|
|
|
136
152
|
getModuleInjector: any;
|
|
137
153
|
loadModuleView: any;
|
|
138
154
|
}
|
|
139
|
-
export declare type WebchatEventType = 'LIFECYCLE.LOADED' | 'LIFECYCLE.READY' | 'UI.OPENED' | 'UI.CLOSED' | 'UI.RESIZE' | 'UI.SET-CLASS' | 'CONFIG.SET' | 'MESSAGE.SENT' | 'MESSAGE.RECEIVED' | 'MESSAGE.SELECTED' | 'USER.CONNECTED';
|
|
155
|
+
export declare type WebchatEventType = 'LIFECYCLE.LOADED' | 'LIFECYCLE.READY' | 'UI.OPENED' | 'UI.CLOSED' | 'UI.RESIZE' | 'UI.SET-CLASS' | 'CONFIG.SET' | 'MESSAGE.SENT' | 'MESSAGE.RECEIVED' | 'MESSAGE.SELECTED' | 'USER.CONNECTED' | 'TRIGGER';
|
|
140
156
|
export interface WebchatEvent {
|
|
141
157
|
type: WebchatEventType;
|
|
142
158
|
value: any;
|
|
@@ -288,6 +304,48 @@ export interface Config {
|
|
|
288
304
|
* Allows setting a custom user id
|
|
289
305
|
*/
|
|
290
306
|
customUser?: UserCredentials;
|
|
307
|
+
/**
|
|
308
|
+
* Allows setting custom data to the user
|
|
309
|
+
*/
|
|
310
|
+
userData?: UserData;
|
|
311
|
+
/**
|
|
312
|
+
* Displays the bot's website in the conversation page
|
|
313
|
+
*/
|
|
314
|
+
website?: string;
|
|
315
|
+
/**
|
|
316
|
+
* Displays the bot's contact phone number in the conversation page
|
|
317
|
+
*/
|
|
318
|
+
phoneNumber?: string;
|
|
319
|
+
/**
|
|
320
|
+
* Displays the bot's terms of service in the conversation page
|
|
321
|
+
*/
|
|
322
|
+
termsConditions?: string;
|
|
323
|
+
/**
|
|
324
|
+
* Displays the bot's privacy policy in the conversation page
|
|
325
|
+
*/
|
|
326
|
+
privacyPolicy?: string;
|
|
327
|
+
/**
|
|
328
|
+
* Displays the bot's email address in the conversation page
|
|
329
|
+
*/
|
|
330
|
+
emailAddress?: string;
|
|
331
|
+
/**
|
|
332
|
+
* Displays the bot's cover picture in the conversation page
|
|
333
|
+
*/
|
|
334
|
+
coverPictureUrl?: string;
|
|
335
|
+
/**
|
|
336
|
+
* Enables the bot's information page in the webchat
|
|
337
|
+
*/
|
|
338
|
+
showBotInfoPage?: boolean;
|
|
339
|
+
/**
|
|
340
|
+
* Display's the webchat close button when the webchat is opened
|
|
341
|
+
*/
|
|
342
|
+
showCloseButton?: boolean;
|
|
343
|
+
/**
|
|
344
|
+
* Replaces < and > with their HTML entities < and >.
|
|
345
|
+
* Setting it to false will let the markdown parser handle html itself
|
|
346
|
+
* @default true
|
|
347
|
+
*/
|
|
348
|
+
escapeHtml?: boolean;
|
|
291
349
|
}
|
|
292
350
|
export interface BotDetails {
|
|
293
351
|
website?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botpress/webchat",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"source": "src/index.tsx",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"@types/crypto-js": "^4.1.1",
|
|
21
21
|
"@types/js-cookie": "^3.0.1",
|
|
22
22
|
"@types/lodash": "^4.14.178",
|
|
23
|
+
"@types/markdown-it": "^12.2.3",
|
|
23
24
|
"@types/mime": "^2.0.3",
|
|
24
25
|
"@types/node": "^16.11.13",
|
|
25
26
|
"@types/react": "^17.0.38",
|
|
@@ -29,8 +30,8 @@
|
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"@blueprintjs/core": "^3.23.1",
|
|
32
|
-
"@botpress/messaging-components": "0.4.
|
|
33
|
-
"@botpress/messaging-socket": "1.
|
|
33
|
+
"@botpress/messaging-components": "0.4.3",
|
|
34
|
+
"@botpress/messaging-socket": "1.3.0",
|
|
34
35
|
"@formatjs/intl-pluralrules": "^4.1.6",
|
|
35
36
|
"@formatjs/intl-utils": "^3.8.4",
|
|
36
37
|
"@juggle/resize-observer": "^3.0.2",
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
"date-fns": "^1.30.1",
|
|
41
42
|
"js-cookie": "^3.0.1",
|
|
42
43
|
"lodash": "^4.17.21",
|
|
44
|
+
"markdown-it": "^13.0.1",
|
|
43
45
|
"mime": "^3.0.0",
|
|
44
46
|
"mobx": "5.15.7",
|
|
45
47
|
"mobx-react": "^6.2.1",
|
|
@@ -48,7 +50,8 @@
|
|
|
48
50
|
"react-dom": "^17.0.2",
|
|
49
51
|
"react-ga": "^2.7.0",
|
|
50
52
|
"react-intl": "^3.12.1",
|
|
53
|
+
"react-scroll-to-bottom": "^4.2.0",
|
|
51
54
|
"snarkdown": "^2.0.0",
|
|
52
55
|
"uuid": "^8.3.2"
|
|
53
56
|
}
|
|
54
|
-
}
|
|
57
|
+
}
|