@botonic/react
Version:
Build Chatbots using React
163 lines • 9.73 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { INPUT, isFacebook, isWhatsapp } from '@botonic/core';
import React, { useContext } from 'react';
import { RequestContext } from '../../contexts';
import { WhatsappButtonList, WhatsappCTAUrlButton } from '..';
import { Text } from '../text';
import { MultichannelFacebook } from './facebook/facebook';
import { MultichannelButton } from './multichannel-button';
import { MultichannelContext } from './multichannel-context';
import { buttonTypes, elementHasPostback, elementHasUrl, elementHasWebview, getButtonType, getMultichannelButtons, getMultichannelReplies, } from './multichannel-utils';
import { DEFAULT_WHATSAPP_MAX_BUTTON_SEPARATOR, MENU_BUTTON_WHATSAPP_BUTTON_LIST, MULTICHANNEL_WHATSAPP_PROPS, WHATSAPP_LIST_MAX_BUTTONS, WHATSAPP_MAX_BUTTONS, } from './whatsapp/constants';
import { convertToMarkdownMeta } from './whatsapp/markdown-meta';
export const MultichannelText = props => {
var _a;
const requestContext = useContext(RequestContext);
const multichannelContext = useContext(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(getMultichannelButtons(React.Children.toArray(props.children)), getMultichannelReplies(React.Children.toArray(props.children)));
const getWhatsappButtons = () => {
const postbackButtons = [];
const urlButtons = [];
const webviewButtons = [];
for (const button of getButtonsAndReplies()) {
if (elementHasUrl(button))
urlButtons.push(button);
else if (elementHasWebview(button))
webviewButtons.push(button);
else if (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 = getButtonType(multichannelButton);
const asText = type === buttonTypes.POSTBACK ? postbackButtonsAsText : true;
const newline = multichannelContext.messageSeparator == null &&
!newLineFirstButton &&
i === 0
? ''
: '\n';
return (_jsx(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 += WHATSAPP_LIST_MAX_BUTTONS) {
messages.push(postbackButtons.slice(i, i + WHATSAPP_LIST_MAX_BUTTONS));
}
return messages;
};
if (isWhatsapp(requestContext.session)) {
const texts = getText(props.children);
const { postbackButtons, urlButtons, webviewButtons } = getWhatsappButtons();
const textElements = texts.map(text => {
const textWithMarkdown = convertToMarkdownMeta(text);
return (props.newline || '') + textWithMarkdown;
});
const webviewButtonElements = webviewButtons.map(regenerateMultichannelButtons(false));
const buttonsTextSeparator = props.buttonsTextSeparator || DEFAULT_WHATSAPP_MAX_BUTTON_SEPARATOR;
const exceedWhatsAppMaxButtonNumber = !postbackButtonsAsText && postbackButtons.length > WHATSAPP_MAX_BUTTONS;
if (exceedWhatsAppMaxButtonNumber) {
const menuButtonTextWhatsappList = props.menuButtonTextWhatsappList || 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 <= WHATSAPP_MAX_BUTTONS) {
return {
type: 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: INPUT.WHATSAPP_BUTTON_LIST,
props: whatsAppButtonListProps,
};
});
const messageWithUrlButtonElements = (_jsx(Text, Object.assign({}, MULTICHANNEL_WHATSAPP_PROPS, props, { children: urlButtonElements }), `msg-with-url-button`));
const messageWithWebviewButtonElements = (_jsxs(Text, Object.assign({}, MULTICHANNEL_WHATSAPP_PROPS, props, { children: [buttonsTextSeparator, webviewButtonElements] }), `msg-with-webview-button`));
return (_jsxs(_Fragment, { children: [messages.map((message, i) => {
if (message.type === INPUT.WHATSAPP_BUTTON_LIST)
return (_jsx(WhatsappButtonList, Object.assign({}, message.props), `msg-${i}-whatsapp-list`));
return (_jsx(Text, Object.assign({}, 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 (_jsx(WhatsappCTAUrlButton, { body: body, displayText: urlButtonElements[0].props.children, url: urlButtonElements[0].props.url }));
}
if (webviewButtonElements.length === 1) {
return (_jsx(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 = [
_jsx(Text, Object.assign({}, MULTICHANNEL_WHATSAPP_PROPS, props, { children: elements }), 0),
];
if (webviewButtonElements.length) {
messages.push(_jsxs(Text, Object.assign({}, MULTICHANNEL_WHATSAPP_PROPS, props, { children: [buttonsTextSeparator, webviewButtonElements] }), 1));
}
return _jsx(_Fragment, { children: messages });
}
if (isFacebook(requestContext.session)) {
const text = getText(props.children);
const multichannelFacebook = new MultichannelFacebook();
const { texts, propsLastText, propsWithoutChildren } = multichannelFacebook.convertText(props, text[0]);
const [lastText, ...buttonsAndReplies] = propsLastText.children;
return (_jsxs(_Fragment, { children: [texts === null || texts === void 0 ? void 0 : texts.map((message, i) => (_jsx(Text, Object.assign({}, propsWithoutChildren, { children: convertToMarkdownMeta(message) }), i))), _jsxs(Text, Object.assign({}, propsLastText, { children: [convertToMarkdownMeta(lastText), buttonsAndReplies] }))] }));
}
return _jsx(Text, Object.assign({}, props, { children: props.children }));
};
//# sourceMappingURL=multichannel-text.js.map