@botonic/react
Version:
Build Chatbots using React
168 lines • 10.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MultichannelText = 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 contexts_1 = require("../../contexts");
const __1 = require("..");
const text_1 = require("../text");
const facebook_1 = require("./facebook/facebook");
const multichannel_button_1 = require("./multichannel-button");
const multichannel_context_1 = require("./multichannel-context");
const multichannel_utils_1 = require("./multichannel-utils");
const constants_1 = require("./whatsapp/constants");
const markdown_meta_1 = require("./whatsapp/markdown-meta");
const MultichannelText = props => {
var _a;
const requestContext = (0, react_1.useContext)(contexts_1.RequestContext);
const multichannelContext = (0, react_1.useContext)(multichannel_context_1.MultichannelContext);
const postbackButtonsAsText = (_a = props.buttonsAsText) !== null && _a !== void 0 ? _a : true;
let elements = [];
const getText = children => {
children = Array.isArray(children) ? children : [children];
const text = children
.filter(e => e && !e.type)
.map(e => {
if (Array.isArray(e))
return getText(e);
else
return String(e);
})
.join('');
if (text == undefined) {
return [];
}
return [text].filter(t => t !== ''); // to avoid line breaks when the carousel doesn't have title or subtitle
};
const getButtonsAndReplies = () => [].concat((0, multichannel_utils_1.getMultichannelButtons)(react_1.default.Children.toArray(props.children)), (0, multichannel_utils_1.getMultichannelReplies)(react_1.default.Children.toArray(props.children)));
const getWhatsappButtons = () => {
const postbackButtons = [];
const urlButtons = [];
const webviewButtons = [];
for (const button of getButtonsAndReplies()) {
if ((0, multichannel_utils_1.elementHasUrl)(button))
urlButtons.push(button);
else if ((0, multichannel_utils_1.elementHasWebview)(button))
webviewButtons.push(button);
else if ((0, multichannel_utils_1.elementHasPostback)(button))
postbackButtons.push(button);
}
return { postbackButtons, urlButtons, webviewButtons };
};
const getDefaultIndex = () => {
if (props.indexMode == undefined) {
return undefined;
}
if (multichannelContext.currentIndex != null) {
return multichannelContext.currentIndex;
}
return props.indexMode === 'letter' ? 'a' : 1;
};
const regenerateMultichannelButtons = (newLineFirstButton = true) => {
const generator = (multichannelButton, i) => {
const type = (0, multichannel_utils_1.getButtonType)(multichannelButton);
const asText = type === multichannel_utils_1.buttonTypes.POSTBACK ? postbackButtonsAsText : true;
const newline = multichannelContext.messageSeparator == null &&
!newLineFirstButton &&
i === 0
? ''
: '\n';
return ((0, jsx_runtime_1.jsx)(multichannel_button_1.MultichannelButton, Object.assign({ newline: newline, asText: asText }, multichannelButton.props, { children: multichannelButton.props.children }), `${type}${i}`));
};
return generator;
};
const splitInWhatsappListButtons = postbackButtons => {
const messages = [];
for (let i = 0; i < postbackButtons.length; i += constants_1.WHATSAPP_LIST_MAX_BUTTONS) {
messages.push(postbackButtons.slice(i, i + constants_1.WHATSAPP_LIST_MAX_BUTTONS));
}
return messages;
};
if ((0, core_1.isWhatsapp)(requestContext.session)) {
const texts = getText(props.children);
const { postbackButtons, urlButtons, webviewButtons } = getWhatsappButtons();
const textElements = texts.map(text => {
const textWithMarkdown = (0, markdown_meta_1.convertToMarkdownMeta)(text);
return (props.newline || '') + textWithMarkdown;
});
const webviewButtonElements = webviewButtons.map(regenerateMultichannelButtons(false));
const buttonsTextSeparator = props.buttonsTextSeparator || constants_1.DEFAULT_WHATSAPP_MAX_BUTTON_SEPARATOR;
const exceedWhatsAppMaxButtonNumber = !postbackButtonsAsText && postbackButtons.length > constants_1.WHATSAPP_MAX_BUTTONS;
if (exceedWhatsAppMaxButtonNumber) {
const menuButtonTextWhatsappList = props.menuButtonTextWhatsappList || constants_1.MENU_BUTTON_WHATSAPP_BUTTON_LIST;
const urlButtonElements = urlButtons.map(regenerateMultichannelButtons(!!texts.length));
const postbackButtonElements = postbackButtons.map(regenerateMultichannelButtons(!!texts.length || !!urlButtons.length));
const messagesPostbackButtonList = splitInWhatsappListButtons(postbackButtonElements);
const messages = messagesPostbackButtonList.map((postbackButtons, index) => {
if (postbackButtons.length <= constants_1.WHATSAPP_MAX_BUTTONS) {
return {
type: core_1.INPUT.TEXT,
children: [...buttonsTextSeparator, ...postbackButtons],
};
}
const rows = postbackButtons.map(postbackButton => {
const row = {
id: postbackButton.props.path
? `__PATH_PAYLOAD__${postbackButton.props.path}`
: postbackButton.props.payload,
title: postbackButton.props.children,
};
return row;
});
const whatsAppButtonListProps = {
body: index === 0 ? texts.join('') : buttonsTextSeparator,
button: menuButtonTextWhatsappList,
sections: [{ rows }],
};
return {
type: core_1.INPUT.WHATSAPP_BUTTON_LIST,
props: whatsAppButtonListProps,
};
});
const messageWithUrlButtonElements = ((0, jsx_runtime_1.jsx)(text_1.Text, Object.assign({}, constants_1.MULTICHANNEL_WHATSAPP_PROPS, props, { children: urlButtonElements }), `msg-with-url-button`));
const messageWithWebviewButtonElements = ((0, jsx_runtime_1.jsxs)(text_1.Text, Object.assign({}, constants_1.MULTICHANNEL_WHATSAPP_PROPS, props, { children: [buttonsTextSeparator, webviewButtonElements] }), `msg-with-webview-button`));
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [messages.map((message, i) => {
if (message.type === core_1.INPUT.WHATSAPP_BUTTON_LIST)
return ((0, jsx_runtime_1.jsx)(__1.WhatsappButtonList, Object.assign({}, message.props), `msg-${i}-whatsapp-list`));
return ((0, jsx_runtime_1.jsx)(text_1.Text, Object.assign({}, constants_1.MULTICHANNEL_WHATSAPP_PROPS, props, { children: message.children }), `msg-${i}-with-postback-buttons`));
}), urlButtonElements.length > 0 && messageWithUrlButtonElements, webviewButtonElements.length > 0 && messageWithWebviewButtonElements] }));
}
multichannelContext.currentIndex = getDefaultIndex();
const postbackButtonElements = postbackButtons.map(regenerateMultichannelButtons(!!texts.length));
const urlButtonElements = urlButtons.map(regenerateMultichannelButtons(!!texts.length || !!postbackButtons.length));
elements = [].concat([...textElements], [...postbackButtonElements], [...urlButtonElements]);
if (postbackButtonElements.length === 0) {
// Use texts[0] instead of textElements[0] as a body to avoid apply the markdownMeta function twice.
// If the markdownMeta function is applied twice, bold is replaced by italics.
const body = texts[0] || '';
if (urlButtonElements.length === 1) {
return ((0, jsx_runtime_1.jsx)(__1.WhatsappCTAUrlButton, { body: body, displayText: urlButtonElements[0].props.children, url: urlButtonElements[0].props.url }));
}
if (webviewButtonElements.length === 1) {
return ((0, jsx_runtime_1.jsx)(__1.WhatsappCTAUrlButton, { body: body, displayText: webviewButtonElements[0].props.children, webview: webviewButtonElements[0].props.webview, params: webviewButtonElements[0].props.params }));
}
}
if (multichannelContext.messageSeparator != null) {
return elements;
}
const messages = [
(0, jsx_runtime_1.jsx)(text_1.Text, Object.assign({}, constants_1.MULTICHANNEL_WHATSAPP_PROPS, props, { children: elements }), 0),
];
if (webviewButtonElements.length) {
messages.push((0, jsx_runtime_1.jsxs)(text_1.Text, Object.assign({}, constants_1.MULTICHANNEL_WHATSAPP_PROPS, props, { children: [buttonsTextSeparator, webviewButtonElements] }), 1));
}
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: messages });
}
if ((0, core_1.isFacebook)(requestContext.session)) {
const text = getText(props.children);
const multichannelFacebook = new facebook_1.MultichannelFacebook();
const { texts, propsLastText, propsWithoutChildren } = multichannelFacebook.convertText(props, text[0]);
const [lastText, ...buttonsAndReplies] = propsLastText.children;
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [texts === null || texts === void 0 ? void 0 : texts.map((message, i) => ((0, jsx_runtime_1.jsx)(text_1.Text, Object.assign({}, propsWithoutChildren, { children: (0, markdown_meta_1.convertToMarkdownMeta)(message) }), i))), (0, jsx_runtime_1.jsxs)(text_1.Text, Object.assign({}, propsLastText, { children: [(0, markdown_meta_1.convertToMarkdownMeta)(lastText), buttonsAndReplies] }))] }));
}
return (0, jsx_runtime_1.jsx)(text_1.Text, Object.assign({}, props, { children: props.children }));
};
exports.MultichannelText = MultichannelText;
//# sourceMappingURL=multichannel-text.js.map