From 3343ddb658e9ad23169e9bd217e4c0cc1b893284 Mon Sep 17 00:00:00 2001 From: Whitewater Date: Tue, 22 Apr 2025 18:14:45 +0800 Subject: [PATCH] fix: adjust layout for Android (#3548) * fix: adjust tab bar height for Android to account for insets * fix(mobile): onboarding screen layout adjustments * fix(mobile): update header height calculation to use Constants for status bar height * fix(mobile): remove unnecessary RootSiblingParent wrapper in Subscriptions component --- .../src/components/layouts/tabbar/Tabbar.tsx | 4 +- .../src/components/layouts/utils/index.tsx | 7 +- .../screens/(stack)/(tabs)/subscriptions.tsx | 25 +++---- apps/mobile/src/screens/OnboardingScreen.tsx | 75 ++++++++++--------- 4 files changed, 57 insertions(+), 54 deletions(-) diff --git a/apps/mobile/src/components/layouts/tabbar/Tabbar.tsx b/apps/mobile/src/components/layouts/tabbar/Tabbar.tsx index 913ae3fb1..f3b21c67a 100644 --- a/apps/mobile/src/components/layouts/tabbar/Tabbar.tsx +++ b/apps/mobile/src/components/layouts/tabbar/Tabbar.tsx @@ -16,6 +16,7 @@ import { SetBottomTabBarHeightContext } from "@/src/components/layouts/tabbar/co import { gentleSpringPreset, quickSpringPreset, softSpringPreset } from "@/src/constants/spring" import { BottomTabContext } from "@/src/lib/navigation/bottom-tab/BottomTabContext" import type { TabbarIconProps, TabScreenProps } from "@/src/lib/navigation/bottom-tab/types" +import { isAndroid } from "@/src/lib/platform" import { PlayerTabBar } from "@/src/modules/player/PlayerTabBar" import { accentColor } from "@/src/theme/colors" @@ -73,7 +74,8 @@ export const Tabbar: FC<{ transform: [{ translateY }], }} onLayout={(e) => { - setTabBarHeight(e.nativeEvent.layout.height) + const tabBarHeight = e.nativeEvent.layout.height + (isAndroid ? insets.bottom : 0) + setTabBarHeight(tabBarHeight) }} > diff --git a/apps/mobile/src/components/layouts/utils/index.tsx b/apps/mobile/src/components/layouts/utils/index.tsx index 9ca411d58..db309c6ba 100644 --- a/apps/mobile/src/components/layouts/utils/index.tsx +++ b/apps/mobile/src/components/layouts/utils/index.tsx @@ -1,4 +1,5 @@ -import { PixelRatio, Platform } from "react-native" +import Constants from "expo-constants" +import { Platform } from "react-native" type Layout = { width: number; height: number } /** @@ -14,7 +15,7 @@ export function getDefaultHeaderHeight( // On models with Dynamic Island the status bar height is smaller than the safe area top inset. const hasDynamicIsland = topInset > 50 - const statusBarHeight = hasDynamicIsland ? topInset - (5 + 1 / PixelRatio.get()) : topInset + const topHeight = hasDynamicIsland ? Constants.statusBarHeight : topInset const isLandscape = layout.width > layout.height @@ -36,5 +37,5 @@ export function getDefaultHeaderHeight( } } - return headerHeight + (!modalPresentation ? statusBarHeight : 0) + return headerHeight + (!modalPresentation ? topHeight : 0) } diff --git a/apps/mobile/src/screens/(stack)/(tabs)/subscriptions.tsx b/apps/mobile/src/screens/(stack)/(tabs)/subscriptions.tsx index d0f54e580..8e628403e 100644 --- a/apps/mobile/src/screens/(stack)/(tabs)/subscriptions.tsx +++ b/apps/mobile/src/screens/(stack)/(tabs)/subscriptions.tsx @@ -1,6 +1,5 @@ import type { FeedViewType } from "@follow/constants" import { useMemo } from "react" -import { RootSiblingParent } from "react-native-root-siblings" import { useColor } from "react-native-uikit-colors" import { ErrorBoundary } from "@/src/components/common/ErrorBoundary" @@ -22,19 +21,17 @@ export default function Subscriptions() { useResetTabOpacityWhenFocused() return ( ({ type: "subscriptions" }), [])}> - - - {whoami ? ( - - ) : ( - - )} - + + {whoami ? ( + + ) : ( + + )} ) } diff --git a/apps/mobile/src/screens/OnboardingScreen.tsx b/apps/mobile/src/screens/OnboardingScreen.tsx index dc9d0a471..65cddf8ff 100644 --- a/apps/mobile/src/screens/OnboardingScreen.tsx +++ b/apps/mobile/src/screens/OnboardingScreen.tsx @@ -1,8 +1,9 @@ import { tracker } from "@follow/tracker" import { useCallback, useEffect, useState } from "react" import { useTranslation } from "react-i18next" -import { SafeAreaView, Text, TouchableOpacity, View } from "react-native" +import { Text, TouchableOpacity, View } from "react-native" import Animated, { FadeInRight, FadeOutLeft } from "react-native-reanimated" +import { useSafeAreaInsets } from "react-native-safe-area-context" import { kv } from "../lib/kv" import { useNavigation } from "../lib/navigation/hooks" @@ -16,6 +17,7 @@ import { isNewUserQueryKey, isOnboardingFinishedStorageKey } from "../store/user export const OnboardingScreen: NavigationControllerView = () => { const { t } = useTranslation("common") + const insets = useSafeAreaInsets() const [currentStep, setCurrentStep] = useState(1) const totalSteps = 4 @@ -39,43 +41,44 @@ export const OnboardingScreen: NavigationControllerView = () => { }, []) return ( - - - + + - + {/* Content */} + {currentStep === 1 && } + {currentStep === 2 && } + {currentStep === 3 && } + {currentStep === 4 && } + + + {/* Navigation buttons */} + + - {/* Content */} - {currentStep === 1 && } - {currentStep === 2 && } - {currentStep === 3 && } - {currentStep === 4 && } - - - {/* Navigation buttons */} - - - - {currentStep < totalSteps - 1 - ? t("words.next") - : currentStep === totalSteps - 1 - ? t("words.finishSetup") - : t("words.letsGo")} - - - - + + {currentStep < totalSteps - 1 + ? t("words.next") + : currentStep === totalSteps - 1 + ? t("words.finishSetup") + : t("words.letsGo")} + + + ) }