import { createContext, PropsWithChildren, ReactElement, useContext, useEffect, useState } from 'react'; import { nativeEventEmitter } from '../native-event-emitter'; const VisibilityChangedContext = createContext(undefined); /** * @name VisibilityChangedProvider * @kind function * @description * 토스 앱 React Native 화면이 보이는지 여부를 관리하는 Provider예요. * 토스 앱의 `visibilityChanged` 이벤트를 구독해서 화면이 보이는지 여부를 감지하고 관리해요. * * @param {ReactNode | undefined} children - 화면이 보이는지 여부를 확인하는 자식 컴포넌트예요. * @param {boolean} isVisible - 화면이 보이는지 여부를 나타내는 `boolean` 값이에요. * @returns {ReactElement} - `VisibilityChangedContext.Provider`로 감싼 React Provider 컴포넌트예요. * @example * ```typescript * export function VisibilityProvider({ isVisible, children }: Props) { * return ( * * {children} * * ); * } * ``` */ export function VisibilityChangedProvider({ children, isVisible, }: PropsWithChildren<{ isVisible: boolean }>): ReactElement { const [visible, setVisible] = useState(isVisible); useEffect(() => { const subscription = nativeEventEmitter.addListener('visibilityChanged', (nextVisible) => { setVisible(nextVisible); }); return () => { subscription.remove(); }; }, []); return {children}; } /** * @name useVisibilityChanged * @category Hooks * @kind function * @description * 토스 앱 React Native 화면이 보이는지 여부를 반환하는 Hook이에요. * @returns {boolean} - 화면이 보이는지 여부를 반환해요. * @throws {Error} `VisibilityChangedProvider` 내부에서 사용되지 않았을 때 에러를 발생시켜요. * @example * ```typescript * const isVisible = useVisibilityChanged(); * console.log(isVisible); * // true or false * ``` */ export function useVisibilityChanged(): boolean { const isVisible = useContext(VisibilityChangedContext); if (isVisible == null) { throw new Error('useVisibilityChanged must be used within a VisibilityChangedProvider'); } return isVisible; }