UNPKG

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

Version:

Applicaster Zapp React Native ui components for the Quick Brick App

138 lines (108 loc) 3.93 kB
import React, { useLayoutEffect } from "react"; import { allowedOrientationsForScreen, ORIENTATIONS, getOrientation, 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 { ZappHookModalContext } from "../../Contexts"; import { HookModalContextT } 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 { isHooksExecutionInProgress } = React.useContext<HookModalContextT>( ZappHookModalContext.ReactContext ); 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; } // 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, isHooksExecutionInProgress, 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]); }