@td-design/react-native
Version:
react-native UI组件库
90 lines (88 loc) • 3.32 kB
JavaScript
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