From 0d6a0db8c6c4a6561884534b5e3b27bb218bfdac Mon Sep 17 00:00:00 2001 From: richardo2016x Date: Thu, 18 Sep 2025 14:09:38 +0800 Subject: [PATCH] feat: add `BottomSheetWebView`, use it on non-sensitive scene. --- .../customized/BottomSheetWebView.tsx | 74 +++++++++++++++++++ .../UserAgreementLikeModalInner.tsx | 12 ++- 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 apps/mobile/src/components/customized/BottomSheetWebView.tsx diff --git a/apps/mobile/src/components/customized/BottomSheetWebView.tsx b/apps/mobile/src/components/customized/BottomSheetWebView.tsx new file mode 100644 index 0000000000..e5dec7e33a --- /dev/null +++ b/apps/mobile/src/components/customized/BottomSheetWebView.tsx @@ -0,0 +1,74 @@ +import React, { useCallback, useContext, useMemo, useRef } from 'react'; + +import { Gesture, GestureDetector } from 'react-native-gesture-handler'; +import { useBottomSheetGestureHandlers } from '@gorhom/bottom-sheet'; + +import WebView, { WebViewProps } from 'react-native-webview'; + +type BottomSheetWebViewProps = WebViewProps & {}; + +function checkIsAtTop(yValue: number) { + 'worklet'; + return yValue <= 5; +} + +const BottomSheetWebViewComponent = React.forwardRef< + WebView, + BottomSheetWebViewProps +>((props: BottomSheetWebViewProps, ref) => { + const { ...webviewProps } = props; + + const { contentPanGestureHandler } = useBottomSheetGestureHandlers(); + + const [isReachTop, setIsReachTop] = React.useState(true); + + const { gesture } = React.useMemo(() => { + const mGesture = Gesture.Pan() + .enabled(isReachTop) + .shouldCancelWhenOutside(false) + .runOnJS(false) + .onStart(contentPanGestureHandler.handleOnStart) + .onChange(contentPanGestureHandler.handleOnChange) + .onEnd(contentPanGestureHandler.handleOnEnd) + .onFinalize(contentPanGestureHandler.handleOnFinalize); + + const native = Gesture.Native() + .shouldActivateOnStart(true) + .disallowInterruption(true); + + const finalGesture = Gesture.Simultaneous(native, mGesture); + + return { + gesture: finalGesture, + }; + }, [ + isReachTop, + contentPanGestureHandler.handleOnStart, + contentPanGestureHandler.handleOnChange, + contentPanGestureHandler.handleOnEnd, + contentPanGestureHandler.handleOnFinalize, + ]); + + return ( + + { + webviewProps?.onScroll?.(e); + + const isReachTop = checkIsAtTop(e.nativeEvent.contentOffset.y); + setIsReachTop(isReachTop); + }} + style={[webviewProps?.style]} + /> + + ); +}); + +export const BottomSheetWebView = React.memo(BottomSheetWebViewComponent); +BottomSheetWebView.displayName = 'BottomSheetWebView'; + +export default BottomSheetWebView; diff --git a/apps/mobile/src/screens/ManagePassword/components/UserAgreementLikeModalInner.tsx b/apps/mobile/src/screens/ManagePassword/components/UserAgreementLikeModalInner.tsx index 7fe3e846dc..7d142fbcaa 100644 --- a/apps/mobile/src/screens/ManagePassword/components/UserAgreementLikeModalInner.tsx +++ b/apps/mobile/src/screens/ManagePassword/components/UserAgreementLikeModalInner.tsx @@ -14,9 +14,9 @@ import { import { MODAL_NAMES } from '@/components/GlobalBottomSheetModal/types'; import AutoLockView from '@/components/AutoLockView'; -import WebView from 'react-native-webview'; import { APP_UA_PARIALS } from '@/constant'; import { checkShouldStartLoadingWithRequestForTrustedContent } from '@/components/WebView/utils'; +import BottomSheetWebView from '@/components/customized/BottomSheetWebView'; export function useShowUserAgreementLikeModal() { const openedModalIdRef = React.useRef(''); @@ -25,6 +25,9 @@ export function useShowUserAgreementLikeModal() { name: MODAL_NAMES.TIP_TERM_OF_USE, title: '', bottomSheetModalProps: { + rootViewType: 'View', + enableContentPanningGesture: true, + enablePanDownToClose: true, onDismiss: () => { removeGlobalBottomSheetModal(openedModalIdRef.current); openedModalIdRef.current = ''; @@ -39,6 +42,9 @@ export function useShowUserAgreementLikeModal() { name: MODAL_NAMES.TIP_PRIVACY_POLICY, title: '', bottomSheetModalProps: { + rootViewType: 'View', + enableContentPanningGesture: true, + enablePanDownToClose: true, onDismiss: () => { removeGlobalBottomSheetModal(openedModal2IdRef.current); openedModal2IdRef.current = ''; @@ -84,7 +90,7 @@ export function UserAgreementLikeModalInner({ uri }: { uri: string }) { return ( {/* @@ -92,7 +98,7 @@ export function UserAgreementLikeModalInner({ uri }: { uri: string }) { {remoteVersion.version} */} -