184 lines
5.5 KiB
TypeScript
184 lines
5.5 KiB
TypeScript
import React, { useEffect, useMemo, useState, useRef } from "react";
|
|
import { View, TouchableOpacity } from "react-native";
|
|
import { WebView } from "react-native-webview";
|
|
import { MessageCircle } from "lucide-react-native";
|
|
import { useAuthStore } from "~/lib/stores";
|
|
|
|
const CHATWOOT_BASE_URL = "https://chat.app.ambapays.com";
|
|
const CHATWOOT_WEBSITE_TOKEN = "or1QS1gRowqkuBBcQVEb3Wib";
|
|
|
|
export default function ChatwootFloatingButton() {
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
const webViewRef = useRef<WebView | null>(null);
|
|
|
|
const user = useAuthStore((state) => state.user);
|
|
const profile = useAuthStore((state) => state.profile);
|
|
|
|
const identifier = user?.uid || user?.email || "";
|
|
const name = profile?.fullName || user?.displayName || "";
|
|
const email = user?.email || "";
|
|
const phone = profile?.phoneNumber || user?.phoneNumber || "";
|
|
|
|
const html = useMemo(
|
|
() => `<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<style>
|
|
html, body { margin: 0; padding: 0; height: 100%; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
window.chatwootSettings = {
|
|
hideMessageBubble: true,
|
|
position: "right",
|
|
type: "standard",
|
|
launcherTitle: "Chat with us",
|
|
};
|
|
(function(d,t) {
|
|
var BASE_URL = '${CHATWOOT_BASE_URL}';
|
|
var g = d.createElement(t), s = d.getElementsByTagName(t)[0];
|
|
g.src = BASE_URL + '/packs/js/sdk.js';
|
|
g.async = true;
|
|
s.parentNode.insertBefore(g, s);
|
|
g.onload = function() {
|
|
if (window.chatwootSDK && typeof window.chatwootSDK.run === 'function') {
|
|
window.chatwootSDK.run({
|
|
websiteToken: '${CHATWOOT_WEBSITE_TOKEN}',
|
|
baseUrl: BASE_URL,
|
|
});
|
|
|
|
if (window.$chatwoot) {
|
|
try {
|
|
if ('${identifier}') {
|
|
window.$chatwoot.setUser('${identifier}', {
|
|
email: '${email}',
|
|
name: '${name}',
|
|
phone_number: '${phone}',
|
|
});
|
|
}
|
|
|
|
window.__ambaChatOpen = false;
|
|
|
|
window.addEventListener('chatwoot:opened', function () {
|
|
window.__ambaChatOpen = true;
|
|
});
|
|
|
|
window.addEventListener('chatwoot:closed', function () {
|
|
window.__ambaChatOpen = false;
|
|
if (
|
|
window.ReactNativeWebView &&
|
|
window.ReactNativeWebView.postMessage
|
|
) {
|
|
window.ReactNativeWebView.postMessage('chatwoot:closed');
|
|
}
|
|
});
|
|
|
|
var originalToggle = window.$chatwoot.toggle;
|
|
window.$chatwoot.toggle = function(state) {
|
|
var result = originalToggle.apply(window.$chatwoot, arguments);
|
|
|
|
// Normalize state: if undefined, treat as a user-driven toggle
|
|
var normalized = state;
|
|
if (typeof normalized === 'undefined') {
|
|
normalized = window.__ambaChatOpen ? 'close' : 'open';
|
|
}
|
|
|
|
if (normalized === 'open') {
|
|
window.__ambaChatOpen = true;
|
|
}
|
|
|
|
if (
|
|
normalized === 'close' &&
|
|
window.__ambaChatOpen &&
|
|
window.ReactNativeWebView &&
|
|
window.ReactNativeWebView.postMessage
|
|
) {
|
|
window.__ambaChatOpen = false;
|
|
window.ReactNativeWebView.postMessage('chatwoot:closed');
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
// Open widget initially
|
|
window.$chatwoot.toggle('open');
|
|
} catch (e) {
|
|
console.log('Chatwoot integration error', e);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
})(document, 'script');
|
|
</script>
|
|
</body>
|
|
</html>`,
|
|
[identifier, name, email, phone]
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (visible && webViewRef.current) {
|
|
webViewRef.current.injectJavaScript(
|
|
"if (window.$chatwoot) { window.$chatwoot.toggle('open'); } true;"
|
|
);
|
|
}
|
|
}, [visible]);
|
|
|
|
return (
|
|
<>
|
|
<TouchableOpacity
|
|
activeOpacity={0.9}
|
|
onPress={() => setVisible(true)}
|
|
style={{
|
|
position: "absolute",
|
|
right: 20,
|
|
bottom: 70,
|
|
width: 56,
|
|
height: 56,
|
|
borderRadius: 28,
|
|
backgroundColor: "#105D38",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
shadowColor: "#000",
|
|
shadowOpacity: 0.2,
|
|
shadowRadius: 6,
|
|
shadowOffset: { width: 0, height: 3 },
|
|
elevation: 6,
|
|
zIndex: 9999,
|
|
}}
|
|
>
|
|
<MessageCircle color="#FFFFFF" size={26} />
|
|
</TouchableOpacity>
|
|
|
|
<View
|
|
pointerEvents={visible ? "auto" : "none"}
|
|
style={{
|
|
position: "absolute",
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
backgroundColor: "transparent",
|
|
opacity: visible ? 1 : 0,
|
|
}}
|
|
>
|
|
<WebView
|
|
ref={webViewRef}
|
|
originWhitelist={["*"]}
|
|
source={{ html, baseUrl: CHATWOOT_BASE_URL }}
|
|
javaScriptEnabled
|
|
domStorageEnabled
|
|
startInLoadingState
|
|
onMessage={(event) => {
|
|
if (event.nativeEvent.data === "chatwoot:closed") {
|
|
setVisible(false);
|
|
}
|
|
}}
|
|
/>
|
|
</View>
|
|
</>
|
|
);
|
|
}
|