UNPKG

@td-design/react-native

Version:

react-native UI组件库

90 lines (88 loc) 3.32 kB
import { useEffect, useMemo, useRef, useState } from 'react'; import { Dimensions } from 'react-native'; import { Easing, interpolate, runOnJS, useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useTheme } from '@shopify/restyle'; import { useMemoizedFn } from '@td-design/rn-hooks'; import helpers from '../helpers'; import { normalShadowOpt, NotifyType } from './constant'; const screenHeight = Dimensions.get('screen').height; const windowHeight = Dimensions.get('window').height; const bottomNavigatorBarHeight = screenHeight - windowHeight; export default function useNotify() { const insets = useSafeAreaInsets(); const theme = useTheme(); const timer = useRef(); const [visible, setVisible] = useState(false); const [options, setOptions] = useState(undefined); const show = params => { if (visible) return; setOptions(params); setVisible(true); }; const hide = async () => { var _options$onClose; options === null || options === void 0 || (_options$onClose = options.onClose) === null || _options$onClose === void 0 ? void 0 : _options$onClose.call(options); setVisible(false); clearTimeout(timer.current); }; const displayed = useSharedValue(visible ? 1 : 0); const handleClose = () => { displayed.value = withTiming(0, { duration: 300, easing: Easing.inOut(Easing.ease) }, finished => { if (finished) { runOnJS(hide)(); } }); }; useEffect(() => { if (visible) { displayed.value = withSpring(1); } }, [visible]); useEffect(() => { if (!visible || !(options !== null && options !== void 0 && options.duration) || !(options !== null && options !== void 0 && options.autoClose)) return; timer.current = setTimeout(handleClose, options.duration); return () => clearTimeout(timer.current); }, [visible, options === null || options === void 0 ? void 0 : options.duration]); const startY = options !== null && options !== void 0 && options.type ? [NotifyType.SUCCESS, NotifyType.FAIL].includes(options.type) ? normalShadowOpt.height + helpers.px(50) : normalShadowOpt.height + helpers.px(10) : normalShadowOpt.height; const endY = -insets.bottom - bottomNavigatorBarHeight - (helpers.isIOS ? insets.bottom : 0); // 提示窗口的位置 const style = useAnimatedStyle(() => ({ transform: [{ translateY: interpolate(displayed.value, [0, 1], [startY, endY]) }] })); // 提示窗口的阴影颜色和背景色 const { shadowColor, bgColor } = useMemo(() => { switch (options === null || options === void 0 ? void 0 : options.type) { case NotifyType.FAIL: return { shadowColor: theme.colors.func600, bgColor: theme.colors.white }; case NotifyType.INFO: case NotifyType.SUCCESS: default: return { shadowColor: theme.colors.primary200, bgColor: theme.colors.white }; } }, [options === null || options === void 0 ? void 0 : options.type, theme]); return { options, shadowColor, bgColor, style, visible, show: useMemoizedFn(show), hide: useMemoizedFn(handleClose) }; } //# sourceMappingURL=useNotify.js.map