From a79795c984f3a4fa1d251e6c3ab05c65bc49cecd Mon Sep 17 00:00:00 2001 From: Saramanda9988 <2074730050@qq.com> Date: Sat, 4 Jul 2026 23:23:21 +0800 Subject: [PATCH 1/2] =?UTF-8?q?:recycle:=20refactor:=20=E5=B0=86SafeAreaVi?= =?UTF-8?q?ew=E6=9B=BF=E6=8D=A2=E4=B8=BAView=EF=BC=8C=E5=B9=B6=E4=BD=BF?= =?UTF-8?q?=E7=94=A8SafeAreaInsets=E5=9C=A8=E9=80=89=E9=A1=B9=E5=8D=A1?= =?UTF-8?q?=E4=B9=8B=E9=97=B4=E8=BF=9B=E8=A1=8C=E4=B8=80=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E5=A1=AB=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(tabs)/_layout.tsx | 1 + app/(tabs)/course.tsx | 55 ++++++++-------------------- app/(tabs)/function.tsx | 9 ++--- app/(tabs)/index.tsx | 9 ++--- app/(tabs)/user.tsx | 6 ++- app/_layout.tsx | 21 +++++++++-- components/layout/tab-background.tsx | 18 ++++++--- 7 files changed, 58 insertions(+), 61 deletions(-) diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index b1ba775..5ed559c 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -64,6 +64,7 @@ export default function TabLayout() { screenOptions={{ tabBarActiveTintColor: theme.tint, headerShown: false, + sceneStyle: { backgroundColor: "transparent" }, }} > store.courses); const termStart = useCourseStore((store) => store.termStart); const isBound = useUserBindStore((store) => store.isBound); - const backgroundImageUri = useScheduleStore((s) => s.backgroundImageUri); - const backgroundImageOpacity = useScheduleStore( - (s) => s.backgroundImageOpacity, - ); - const backgroundImageBlurRadius = useScheduleStore( - (s) => s.backgroundImageBlurRadius, - ); + const hasBgImage = useScheduleStore((s) => !!s.backgroundImageUri); const [week, setWeek] = useState(() => getCurrentWeek(termStart)); const today = getCurrentDayOfWeek(); const haptic = useHaptics(); @@ -163,38 +153,23 @@ export default function CourseScreen() { return ( - {!!backgroundImageUri && ( - <> - - - + height: insets.top + COURSE_HEADER_HEIGHT, + backgroundColor: Colors[isDark ? "dark" : "light"].background, + }, + headerBackdropStyle, + ]} + /> )} - + - + diff --git a/app/(tabs)/function.tsx b/app/(tabs)/function.tsx index 5a249ef..f110a80 100644 --- a/app/(tabs)/function.tsx +++ b/app/(tabs)/function.tsx @@ -13,9 +13,8 @@ import { useWindowDimensions, View, } from "react-native"; -import { SafeAreaView } from "react-native-safe-area-context"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; -import { TabBackground } from "@/components/layout/tab-background"; import { ConfirmSheet } from "@/components/ui/confirm-sheet"; import { IS_DEV } from "@/constants/is-dev"; import { useColorScheme } from "@/hooks/use-color-scheme"; @@ -130,6 +129,7 @@ export default function FunctionScreen() { const haptic = useHaptics(); const colorScheme = useColorScheme(); const isDark = colorScheme === "dark"; + const insets = useSafeAreaInsets(); const hasBgImage = useScheduleStore((s) => !!s.backgroundImageUri); const { height } = useWindowDimensions(); const [showBrowser, setShowBrowser] = useState(false); @@ -158,8 +158,7 @@ export default function FunctionScreen() { return ( - - + - + ); } diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 200dad6..e8c861f 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -12,12 +12,11 @@ import { import type PagerView from "react-native-pager-view"; import { type PagerViewOnPageSelectedEvent } from "react-native-pager-view"; import Animated, { useAnimatedStyle } from "react-native-reanimated"; -import { SafeAreaView } from "react-native-safe-area-context"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; import { CourseDetailModal } from "@/components/layout/course-detail-modal"; import { CourseShareSheet } from "@/components/share/course-share-sheet"; import { HomeMenu } from "@/components/layout/home-menu"; -import { TabBackground } from "@/components/layout/tab-background"; import { AnnouncementBanner } from "@/components/ui/announcement-banner"; import { getDayLabels } from "@/constants/weekdays"; import { useColorScheme } from "@/hooks/use-color-scheme"; @@ -161,6 +160,7 @@ export default function HomeScreen() { const t = useT(); const colorScheme = useColorScheme(); const isDark = colorScheme === "dark"; + const insets = useSafeAreaInsets(); const haptic = useHaptics(); const courses = useCourseStore((s) => s.courses); const termStart = useCourseStore((s) => s.termStart); @@ -402,8 +402,7 @@ export default function HomeScreen() { return ( - - + @@ -703,7 +702,7 @@ export default function HomeScreen() { )} - + - {children} + {children} ); } diff --git a/app/_layout.tsx b/app/_layout.tsx index 69f7962..e90a4a3 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -42,8 +42,9 @@ import { import Toast from "react-native-toast-message"; import { AppBlurTargetProvider } from "@/components/ui/app-blur-target"; +import { TabBackground } from "@/components/layout/tab-background"; import { UpdateModal } from "@/components/ui/update-modal"; -import { Themes } from "@/constants/theme"; +import { Colors, Themes } from "@/constants/theme"; import { useColorScheme } from "@/hooks/use-color-scheme"; import { refreshSystemLocale } from "@/lib/i18n"; import { syncCoursesToCalendar } from "@/services/calendar-sync"; @@ -204,11 +205,19 @@ function RootLayout() { return ( - + + - + diff --git a/components/layout/tab-background.tsx b/components/layout/tab-background.tsx index ca559b8..faf85fb 100644 --- a/components/layout/tab-background.tsx +++ b/components/layout/tab-background.tsx @@ -3,15 +3,20 @@ import { LinearGradient } from "expo-linear-gradient"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { useColorScheme } from "@/hooks/use-color-scheme"; -import { DEFAULT_SCHEDULE_VISUAL, useScheduleStore } from "@/store/schedule"; +import { useScheduleStore } from "@/store/schedule"; /** - * 首页/功能页的全屏背景图。 - * 固定使用默认透明度与模糊值,不受“课表外观”里的滑杆设置影响; - * 顶部叠一层向下消隐的底色渐变,保证状态栏与页面标题区域清晰。 + * Tabs shared background. Mounted above the tab navigator so switching tabs + * does not remount/reload the image layer. */ export function TabBackground() { const backgroundImageUri = useScheduleStore((s) => s.backgroundImageUri); + const backgroundImageOpacity = useScheduleStore( + (s) => s.backgroundImageOpacity, + ); + const backgroundImageBlurRadius = useScheduleStore( + (s) => s.backgroundImageBlurRadius, + ); const isDark = useColorScheme() === "dark"; const insets = useSafeAreaInsets(); @@ -22,6 +27,7 @@ export function TabBackground() { return ( <> Date: Sat, 4 Jul 2026 23:36:05 +0800 Subject: [PATCH 2/2] =?UTF-8?q?:recycle:=20refactor:=20=E4=BF=9D=E8=AF=81b?= =?UTF-8?q?lur=E7=AD=89=E6=95=88=E6=9E=9C=E7=9A=84=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E5=8F=AA=E5=9C=A8=E8=AF=BE=E8=A1=A8=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/layout/tab-background.tsx | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/components/layout/tab-background.tsx b/components/layout/tab-background.tsx index faf85fb..f0e046e 100644 --- a/components/layout/tab-background.tsx +++ b/components/layout/tab-background.tsx @@ -1,15 +1,17 @@ import { Image } from "expo-image"; import { LinearGradient } from "expo-linear-gradient"; +import { useSegments } from "expo-router"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { useColorScheme } from "@/hooks/use-color-scheme"; -import { useScheduleStore } from "@/store/schedule"; +import { DEFAULT_SCHEDULE_VISUAL, useScheduleStore } from "@/store/schedule"; /** * Tabs shared background. Mounted above the tab navigator so switching tabs * does not remount/reload the image layer. */ export function TabBackground() { + const segments = useSegments(); const backgroundImageUri = useScheduleStore((s) => s.backgroundImageUri); const backgroundImageOpacity = useScheduleStore( (s) => s.backgroundImageOpacity, @@ -19,10 +21,17 @@ export function TabBackground() { ); const isDark = useColorScheme() === "dark"; const insets = useSafeAreaInsets(); + const isCourseTab = segments[0] === "(tabs)" && segments[1] === "course"; if (!backgroundImageUri) return null; const scrimColor = isDark ? "21,23,24" : "255,255,255"; + const opacity = isCourseTab + ? backgroundImageOpacity + : DEFAULT_SCHEDULE_VISUAL.backgroundImageOpacity; + const blurRadius = isCourseTab + ? backgroundImageBlurRadius + : DEFAULT_SCHEDULE_VISUAL.backgroundImageBlurRadius; return ( <> @@ -35,10 +44,10 @@ export function TabBackground() { left: 0, right: 0, bottom: 0, - opacity: backgroundImageOpacity, + opacity, }} contentFit="cover" - blurRadius={backgroundImageBlurRadius} + blurRadius={blurRadius} />