Skip to content

Commit

Permalink
Use safe area insets to adjust keyboard offset
Browse files Browse the repository at this point in the history
  • Loading branch information
mhoran committed Dec 17, 2024
1 parent d343e66 commit 4c317b7
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 49 deletions.
2 changes: 1 addition & 1 deletion src/usecase/settings/ConnectionSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class ConnectionSettings extends React.PureComponent<Props, State> {
return (
<View style={styles.container}>
<SafeAreaView edges={['right', 'bottom', 'left']}>
<StatusBar barStyle="dark-content" />
<StatusBar barStyle="dark-content" translucent={true} />
<Text style={styles.text}>
WeechatRN is a relay client for the WeeChat IRC client. WeechatRN
supports the WebSocket connection method only. Configure your relay
Expand Down
9 changes: 2 additions & 7 deletions src/usecase/settings/UploadSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useHeaderHeight } from '@react-navigation/elements';
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import { memo, useCallback, useEffect, useReducer, useRef } from 'react';
import {
Expand Down Expand Up @@ -29,7 +28,6 @@ const mergeState = <T,>(oldState: T, newState: Partial<T>): T => ({

const UploadSettings: React.FC<NavigationProps> = ({ navigation }) => {
const dispatch = useAppDispatch();
const headerHeight = useHeaderHeight();

const uploadOptions = useAppSelector(
(state) => state.connection.mediaUploadOptions
Expand Down Expand Up @@ -91,12 +89,9 @@ const UploadSettings: React.FC<NavigationProps> = ({ navigation }) => {

return (
<SafeAreaView style={styles.container} edges={['right', 'bottom', 'left']}>
<KeyboardAvoidingView
keyboardVerticalOffset={headerHeight}
behavior="padding"
>
<KeyboardAvoidingView behavior="padding">
<ScrollView alwaysBounceVertical={false}>
<StatusBar barStyle="dark-content" />
<StatusBar barStyle="dark-content" translucent={true} />
<Text style={styles.text}>
Use the form below to configure media upload settings. This allows
for uploading media to hosting provider and will automatically paste
Expand Down
46 changes: 5 additions & 41 deletions src/usecase/shared/KeyboardAvoidingView.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,28 @@
import { useCallback } from 'react';
import type { LayoutChangeEvent, LayoutRectangle } from 'react-native';
import { Platform, useWindowDimensions, type ViewStyle } from 'react-native';
import { type ViewStyle } from 'react-native';
import Animated, {
KeyboardState,
runOnUI,
useAnimatedKeyboard,
useAnimatedStyle,
useSharedValue
useAnimatedStyle
} from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

interface Props {
style?: ViewStyle;
behavior?: string;
keyboardVerticalOffset?: number;
}

export const KeyboardAvoidingView: React.FC<React.PropsWithChildren<Props>> = ({
children,
style,
behavior,
keyboardVerticalOffset = 0
behavior
}) => {
const keyboard = useAnimatedKeyboard({
isStatusBarTranslucentAndroid: true
});
const currentFrame = useSharedValue<LayoutRectangle | null>(null);
const { height: screenHeight } = useWindowDimensions();
const safeAreaInsets = useSafeAreaInsets();
const topInset = Platform.OS === 'android' ? safeAreaInsets.top : 0;

const setCurrentFrame = useCallback(
(layout: LayoutRectangle) => {
'worklet';
currentFrame.value = layout;
},
[currentFrame]
);

const onLayout = useCallback(
(event: LayoutChangeEvent) => {
runOnUI(setCurrentFrame)(event.nativeEvent.layout);
},
[setCurrentFrame]
);

const animatedStyles = useAnimatedStyle(() => {
if (!currentFrame.value) return {};

const offset = Math.max(
currentFrame.value.y +
currentFrame.value.height -
(screenHeight +
topInset -
keyboard.height.value -
keyboardVerticalOffset),
0
);
const offset = Math.max(keyboard.height.value - safeAreaInsets.bottom, 0);

if (behavior === 'padding') {
return { paddingBottom: offset };
Expand All @@ -71,8 +37,6 @@ export const KeyboardAvoidingView: React.FC<React.PropsWithChildren<Props>> = ({
});

return (
<Animated.View onLayout={onLayout} style={[style, animatedStyles]}>
{children}
</Animated.View>
<Animated.View style={[style, animatedStyles]}>{children}</Animated.View>
);
};

0 comments on commit 4c317b7

Please sign in to comment.