@botonic/react
Version:
Build Chatbots using React
151 lines • 10.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Message = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const core_1 = require("@botonic/core");
const react_1 = tslib_1.__importStar(require("react"));
const uuid_1 = require("uuid");
const constants_1 = require("../../constants");
const contexts_1 = require("../../contexts");
const index_types_1 = require("../../index-types");
const styles_1 = require("../../shared/styles");
const environment_1 = require("../../util/environment");
const react_2 = require("../../util/react");
const context_1 = require("../../webchat/context");
const index_1 = require("../button/index");
const buttons_disabler_1 = require("../buttons-disabler");
const markdown_1 = require("../markdown");
const reply_1 = require("../reply");
const message_footer_1 = require("./message-footer");
const message_image_1 = require("./message-image");
const styles_2 = require("./styles");
const timestamps_1 = require("./timestamps");
const Message = props => {
const { defaultTyping, defaultDelay } = (0, react_1.useContext)(contexts_1.RequestContext);
let { type = '', blob = true, sentBy, delay = defaultDelay, typing = defaultTyping, children, enabletimestamps = props.enabletimestamps || props.enableTimestamps, json, style, imagestyle = props.imagestyle || props.imageStyle, isUnread = true, feedbackEnabled, inferenceId, botInteractionId } = props, otherProps = tslib_1.__rest(props, ["type", "blob", "sentBy", "delay", "typing", "children", "enabletimestamps", "json", "style", "imagestyle", "isUnread", "feedbackEnabled", "inferenceId", "botInteractionId"]);
const isSentByUser = sentBy === index_types_1.SENDERS.user;
const isSentByBot = sentBy === index_types_1.SENDERS.bot;
const markdown = props.markdown;
const { webchatState, addMessage, updateReplies, getThemeProperty } = (0, react_1.useContext)(context_1.WebchatContext);
const [state] = (0, react_1.useState)({
id: props.id || (0, uuid_1.v7)(),
});
const [disabled, setDisabled] = (0, react_1.useState)(false);
children = buttons_disabler_1.ButtonsDisabler.updateChildrenButtons(children, {
parentId: state.id,
disabled,
setDisabled,
});
const replies = react_1.default.Children.toArray(children).filter(e => e.type === reply_1.Reply);
const buttons = react_1.default.Children.toArray(children).filter(e => e.type === index_1.Button);
let textChildren = react_1.default.Children.toArray(children).filter(e => ![index_1.Button, reply_1.Reply].includes(e.type));
if (isSentByUser)
textChildren = textChildren.map(e => typeof e === 'string' ? (0, markdown_1.renderLinks)(e) : e);
const { timestampsEnabled, getFormattedTimestamp } = (0, timestamps_1.resolveMessageTimestamps)(getThemeProperty, enabletimestamps);
const getEnvAck = () => {
if (environment_1.isDev)
return 1;
if (!isSentByUser)
return 1;
if (props.ack !== undefined)
return props.ack;
return 0;
};
const ack = getEnvAck();
(0, react_1.useEffect)(() => {
if ((0, core_1.isBrowser)()) {
const decomposedChildren = json;
const message = {
id: state.id,
type,
data: decomposedChildren ? decomposedChildren : textChildren,
timestamp: props.timestamp || getFormattedTimestamp,
markdown,
sentBy,
buttons: buttons.map(b => (Object.assign({ parentId: b.props.parentId, payload: b.props.payload, path: b.props.path, url: b.props.url, target: b.props.target, webview: b.props.webview && String(b.props.webview), title: b.props.children }, buttons_disabler_1.ButtonsDisabler.withDisabledProps(b.props)))),
delay,
typing,
replies: replies.map(r => ({
payload: r.props.payload,
path: r.props.path,
url: r.props.url,
text: r.props.children,
})),
display: delay + typing == 0,
customTypeName: decomposedChildren.customTypeName,
ack: ack,
isUnread: isUnread === 1 || isUnread === true,
feedbackEnabled,
inferenceId,
botInteractionId,
};
addMessage(message);
}
}, []);
(0, react_1.useEffect)(() => {
if ((0, core_1.isBrowser)()) {
const msg = webchatState.messagesJSON.find(m => m.id === state.id);
if (msg &&
msg.display &&
webchatState.messagesJSON.filter(m => !m.display).length == 0) {
updateReplies(replies);
}
}
}, [webchatState.messagesJSON]);
const brandColor = getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.brandColor);
const getBgColor = () => {
if (!blob)
return constants_1.COLORS.TRANSPARENT;
if (isSentByUser) {
return getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.userMessageBackground, brandColor);
}
return getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.botMessageBackground, constants_1.COLORS.SEASHELL_WHITE);
};
const getMessageStyle = () => isSentByUser
? getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.userMessageStyle)
: getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.botMessageStyle);
const userOrBotMessage = isSentByUser ? index_types_1.SENDERS.user : index_types_1.SENDERS.bot;
const hasBlobTick = () => getThemeProperty(`message.${userOrBotMessage}.blobTick`);
const renderBrowser = () => {
const messageJSON = webchatState.messagesJSON.find(m => m.id === state.id);
if (!messageJSON || !messageJSON.display)
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
const getBlobTick = pointerSize => {
// to add a border to the blobTick we need to create two triangles and overlap them
// that is why the color depends on the pointerSize
// https://developpaper.com/realization-code-of-css-drawing-triangle-border-method/
const color = pointerSize == 5
? getBgColor()
: getThemeProperty(`message.${userOrBotMessage}.style.borderColor`, constants_1.COLORS.TRANSPARENT);
const containerStyle = Object.assign({}, getThemeProperty(`message.${userOrBotMessage}.blobTickStyle`));
const blobTickStyle = {};
if (isSentByUser) {
containerStyle.right = 0;
containerStyle.marginRight = -pointerSize;
blobTickStyle.borderRight = 0;
blobTickStyle.borderLeftColor = color;
}
else {
containerStyle.left = 0;
containerStyle.marginLeft = -pointerSize;
blobTickStyle.borderLeft = 0;
blobTickStyle.borderRightColor = color;
}
return ((0, jsx_runtime_1.jsx)(styles_2.BlobTickContainer, Object.assign({ style: containerStyle }, { children: (0, jsx_runtime_1.jsx)(styles_2.BlobTick, { pointerSize: pointerSize, style: blobTickStyle }) })));
};
const animationsEnabled = getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.enableAnimations);
const resolveCustomTypeName = () => isSentByBot && type === core_1.INPUT.CUSTOM
? ` ${messageJSON.customTypeName}`
: '';
const className = `${type}-${userOrBotMessage}${resolveCustomTypeName()}`;
return ((0, jsx_runtime_1.jsx)(react_2.ConditionalWrapper, Object.assign({ condition: animationsEnabled, wrapper: children => (0, jsx_runtime_1.jsx)(styles_1.Fade, { children: children }) }, { children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(styles_2.MessageContainer, Object.assign({ isSentByUser: isSentByUser, style: Object.assign({}, getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.messageStyle)) }, { children: [(0, jsx_runtime_1.jsx)(message_image_1.MessageImage, { imagestyle: imagestyle, sentBy: sentBy }), (0, jsx_runtime_1.jsxs)(styles_2.BlobContainer, Object.assign({ className: className, bgcolor: getBgColor(), color: isSentByUser ? constants_1.COLORS.SOLID_WHITE : constants_1.COLORS.SOLID_BLACK, blobwidth: getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.botMessageBlobWidth), blob: blob, style: Object.assign(Object.assign(Object.assign({}, getMessageStyle()), style), { opacity: ack === 0 ? 0.6 : 1 }) }, otherProps, { children: [markdown ? ((0, jsx_runtime_1.jsx)(styles_2.BlobText, { blob: blob, dangerouslySetInnerHTML: {
__html: (0, markdown_1.renderMarkdown)(textChildren),
}, markdownstyle: (0, markdown_1.getMarkdownStyle)(getThemeProperty, isSentByUser ? constants_1.COLORS.SEASHELL_WHITE : brandColor) })) : ((0, jsx_runtime_1.jsx)(styles_2.BlobText, Object.assign({ blob: blob }, { children: textChildren }))), !!buttons.length && ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'message-buttons-container' }, { children: buttons }))), Boolean(blob) && hasBlobTick() && getBlobTick(6), Boolean(blob) && hasBlobTick() && getBlobTick(5)] }))] })), timestampsEnabled || feedbackEnabled ? ((0, jsx_runtime_1.jsx)(message_footer_1.MessageFooter, { enabletimestamps: timestampsEnabled, messageJSON: messageJSON, sentBy: sentBy, feedbackEnabled: feedbackEnabled, inferenceId: inferenceId, botInteractionId: botInteractionId })) : null] }) })));
};
const { blob: _blob, json: _json } = props, nodeProps = tslib_1.__rest(props, ["blob", "json"]);
const renderNode = () => type === core_1.INPUT.CUSTOM ? ((0, jsx_runtime_1.jsx)("message", Object.assign({ json: JSON.stringify(_json), typing: typing, delay: delay }, nodeProps))) : ((0, jsx_runtime_1.jsx)("message", Object.assign({ typing: typing, delay: delay }, nodeProps, { children: children })));
return (0, react_2.renderComponent)({ renderBrowser, renderNode });
};
exports.Message = Message;
//# sourceMappingURL=index.js.map