Fix problems with BottomSheet and the report dialog (#3297)

* use @discord/bottom-sheet

* add @types/invariant

* some progress on keyboard dialog

* rework

rework

add a comment

use discord bottom sheet

* remove `@gorhom/bottom-sheet`

* remove android specific code

* organize imports
This commit is contained in:
Hailey 2024-03-20 17:26:38 -07:00 committed by GitHub
parent c649ee1afa
commit ad3dd9f6dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 138 additions and 126 deletions

View file

@ -1,31 +1,31 @@
import React, {useImperativeHandle} from 'react'
import {View, Dimensions, Keyboard, Pressable} from 'react-native'
import {Dimensions, Pressable, View} from 'react-native'
import Animated, {useAnimatedStyle} from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import BottomSheet, {
BottomSheetBackdropProps,
BottomSheetScrollView,
BottomSheetScrollViewMethods,
BottomSheetTextInput,
BottomSheetView,
useBottomSheet,
WINDOW_HEIGHT,
} from '@gorhom/bottom-sheet'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import Animated, {useAnimatedStyle} from 'react-native-reanimated'
} from '@discord/bottom-sheet/src'
import {useTheme, atoms as a, flatten} from '#/alf'
import {Portal} from '#/components/Portal'
import {createInput} from '#/components/forms/TextField'
import {logger} from '#/logger'
import {useDialogStateControlContext} from '#/state/dialogs'
import {isNative} from 'platform/detection'
import {atoms as a, flatten, useTheme} from '#/alf'
import {Context} from '#/components/Dialog/context'
import {
DialogOuterProps,
DialogControlProps,
DialogInnerProps,
DialogOuterProps,
} from '#/components/Dialog/types'
import {Context} from '#/components/Dialog/context'
import {isNative} from 'platform/detection'
import {createInput} from '#/components/forms/TextField'
import {Portal} from '#/components/Portal'
export {useDialogControl, useDialogContext} from '#/components/Dialog/context'
export {useDialogContext, useDialogControl} from '#/components/Dialog/context'
export * from '#/components/Dialog/types'
// @ts-ignore
export const Input = createInput(BottomSheetTextInput)
@ -122,7 +122,6 @@ export function Outer({
)
const onCloseInner = React.useCallback(() => {
Keyboard.dismiss()
try {
closeCallback.current?.()
} catch (e: any) {
@ -206,16 +205,14 @@ export function Inner({children, style}: DialogInnerProps) {
)
}
export function ScrollableInner({
children,
keyboardDismissMode,
style,
}: DialogInnerProps) {
export const ScrollableInner = React.forwardRef<
BottomSheetScrollViewMethods,
DialogInnerProps
>(function ScrollableInner({children, style}, ref) {
const insets = useSafeAreaInsets()
return (
<BottomSheetScrollView
keyboardShouldPersistTaps="handled"
keyboardDismissMode={keyboardDismissMode || 'on-drag'}
style={[
a.flex_1, // main diff is this
a.p_xl,
@ -227,24 +224,19 @@ export function ScrollableInner({
},
flatten(style),
]}
contentContainerStyle={isNative ? a.pb_4xl : undefined}>
contentContainerStyle={isNative ? a.pb_4xl : undefined}
ref={ref}>
{children}
<View style={{height: insets.bottom + a.pt_5xl.paddingTop}} />
</BottomSheetScrollView>
)
}
})
export function Handle() {
const t = useTheme()
const onTouchStart = React.useCallback(() => {
Keyboard.dismiss()
}, [])
return (
<View
style={[a.absolute, a.w_full, a.align_center, a.z_10, {height: 40}]}
onTouchStart={onTouchStart}>
<View style={[a.absolute, a.w_full, a.align_center, a.z_10, {height: 40}]}>
<View
style={[
a.rounded_sm,

View file

@ -4,7 +4,7 @@ import type {
GestureResponderEvent,
ScrollViewProps,
} from 'react-native'
import {BottomSheetProps} from '@gorhom/bottom-sheet'
import {BottomSheetProps} from '@discord/bottom-sheet/src'
import {ViewStyleProp} from '#/alf'

View file

@ -1,22 +1,24 @@
import React from 'react'
import {View, Pressable} from 'react-native'
import {Pressable, View} from 'react-native'
import {Trans} from '@lingui/macro'
import {useMyLabelersQuery} from '#/state/queries/preferences'
import {ReportOption} from '#/lib/moderation/useReportOptions'
import {useMyLabelersQuery} from '#/state/queries/preferences'
export {useDialogControl as useReportDialogControl} from '#/components/Dialog'
import {atoms as a} from '#/alf'
import {Loader} from '#/components/Loader'
import * as Dialog from '#/components/Dialog'
import {Text} from '#/components/Typography'
import {AppBskyLabelerDefs} from '@atproto/api'
import {BottomSheetScrollViewMethods} from '@discord/bottom-sheet/src'
import {ReportDialogProps} from './types'
import {atoms as a} from '#/alf'
import * as Dialog from '#/components/Dialog'
import {useDelayedLoading} from '#/components/hooks/useDelayedLoading'
import {useOnKeyboardDidShow} from '#/components/hooks/useOnKeyboard'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
import {SelectLabelerView} from './SelectLabelerView'
import {SelectReportOptionView} from './SelectReportOptionView'
import {SubmitView} from './SubmitView'
import {useDelayedLoading} from '#/components/hooks/useDelayedLoading'
import {AppBskyLabelerDefs} from '@atproto/api'
import {ReportDialogProps} from './types'
export function ReportDialog(props: ReportDialogProps) {
return (
@ -36,10 +38,13 @@ function ReportDialogInner(props: ReportDialogProps) {
} = useMyLabelersQuery()
const isLoading = useDelayedLoading(500, isLabelerLoading)
const ref = React.useRef<BottomSheetScrollViewMethods>(null)
useOnKeyboardDidShow(() => {
ref.current?.scrollToEnd({animated: true})
})
return (
<Dialog.ScrollableInner
label="Report Dialog"
keyboardDismissMode="interactive">
<Dialog.ScrollableInner label="Report Dialog" ref={ref}>
{isLoading ? (
<View style={[a.align_center, {height: 100}]}>
<Loader size="xl" />
@ -55,8 +60,6 @@ function ReportDialogInner(props: ReportDialogProps) {
) : (
<ReportDialogLoaded labelers={labelers} {...props} />
)}
<Dialog.Close />
</Dialog.ScrollableInner>
)
}

View file

@ -0,0 +1,12 @@
import React from 'react'
import {Keyboard} from 'react-native'
export function useOnKeyboardDidShow(cb: () => unknown) {
React.useEffect(() => {
const subscription = Keyboard.addListener('keyboardDidShow', cb)
return () => {
subscription.remove()
}
}, [cb])
}