@botpress/webchat 0.5.0 → 0.5.1
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/components/common/Avatar/index.d.ts +2 -2
- package/dist/components/common/BotInfo/index.d.ts +1 -1
- package/dist/components/common/BotInfo/index.js +28 -23
- package/dist/components/messages/MessageList.js +68 -74
- package/dist/declaration.d.ts +1 -0
- package/dist/store/index.d.ts +7 -0
- package/dist/store/index.js +28 -0
- package/dist/store/view.js +7 -3
- package/dist/typings.d.ts +32 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| File | ✅ | |
|
|
14
14
|
| Audio | ✅ | |
|
|
15
15
|
| Video | ✅ | |
|
|
16
|
-
| Location |
|
|
16
|
+
| Location | ✅ | |
|
|
17
17
|
|
|
18
18
|
### Receiving
|
|
19
19
|
|
|
@@ -23,9 +23,19 @@
|
|
|
23
23
|
| Quick Reply | ✅ | |
|
|
24
24
|
| Postback | ✅ | |
|
|
25
25
|
| Say Something | ✅ | |
|
|
26
|
-
| Voice |
|
|
26
|
+
| Voice | ✅ | |
|
|
27
27
|
| Image | ❌ | |
|
|
28
28
|
| File | ❌ | |
|
|
29
29
|
| Audio | ❌ | |
|
|
30
30
|
| Video | ❌ | |
|
|
31
31
|
| Location | ❌ | |
|
|
32
|
+
|
|
33
|
+
## Development
|
|
34
|
+
|
|
35
|
+
When working on the webchat, to see changes made to the codebase, you will need to follow the steps detailed [here](../inject/README.md). The inject script is the part that links any web page to a webchat. This is the easiest way to manually test the webchat.
|
|
36
|
+
|
|
37
|
+
## Tests
|
|
38
|
+
|
|
39
|
+
To run automated E2E tests, simply run the command `yarn test:chat [--browser <chromium | firefox | edge | electron>]` (for the list of supported browsers see: https://docs.cypress.io/guides/guides/launching-browsers#Browsers).
|
|
40
|
+
|
|
41
|
+
Tests can be found in `tests/e2e` and uses Cypress as the test framework. Configurations for Cypress can be found in the `cypress.json` file at the root of the repository.
|
|
@@ -7,4 +7,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
|
|
|
7
7
|
WrappedComponent: React.ComponentType<BotInfoProps>;
|
|
8
8
|
} & import("mobx-react").IWrappedComponent<unknown>;
|
|
9
9
|
export default _default;
|
|
10
|
-
declare type BotInfoProps = WrappedComponentProps & Pick<StoreDef, '
|
|
10
|
+
declare type BotInfoProps = WrappedComponentProps & Pick<StoreDef, 'coverPictureUrl' | 'description' | 'phoneNumber' | 'website' | 'emailAddress' | 'termsConditions' | 'privacyPolicy' | 'botInfo' | 'botName' | 'avatarUrl' | 'toggleBotInfo' | 'updatePreferredLanguage' | 'preferredLanguage' | 'escapeHTML' | 'rtl'>;
|
|
@@ -31,8 +31,8 @@ const Phone_1 = __importDefault(require("../../../icons/Phone"));
|
|
|
31
31
|
const Website_1 = __importDefault(require("../../../icons/Website"));
|
|
32
32
|
const utils_1 = require("../../../utils");
|
|
33
33
|
const Avatar_1 = __importDefault(require("../Avatar"));
|
|
34
|
-
const CoverPicture = ({
|
|
35
|
-
react_1.default.createElement("img", { className: 'bpw-botinfo-cover-picture', src:
|
|
34
|
+
const CoverPicture = ({ coverPictureUrl }) => (react_1.default.createElement("div", { className: 'bpw-botinfo-cover-picture-wrapper' },
|
|
35
|
+
react_1.default.createElement("img", { className: 'bpw-botinfo-cover-picture', src: coverPictureUrl })));
|
|
36
36
|
class BotInfoPage extends react_1.default.Component {
|
|
37
37
|
constructor() {
|
|
38
38
|
super(...arguments);
|
|
@@ -50,51 +50,56 @@ class BotInfoPage extends react_1.default.Component {
|
|
|
50
50
|
return react_1.default.createElement("div", { className: 'bpw-botinfo-description', dangerouslySetInnerHTML: { __html: html } });
|
|
51
51
|
}
|
|
52
52
|
render() {
|
|
53
|
-
const {
|
|
54
|
-
const onDismiss = this.props.isConversationStarted ? this.props.toggleBotInfo : this.props.startConversation;
|
|
53
|
+
const { botName, avatarUrl, coverPictureUrl, description, phoneNumber, website, emailAddress, termsConditions, privacyPolicy, botInfo } = this.props;
|
|
55
54
|
return (react_1.default.createElement(react_1.Fragment, null,
|
|
56
55
|
react_1.default.createElement("link", { rel: "stylesheet", href: "style.scss" }),
|
|
57
56
|
react_1.default.createElement("div", { className: (0, classnames_1.default)('bpw-botinfo-container', {
|
|
58
57
|
'bpw-rtl': this.props.rtl
|
|
59
58
|
}) },
|
|
60
|
-
react_1.default.createElement(CoverPicture, {
|
|
59
|
+
coverPictureUrl ? react_1.default.createElement(CoverPicture, { coverPictureUrl: coverPictureUrl }) : react_1.default.createElement("div", { style: { height: '42px' } }),
|
|
61
60
|
react_1.default.createElement("div", { className: 'bpw-botinfo-summary' },
|
|
62
61
|
react_1.default.createElement(Avatar_1.default, { name: botName, avatarUrl: avatarUrl, height: 64, width: 64 }),
|
|
63
|
-
react_1.default.createElement("h3",
|
|
64
|
-
this.renderDescription(
|
|
65
|
-
|
|
62
|
+
react_1.default.createElement("h3", { style: { marginBottom: '10px' } }, botName),
|
|
63
|
+
description && this.renderDescription(description)),
|
|
64
|
+
react_1.default.createElement(react_1.default.Fragment, null,
|
|
66
65
|
react_1.default.createElement("div", { className: 'bpw-botinfo-links' },
|
|
67
|
-
|
|
66
|
+
phoneNumber && (react_1.default.createElement("div", { className: 'bpw-botinfo-link' },
|
|
68
67
|
react_1.default.createElement("i", null,
|
|
69
68
|
react_1.default.createElement(Phone_1.default, null)),
|
|
70
|
-
react_1.default.createElement("a", { target: '_blank', href: `tel:${
|
|
71
|
-
|
|
69
|
+
react_1.default.createElement("a", { target: '_blank', rel: "noopener noreferrer", href: `tel:${phoneNumber}` }, phoneNumber))),
|
|
70
|
+
website && (react_1.default.createElement("div", { className: 'bpw-botinfo-link' },
|
|
72
71
|
react_1.default.createElement("i", null,
|
|
73
72
|
react_1.default.createElement(Website_1.default, null)),
|
|
74
|
-
react_1.default.createElement("a", { target: '_blank', href:
|
|
75
|
-
|
|
73
|
+
react_1.default.createElement("a", { target: '_blank', rel: "noopener noreferrer", href: website }, website))),
|
|
74
|
+
emailAddress && (react_1.default.createElement("div", { className: 'bpw-botinfo-link' },
|
|
76
75
|
react_1.default.createElement("i", null,
|
|
77
76
|
react_1.default.createElement(Email_1.default, null)),
|
|
78
|
-
react_1.default.createElement("a", { target: '_blank', href: `mailto:${
|
|
79
|
-
|
|
80
|
-
react_1.default.createElement("a", { target: '_blank', href:
|
|
77
|
+
react_1.default.createElement("a", { target: '_blank', rel: "noopener noreferrer", href: `mailto:${emailAddress}` }, emailAddress)))),
|
|
78
|
+
termsConditions && (react_1.default.createElement("div", { className: 'bpw-botinfo-terms' },
|
|
79
|
+
react_1.default.createElement("a", { target: '_blank', rel: "noopener noreferrer", href: termsConditions },
|
|
81
80
|
react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.termsAndConditions' })))),
|
|
82
|
-
|
|
83
|
-
react_1.default.createElement("a", { target: '_blank', href:
|
|
84
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.privacyPolicy' })))))
|
|
85
|
-
botInfo.languages.length > 1 && (react_1.default.createElement("div", { className: 'bpw-botinfo-preferred-language' },
|
|
81
|
+
privacyPolicy && (react_1.default.createElement("div", { className: 'bpw-botinfo-terms' },
|
|
82
|
+
react_1.default.createElement("a", { target: '_blank', rel: "noopener noreferrer", href: privacyPolicy },
|
|
83
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.privacyPolicy' }))))),
|
|
84
|
+
(botInfo === null || botInfo === void 0 ? void 0 : botInfo.languages) && botInfo.languages.length > 1 && (react_1.default.createElement("div", { className: 'bpw-botinfo-preferred-language' },
|
|
86
85
|
react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.preferredLanguage' }),
|
|
87
86
|
react_1.default.createElement("select", { value: this.props.preferredLanguage, onChange: this.changeLanguage }, botInfo.languages.map((lang) => (react_1.default.createElement("option", { key: lang, value: lang }, lang.toUpperCase())))))),
|
|
88
|
-
react_1.default.createElement("button", { tabIndex: 1, ref: (el) => (this.btnEl = el), className: 'bpw-botinfo-start-button', onClick:
|
|
87
|
+
react_1.default.createElement("button", { tabIndex: 1, ref: (el) => (this.btnEl = el), className: 'bpw-botinfo-start-button', onClick: this.props.toggleBotInfo.bind(this, undefined) },
|
|
88
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'botInfo.backToConversation' })))));
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
exports.default = (0, mobx_react_1.inject)(({ store }) => ({
|
|
92
|
+
coverPictureUrl: store.coverPictureUrl,
|
|
93
|
+
description: store.description,
|
|
94
|
+
phoneNumber: store.phoneNumber,
|
|
95
|
+
website: store.website,
|
|
96
|
+
emailAddress: store.emailAddress,
|
|
97
|
+
termsConditions: store.termsConditions,
|
|
98
|
+
privacyPolicy: store.privacyPolicy,
|
|
92
99
|
botName: store.botName,
|
|
93
100
|
botInfo: store.botInfo,
|
|
94
101
|
avatarUrl: store.botAvatarUrl,
|
|
95
|
-
startConversation: store.startConversation,
|
|
96
102
|
toggleBotInfo: store.view.toggleBotInfo,
|
|
97
|
-
isConversationStarted: store.isConversationStarted,
|
|
98
103
|
updatePreferredLanguage: store.updatePreferredLanguage,
|
|
99
104
|
preferredLanguage: store.preferredLanguage,
|
|
100
105
|
escapeHTML: store.escapeHTML,
|
|
@@ -1,90 +1,88 @@
|
|
|
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
|
focus.newValue === 'convo' && this.messagesDiv.focus();
|
|
34
39
|
});
|
|
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
40
|
}
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
render() {
|
|
42
|
+
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) => {
|
|
43
|
+
this.messagesDiv = m;
|
|
44
|
+
}, followButtonClassName: 'bpw-msg-list-follow' },
|
|
45
|
+
react_1.default.createElement(Content, Object.assign({}, this.props))));
|
|
55
46
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
}
|
|
48
|
+
const Content = (0, mobx_react_1.observer)((props) => {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
const [state, setState] = (0, react_1.useState)({
|
|
51
|
+
showNewMessageIndicator: false,
|
|
52
|
+
messagesLength: undefined
|
|
53
|
+
});
|
|
54
|
+
const scrollToBottom = (0, react_scroll_to_bottom_1.useScrollToBottom)();
|
|
55
|
+
const [sticky] = (0, react_scroll_to_bottom_1.useSticky)();
|
|
56
|
+
(0, react_1.useEffect)(() => {
|
|
57
|
+
var _a, _b;
|
|
58
|
+
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 });
|
|
59
|
+
if (!sticky && state.messagesLength !== ((_b = props === null || props === void 0 ? void 0 : props.currentMessages) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
60
|
+
setState(Object.assign(Object.assign({}, stateUpdate), { showNewMessageIndicator: true }));
|
|
59
61
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Discard the error
|
|
69
|
-
}
|
|
70
|
-
}, delayed ? 250 : 0);
|
|
71
|
-
}
|
|
72
|
-
renderDate(date) {
|
|
62
|
+
else {
|
|
63
|
+
setState(Object.assign(Object.assign({}, stateUpdate), { showNewMessageIndicator: false }));
|
|
64
|
+
}
|
|
65
|
+
}, [(_a = props === null || props === void 0 ? void 0 : props.currentMessages) === null || _a === void 0 ? void 0 : _a.length, sticky]);
|
|
66
|
+
const shouldDisplayMessage = (m) => {
|
|
67
|
+
return m.payload.type !== 'postback';
|
|
68
|
+
};
|
|
69
|
+
const renderDate = (date) => {
|
|
73
70
|
return (react_1.default.createElement("div", { className: 'bpw-date-container' },
|
|
74
|
-
new Intl.DateTimeFormat(
|
|
71
|
+
new Intl.DateTimeFormat(props.intl.locale || 'en', {
|
|
75
72
|
month: 'short',
|
|
76
73
|
day: 'numeric',
|
|
77
74
|
hour: 'numeric',
|
|
78
75
|
minute: 'numeric'
|
|
79
76
|
}).format(new Date(date)),
|
|
80
77
|
react_1.default.createElement("div", { className: 'bpw-small-line' })));
|
|
81
|
-
}
|
|
82
|
-
renderAvatar(name, url) {
|
|
78
|
+
};
|
|
79
|
+
const renderAvatar = (name, url) => {
|
|
83
80
|
const avatarSize = 40;
|
|
84
81
|
return react_1.default.createElement(Avatar_1.default, { name: name, avatarUrl: url, height: avatarSize, width: avatarSize });
|
|
85
|
-
}
|
|
86
|
-
renderMessageGroups() {
|
|
87
|
-
|
|
82
|
+
};
|
|
83
|
+
const renderMessageGroups = () => {
|
|
84
|
+
var _a;
|
|
85
|
+
const messages = (props.currentMessages || []).filter((m) => shouldDisplayMessage(m));
|
|
88
86
|
const groups = [];
|
|
89
87
|
let lastSpeaker = undefined;
|
|
90
88
|
let lastDate = undefined;
|
|
@@ -106,7 +104,7 @@ class MessageList extends react_1.default.Component {
|
|
|
106
104
|
lastSpeaker = speaker;
|
|
107
105
|
lastDate = date;
|
|
108
106
|
});
|
|
109
|
-
if (
|
|
107
|
+
if ((_a = props === null || props === void 0 ? void 0 : props.isBotTyping) === null || _a === void 0 ? void 0 : _a.get()) {
|
|
110
108
|
if (lastSpeaker !== 'bot') {
|
|
111
109
|
currentGroup = [];
|
|
112
110
|
groups.push(currentGroup);
|
|
@@ -123,24 +121,20 @@ class MessageList extends react_1.default.Component {
|
|
|
123
121
|
const groupDate = group === null || group === void 0 ? void 0 : group[0].sentOn;
|
|
124
122
|
const isDateNeeded = !groups[i - 1] ||
|
|
125
123
|
(0, difference_in_minutes_1.default)(new Date(groupDate), new Date(lastDate)) > constants_1.default.TIME_BETWEEN_DATES;
|
|
126
|
-
const
|
|
127
|
-
const avatar = !authorId &&
|
|
124
|
+
const { authorId } = (0, last_1.default)(group);
|
|
125
|
+
const avatar = !authorId && renderAvatar(props.botName, props.botAvatarUrl);
|
|
128
126
|
return (react_1.default.createElement("div", { key: i },
|
|
129
|
-
isDateNeeded &&
|
|
127
|
+
isDateNeeded && renderDate(group[0].sentOn),
|
|
130
128
|
react_1.default.createElement(MessageGroup_1.default, { isBot: !authorId, avatar: avatar, key: `msg-group-${i}`, isLastGroup: i >= groups.length - 1, messages: group })));
|
|
131
129
|
})));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
})))),
|
|
141
|
-
this.renderMessageGroups()));
|
|
142
|
-
}
|
|
143
|
-
}
|
|
130
|
+
};
|
|
131
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
132
|
+
state.showNewMessageIndicator && (react_1.default.createElement("div", { className: "bpw-new-messages-indicator", onClick: (e) => scrollToBottom() },
|
|
133
|
+
react_1.default.createElement("span", null, props.intl.formatMessage({
|
|
134
|
+
id: `messages.newMessage${((_b = props === null || props === void 0 ? void 0 : props.currentMessages) === null || _b === void 0 ? void 0 : _b.length) === 1 ? '' : 's'}`
|
|
135
|
+
})))),
|
|
136
|
+
renderMessageGroups()));
|
|
137
|
+
});
|
|
144
138
|
exports.default = (0, mobx_react_1.inject)(({ store }) => ({
|
|
145
139
|
intl: store.intl,
|
|
146
140
|
botName: store.botName,
|
package/dist/declaration.d.ts
CHANGED
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[];
|
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
|
}
|
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
|
@@ -288,6 +288,38 @@ export interface Config {
|
|
|
288
288
|
* Allows setting a custom user id
|
|
289
289
|
*/
|
|
290
290
|
customUser?: UserCredentials;
|
|
291
|
+
/**
|
|
292
|
+
* Displays the bot's website in the conversation page
|
|
293
|
+
*/
|
|
294
|
+
website?: string;
|
|
295
|
+
/**
|
|
296
|
+
* Displays the bot's contact phone number in the conversation page
|
|
297
|
+
*/
|
|
298
|
+
phoneNumber?: string;
|
|
299
|
+
/**
|
|
300
|
+
* Displays the bot's terms of service in the conversation page
|
|
301
|
+
*/
|
|
302
|
+
termsConditions?: string;
|
|
303
|
+
/**
|
|
304
|
+
* Displays the bot's privacy policy in the conversation page
|
|
305
|
+
*/
|
|
306
|
+
privacyPolicy?: string;
|
|
307
|
+
/**
|
|
308
|
+
* Displays the bot's email address in the conversation page
|
|
309
|
+
*/
|
|
310
|
+
emailAddress?: string;
|
|
311
|
+
/**
|
|
312
|
+
* Displays the bot's cover picture in the conversation page
|
|
313
|
+
*/
|
|
314
|
+
coverPictureUrl?: string;
|
|
315
|
+
/**
|
|
316
|
+
* Enables the bot's information page in the webchat
|
|
317
|
+
*/
|
|
318
|
+
showBotInfoPage?: boolean;
|
|
319
|
+
/**
|
|
320
|
+
* Display's the webchat close button when the webchat is opened
|
|
321
|
+
*/
|
|
322
|
+
showCloseButton?: boolean;
|
|
291
323
|
}
|
|
292
324
|
export interface BotDetails {
|
|
293
325
|
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.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"source": "src/index.tsx",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@blueprintjs/core": "^3.23.1",
|
|
32
|
-
"@botpress/messaging-components": "0.4.
|
|
32
|
+
"@botpress/messaging-components": "0.4.3",
|
|
33
33
|
"@botpress/messaging-socket": "1.2.0",
|
|
34
34
|
"@formatjs/intl-pluralrules": "^4.1.6",
|
|
35
35
|
"@formatjs/intl-utils": "^3.8.4",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"react-dom": "^17.0.2",
|
|
49
49
|
"react-ga": "^2.7.0",
|
|
50
50
|
"react-intl": "^3.12.1",
|
|
51
|
+
"react-scroll-to-bottom": "^4.2.0",
|
|
51
52
|
"snarkdown": "^2.0.0",
|
|
52
53
|
"uuid": "^8.3.2"
|
|
53
54
|
}
|