mirror of
https://github.com/zimplexing/OrionTV.git
synced 2026-02-04 03:36:29 +08:00
fix(ui): resolve status bar overlay issue across all screens
Add SafeAreaProvider to root layout and implement proper safe area handling: - Wrap app in SafeAreaProvider in _layout.tsx - Update HomeScreen to use safe area insets for proper top padding - Fix SettingsScreen safe area handling for all device types - Update ResponsiveHeader to use SafeAreaContext instead of manual calculation This ensures content is not covered by the status bar on mobile and tablet devices while maintaining TV compatibility.
This commit is contained in:
@@ -5,6 +5,7 @@ import * as SplashScreen from "expo-splash-screen";
|
||||
import { useEffect } from "react";
|
||||
import { Platform, View, StyleSheet } from "react-native";
|
||||
import Toast from "react-native-toast-message";
|
||||
import { SafeAreaProvider } from "react-native-safe-area-context";
|
||||
|
||||
import { useSettingsStore } from "@/stores/settingsStore";
|
||||
import { useRemoteControlStore } from "@/stores/remoteControlStore";
|
||||
@@ -76,23 +77,25 @@ export default function RootLayout() {
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
|
||||
<View style={styles.container}>
|
||||
<Stack>
|
||||
<Stack.Screen name="index" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="detail" options={{ headerShown: false }} />
|
||||
{Platform.OS !== "web" && <Stack.Screen name="play" options={{ headerShown: false }} />}
|
||||
<Stack.Screen name="search" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="live" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="settings" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="favorites" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="+not-found" />
|
||||
</Stack>
|
||||
</View>
|
||||
<Toast />
|
||||
<LoginModal />
|
||||
<UpdateModal />
|
||||
</ThemeProvider>
|
||||
<SafeAreaProvider>
|
||||
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
|
||||
<View style={styles.container}>
|
||||
<Stack>
|
||||
<Stack.Screen name="index" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="detail" options={{ headerShown: false }} />
|
||||
{Platform.OS !== "web" && <Stack.Screen name="play" options={{ headerShown: false }} />}
|
||||
<Stack.Screen name="search" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="live" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="settings" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="favorites" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="+not-found" />
|
||||
</Stack>
|
||||
</View>
|
||||
<Toast />
|
||||
<LoginModal />
|
||||
<UpdateModal />
|
||||
</ThemeProvider>
|
||||
</SafeAreaProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ export default function HomeScreen() {
|
||||
const dynamicStyles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
paddingTop: deviceType === "mobile" ? 0 : 40,
|
||||
paddingTop: deviceType === "mobile" ? insets.top : deviceType === "tablet" ? insets.top + 20 : 40,
|
||||
},
|
||||
headerContainer: {
|
||||
flexDirection: "row",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { View, StyleSheet, FlatList, Alert, KeyboardAvoidingView, Platform } from "react-native";
|
||||
import { useTVEventHandler } from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { ThemedText } from "@/components/ThemedText";
|
||||
import { ThemedView } from "@/components/ThemedView";
|
||||
import { StyledButton } from "@/components/StyledButton";
|
||||
@@ -24,6 +25,7 @@ export default function SettingsScreen() {
|
||||
const { loadSettings, saveSettings, setApiBaseUrl, setM3uUrl } = useSettingsStore();
|
||||
const { lastMessage, targetPage, clearMessage } = useRemoteControlStore();
|
||||
const backgroundColor = useThemeColor({}, "background");
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
// 响应式布局配置
|
||||
const responsiveConfig = useResponsiveLayout();
|
||||
@@ -162,7 +164,7 @@ export default function SettingsScreen() {
|
||||
useTVEventHandler(deviceType === "tv" ? handleTVEvent : () => {});
|
||||
|
||||
// 动态样式
|
||||
const dynamicStyles = createResponsiveStyles(deviceType, spacing);
|
||||
const dynamicStyles = createResponsiveStyles(deviceType, spacing, insets);
|
||||
|
||||
const renderSettingsContent = () => (
|
||||
<KeyboardAvoidingView style={{ flex: 1, backgroundColor }} behavior={Platform.OS === "ios" ? "padding" : "height"}>
|
||||
@@ -214,7 +216,7 @@ export default function SettingsScreen() {
|
||||
);
|
||||
}
|
||||
|
||||
const createResponsiveStyles = (deviceType: string, spacing: number) => {
|
||||
const createResponsiveStyles = (deviceType: string, spacing: number, insets: any) => {
|
||||
const isMobile = deviceType === "mobile";
|
||||
const isTablet = deviceType === "tablet";
|
||||
const isTV = deviceType === "tv";
|
||||
@@ -224,7 +226,7 @@ const createResponsiveStyles = (deviceType: string, spacing: number) => {
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: spacing,
|
||||
paddingTop: isTV ? spacing * 2 : 0,
|
||||
paddingTop: isTV ? spacing * 2 : isMobile ? insets.top + spacing : insets.top + spacing * 1.5,
|
||||
},
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
|
||||
Reference in New Issue
Block a user