UNPKG

@told.club/sdk-rn

Version:
163 lines (159 loc) 5.99 kB
import * as React from 'react'; import { Animated, StyleSheet, useWindowDimensions, KeyboardAvoidingView, Modal, Linking } from 'react-native'; import { WebView } from 'react-native-webview'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import ToldContext from './ToldContext'; import { setReplied, setSeen } from './ToldStorage'; import { Platform } from 'react-native'; import { convertToJSONString } from './utils/hiddenFields'; const transferMessagesToRN = ` window.addEventListener('message', (e) => { window.ReactNativeWebView.postMessage(JSON.stringify(e.data)); }); window.console.log = (msg, other = '') => window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'LOG', msg: msg + other })); `; export default function ToldWidget({ surveyId, sourceID, params, widgetUrl }) { const insets = useSafeAreaInsets(); const { height } = useWindowDimensions(); const webviewRef = React.useRef(null); const { close, hiddenFields } = React.useContext(ToldContext); const [currentHeight, setCurrentHeight] = React.useState(500); const [urlModalLink, setUrlModalLink] = React.useState(null); // Animated values const animatedHeight = React.useRef(new Animated.Value(500)).current; const animatedOpacity = React.useRef(new Animated.Value(0)).current; React.useEffect(() => { // When the widget is mounted, we set the survey as seen if (surveyId) setSeen(surveyId); }, [surveyId]); // METHOD: Animate the webview height const updateWebviewHeight = React.useCallback((newHeight, animated) => { Animated.timing(animatedHeight, { toValue: newHeight, duration: animated ? 300 : 0, useNativeDriver: false }).start(); }, [animatedHeight]); // EVENT: Message received from the webview const onMessageReceived = React.useCallback(event => { var _webviewRef$current, _data$value; const data = JSON.parse(event.nativeEvent.data); const type = data === null || data === void 0 ? void 0 : data.type; switch (type) { case 'LOG': if (params.includes('debug')) console.log(`[LOG] ${data.msg}`); return; case 'IS_LOADED': const formattedHiddenFields = convertToJSONString(hiddenFields); (_webviewRef$current = webviewRef.current) === null || _webviewRef$current === void 0 || _webviewRef$current.injectJavaScript(` window.postMessage({type: 'OS_TYPE', value: '${Platform.OS.toUpperCase()}'}, '*'); window.postMessage({type: 'DEVICE_TYPE', value: 'phone'}, '*'); window.postMessage({type: 'SAFE_AREA', value: '${insets.bottom}'}, '*'); window.postMessage({type: 'UPDATE_HIDDENFIELDS', value: '${formattedHiddenFields}'}, '*'); `); break; case 'HEIGHT_CHANGE': const value = data === null || data === void 0 ? void 0 : data.value; const newHeight = value > height ? height - insets.top : value; updateWebviewHeight(newHeight, /*currentHeight > newHeight*/false); if (currentHeight === 500) { Animated.timing(animatedOpacity, { toValue: 1, duration: 300, useNativeDriver: false }).start(); } setCurrentHeight(newHeight); break; case 'LAUNCH_CALENDAR': const url = data === null || data === void 0 || (_data$value = data.value) === null || _data$value === void 0 ? void 0 : _data$value.iframeUrl; // if (url) Linking.openURL(url); if (url) setUrlModalLink(url); break; case 'ADD_COOKIE': const reply = data === null || data === void 0 ? void 0 : data.reply; if (reply) setReplied(surveyId); break; case 'CLOSE': Animated.timing(animatedOpacity, { toValue: 0, duration: 125, useNativeDriver: false }).start(() => close()); break; default: break; } if (params.includes('debug')) console.log(`[MSG RECEIVED] ${event.nativeEvent.data}`); }, [params, insets, height, updateWebviewHeight, currentHeight, surveyId, animatedOpacity, close, hiddenFields]); // EVENT: Open a new window const onOpenWindow = React.useCallback(event => { var _event$nativeEvent; Linking.openURL(event === null || event === void 0 || (_event$nativeEvent = event.nativeEvent) === null || _event$nativeEvent === void 0 ? void 0 : _event$nativeEvent.targetUrl); }, []); const onLinkModalClose = React.useCallback(() => { setUrlModalLink(null); }, []); return /*#__PURE__*/React.createElement(Modal, { transparent: true, visible: true }, /*#__PURE__*/React.createElement(KeyboardAvoidingView, { behavior: "padding", style: styles.container }, /*#__PURE__*/React.createElement(Animated.View, { style: [styles.animatedContainer, { height: animatedHeight, opacity: animatedOpacity }] }, /*#__PURE__*/React.createElement(WebView, { ref: webviewRef, source: { uri: `${widgetUrl}/?id=${surveyId}&toldProjectID=${sourceID}` }, bounces: false, containerStyle: styles.webViewContainer, style: styles.webView, injectedJavaScript: transferMessagesToRN, onMessage: onMessageReceived, onOpenWindow: onOpenWindow, scrollEnabled: false }))), /*#__PURE__*/React.createElement(Modal, { animationType: "slide", presentationStyle: "pageSheet", visible: urlModalLink !== null, onRequestClose: onLinkModalClose }, urlModalLink && /*#__PURE__*/React.createElement(WebView, { source: { uri: urlModalLink }, containerStyle: styles.webViewContainer, onOpenWindow: onOpenWindow, scrollEnabled: true }))); } const styles = StyleSheet.create({ container: { flex: 1, flexDirection: 'column-reverse' }, animatedContainer: { flex: 0 }, webViewContainer: { flex: 1 }, webView: { backgroundColor: 'transparent' } }); //# sourceMappingURL=ToldWidget.js.map