import { reaction } from "mobx"; import { DependencyList, useContext, useEffect, useMemo, useRef, useState, } from "react"; import { StatusBar } from "react-native"; import { cancelAnimation, useSharedValue } from "react-native-reanimated"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { TContext } from "../TProvider"; import { Platform_iOS, vs } from "../commons"; import { tBaseStore } from "../store"; import { DimensionsType, MeasureFunc } from "../types"; export * from "./useOTPCode"; const STATUS_BAR_HEIGHT = StatusBar.currentHeight || 0; export const useColors = () => { return useContext(TContext).theme; }; export const useSafeArea = (withDefaultValue?: boolean) => { const insets = useSafeAreaInsets(); return { ...insets, bottom: insets.bottom || (withDefaultValue ? 0 : vs(16)), top: Platform_iOS ? insets.top : Math.max(STATUS_BAR_HEIGHT, withDefaultValue ? 0 : vs(32)), }; }; export const useReanimatedValue = (value: T) => { const val = useSharedValue(value); useEffect(() => { return () => { cancelAnimation(val); }; }, []); return val; }; export const useReaction = ( expression: () => T, effect: (v: T) => void, deps: DependencyList = [] ) => { const sub = useMemo(() => reaction(expression, effect), deps); useEffect(() => { return () => { sub(); }; }, deps); }; export const useDimensions = ( callback?: boolean | ((d: DimensionsType) => void) ) => { const [dimens, setDimens] = useState(tBaseStore.dimens); useReaction( () => tBaseStore.dimens, (d) => (typeof callback === "boolean" ? setDimens(d) : callback?.(d)) ); return dimens; }; export const useMeasure = ( duration?: number ): [any, (cb: MeasureFunc) => void] => { const refView = useRef(); const refTimeout = useRef(0); const run = (callback: MeasureFunc) => { refView.current?.[Platform_iOS ? "measureInWindow" : "measure"]( (x: number, y: number, w: number, h: number, pX: number, pY: number) => { callback({ x: Platform_iOS ? x : pX, w, h, y: Platform_iOS ? y : pY }); } ); }; const measure = (callback: MeasureFunc) => { if (duration) refTimeout.current = setTimeout(() => { run(callback); }, duration); else run(callback); }; useEffect(() => { return () => { refTimeout.current && clearTimeout(refTimeout.current); }; }, []); return [refView, measure]; }; export const useModal = (): [any, () => void, () => void] => { const refModal = useRef(); const show = () => { refModal.current?.show(); }; const dismiss = () => { refModal.current?.dismiss(); }; return [refModal, show, dismiss]; }; export const useTab = (): [ any, (i: number) => void, () => void, () => void ] => { const refTab = useRef(); const set = (i: number) => { refTab.current?.set(i); }; const prev = () => { refTab.current?.prev(); }; const next = () => { refTab.current?.next(); }; return [refTab, set, prev, next]; };