import React, { useEffect, useRef, useState } from 'react'; import { DeviceEventEmitter, BackHandler, Dimensions, Image, KeyboardAvoidingView, Platform, StatusBar, StyleSheet, TouchableOpacity, View, ActivityIndicator } from 'react-native'; import { WebView } from 'react-native-webview'; const { height, width } = Dimensions.get('screen'); interface ChatbotProps { embedToken: string | null; bridgeName: string | null; threadId: string | null; openInContainer?: boolean; hideIcon?: boolean; defaultOpen?: boolean; hideCloseButton?: boolean; variables?: any; } const ChatBot: React.FC = (props) => { const [isWebViewVisible, setIsWebViewVisible] = useState(false); const { embedToken, bridgeName, threadId = "", openInContainer = false, hideIcon = false, defaultOpen = false, hideCloseButton = false, variables = {} } = props || {}; const webViewRef = useRef(null); const [chatbotProps, setChatbotProps] = useState({ ...props }); // Update state when props change useEffect(() => { setChatbotProps((prevProps: any) => ({ bridgeName: bridgeName || prevProps.bridgeName, threadId: threadId || prevProps.threadId, variables: { ...prevProps.variables, ...(variables || {}) } })); }, [props]); const handleEvent = (event: any) => { if (event?.type === 'openChatbot') { setIsWebViewVisible(true); } else if (event?.type === 'closeChatbot') { setIsWebViewVisible(false); } else if (event?.type === 'SendDataToChatbot') { const data = event.data; setChatbotProps((prevProps: any) => ({ ...prevProps, ...data })); } } useEffect(() => { DeviceEventEmitter.addListener('openChatbot', handleEvent); DeviceEventEmitter.addListener('closeChatbot', handleEvent); DeviceEventEmitter.addListener('SendDataToChatbot', handleEvent); return () => { DeviceEventEmitter.removeAllListeners('openChatbot'); DeviceEventEmitter.removeAllListeners('closeChatbot'); DeviceEventEmitter.removeAllListeners("SendDataToChatbot"); } }, []); const handleCloseChatbot = (isWebViewVisibleHai: any) => { if (isWebViewVisibleHai) { // Close the chatbot and indicate back press is handled setIsWebViewVisible(false); handleDataSending("closeChatbot"); return true; // Prevent default back button action } return false; // Allow default back button action } useEffect(() => { const backHandlerListener = BackHandler.addEventListener( "hardwareBackPress", () => handleCloseChatbot(isWebViewVisible) ); return () => { backHandlerListener.remove(); } }, [isWebViewVisible]) const handleDataSending = (type: string) => { // Ensure WebView is loaded before injecting JS let script = ""; if (webViewRef.current) { switch (type) { case "sendData": script = ` if (window.SendDataToChatbot) { window.SendDataToChatbot(${JSON.stringify(chatbotProps)}); } else { console.log("window.SendDataToChatbot is not available"); } `; break; case "openChatbot": script = ` if (window.openChatbot) { window.openChatbot(); } else { console.log("window.openChatbot is not available"); } `; break; case "closeChatbot": script = ` if (window.closeChatbot) { window.closeChatbot(); } else { console.log("window.closeChatbot is not available"); } `; break; case "hideCloseButton": script = ` if (window.SendDataToChatbot) { window.SendDataToChatbot(${JSON.stringify({ hideCloseButton: true })}); } else { console.log("window.openChatbot is not available"); } `; break; default: console.log("Unknown type"); } webViewRef.current.injectJavaScript(script); // Inject JavaScript to trigger chatbot opening } }; useEffect(() => { handleDataSending("sendData"); }, [chatbotProps]); // Handle message from WebView const handleOnMessage = (event: any) => { const data = JSON.parse(event.nativeEvent.data); if (data?.type === "close") { setIsWebViewVisible(false); } }; const handleOpenChatbot = () => { handleDataSending("openChatbot"); } useEffect(() => { if (isWebViewVisible) { handleOpenChatbot(); } }, [isWebViewVisible]) // Create the HTML string with the chatbot script const generateHtmlContent = (embedToken: string, bridgeName: string, threadId: string) => ` Chatbot `; const [htmlContent, setHtmlContent] = useState(generateHtmlContent(embedToken, bridgeName, threadId)); useEffect(() => { if (embedToken) { setHtmlContent(generateHtmlContent(embedToken, bridgeName, threadId)); } }, [embedToken]); const hasNotch = StatusBar.currentHeight > 24; const iosKeyboardAvoidingHeight = hasNotch ? height - StatusBar.currentHeight : height - StatusBar.currentHeight * 3; // const hasNotch = false; if (!embedToken) { return ( null ) } return ( <> {!hideIcon && setIsWebViewVisible(true)} style={{ position: 'absolute', bottom: 20, right: 20, width: 50, height: 50, borderRadius: 30, zIndex: 99999, backgroundColor: 'black', justifyContent: 'center', alignItems: 'center', cursor: 'pointer', }} > } } onLoadEnd={() => { // You can call the method to open the chatbot once it is loaded handleDataSending("sendData"); if (defaultOpen) { handleDataSending("openChatbot"); setIsWebViewVisible(true); } if (hideCloseButton) { handleDataSending("hideCloseButton"); } }} onMessage={handleOnMessage} // Listen to messages from WebView onError={(error) => console.log('error', error)} onHttpError={(error) => console.log('http error', error)} pullToRefreshEnabled={true} refreshControlLightMode={true} /> ); }; const styles = StyleSheet.create({ webview: { flex: 1, // Make sure the WebView takes up the full screen }, }); export default ChatBot;