Android sheets edge to edge (#8342)
This commit is contained in:
+1
-1
@@ -3,6 +3,7 @@ import '#/view/icons'
|
||||
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {GestureHandlerRootView} from 'react-native-gesture-handler'
|
||||
import {KeyboardProvider as KeyboardControllerProvider} from 'react-native-keyboard-controller'
|
||||
import {
|
||||
initialWindowMetrics,
|
||||
SafeAreaProvider,
|
||||
@@ -14,7 +15,6 @@ import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import * as Sentry from '@sentry/react-native'
|
||||
|
||||
import {KeyboardControllerProvider} from '#/lib/hooks/useEnableKeyboardController'
|
||||
import {Provider as HideBottomBarBorderProvider} from '#/lib/hooks/useHideBottomBarBorder'
|
||||
import {QueryProvider} from '#/lib/react-query'
|
||||
import {s} from '#/lib/styles'
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from 'react-native'
|
||||
import {
|
||||
KeyboardAwareScrollView,
|
||||
type KeyboardAwareScrollViewRef,
|
||||
useKeyboardHandler,
|
||||
useReanimatedKeyboardAnimation,
|
||||
} from 'react-native-keyboard-controller'
|
||||
@@ -23,7 +24,6 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {useEnableKeyboardController} from '#/lib/hooks/useEnableKeyboardController'
|
||||
import {ScrollProvider} from '#/lib/ScrollContext'
|
||||
import {logger} from '#/logger'
|
||||
import {useA11y} from '#/state/a11y'
|
||||
@@ -209,10 +209,9 @@ export const ScrollableInner = React.forwardRef<ScrollView, DialogInnerProps>(
|
||||
const {nativeSnapPoint, disableDrag, setDisableDrag} = useDialogContext()
|
||||
const insets = useSafeAreaInsets()
|
||||
|
||||
useEnableKeyboardController(IS_IOS)
|
||||
|
||||
const [keyboardHeight, setKeyboardHeight] = React.useState(0)
|
||||
|
||||
// note: iOS-only. keyboard-controller doesn't seem to work inside the sheets on Android
|
||||
useKeyboardHandler(
|
||||
{
|
||||
onEnd: e => {
|
||||
@@ -231,7 +230,6 @@ export const ScrollableInner = React.forwardRef<ScrollView, DialogInnerProps>(
|
||||
}
|
||||
paddingBottom = Math.max(paddingBottom, tokens.space._2xl)
|
||||
} else {
|
||||
paddingBottom += keyboardHeight
|
||||
if (nativeSnapPoint === BottomSheetSnapPoint.Full) {
|
||||
paddingBottom += insets.top
|
||||
}
|
||||
@@ -259,7 +257,7 @@ export const ScrollableInner = React.forwardRef<ScrollView, DialogInnerProps>(
|
||||
{paddingBottom},
|
||||
contentContainerStyle,
|
||||
]}
|
||||
ref={ref}
|
||||
ref={ref as React.Ref<KeyboardAwareScrollViewRef>}
|
||||
showsVerticalScrollIndicator={IS_ANDROID ? false : undefined}
|
||||
{...props}
|
||||
bounces={nativeSnapPoint === BottomSheetSnapPoint.Full}
|
||||
@@ -289,8 +287,6 @@ export const InnerFlatList = React.forwardRef<
|
||||
const insets = useSafeAreaInsets()
|
||||
const {nativeSnapPoint, disableDrag, setDisableDrag} = useDialogContext()
|
||||
|
||||
useEnableKeyboardController(IS_IOS)
|
||||
|
||||
const onScroll = (e: ScrollEvent) => {
|
||||
'worklet'
|
||||
if (!IS_ANDROID) {
|
||||
|
||||
@@ -28,7 +28,7 @@ export function VerifierDialog({
|
||||
verificationState: FullVerificationState
|
||||
}) {
|
||||
return (
|
||||
<Dialog.Outer control={control}>
|
||||
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
|
||||
<Dialog.Handle />
|
||||
<Inner
|
||||
control={control}
|
||||
@@ -123,7 +123,6 @@ function Inner({
|
||||
}),
|
||||
)}
|
||||
size="small"
|
||||
variant="solid"
|
||||
color="primary"
|
||||
style={[a.justify_center]}
|
||||
onPress={() => {
|
||||
@@ -138,7 +137,6 @@ function Inner({
|
||||
<Button
|
||||
label={_(msg`Close dialog`)}
|
||||
size="small"
|
||||
variant="solid"
|
||||
color="secondary"
|
||||
onPress={() => {
|
||||
control.close()
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
} from 'react'
|
||||
import {
|
||||
KeyboardProvider,
|
||||
useKeyboardController,
|
||||
} from 'react-native-keyboard-controller'
|
||||
import {useFocusEffect} from '@react-navigation/native'
|
||||
|
||||
const KeyboardControllerRefCountContext = createContext<{
|
||||
incrementRefCount: () => void
|
||||
decrementRefCount: () => void
|
||||
}>({
|
||||
incrementRefCount: () => {},
|
||||
decrementRefCount: () => {},
|
||||
})
|
||||
KeyboardControllerRefCountContext.displayName =
|
||||
'KeyboardControllerRefCountContext'
|
||||
|
||||
export function KeyboardControllerProvider({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<KeyboardProvider enabled={false} preload={false}>
|
||||
<KeyboardControllerProviderInner>
|
||||
{children}
|
||||
</KeyboardControllerProviderInner>
|
||||
</KeyboardProvider>
|
||||
)
|
||||
}
|
||||
|
||||
function KeyboardControllerProviderInner({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const {setEnabled} = useKeyboardController()
|
||||
const refCount = useRef(0)
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
incrementRefCount: () => {
|
||||
refCount.current++
|
||||
setEnabled(refCount.current > 0)
|
||||
},
|
||||
decrementRefCount: () => {
|
||||
refCount.current--
|
||||
setEnabled(refCount.current > 0)
|
||||
|
||||
if (__DEV__ && refCount.current < 0) {
|
||||
console.error('KeyboardController ref count < 0')
|
||||
}
|
||||
},
|
||||
}),
|
||||
[setEnabled],
|
||||
)
|
||||
|
||||
return (
|
||||
<KeyboardControllerRefCountContext.Provider value={value}>
|
||||
{children}
|
||||
</KeyboardControllerRefCountContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useEnableKeyboardController(shouldEnable: boolean) {
|
||||
const {incrementRefCount, decrementRefCount} = useContext(
|
||||
KeyboardControllerRefCountContext,
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (!shouldEnable) {
|
||||
return
|
||||
}
|
||||
incrementRefCount()
|
||||
return () => {
|
||||
decrementRefCount()
|
||||
}
|
||||
}, [shouldEnable, incrementRefCount, decrementRefCount])
|
||||
}
|
||||
|
||||
/**
|
||||
* Like `useEnableKeyboardController`, but using `useFocusEffect`
|
||||
*/
|
||||
export function useEnableKeyboardControllerScreen(shouldEnable: boolean) {
|
||||
const {incrementRefCount, decrementRefCount} = useContext(
|
||||
KeyboardControllerRefCountContext,
|
||||
)
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
if (!shouldEnable) {
|
||||
return
|
||||
}
|
||||
incrementRefCount()
|
||||
return () => {
|
||||
decrementRefCount()
|
||||
}
|
||||
}, [shouldEnable, incrementRefCount, decrementRefCount]),
|
||||
)
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {usePreventRemove} from '@react-navigation/native'
|
||||
|
||||
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
|
||||
import {
|
||||
type AllNavigatorParams,
|
||||
type NativeStackScreenProps,
|
||||
@@ -37,8 +36,6 @@ export function FindContactsFlowScreen({navigation}: Props) {
|
||||
})
|
||||
})
|
||||
|
||||
useEnableKeyboardControllerScreen(true)
|
||||
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const effect = useCallback(() => {
|
||||
setMinimalShellMode(true)
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
} from '@react-navigation/native'
|
||||
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
|
||||
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {
|
||||
type CommonNavigatorParams,
|
||||
@@ -68,8 +67,6 @@ export function MessagesConversationScreenInner({route}: Props) {
|
||||
const convoId = route.params.conversation
|
||||
const {setCurrentConvoId} = useCurrentConvoId()
|
||||
|
||||
useEnableKeyboardControllerScreen(true)
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
setCurrentConvoId(convoId)
|
||||
|
||||
@@ -2,7 +2,6 @@ import {useMemo, useReducer} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import * as bcp47Match from 'bcp-47-match'
|
||||
|
||||
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {
|
||||
Layout,
|
||||
@@ -60,8 +59,6 @@ export function Onboarding() {
|
||||
)
|
||||
const [contactsFlowState, contactsFlowDispatch] = useFindContactsFlowState()
|
||||
|
||||
useEnableKeyboardControllerScreen(true)
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<View style={[a.absolute, a.inset_0, t.atoms.bg]}>
|
||||
|
||||
@@ -16,7 +16,6 @@ import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
||||
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
|
||||
import {STARTER_PACK_MAX_SIZE} from '#/lib/constants'
|
||||
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {
|
||||
type CommonNavigatorParams,
|
||||
@@ -185,8 +184,6 @@ function WizardInner({
|
||||
})
|
||||
}, [navigation])
|
||||
|
||||
useEnableKeyboardControllerScreen(true)
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
setMinimalShellMode(true)
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
BLUESKY_MOD_SERVICE_HEADERS,
|
||||
MAX_REPORT_REASON_GRAPHEME_LENGTH,
|
||||
} from '#/lib/constants'
|
||||
import {useEnableKeyboardController} from '#/lib/hooks/useEnableKeyboardController'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {useAgent, useSession, useSessionApi} from '#/state/session'
|
||||
import {CharProgress} from '#/view/com/composer/char-progress/CharProgress'
|
||||
@@ -121,8 +120,6 @@ export function Takendown() {
|
||||
|
||||
const webLayout = IS_WEB && gtMobile
|
||||
|
||||
useEnableKeyboardController(true)
|
||||
|
||||
return (
|
||||
<View style={[a.util_screen_outer, a.flex_1]}>
|
||||
<KeyboardAwareScrollView style={[a.flex_1, t.atoms.bg]} centerContent>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {msg, Plural, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {MAX_ALT_TEXT} from '#/lib/constants'
|
||||
import {useIsKeyboardVisible} from '#/lib/hooks/useIsKeyboardVisible'
|
||||
import {enforceLen} from '#/lib/strings/helpers'
|
||||
import {type ComposerImage} from '#/state/gallery'
|
||||
import {AltTextCounterWrapper} from '#/view/com/composer/AltTextCounterWrapper'
|
||||
@@ -28,6 +29,7 @@ export const ImageAltTextDialog = ({
|
||||
image,
|
||||
onChange,
|
||||
}: Props): React.ReactNode => {
|
||||
const {height: minHeight} = useWindowDimensions()
|
||||
const [altText, setAltText] = React.useState(image.alt)
|
||||
|
||||
return (
|
||||
@@ -38,7 +40,8 @@ export const ImageAltTextDialog = ({
|
||||
...image,
|
||||
alt: enforceLen(altText, MAX_ALT_TEXT, true),
|
||||
})
|
||||
}}>
|
||||
}}
|
||||
nativeOptions={{minHeight}}>
|
||||
<Dialog.Handle />
|
||||
<ImageAltTextInner
|
||||
control={control}
|
||||
@@ -65,6 +68,8 @@ const ImageAltTextInner = ({
|
||||
const t = useTheme()
|
||||
const windim = useWindowDimensions()
|
||||
|
||||
const [isKeyboardVisible] = useIsKeyboardVisible()
|
||||
|
||||
const imageStyle = React.useMemo<ImageStyle>(() => {
|
||||
const maxWidth = IS_WEB ? 450 : windim.width
|
||||
const source = image.transformed ?? image.source
|
||||
@@ -165,7 +170,7 @@ const ImageAltTextInner = ({
|
||||
</AltTextCounterWrapper>
|
||||
</View>
|
||||
{/* Maybe fix this later -h */}
|
||||
{IS_ANDROID ? <View style={{height: 300}} /> : null}
|
||||
{IS_ANDROID && isKeyboardVisible ? <View style={{height: 300}} /> : null}
|
||||
</Dialog.ScrollableInner>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user