attempt to get something working on web
This commit is contained in:
+68
-42
@@ -30,6 +30,7 @@ import {logger as notyLogger} from '#/lib/notifications/util'
|
|||||||
import {buildStateObject} from '#/lib/routes/helpers'
|
import {buildStateObject} from '#/lib/routes/helpers'
|
||||||
import {
|
import {
|
||||||
type AllNavigatorParams,
|
type AllNavigatorParams,
|
||||||
|
type AuthNavigatorParams,
|
||||||
type BottomTabNavigatorParams,
|
type BottomTabNavigatorParams,
|
||||||
type CoreNavigatorParams,
|
type CoreNavigatorParams,
|
||||||
type FlatNavigatorParams,
|
type FlatNavigatorParams,
|
||||||
@@ -149,10 +150,12 @@ import {useNonReactiveCallback} from './lib/hooks/useNonReactiveCallback'
|
|||||||
import {useLoggedOutViewControls} from './state/shell/logged-out'
|
import {useLoggedOutViewControls} from './state/shell/logged-out'
|
||||||
import {useLoggedOutView} from './state/shell/logged-out'
|
import {useLoggedOutView} from './state/shell/logged-out'
|
||||||
import {useCloseAllActiveElements} from './state/util'
|
import {useCloseAllActiveElements} from './state/util'
|
||||||
|
import {AuthModal} from './view/shell/desktop/AuthLayout'
|
||||||
|
|
||||||
const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
|
const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
|
||||||
|
|
||||||
const Core = createNativeStackNavigator<CoreNavigatorParams>()
|
const Core = createNativeStackNavigator<CoreNavigatorParams>()
|
||||||
|
const Auth = createNativeStackNavigator<AuthNavigatorParams>()
|
||||||
const HomeTab = createNativeStackNavigatorWithAuth<HomeTabNavigatorParams>()
|
const HomeTab = createNativeStackNavigatorWithAuth<HomeTabNavigatorParams>()
|
||||||
const SearchTab = createNativeStackNavigatorWithAuth<SearchTabNavigatorParams>()
|
const SearchTab = createNativeStackNavigatorWithAuth<SearchTabNavigatorParams>()
|
||||||
const NotificationsTab =
|
const NotificationsTab =
|
||||||
@@ -778,10 +781,74 @@ const FlatNavigator = () => {
|
|||||||
options={{title: title(msg`Home`)}}
|
options={{title: title(msg`Home`)}}
|
||||||
/>
|
/>
|
||||||
{commonScreens(Flat, numUnread)}
|
{commonScreens(Flat, numUnread)}
|
||||||
|
<Flat.Screen
|
||||||
|
name="Auth"
|
||||||
|
getComponent={() => AuthNavigator}
|
||||||
|
options={{
|
||||||
|
title: title(msg`Login or Sign Up`),
|
||||||
|
presentation: 'modal',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Flat.Navigator>
|
</Flat.Navigator>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AuthNavigator() {
|
||||||
|
const t = useTheme()
|
||||||
|
return (
|
||||||
|
<Auth.Navigator screenOptions={screenOptions(t)} layout={AuthModal}>
|
||||||
|
{authScreens({navigator: Auth})}
|
||||||
|
</Auth.Navigator>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function authScreens({navigator: Navigator}: {navigator: typeof Auth}) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Navigator.Screen
|
||||||
|
name="Landing"
|
||||||
|
getComponent={() => LandingScreen}
|
||||||
|
options={{animation: 'fade', animationDuration: 200}}
|
||||||
|
/>
|
||||||
|
<Navigator.Screen
|
||||||
|
name="StarterPackLanding"
|
||||||
|
getComponent={() => StarterPackLandingScreen}
|
||||||
|
/>
|
||||||
|
<Navigator.Group>
|
||||||
|
<Navigator.Screen
|
||||||
|
name="SelectAccount"
|
||||||
|
getComponent={() => SelectAccountScreen}
|
||||||
|
/>
|
||||||
|
<Navigator.Screen name="SignIn" getComponent={() => SignInScreen} />
|
||||||
|
<Navigator.Screen
|
||||||
|
name="ForgotPassword"
|
||||||
|
getComponent={() => ForgotPasswordScreen}
|
||||||
|
/>
|
||||||
|
<Navigator.Screen
|
||||||
|
name="SetNewPassword"
|
||||||
|
getComponent={() => SetNewPasswordScreen}
|
||||||
|
/>
|
||||||
|
<Navigator.Screen
|
||||||
|
name="PasswordUpdated"
|
||||||
|
getComponent={() => PasswordUpdatedScreen}
|
||||||
|
/>
|
||||||
|
<Navigator.Screen
|
||||||
|
name="SignUpInfo"
|
||||||
|
getComponent={() => SignUpInfoScreen}
|
||||||
|
/>
|
||||||
|
<Navigator.Screen
|
||||||
|
name="SignUpHandle"
|
||||||
|
getComponent={() => SignUpHandleScreen}
|
||||||
|
/>
|
||||||
|
<Navigator.Screen
|
||||||
|
name="SignUpCaptcha"
|
||||||
|
getComponent={() => SignUpCaptchaScreen}
|
||||||
|
/>
|
||||||
|
</Navigator.Group>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The core navigator on native handles authentication, switching between
|
* The core navigator on native handles authentication, switching between
|
||||||
* the main tab navigator when logged in and the auth screen when logged out.
|
* the main tab navigator when logged in and the auth screen when logged out.
|
||||||
@@ -800,48 +867,7 @@ export const NativeNavigator = () => {
|
|||||||
options={{animation: 'fade', animationDuration: 200}}
|
options={{animation: 'fade', animationDuration: 200}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
authScreens({navigator: Core as typeof Auth})
|
||||||
<Core.Screen
|
|
||||||
name="Landing"
|
|
||||||
getComponent={() => LandingScreen}
|
|
||||||
options={{animation: 'fade', animationDuration: 200}}
|
|
||||||
/>
|
|
||||||
<Core.Screen
|
|
||||||
name="StarterPackLanding"
|
|
||||||
getComponent={() => StarterPackLandingScreen}
|
|
||||||
/>
|
|
||||||
<Core.Group>
|
|
||||||
<Core.Screen
|
|
||||||
name="SelectAccount"
|
|
||||||
getComponent={() => SelectAccountScreen}
|
|
||||||
/>
|
|
||||||
<Core.Screen name="SignIn" getComponent={() => SignInScreen} />
|
|
||||||
<Core.Screen
|
|
||||||
name="ForgotPassword"
|
|
||||||
getComponent={() => ForgotPasswordScreen}
|
|
||||||
/>
|
|
||||||
<Core.Screen
|
|
||||||
name="SetNewPassword"
|
|
||||||
getComponent={() => SetNewPasswordScreen}
|
|
||||||
/>
|
|
||||||
<Core.Screen
|
|
||||||
name="PasswordUpdated"
|
|
||||||
getComponent={() => PasswordUpdatedScreen}
|
|
||||||
/>
|
|
||||||
<Core.Screen
|
|
||||||
name="SignUpInfo"
|
|
||||||
getComponent={() => SignUpInfoScreen}
|
|
||||||
/>
|
|
||||||
<Core.Screen
|
|
||||||
name="SignUpHandle"
|
|
||||||
getComponent={() => SignUpHandleScreen}
|
|
||||||
/>
|
|
||||||
<Core.Screen
|
|
||||||
name="SignUpCaptcha"
|
|
||||||
getComponent={() => SignUpCaptchaScreen}
|
|
||||||
/>
|
|
||||||
</Core.Group>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</Core.Navigator>
|
</Core.Navigator>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
|||||||
|
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {useShellLayout} from '#/state/shell/shell-layout'
|
import {useShellLayout} from '#/state/shell/shell-layout'
|
||||||
|
import {useIsWithinAuthLayout} from '#/view/shell/desktop/AuthLayout'
|
||||||
import {
|
import {
|
||||||
atoms as a,
|
atoms as a,
|
||||||
useBreakpoints,
|
useBreakpoints,
|
||||||
@@ -38,16 +39,24 @@ export type ScreenProps = React.ComponentProps<typeof View> & {
|
|||||||
export const Screen = memo(function Screen({
|
export const Screen = memo(function Screen({
|
||||||
style,
|
style,
|
||||||
noInsetTop,
|
noInsetTop,
|
||||||
|
children,
|
||||||
...props
|
...props
|
||||||
}: ScreenProps) {
|
}: ScreenProps) {
|
||||||
const {top} = useSafeAreaInsets()
|
const {top} = useSafeAreaInsets()
|
||||||
|
const withinAuthLayout = useIsWithinAuthLayout()
|
||||||
|
|
||||||
|
if (withinAuthLayout) {
|
||||||
|
return children
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isWeb && <WebCenterBorders />}
|
{isWeb && <WebCenterBorders />}
|
||||||
<View
|
<View
|
||||||
style={[a.util_screen_outer, {paddingTop: noInsetTop ? 0 : top}, style]}
|
style={[a.util_screen_outer, {paddingTop: noInsetTop ? 0 : top}, style]}
|
||||||
{...props}
|
{...props}>
|
||||||
/>
|
{children}
|
||||||
|
</View>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ export type FlatNavigatorParams = CommonNavigatorParams & {
|
|||||||
Feeds: undefined
|
Feeds: undefined
|
||||||
Notifications: undefined
|
Notifications: undefined
|
||||||
Messages: {pushToConversation?: string; animation?: 'push' | 'pop'}
|
Messages: {pushToConversation?: string; animation?: 'push' | 'pop'}
|
||||||
|
Auth: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AllNavigatorParams = CommonNavigatorParams & {
|
export type AllNavigatorParams = CommonNavigatorParams & {
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import {type FlatNavigatorParams} from './lib/routes/types'
|
|||||||
|
|
||||||
type AllNavigatableRoutes = Omit<
|
type AllNavigatableRoutes = Omit<
|
||||||
FlatNavigatorParams,
|
FlatNavigatorParams,
|
||||||
'NotFound' | 'SharedPreferencesTester'
|
'Auth' | 'NotFound' | 'SharedPreferencesTester'
|
||||||
>
|
>
|
||||||
|
|
||||||
export const router = new Router<AllNavigatableRoutes>({
|
export const router = new Router<AllNavigatableRoutes>({
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as React from 'react'
|
import {useCallback, useEffect} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
// Based on @react-navigation/native-stack/src/navigators/createNativeStackNavigator.ts
|
// Based on @react-navigation/native-stack/src/navigators/createNativeStackNavigator.ts
|
||||||
// MIT License
|
// MIT License
|
||||||
@@ -6,6 +6,7 @@ import {View} from 'react-native'
|
|||||||
import {
|
import {
|
||||||
createNavigatorFactory,
|
createNavigatorFactory,
|
||||||
type EventArg,
|
type EventArg,
|
||||||
|
type NavigationProp,
|
||||||
type NavigatorTypeBagBase,
|
type NavigatorTypeBagBase,
|
||||||
type ParamListBase,
|
type ParamListBase,
|
||||||
type StackActionHelpers,
|
type StackActionHelpers,
|
||||||
@@ -15,6 +16,8 @@ import {
|
|||||||
type StackRouterOptions,
|
type StackRouterOptions,
|
||||||
type StaticConfig,
|
type StaticConfig,
|
||||||
type TypedNavigator,
|
type TypedNavigator,
|
||||||
|
useFocusEffect,
|
||||||
|
useNavigation,
|
||||||
useNavigationBuilder,
|
useNavigationBuilder,
|
||||||
} from '@react-navigation/native'
|
} from '@react-navigation/native'
|
||||||
import {NativeStackView} from '@react-navigation/native-stack'
|
import {NativeStackView} from '@react-navigation/native-stack'
|
||||||
@@ -27,14 +30,11 @@ import {
|
|||||||
|
|
||||||
import {PWI_ENABLED} from '#/lib/build-flags'
|
import {PWI_ENABLED} from '#/lib/build-flags'
|
||||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||||
|
import {type FlatNavigatorParams} from '#/lib/routes/types'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {useOnboardingState} from '#/state/shell'
|
import {useOnboardingState} from '#/state/shell'
|
||||||
import {
|
import {useLoggedOutView} from '#/state/shell/logged-out'
|
||||||
useLoggedOutView,
|
|
||||||
useLoggedOutViewControls,
|
|
||||||
} from '#/state/shell/logged-out'
|
|
||||||
import {LoggedOut} from '#/view/com/auth/LoggedOut'
|
|
||||||
import {Deactivated} from '#/screens/Deactivated'
|
import {Deactivated} from '#/screens/Deactivated'
|
||||||
import {Onboarding} from '#/screens/Onboarding'
|
import {Onboarding} from '#/screens/Onboarding'
|
||||||
import {SignupQueued} from '#/screens/SignupQueued'
|
import {SignupQueued} from '#/screens/SignupQueued'
|
||||||
@@ -76,7 +76,7 @@ function NativeStackNavigator({
|
|||||||
screenLayout,
|
screenLayout,
|
||||||
})
|
})
|
||||||
|
|
||||||
React.useEffect(
|
useEffect(
|
||||||
() =>
|
() =>
|
||||||
// @ts-expect-error: there may not be a tab navigator in parent
|
// @ts-expect-error: there may not be a tab navigator in parent
|
||||||
navigation?.addListener?.('tabPress', (e: any) => {
|
navigation?.addListener?.('tabPress', (e: any) => {
|
||||||
@@ -108,23 +108,40 @@ function NativeStackNavigator({
|
|||||||
const activeDescriptor = descriptors[activeRoute.key]
|
const activeDescriptor = descriptors[activeRoute.key]
|
||||||
const activeRouteRequiresAuth = activeDescriptor.options.requireAuth ?? false
|
const activeRouteRequiresAuth = activeDescriptor.options.requireAuth ?? false
|
||||||
const onboardingState = useOnboardingState()
|
const onboardingState = useOnboardingState()
|
||||||
const {showLoggedOut} = useLoggedOutView()
|
|
||||||
const {setShowLoggedOut} = useLoggedOutViewControls()
|
|
||||||
const {isMobile} = useWebMediaQueries()
|
const {isMobile} = useWebMediaQueries()
|
||||||
const {leftNavMinimal} = useLayoutBreakpoints()
|
const {leftNavMinimal} = useLayoutBreakpoints()
|
||||||
// Temp: use old system for web. TODO: unify
|
const {showLoggedOut} = useLoggedOutView()
|
||||||
if (isWeb && !hasSession && (!PWI_ENABLED || activeRouteRequiresAuth)) {
|
|
||||||
return <LoggedOut />
|
const shouldRedirectToAuth =
|
||||||
}
|
isWeb && activeRoute.name !== 'Auth' && (showLoggedOut || !PWI_ENABLED)
|
||||||
|
useEffect(() => {
|
||||||
|
if (shouldRedirectToAuth) {
|
||||||
|
navigation.navigate('Auth')
|
||||||
|
}
|
||||||
|
}, [navigation, shouldRedirectToAuth])
|
||||||
|
|
||||||
|
const shouldRedirectAwayFromAuth =
|
||||||
|
isWeb &&
|
||||||
|
activeRoute.name === 'Auth' &&
|
||||||
|
!showLoggedOut &&
|
||||||
|
PWI_ENABLED &&
|
||||||
|
!activeRouteRequiresAuth
|
||||||
|
useEffect(() => {
|
||||||
|
if (shouldRedirectAwayFromAuth) {
|
||||||
|
if (navigation.canGoBack()) {
|
||||||
|
navigation.goBack()
|
||||||
|
} else {
|
||||||
|
navigation.replace('Home')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [navigation, shouldRedirectAwayFromAuth])
|
||||||
|
|
||||||
if (hasSession && currentAccount?.signupQueued) {
|
if (hasSession && currentAccount?.signupQueued) {
|
||||||
return <SignupQueued />
|
return <SignupQueued />
|
||||||
}
|
}
|
||||||
if (hasSession && currentAccount?.status === 'takendown') {
|
if (hasSession && currentAccount?.status === 'takendown') {
|
||||||
return <Takendown />
|
return <Takendown />
|
||||||
}
|
}
|
||||||
if (isWeb && showLoggedOut) {
|
|
||||||
return <LoggedOut onDismiss={() => setShowLoggedOut(false)} />
|
|
||||||
}
|
|
||||||
if (currentAccount?.status === 'deactivated') {
|
if (currentAccount?.status === 'deactivated') {
|
||||||
return <Deactivated />
|
return <Deactivated />
|
||||||
}
|
}
|
||||||
@@ -139,7 +156,7 @@ function NativeStackNavigator({
|
|||||||
...descriptor,
|
...descriptor,
|
||||||
render() {
|
render() {
|
||||||
if (requireAuth && !hasSession) {
|
if (requireAuth && !hasSession) {
|
||||||
return <View />
|
return <RedirectToAuth />
|
||||||
} else {
|
} else {
|
||||||
return descriptor.render()
|
return descriptor.render()
|
||||||
}
|
}
|
||||||
@@ -158,7 +175,7 @@ function NativeStackNavigator({
|
|||||||
{...rest}
|
{...rest}
|
||||||
state={state}
|
state={state}
|
||||||
navigation={navigation}
|
navigation={navigation}
|
||||||
descriptors={descriptors}
|
descriptors={newDescriptors}
|
||||||
describe={describe}
|
describe={describe}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
@@ -172,6 +189,25 @@ function NativeStackNavigator({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects to the auth screen on web. On native, this is handled by swapping
|
||||||
|
* out the screens instead - see `NativeNavigator`
|
||||||
|
*/
|
||||||
|
function RedirectToAuth() {
|
||||||
|
const navigation = useNavigation<NavigationProp<FlatNavigatorParams>>()
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
if (isWeb) {
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
navigation.navigate('Auth')
|
||||||
|
}, 500)
|
||||||
|
return () => clearTimeout(timeout)
|
||||||
|
}
|
||||||
|
}, [navigation]),
|
||||||
|
)
|
||||||
|
return <View />
|
||||||
|
}
|
||||||
|
|
||||||
export function createNativeStackNavigatorWithAuth<
|
export function createNativeStackNavigatorWithAuth<
|
||||||
const ParamList extends ParamListBase,
|
const ParamList extends ParamListBase,
|
||||||
const NavigatorID extends string | undefined = undefined,
|
const NavigatorID extends string | undefined = undefined,
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export function AuthLayout({children}: {children: React.ReactNode}) {
|
||||||
|
return children
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useIsWithinAuthLayout() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
import {createContext, useContext} from 'react'
|
||||||
|
import {Pressable, View} from 'react-native'
|
||||||
|
import {msg} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {DismissableLayer, FocusGuards, FocusScope} from 'radix-ui/internal'
|
||||||
|
import {createPortal} from 'react-dom'
|
||||||
|
import {RemoveScrollBar} from 'react-remove-scroll-bar'
|
||||||
|
|
||||||
|
import {useA11y} from '#/state/a11y'
|
||||||
|
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||||
|
import {atoms as a, flatten, useTheme, web} from '#/alf'
|
||||||
|
|
||||||
|
const stopPropagation = (e: any) => e.stopPropagation()
|
||||||
|
const preventDefault = (e: any) => e.preventDefault()
|
||||||
|
|
||||||
|
const WithinAuthLayoutContext = createContext(false)
|
||||||
|
|
||||||
|
export function AuthModal({children}: {children: React.ReactNode}) {
|
||||||
|
const t = useTheme()
|
||||||
|
const {_} = useLingui()
|
||||||
|
const {reduceMotionEnabled} = useA11y()
|
||||||
|
const {setShowLoggedOut} = useLoggedOutViewControls()
|
||||||
|
FocusGuards.useFocusGuards()
|
||||||
|
|
||||||
|
console.log('auth modal')
|
||||||
|
|
||||||
|
return createPortal(
|
||||||
|
<Pressable
|
||||||
|
accessibilityLabel={_(msg`Close active dialog`)}
|
||||||
|
accessibilityHint={undefined}
|
||||||
|
onPress={() => setShowLoggedOut(false)}>
|
||||||
|
<RemoveScrollBar />
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.fixed,
|
||||||
|
a.inset_0,
|
||||||
|
a.z_10,
|
||||||
|
a.px_xl,
|
||||||
|
a.align_center,
|
||||||
|
a.justify_center,
|
||||||
|
web({overflowY: 'auto'}),
|
||||||
|
{zIndex: 999999},
|
||||||
|
]}>
|
||||||
|
<Backdrop />
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.w_full,
|
||||||
|
a.z_20,
|
||||||
|
a.align_center,
|
||||||
|
web({minHeight: '60vh', position: 'static'}),
|
||||||
|
]}>
|
||||||
|
<FocusScope.FocusScope loop asChild trapped>
|
||||||
|
<View
|
||||||
|
role="dialog"
|
||||||
|
aria-role="dialog"
|
||||||
|
aria-label={_(msg`Log in or sign up`)}
|
||||||
|
// @ts-expect-error web only -prf
|
||||||
|
onClick={stopPropagation}
|
||||||
|
onStartShouldSetResponder={_ => true}
|
||||||
|
onTouchEnd={stopPropagation}
|
||||||
|
style={flatten([
|
||||||
|
a.relative,
|
||||||
|
a.rounded_md,
|
||||||
|
a.w_full,
|
||||||
|
a.border,
|
||||||
|
t.atoms.bg,
|
||||||
|
{
|
||||||
|
minHeight: '100%',
|
||||||
|
maxWidth: 600,
|
||||||
|
borderColor: t.palette.contrast_200,
|
||||||
|
shadowColor: t.palette.black,
|
||||||
|
shadowOpacity: t.name === 'light' ? 0.1 : 0.4,
|
||||||
|
shadowRadius: 30,
|
||||||
|
},
|
||||||
|
!reduceMotionEnabled && a.zoom_fade_in,
|
||||||
|
a.p_xl,
|
||||||
|
])}>
|
||||||
|
<DismissableLayer.DismissableLayer
|
||||||
|
onInteractOutside={preventDefault}
|
||||||
|
onFocusOutside={preventDefault}
|
||||||
|
onDismiss={close}
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
flex: '1 1 0',
|
||||||
|
}}>
|
||||||
|
<WithinAuthLayoutContext.Provider value={true}>
|
||||||
|
{children}
|
||||||
|
</WithinAuthLayoutContext.Provider>
|
||||||
|
</DismissableLayer.DismissableLayer>
|
||||||
|
</View>
|
||||||
|
</FocusScope.FocusScope>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Pressable>,
|
||||||
|
document.querySelector('#root')!,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Backdrop() {
|
||||||
|
const t = useTheme()
|
||||||
|
const {reduceMotionEnabled} = useA11y()
|
||||||
|
return (
|
||||||
|
<View style={{opacity: 0.8}}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.fixed,
|
||||||
|
a.inset_0,
|
||||||
|
{backgroundColor: t.palette.black},
|
||||||
|
!reduceMotionEnabled && a.fade_in,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useIsWithinAuthLayout() {
|
||||||
|
return useContext(WithinAuthLayoutContext)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user