/******************************************************************************************** * Copyright (C) 2025 Acoustic, L.P. All rights reserved. * * NOTICE: This file contains material that is confidential and proprietary to * Acoustic, L.P. and/or other developers. No license is granted under any intellectual or * industrial property rights of Acoustic, L.P. except as may be provided in an agreement with * Acoustic, L.P. Any unauthorized copying or distribution of content from this file is * prohibited. ********************************************************************************************/ import React, { useCallback, useEffect, useRef, forwardRef } from "react"; import { View, StyleSheet, Platform, NativeModules, findNodeHandle } from "react-native"; import type { LayoutChangeEvent } from "react-native"; // Use type-only import for LayoutChangeEvent import TLTRN from '../TLTRN'; interface ConnectProps { children: React.ReactNode; captureKeyboardEvents: boolean; captureDialogEvents?: boolean; // New prop for dialog event capture } const Connect: React.FC = ({ children, captureKeyboardEvents, captureDialogEvents = false }) => { const navigation = (children as any).ref; // Type assertion for children with ref const currentRoute = useRef(undefined); const initial = useRef(false); useEffect(() => { TLTRN.interceptKeyboardEvents(captureKeyboardEvents); }, [captureKeyboardEvents]); useEffect(() => { TLTRN.interceptDialogEvents(captureDialogEvents); }, [captureDialogEvents]); useEffect(() => { if ( !navigation || typeof navigation.current.addListener !== "function" || typeof navigation.current.getCurrentRoute !== "function" ) { console.warn( "Connect: The Connect component's first child must be a NavigationContainer with a ref." ); return; } // Listen for the 'state' event to track navigation state changes const unsubscribeState = navigation.current.addListener("state", () => { currentRoute.current = extractName(navigation) || navigation.current.getCurrentRoute()?.name; console.log("State change - ", currentRoute.current); if (Platform.OS === "ios" && currentRoute && currentRoute.current) { TLTRN.logScreenViewPageName(currentRoute.current); } else if (Platform.OS === "android") { TLTRN.logScreenViewPageName(currentRoute.current); TLTRN.logScreenLayout(currentRoute.current); } }); // Cleanup listeners when the component unmounts or dependencies change return () => { unsubscribeState(); }; }, [navigation]); const onStartShouldSetResponderCapture = useCallback((event: any) => { currentRoute.current = extractName(navigation) || navigation.current.getCurrentRoute()?.name; if (currentRoute && currentRoute.current) { TLTRN.logScreenViewPageName(currentRoute.current); } TLTRN.logClickEvent(event); return false; // Must be false; true means this component becomes the touch responder and events don't bubble }, []); const onLayout = useCallback((event: LayoutChangeEvent) => { if (initial.current) { return false; } initial.current = true; console.log("event - ", event.nativeEvent); currentRoute.current = navigation.current.getCurrentRoute()?.name; if (Platform.OS === "ios" && currentRoute && currentRoute.current) { TLTRN.logScreenViewPageName(currentRoute.current); } else if (Platform.OS === "android") { TLTRN.logScreenLayout(currentRoute.current); } return true }, [navigation]); return ( {children} ); }; function extractName(navigation: any): string { const routeParams = navigation.current.getCurrentRoute()?.params; if (routeParams) { const { name } = routeParams; return name ? name : navigation.current?.getCurrentRoute()?.name || ""; } return ""; } export default Connect; const styles = StyleSheet.create({ connect_main: { flex: 1, }, });