UNPKG

@botonic/react

Version:

Build Chatbots using React

115 lines (102 loc) 3.02 kB
import React, { useContext, useEffect } from 'react' import Frame from 'react-frame-component' import styled from 'styled-components' import { COLORS, ROLES, WEBCHAT } from '../constants' import { RequestContext, WebchatContext } from '../contexts' const StyledWebview = styled.div` position: absolute; display: flex; flex-direction: column; bottom: 0; width: 100%; height: 100%; background-color: ${COLORS.SOLID_WHITE}; z-index: 2; border-radius: ${WEBCHAT.DEFAULTS.BORDER_RADIUS_TOP_CORNERS}; ` const StyledWebviewHeader = styled.div` text-align: right; background-color: ${COLORS.WILD_SAND_WHITE}; border-top: 1px solid ${COLORS.SOLID_BLACK_ALPHA_0_2}; border-bottom: 1px solid ${COLORS.SOLID_BLACK_ALPHA_0_2}; border-radius: ${WEBCHAT.DEFAULTS.BORDER_RADIUS_TOP_CORNERS}; ` const StyledCloseHeader = styled.div` display: inline-block; padding: 8px 12px; cursor: pointer; ` const StyledWebviewContent = styled.div` flex: 1; overflow: auto; ` const StyledFrame = styled.iframe` border-style: none; width: 100%; height: 100%; ` const WebviewMode = props => { /* Default mode is with divs. Setting the prop "asframe" will render the webview inside an iframe. Pros and Cons of this "asframe" mode are: Pros: OAuth2 flows can be tested locally with an iframe. Cons: We won't be able to visualize correctly css styles in botonic serve (although styles will work in production). */ const style = { borderStyle: 'none', width: '100%', height: '100%', } if (props.asframe) { return <Frame style={style}>{props.children}</Frame> } return <div style={style}>{props.children}</div> } export const WebviewHeader = () => { const { closeWebview } = useContext(RequestContext) const { getThemeProperty } = useContext(WebchatContext) return ( <StyledWebviewHeader role={ROLES.WEBVIEW_HEADER} style={{ ...getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.webviewHeaderStyle), }} > <StyledCloseHeader onClick={closeWebview}></StyledCloseHeader> </StyledWebviewHeader> ) } export const WebviewContainer = props => { const { webchatState } = useContext(WebchatContext) const { closeWebview } = useContext(RequestContext) const Webview = webchatState.webview const close = e => e.data == 'botonicCloseWebview' && closeWebview() useEffect(() => { if (window.addEventListener) { window.addEventListener('message', close, false) } else if (window.attachEvent) { // ie8 window.attachEvent('onmessage', close) } }, []) return ( <StyledWebview role={ROLES.WEBVIEW} style={{ ...props.style, }} > <WebviewHeader style={{ flex: 'none' }} /> <StyledWebviewContent> {typeof Webview === 'string' ? ( <StyledFrame src={Webview} /> ) : ( <WebviewMode> <Webview /> </WebviewMode> )} </StyledWebviewContent> </StyledWebview> ) }