diff --git a/native/bottom-sheet/bottom-sheet-backdrop.react.js b/native/bottom-sheet/bottom-sheet-backdrop.react.js index fbad49370..bac5c0850 100644 --- a/native/bottom-sheet/bottom-sheet-backdrop.react.js +++ b/native/bottom-sheet/bottom-sheet-backdrop.react.js @@ -1,40 +1,36 @@ // @flow -import { BottomSheetBackdrop as Backdrop } from '@gorhom/bottom-sheet'; +import { useBottomSheet } from '@gorhom/bottom-sheet'; import * as React from 'react'; -import type { SharedValue } from 'react-native-reanimated'; - -type BackdropPressBehavior = 'none' | 'close' | 'collapse'; +import { View, TouchableWithoutFeedback, StyleSheet } from 'react-native'; +import { type SharedValue } from 'react-native-reanimated'; type Props = { +animatedIndex: SharedValue, - +animatedPosition: SharedValue, - +opacity?: number, - +appearsOnIndex?: number, - +disappearsOnIndex?: number, - +enableTouchThrough?: boolean, - +pressBehavior?: BackdropPressBehavior | number, }; function BottomSheetBackdrop(props: Props): React.Node { - const { - opacity, - appearsOnIndex, - disappearsOnIndex, - enableTouchThrough, - pressBehavior, - } = props; + const { animatedIndex } = props; + + const { close } = useBottomSheet(); + + const onPressBackdrop = React.useCallback(() => { + if (animatedIndex.value >= 0) { + close(); + } + }, [animatedIndex.value, close]); return ( - + + + ); } +const styles = StyleSheet.create({ + backdropContainer: { + flex: 1, + }, +}); + export default BottomSheetBackdrop; diff --git a/native/navigation/root-navigator.react.js b/native/navigation/root-navigator.react.js index b576f849c..218755933 100644 --- a/native/navigation/root-navigator.react.js +++ b/native/navigation/root-navigator.react.js @@ -1,290 +1,291 @@ // @flow import { createNavigatorFactory, useNavigationBuilder, type StackNavigationState, type StackOptions, type StackNavigationEventMap, type StackNavigatorProps, type ExtraStackNavigatorProps, type ParamListBase, type StackNavigationHelpers, type StackNavigationProp, } from '@react-navigation/native'; import { StackView, TransitionPresets } from '@react-navigation/stack'; import * as React from 'react'; import { Platform } from 'react-native'; import { enableScreens } from 'react-native-screens'; import AppNavigator from './app-navigator.react.js'; import InviteLinkModal from './invite-link-modal.react.js'; import { defaultStackScreenOptions } from './options.js'; import { RootNavigatorContext } from './root-navigator-context.js'; import RootRouter, { type RootRouterExtraNavigationHelpers, } from './root-router.js'; import { LoggedOutModalRouteName, AppRouteName, ThreadPickerModalRouteName, ImagePasteModalRouteName, AddUsersModalRouteName, CustomServerModalRouteName, ColorSelectorModalRouteName, ComposeSubchannelModalRouteName, SidebarListModalRouteName, SubchannelsListModalRouteName, MessageReactionsModalRouteName, type ScreenParamList, type RootParamList, TermsAndPrivacyRouteName, RegistrationRouteName, InviteLinkModalRouteName, InviteLinkNavigatorRouteName, CommunityCreationRouteName, RolesNavigatorRouteName, QRCodeSignInNavigatorRouteName, UserProfileBottomSheetRouteName, } from './route-names.js'; import LoggedOutModal from '../account/logged-out-modal.react.js'; import RegistrationNavigator from '../account/registration/registration-navigator.react.js'; import TermsAndPrivacyModal from '../account/terms-and-privacy-modal.react.js'; import ThreadPickerModal from '../calendar/thread-picker-modal.react.js'; import ImagePasteModal from '../chat/image-paste-modal.react.js'; import MessageReactionsModal from '../chat/message-reactions-modal.react.js'; import AddUsersModal from '../chat/settings/add-users-modal.react.js'; import ColorSelectorModal from '../chat/settings/color-selector-modal.react.js'; import ComposeSubchannelModal from '../chat/settings/compose-subchannel-modal.react.js'; import SidebarListModal from '../chat/sidebar-list-modal.react.js'; import SubchannelsListModal from '../chat/subchannels-list-modal.react.js'; import CommunityCreationNavigator from '../community-creation/community-creation-navigator.react.js'; import InviteLinksNavigator from '../invite-links/invite-links-navigator.react.js'; import CustomServerModal from '../profile/custom-server-modal.react.js'; import QRCodeSignInNavigator from '../qr-code/qr-code-sign-in-navigator.react.js'; import RolesNavigator from '../roles/roles-navigator.react.js'; import UserProfileBottomSheet from '../user-profile/user-profile-bottom-sheet.react.js'; enableScreens(); export type RootNavigationHelpers = { ...$Exact>, ...RootRouterExtraNavigationHelpers, ... }; type RootNavigatorProps = StackNavigatorProps>; function RootNavigator({ initialRouteName, children, screenOptions, defaultScreenOptions, screenListeners, id, ...rest }: RootNavigatorProps) { const [keyboardHandlingEnabled, setKeyboardHandlingEnabled] = React.useState(true); const mergedScreenOptions = React.useMemo(() => { if (typeof screenOptions === 'function') { return input => ({ ...screenOptions(input), keyboardHandlingEnabled, }); } return { ...screenOptions, keyboardHandlingEnabled, }; }, [screenOptions, keyboardHandlingEnabled]); const { state, descriptors, navigation } = useNavigationBuilder(RootRouter, { id, initialRouteName, children, screenOptions: mergedScreenOptions, defaultScreenOptions, screenListeners, }); const rootNavigationContext = React.useMemo( () => ({ setKeyboardHandlingEnabled }), [setKeyboardHandlingEnabled], ); return ( ); } const createRootNavigator = createNavigatorFactory< StackNavigationState, StackOptions, StackNavigationEventMap, RootNavigationHelpers<>, ExtraStackNavigatorProps, >(RootNavigator); const baseTransitionPreset = Platform.select({ ios: TransitionPresets.ModalSlideFromBottomIOS, default: TransitionPresets.FadeFromBottomAndroid, }); const transitionPreset = { ...baseTransitionPreset, cardStyleInterpolator: interpolatorProps => { const baseCardStyleInterpolator = baseTransitionPreset.cardStyleInterpolator(interpolatorProps); const overlayOpacity = interpolatorProps.current.progress.interpolate({ inputRange: [0, 1], outputRange: ([0, 0.7]: number[]), // Flow... extrapolate: 'clamp', }); return { ...baseCardStyleInterpolator, overlayStyle: [ baseCardStyleInterpolator.overlayStyle, { opacity: overlayOpacity }, ], }; }, }; const defaultScreenOptions = { ...defaultStackScreenOptions, ...transitionPreset, cardStyle: { backgroundColor: 'transparent' }, presentation: 'modal', headerShown: false, }; const disableGesturesScreenOptions = { gestureEnabled: false, }; const modalOverlayScreenOptions = { cardOverlayEnabled: true, presentation: 'transparentModal', }; const termsAndPrivacyModalScreenOptions = { gestureEnabled: false, cardOverlayEnabled: true, presentation: 'transparentModal', }; export type RootRouterNavigationProp< ParamList: ParamListBase = ParamListBase, RouteName: $Keys = $Keys, > = { ...StackNavigationProp, ...RootRouterExtraNavigationHelpers, }; export type RootNavigationProp< RouteName: $Keys = $Keys, > = { ...StackNavigationProp, ...RootRouterExtraNavigationHelpers, }; const Root = createRootNavigator< ScreenParamList, RootParamList, RootNavigationHelpers, >(); function RootComponent(): React.Node { return ( ); } export default RootComponent;