/// import React from "react"; import { AccessibilityInfo, findNodeHandle, View } from "react-native"; import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks"; import { useTheme } from "@applicaster/zapp-react-native-utils/theme"; import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils"; import { getNavBarProps, getScreenId, shouldNavBarDisplayMenu, } from "@applicaster/zapp-react-native-utils/navigationUtils"; import { useCurrentScreenData, useIsScreenActive, useNavbarState, useNavigation, useRoute, useScreenData, } from "@applicaster/zapp-react-native-utils/reactHooks"; import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers"; import { isValidColor, isTransparentColor, } from "@applicaster/zapp-react-native-utils/colorUtils"; import { RouteManager } from "../RouteManager"; import { useScreenConfiguration } from "../River/useScreenConfiguration"; import { useWaitForValidOrientation } from "./hooks"; const screenStyles = { flex: 1, paddingTop: 0, // paddingBottom: insets.bottom, // Should be applied directly by UI plugin // paddingLeft: insets.left, // Should be applied directly by UI plugin // paddingRight: insets.right, // Should be applied directly by UI plugin }; type Props = { pathname: unknown; screenData: unknown; }; export function Screen(_props: Props) { const theme = useTheme(); const navigation = useNavigation(); const { plugins } = usePickFromState(["plugins"]); // Gets the data for the current screen configuration const currentScreenData = useCurrentScreenData(); const { backgroundColor } = useScreenConfiguration(currentScreenData.id); const { screenData, pathname } = useRoute(); const currentRiver = useScreenData( getScreenId(screenData, navigation.activeRiver) ); const { title } = useNavbarState(); const hasMenu = shouldNavBarDisplayMenu(currentRiver, plugins); const navBarProps = React.useMemo( () => getNavBarProps(currentRiver, pathname, title), [currentRiver, pathname, title] ); const NavBar = React.useMemo( () => getNavigationPluginModule( "nav_bar", currentRiver, plugins ) as React.ComponentType, [] ); const offlinePlugin = getComponentModule({ plugins, components: {}, componentType: "offline-experience", }); const { OfflineFallbackScreen } = offlinePlugin; const style = React.useMemo( () => ({ ...screenStyles, backgroundColor: isValidColor(backgroundColor) && !isTransparentColor(backgroundColor) ? backgroundColor : theme.app_background_color, }), [theme.app_background_color, backgroundColor] ); const isActive = useIsScreenActive(); const ref = React.useRef(null); const isOrientationReady = useWaitForValidOrientation(); // Playable screens handle their own orientation via the native player plugin, // so we skip the orientation wait gate to avoid a deadlock where the screen // waits for landscape but blocks rendering that would trigger the rotation. const isPlayableRoute = pathname?.includes("/playable"); const isReady = isOrientationReady || isPlayableRoute; React.useEffect(() => { if (ref.current && isActive && isReady) { const nodeHandle = findNodeHandle(ref.current); if (nodeHandle != null) { AccessibilityInfo.setAccessibilityFocus(nodeHandle); } } }, [isActive, isReady]); // We prevent rendering of the screen until UI is actually rotated to screen desired orientation. // This saves unnecessary re-renders and user will not see distorted aspect screen. return ( {isReady ? ( <> {navBarProps ? : null} {/* @TODO RouteManager doesn't use props, can they be removed ? */} ) : null} ); }