import { observer } from "mobx-react-lite";
import React, { useEffect, useRef } from "react";
import { RefreshControl, ScrollView, ScrollViewProps } from "react-native";
import { HScrollView } from "react-native-head-tab-view";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import Animated, {
runOnJS,
useAnimatedStyle,
withTiming,
} from "react-native-reanimated";
import {
Platform_iOS,
useColors,
useDimensions,
useMeasure,
useReanimatedValue,
useSafeArea,
vs,
} from "../commons";
import { KeyboardProps, Spinner, View } from "../components";
import { tBaseStore } from "../store";
export type ScrollProps = ScrollViewProps & {
refScrollView?: any;
reanimated?: boolean;
isRefreshing?: boolean;
hideOverflow?: boolean;
showIndicator?: boolean;
awareKeyboard?: boolean;
hViewIndex?: number;
onRefreshing?: () => void;
};
const AScrollView = Animated.createAnimatedComponent(ScrollView);
const AHScrollView = Animated.createAnimatedComponent(HScrollView);
const AKeyboardAwareScrollView = Animated.createAnimatedComponent(
KeyboardAwareScrollView
);
export const Scroll = observer((props: ScrollProps) => {
const {
refScrollView,
reanimated,
isRefreshing,
hideOverflow,
showIndicator,
awareKeyboard,
hViewIndex,
children,
contentContainerStyle,
onRefreshing,
} = props;
const enableRefresh = typeof isRefreshing === "boolean";
const colors = useColors();
const renderRefresh = () => {
if (!enableRefresh) return undefined;
return (
);
};
const renderRefreshControl = () => {
return ;
};
const MyScroll =
typeof hViewIndex === "number"
? reanimated
? AHScrollView
: HScrollView
: awareKeyboard && Platform_iOS
? reanimated
? AKeyboardAwareScrollView
: KeyboardAwareScrollView
: reanimated
? AScrollView
: ScrollView;
return (
{children}
);
});
export const ScrollKeyboard = (props: ScrollProps & KeyboardProps) => {
const { bottom } = useSafeArea();
const {
awareKeyboard,
before = bottom,
after = vs(16),
enableAndroid,
onShow,
onHide,
} = props;
const { height, keyboard, duration } = useDimensions(true);
const [refView, measureView] = useMeasure(duration);
const v1H = useReanimatedValue(Platform_iOS ? before : after);
const v2H = useReanimatedValue(0);
const yOffsetValue = useRef(0);
const callback = (show: boolean) => {
show ? onShow?.() : onHide?.();
};
const onLayout = () => {
measureView(({ y }) => {
if (y && !keyboard) yOffsetValue.current = Math.max(0, height - y);
});
};
useEffect(() => {
if (Platform_iOS || enableAndroid) {
v1H.value = withTiming(
keyboard ? after : before,
{
duration,
},
(finished) => {
finished && runOnJS(callback)(!!keyboard);
}
);
if (awareKeyboard) return;
v2H.value = withTiming(keyboard ? keyboard - yOffsetValue.current : 0, {
duration,
});
} else callback(!!keyboard);
}, [before, after, enableAndroid, onShow, onHide, keyboard, duration]);
const v1S = useAnimatedStyle(
() => ({
height: v1H.value,
}),
[]
);
const v2S = useAnimatedStyle(
() => ({
height: v2H.value,
}),
[]
);
return (
<>
{props.children}
>
);
};