UNPKG

@botonic/react

Version:

Build Chatbots using React

163 lines 9.73 kB
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