Display the language selection dialog correctly on web (#2719)

* add event to callback

* position translation button correctly based on press position

* properly place the background

* remove worthless comment
zio/stable
Hailey 2024-02-06 12:51:32 -08:00 committed by GitHub
parent 9ccad0ba6c
commit 52f57b3aec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 15 deletions

View File

@ -9,15 +9,13 @@ import {
PressableStateCallbackType,
ActivityIndicator,
View,
NativeSyntheticEvent,
NativeTouchEvent,
} from 'react-native'
import {Text} from '../text/Text'
import {useTheme} from 'lib/ThemeContext'
import {choose} from 'lib/functions'
type Event =
| React.MouseEvent<HTMLAnchorElement, MouseEvent>
| GestureResponderEvent
export type ButtonType =
| 'primary'
| 'secondary'
@ -59,7 +57,7 @@ export function Button({
style?: StyleProp<ViewStyle>
labelContainerStyle?: StyleProp<ViewStyle>
labelStyle?: StyleProp<TextStyle>
onPress?: () => void | Promise<void>
onPress?: (e: NativeSyntheticEvent<NativeTouchEvent>) => void | Promise<void>
testID?: string
accessibilityLabel?: string
accessibilityHint?: string
@ -148,11 +146,11 @@ export function Button({
const [isLoading, setIsLoading] = React.useState(false)
const onPressWrapped = React.useCallback(
async (event: Event) => {
async (event: GestureResponderEvent) => {
event.stopPropagation()
event.preventDefault()
withLoading && setIsLoading(true)
await onPress?.()
await onPress?.(event)
withLoading && setIsLoading(false)
},
[onPress, withLoading],

View File

@ -1,10 +1,12 @@
import React, {PropsWithChildren, useMemo, useRef} from 'react'
import {
Dimensions,
GestureResponderEvent,
StyleProp,
StyleSheet,
TouchableOpacity,
TouchableWithoutFeedback,
useWindowDimensions,
View,
ViewStyle,
} from 'react-native'
@ -19,6 +21,7 @@ import {useTheme} from 'lib/ThemeContext'
import {HITSLOP_10} from 'lib/constants'
import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro'
import {isWeb} from 'platform/detection'
const ESTIMATED_BTN_HEIGHT = 50
const ESTIMATED_SEP_HEIGHT = 16
@ -80,21 +83,22 @@ export function DropdownButton({
const ref1 = useRef<TouchableOpacity>(null)
const ref2 = useRef<View>(null)
const onPress = () => {
const onPress = (e: GestureResponderEvent) => {
const ref = ref1.current || ref2.current
const {height: winHeight} = Dimensions.get('window')
const pressY = e.nativeEvent.pageY
ref?.measure(
(
_x: number,
_y: number,
width: number,
height: number,
_height: number,
pageX: number,
pageY: number,
) => {
if (!menuWidth) {
menuWidth = 200
}
const winHeight = Dimensions.get('window').height
let estimatedMenuHeight = 0
for (const item of items) {
if (item && isSep(item)) {
@ -108,13 +112,16 @@ export function DropdownButton({
const newX = openToRight
? pageX + width + rightOffset
: pageX + width - menuWidth
let newY = pageY + height + bottomOffset
// Add a bit of additional room
let newY = pressY + bottomOffset + 20
if (openUpwards || newY + estimatedMenuHeight > winHeight) {
newY -= estimatedMenuHeight
}
createDropdownMenu(
newX,
newY,
pageY,
menuWidth,
items.filter(v => !!v) as DropdownItem[],
)
@ -168,6 +175,7 @@ export function DropdownButton({
function createDropdownMenu(
x: number,
y: number,
pageY: number,
width: number,
items: DropdownItem[],
): RootSiblings {
@ -185,6 +193,7 @@ function createDropdownMenu(
onOuterPress={onOuterPress}
x={x}
y={y}
pageY={pageY}
width={width}
items={items}
onPressItem={onPressItem}
@ -198,6 +207,7 @@ type DropDownItemProps = {
onOuterPress: () => void
x: number
y: number
pageY: number
width: number
items: DropdownItem[]
onPressItem: (index: number) => void
@ -207,6 +217,7 @@ const DropdownItems = ({
onOuterPress,
x,
y,
pageY,
width,
items,
onPressItem,
@ -214,6 +225,7 @@ const DropdownItems = ({
const pal = usePalette('default')
const theme = useTheme()
const {_} = useLingui()
const {height: screenHeight} = useWindowDimensions()
const dropDownBackgroundColor =
theme.colorScheme === 'dark' ? pal.btn : pal.view
const separatorColor =
@ -233,7 +245,21 @@ const DropdownItems = ({
onPress={onOuterPress}
accessibilityLabel={_(msg`Toggle dropdown`)}
accessibilityHint="">
<View style={[styles.bg]} />
<View
style={[
styles.bg,
// On web we need to adjust the top and bottom relative to the scroll position
isWeb
? {
top: -pageY,
bottom: pageY - screenHeight,
}
: {
top: 0,
bottom: 0,
},
]}
/>
</TouchableWithoutFeedback>
<View
style={[
@ -295,10 +321,8 @@ function isBtn(item: DropdownItem): item is DropdownItemButton {
const styles = StyleSheet.create({
bg: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
width: '100%',
backgroundColor: '#000',
opacity: 0.1,
},