UNPKG

@applicaster/zapp-react-native-ui-components

Version:

Applicaster Zapp React Native ui components for the Quick Brick App

135 lines (106 loc) 3.87 kB
import { useLayoutEffect } from "react"; import { allowedOrientationsForScreen, getOrientation, ORIENTATIONS, useGetScreenOrientation, } from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper"; import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils"; import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks"; import { findPluginByType } from "@applicaster/zapp-react-native-utils/pluginUtils"; import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks"; import { zappHookModalStore } from "../../Contexts/ZappHookModalContext"; /** * This function calls the native module needed to set orientation * @param {ORIENTATIONS} orientation desired orientation */ function setOrientation(orientation: ORIENTATIONS) { allowedOrientationsForScreen(orientation); } type OrientationHookArgs = { screenData: {}; }; // Current device orienatation state, can not be inside ref, // because ref lifetime connected to components (i.e. we lose state) let current = null; // Override function we use until player screen will start to provide orientation // in a generic way as other screens const getPlayerOrientation = ({ screenData, plugins, screenOrientation }) => { if (!screenData) { return null; } const isPlayer = screenData.plugin_type === "player" || screenData.screenType === "playable"; if (!isPlayer) { return null; } if (screenOrientation) { // Prefer layout screen orientation return screenOrientation; } const player = findPluginByType("player", plugins, { returnFullObject: true, }); const playerPluginOrientation = getOrientation( player?.configuration?.screen_orientation ); return playerPluginOrientation || ORIENTATIONS.landscapeSensor; }; export function useNewOrientationForScreenData({ screenData, }: OrientationHookArgs) { const isTablet = useIsTablet(); const { appData, plugins } = usePickFromState(["appData", "plugins"]); const isTabletPortrait = appData?.isTabletPortrait; const isLandscapeTablet = isTablet && !isTabletPortrait; const screenOrientation = useGetScreenOrientation(screenData); current = current || (isLandscapeTablet ? ORIENTATIONS.landscapeSensor : ORIENTATIONS.portrait); return isLandscapeTablet ? ORIENTATIONS.landscapeSensor : getPlayerOrientation({ screenData, plugins, screenOrientation }) || screenOrientation; } type Props = { screenData: { screen: {}; }; isActive: boolean; }; export function useScreenOrientationHandler({ screenData, isActive }: Props) { const prevIsActive = usePrevious(isActive); const newOrientation = useNewOrientationForScreenData({ screenData: screenData.screen, }); useLayoutEffect(() => { // Null means screen does not have orientation preference, so we can skip rotate if (!newOrientation) { return; } // TODO: make sure it can be static getter and subscription is not needed const { isHooksExecutionInProgress } = zappHookModalStore.getState(); // If modal hook presented we need to skip // Change orientation for presenter screen if (isHooksExecutionInProgress) { return; } if (!prevIsActive && isActive && newOrientation !== current) { current = newOrientation; setOrientation(newOrientation); } }, [newOrientation, prevIsActive, isActive]); } export function useOrientationHandler({ screenData }: OrientationHookArgs) { const newOrientation = useNewOrientationForScreenData({ screenData }); useLayoutEffect(() => { // Null means screen does not have orientation preference, so we can skip rotate if (!newOrientation) { return; } if (newOrientation !== current) { current = newOrientation; setOrientation(newOrientation); } }, [newOrientation]); }