mirror of
https://github.com/RSSNext/Folo.git
synced 2026-10-17 05:08:13 +08:00
fix(mobile): apply the banner status bar only while its screen is on top
The settings tab stays focused while another screen is pushed over it, so the light status bar for the banner also applied to screens such as Data Control, leaving white text on a light header. The banner status bar now also requires that no screen is pushed or presented over its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,30 @@
|
||||
import { StatusBar } from "expo-status-bar"
|
||||
import { useState } from "react"
|
||||
import { useAtomValue } from "jotai"
|
||||
import { selectAtom } from "jotai/utils"
|
||||
import { use, useMemo, useState } from "react"
|
||||
import type { SharedValue } from "react-native-reanimated"
|
||||
import { runOnJS, useAnimatedReaction } from "react-native-reanimated"
|
||||
|
||||
import { Navigation } from "@/src/lib/navigation/Navigation"
|
||||
import { ScreenItemContext } from "@/src/lib/navigation/ScreenItemContext"
|
||||
|
||||
// Whether no other screen is pushed or presented over the screen this renders in
|
||||
const useIsTopScreen = () => {
|
||||
const { screenId } = use(ScreenItemContext)
|
||||
return useAtomValue(
|
||||
useMemo(
|
||||
() =>
|
||||
selectAtom(Navigation.rootNavigation.__dangerous_getCtxValue().routesAtom, (routes) =>
|
||||
// The root and the tab screens are no routes; they are on top while nothing else is
|
||||
routes.some((route) => route.id === screenId)
|
||||
? routes.at(-1)?.id === screenId
|
||||
: routes.length === 0,
|
||||
),
|
||||
[screenId],
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The status bar sits on the user banner until the header fades in, so its text follows the
|
||||
* banner colors, or it is dark on dark.
|
||||
@@ -16,6 +38,7 @@ export const BannerStatusBar = ({
|
||||
scrollY: SharedValue<number>
|
||||
enabled?: boolean
|
||||
}) => {
|
||||
const isTopScreen = useIsTopScreen()
|
||||
const [isOverBanner, setIsOverBanner] = useState(true)
|
||||
useAnimatedReaction(
|
||||
() => scrollY.value < 50,
|
||||
@@ -23,6 +46,6 @@ export const BannerStatusBar = ({
|
||||
if (current !== previous) runOnJS(setIsOverBanner)(current)
|
||||
},
|
||||
)
|
||||
if (!enabled || !isOverBanner) return null
|
||||
if (!enabled || !isTopScreen || !isOverBanner) return null
|
||||
return <StatusBar animated style={gradientLight ? "dark" : "light"} />
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user