Use a transparent navbar

This commit is contained in:
Zoe Roux 2023-12-14 12:21:23 +01:00
parent 0f7a8bd4f3
commit 0fc23e2c86
9 changed files with 76 additions and 10 deletions

View File

@ -43,12 +43,11 @@ export default function SignGuard() {
return ( return (
<Stack <Stack
screenOptions={{ screenOptions={{
navigationBarColor: theme.variant.background, navigationBarColor: "transparent",
headerTitle: () => <NavbarTitle />, headerTitle: () => <NavbarTitle />,
headerRight: () => <NavbarRight />, headerRight: () => <NavbarRight />,
contentStyle: { contentStyle: {
backgroundColor: theme.background, backgroundColor: theme.background,
paddingBottom: insets.bottom,
paddingLeft: insets.left, paddingLeft: insets.left,
paddingRight: insets.right, paddingRight: insets.right,
}, },

View File

@ -24,3 +24,4 @@ export * from "./head";
export * from "./spacing"; export * from "./spacing";
export * from "./capitalize"; export * from "./capitalize";
export * from "./touchonly"; export * from "./touchonly";
export * from "./page-style";

View File

@ -0,0 +1,26 @@
/*
* Kyoo - A portable and vast media library solution.
* Copyright (c) Kyoo.
*
* See AUTHORS.md and LICENSE file in the project root for full license information.
*
* Kyoo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Kyoo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/
import { useSafeAreaInsets } from "react-native-safe-area-context";
export const usePageStyle = () => {
const insets = useSafeAreaInsets();
return { paddingBottom: insets.bottom } as const;
};

View File

@ -0,0 +1,23 @@
/*
* Kyoo - A portable and vast media library solution.
* Copyright (c) Kyoo.
*
* See AUTHORS.md and LICENSE file in the project root for full license information.
*
* Kyoo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Kyoo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/
export const usePageStyle = () => {
return {} as const;
};

View File

@ -29,7 +29,7 @@ import {
getDisplayDate, getDisplayDate,
} from "@kyoo/models"; } from "@kyoo/models";
import { Header as ShowHeader, TitleLine } from "../details/header"; import { Header as ShowHeader, TitleLine } from "../details/header";
import { Container, Head, ImageBackground, P, Skeleton, ts } from "@kyoo/primitives"; import { Container, Head, ImageBackground, P, Skeleton, ts, usePageStyle } from "@kyoo/primitives";
import { percent, px, useYoshiki } from "yoshiki/native"; import { percent, px, useYoshiki } from "yoshiki/native";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { forwardRef } from "react"; import { forwardRef } from "react";
@ -122,6 +122,7 @@ const CollectionHeader = forwardRef<View, ViewProps & { slug: string }>(function
<View {...css({ bg: theme.background, paddingTop: { xs: ts(8), md: 0 } })}> <View {...css({ bg: theme.background, paddingTop: { xs: ts(8), md: 0 } })}>
<View <View
{...css({ {...css({
width: percent(100),
maxWidth: { xs: percent(100), lg: px(1170) }, maxWidth: { xs: percent(100), lg: px(1170) },
alignSelf: "center", alignSelf: "center",
})} })}
@ -137,10 +138,13 @@ const query = (slug: string): QueryIdentifier<LibraryItem> => ({
parser: LibraryItemP, parser: LibraryItemP,
path: ["collections", slug, "items"], path: ["collections", slug, "items"],
infinite: true, infinite: true,
params: {
fields: ["firstEpisode", "episodesCount", "watchStatus"],
},
}); });
export const CollectionPage: QueryPage<{ slug: string }> = ({ slug }) => { export const CollectionPage: QueryPage<{ slug: string }> = ({ slug }) => {
const { css } = useYoshiki(); const pageStyle = usePageStyle();
return ( return (
<InfiniteFetch <InfiniteFetch
@ -149,7 +153,7 @@ export const CollectionPage: QueryPage<{ slug: string }> = ({ slug }) => {
layout={{ ...ItemDetails.layout, numColumns: { xs: 1, md: 2 } }} layout={{ ...ItemDetails.layout, numColumns: { xs: 1, md: 2 } }}
Header={CollectionHeader} Header={CollectionHeader}
headerProps={{ slug }} headerProps={{ slug }}
{...css({ padding: { xs: ts(1), sm: ts(8) } })} contentContainerStyle={pageStyle}
> >
{(x) => ( {(x) => (
<ItemDetails <ItemDetails
@ -162,6 +166,12 @@ export const CollectionPage: QueryPage<{ slug: string }> = ({ slug }) => {
genres={"genres" in x ? x.genres : null} genres={"genres" in x ? x.genres : null}
href={x.href} href={x.href}
playHref={x.kind !== ItemKind.Collection && !x.isLoading ? x.playHref : undefined} playHref={x.kind !== ItemKind.Collection && !x.isLoading ? x.playHref : undefined}
watchStatus={
!x.isLoading && x.kind !== ItemKind.Collection ? x.watchStatus?.status ?? null : null
}
unseenEpisodesCount={
x.kind === ItemKind.Show ? x.watchStatus?.unseenEpisodesCount ?? x.episodesCount! : null
}
/> />
)} )}
</InfiniteFetch> </InfiniteFetch>

View File

@ -24,6 +24,7 @@ import { useYoshiki } from "yoshiki/native";
import { DefaultLayout } from "../layout"; import { DefaultLayout } from "../layout";
import { Header } from "./header"; import { Header } from "./header";
import { DetailsCollections } from "./collection"; import { DetailsCollections } from "./collection";
import { usePageStyle } from "@kyoo/primitives";
const query = (slug: string): QueryIdentifier<Movie> => ({ const query = (slug: string): QueryIdentifier<Movie> => ({
parser: MovieP, parser: MovieP,
@ -35,10 +36,11 @@ const query = (slug: string): QueryIdentifier<Movie> => ({
export const MovieDetails: QueryPage<{ slug: string }> = ({ slug }) => { export const MovieDetails: QueryPage<{ slug: string }> = ({ slug }) => {
const { css } = useYoshiki(); const { css } = useYoshiki();
const pageStyle = usePageStyle();
return ( return (
<ScrollView <ScrollView
{...css( {...css([
Platform.OS === "web" && { Platform.OS === "web" && {
// @ts-ignore Web only property // @ts-ignore Web only property
overflow: "auto" as any, overflow: "auto" as any,
@ -47,7 +49,8 @@ export const MovieDetails: QueryPage<{ slug: string }> = ({ slug }) => {
// @ts-ignore Web only property // @ts-ignore Web only property
overflowY: "overlay", overflowY: "overlay",
}, },
)} pageStyle,
])}
> >
<Header type="movie" query={query(slug)} /> <Header type="movie" query={query(slug)} />
<DetailsCollections type="movie" slug={slug} /> <DetailsCollections type="movie" slug={slug} />

View File

@ -26,7 +26,7 @@ import {
SeasonP, SeasonP,
useInfiniteFetch, useInfiniteFetch,
} from "@kyoo/models"; } from "@kyoo/models";
import { Skeleton, H6, HR, P, ts, Menu, IconButton, tooltip } from "@kyoo/primitives"; import { Skeleton, H6, HR, P, ts, Menu, IconButton, tooltip, usePageStyle } from "@kyoo/primitives";
import { rem, useYoshiki } from "yoshiki/native"; import { rem, useYoshiki } from "yoshiki/native";
import { View } from "react-native"; import { View } from "react-native";
import { InfiniteFetch } from "../fetch-infinite"; import { InfiniteFetch } from "../fetch-infinite";
@ -114,6 +114,7 @@ export const EpisodeList = <Props,>({
Header: ComponentType<Props & { children: JSX.Element }>; Header: ComponentType<Props & { children: JSX.Element }>;
headerProps: Props; headerProps: Props;
}) => { }) => {
const pageStyle = usePageStyle();
const { t } = useTranslation(); const { t } = useTranslation();
const { items: seasons, error } = useInfiniteFetch(SeasonHeader.query(slug)); const { items: seasons, error } = useInfiniteFetch(SeasonHeader.query(slug));
@ -128,6 +129,7 @@ export const EpisodeList = <Props,>({
Header={Header} Header={Header}
headerProps={headerProps} headerProps={headerProps}
getItemType={(item) => (item.firstOfSeason ? "withHeader" : "normal")} getItemType={(item) => (item.firstOfSeason ? "withHeader" : "normal")}
contentContainerStyle={pageStyle}
> >
{(item) => { {(item) => {
const sea = item?.firstOfSeason const sea = item?.firstOfSeason

View File

@ -31,7 +31,6 @@ import {
import { import {
Chip, Chip,
H3, H3,
Icon,
IconFab, IconFab,
imageBorderRadius, imageBorderRadius,
Link, Link,

View File

@ -25,10 +25,11 @@ import { createParam } from "solito";
import { DefaultLayout } from "../layout"; import { DefaultLayout } from "../layout";
import { InfiniteFetch } from "../fetch-infinite"; import { InfiniteFetch } from "../fetch-infinite";
import { itemMap } from "../browse"; import { itemMap } from "../browse";
import { SearchSort, SortOrd, SortBy, Layout } from "../browse/types"; import { SearchSort, SortOrd, Layout } from "../browse/types";
import { BrowseSettings } from "../browse/header"; import { BrowseSettings } from "../browse/header";
import { ItemGrid } from "../browse/grid"; import { ItemGrid } from "../browse/grid";
import { ItemList } from "../browse/list"; import { ItemList } from "../browse/list";
import { usePageStyle } from "@kyoo/primitives";
const { useParam } = createParam<{ sortBy?: string }>(); const { useParam } = createParam<{ sortBy?: string }>();
@ -48,6 +49,7 @@ const query = (
}); });
export const SearchPage: QueryPage<{ q?: string }> = ({ q }) => { export const SearchPage: QueryPage<{ q?: string }> = ({ q }) => {
const pageStyle = usePageStyle();
const { t } = useTranslation(); const { t } = useTranslation();
const [sort, setSort] = useParam("sortBy"); const [sort, setSort] = useParam("sortBy");
const sortKey = (sort?.split(":")[0] as SearchSort) || SearchSort.Relevance; const sortKey = (sort?.split(":")[0] as SearchSort) || SearchSort.Relevance;
@ -74,6 +76,7 @@ export const SearchPage: QueryPage<{ q?: string }> = ({ q }) => {
setLayout={setLayout} setLayout={setLayout}
/> />
} }
contentContainerStyle={pageStyle}
> >
{(item) => <LayoutComponent {...itemMap(item)} />} {(item) => <LayoutComponent {...itemMap(item)} />}
</InfiniteFetch> </InfiniteFetch>