Add dark overlay on transparent navbars

This commit is contained in:
Zoe Roux 2026-02-13 19:02:22 +01:00
parent 433da2f6c4
commit 619247d5fd
No known key found for this signature in database
8 changed files with 64 additions and 29 deletions

View File

@ -3,10 +3,9 @@ import MoreHoriz from "@material-symbols/svg-400/rounded/more_horiz.svg";
import MovieInfo from "@material-symbols/svg-400/rounded/movie_info.svg";
import PlayArrow from "@material-symbols/svg-400/rounded/play_arrow-fill.svg";
import Theaters from "@material-symbols/svg-400/rounded/theaters-fill.svg";
import { Stack } from "expo-router";
import { Fragment } from "react";
import { useTranslation } from "react-i18next";
import { View, ViewProps } from "react-native";
import { View, type ViewProps } from "react-native";
import { WatchListInfo } from "~/components/items/watchlist-info";
import { Rating } from "~/components/rating";
import {

View File

@ -2,7 +2,7 @@ import { useState } from "react";
import Animated from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useQueryState } from "~/utils";
import { useScrollNavbar } from "../navbar";
import { HeaderBackground, useScrollNavbar } from "../navbar";
import { Header } from "./header";
export const MovieDetails = () => {
@ -13,7 +13,7 @@ export const MovieDetails = () => {
return (
<>
<Animated.View {...headerProps} />
<HeaderBackground {...headerProps} />
<Animated.ScrollView
onScroll={scrollHandler}
scrollEventThrottle={16}

View File

@ -1,6 +1,6 @@
import { useState, type ComponentProps } from "react";
import { type ComponentProps, useState } from "react";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { View, type ViewProps } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Path } from "react-native-svg";
import { EntryLine, entryDisplayNumber } from "~/components/entries";
@ -8,11 +8,9 @@ import type { Entry, Serie } from "~/models";
import { Container, H2, Svg } from "~/primitives";
import { Fetch } from "~/query";
import { useQueryState } from "~/utils";
import { HeaderBackground, useScrollNavbar } from "../navbar";
import { Header } from "./header";
import { EntryList } from "./season";
import { useScrollNavbar } from "../navbar";
import Animated from "react-native-reanimated";
import { ViewProps } from "react-native";
export const SvgWave = (props: ComponentProps<typeof Svg>) => {
// aspect-[width/height]: width/height of the svg
@ -94,7 +92,7 @@ export const SerieDetails = () => {
return (
<View className="flex-1 bg-card">
<Animated.View {...headerProps} />
<HeaderBackground {...headerProps} />
<EntryList
slug={slug}
season={season}

View File

@ -1,7 +1,7 @@
import Info from "@material-symbols/svg-400/rounded/info.svg";
import PlayArrow from "@material-symbols/svg-400/rounded/play_arrow-fill.svg";
import { LinearGradient } from "expo-linear-gradient";
import { ComponentProps } from "react";
import type { ComponentProps } from "react";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { min, percent, px, rem, vh } from "yoshiki/native";

View File

@ -4,7 +4,7 @@ import Animated from "react-native-reanimated";
import { Genre } from "~/models";
import { Fetch, useRefresh } from "~/query";
import { shuffle } from "~/utils";
import { useScrollNavbar } from "../navbar";
import { HeaderBackground, useScrollNavbar } from "../navbar";
import { GenreGrid } from "./genre";
import { Header } from "./header";
import { NewsList } from "./news";
@ -23,7 +23,7 @@ export const HomePage = () => {
return (
<>
<Animated.View {...headerProps} />
<HeaderBackground {...headerProps} />
<Animated.ScrollView
onScroll={scrollHandler}
scrollEventThrottle={16}

View File

@ -7,8 +7,8 @@ import { Show } from "~/models";
import { Button, Link, P, ts } from "~/primitives";
import { useAccount } from "~/providers/account-context";
import { InfiniteFetch, type QueryIdentifier } from "~/query";
import { getDisplayDate } from "~/utils";
import { EmptyView } from "~/ui/empty-view";
import { getDisplayDate } from "~/utils";
import { Header } from "./genre";
export const WatchlistList = () => {

View File

@ -4,6 +4,7 @@ import Login from "@material-symbols/svg-400/rounded/login.svg";
import Logout from "@material-symbols/svg-400/rounded/logout.svg";
import Search from "@material-symbols/svg-400/rounded/search-fill.svg";
import Settings from "@material-symbols/svg-400/rounded/settings.svg";
import { useIsFocused } from "@react-navigation/native";
import {
useGlobalSearchParams,
useNavigation,
@ -15,10 +16,9 @@ import {
type ComponentProps,
type Ref,
useEffect,
useLayoutEffect,
useRef,
useState,
useLayoutEffect,
useCallback,
} from "react";
import { useTranslation } from "react-i18next";
import {
@ -27,8 +27,16 @@ import {
type TextInput,
type TextInputProps,
View,
Animated,
type ViewProps,
} from "react-native";
import Animated, {
interpolate,
useAnimatedScrollHandler,
useAnimatedStyle,
useSharedValue,
} from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useCSSVariable } from "uniwind";
import {
A,
Avatar,
@ -43,15 +51,6 @@ import {
import { useAccount, useAccounts } from "~/providers/account-context";
import { logout } from "~/ui/login/logic";
import { cn } from "~/utils";
import {
interpolate,
useAnimatedScrollHandler,
useAnimatedStyle,
useSharedValue,
} from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useIsFocused } from "@react-navigation/native";
import { useCSSVariable } from "uniwind";
export const NavbarTitle = ({
className,
@ -227,6 +226,12 @@ export const useScrollNavbar = ({
}),
[imageHeight, height],
);
const reverse = useAnimatedStyle(
() => ({
opacity: interpolate(scrollY.value, [0, imageHeight - height], [1, 0]),
}),
[imageHeight, height],
);
const nav = useNavigation();
const focused = useIsFocused();
@ -249,9 +254,39 @@ export const useScrollNavbar = ({
return {
scrollHandler,
headerProps: {
className: cn("absolute z-10 w-full bg-accent"),
style: [{ height }, opacity],
opacity,
reverse,
height,
},
headerHeight: height,
};
};
export const HeaderBackground = ({
children,
opacity,
reverse,
height,
className,
style,
...props
}: ViewProps & ReturnType<typeof useScrollNavbar>["headerProps"]) => {
return (
<>
<Animated.View
className={cn("absolute z-10 w-full bg-accent", className)}
style={[{ height }, opacity, style]}
{...props}
/>
<Animated.View
className={cn(
"absolute z-10 w-full bg-linear-to-b from-slate-950/70 to-transparent",
className,
)}
style={[{ height }, reverse, style]}
{...props}
/>
{children}
</>
);
};

View File

@ -88,7 +88,10 @@ export const TouchControls = ({
// instantly hide the controls when mouse leaves the view
if (e.nativeEvent.pointerType === "mouse") show(false);
}}
className={cn("absolute inset-0 cursor-default", !shouldShow && "cursor-none")}
className={cn(
"absolute inset-0 cursor-default",
!shouldShow && "cursor-none",
)}
/>
{shouldShow && children}
</View>