fix: posters

This commit is contained in:
Fredrik Burmester
2024-08-26 08:30:12 +02:00
parent d962507749
commit c12b58e5cb
10 changed files with 179 additions and 29 deletions

View File

@@ -9,11 +9,13 @@ import { WatchedIndicator } from "./WatchedIndicator";
type ContinueWatchingPosterProps = {
item: BaseItemDto;
width?: number;
useEpisodePoster?: boolean;
};
const ContinueWatchingPoster: React.FC<ContinueWatchingPosterProps> = ({
item,
width = 176,
useEpisodePoster = false,
}) => {
const [api] = useAtom(apiAtom);
@@ -22,6 +24,9 @@ const ContinueWatchingPoster: React.FC<ContinueWatchingPosterProps> = ({
*/
const url = useMemo(() => {
if (!api) return;
if (item.Type === "Episode" && useEpisodePoster) {
return `${api?.basePath}/Items/${item.Id}/Images/Primary?fillHeight=389&quality=80`;
}
if (item.Type === "Episode") {
if (item.ParentBackdropItemId && item.ParentThumbImageTag)
return `${api?.basePath}/Items/${item.ParentBackdropItemId}/Images/Thumb?fillHeight=389&quality=80&tag=${item.ParentThumbImageTag}`;

View File

@@ -1,4 +1,4 @@
import type { PropsWithChildren, ReactElement } from "react";
import { useMemo, type PropsWithChildren, type ReactElement } from "react";
import { View } from "react-native";
import Animated, {
interpolate,
@@ -8,16 +8,18 @@ import Animated, {
} from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
const HEADER_HEIGHT = 400;
type Props = PropsWithChildren<{
headerImage: ReactElement;
logo?: ReactElement;
episodePoster?: ReactElement;
headerHeight?: number;
}>;
export const ParallaxScrollView: React.FC<Props> = ({
children,
headerImage,
episodePoster,
headerHeight = 400,
logo,
}: Props) => {
const scrollRef = useAnimatedRef<Animated.ScrollView>();
@@ -29,14 +31,14 @@ export const ParallaxScrollView: React.FC<Props> = ({
{
translateY: interpolate(
scrollOffset.value,
[-HEADER_HEIGHT, 0, HEADER_HEIGHT],
[-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75]
[-headerHeight, 0, headerHeight],
[-headerHeight / 2, 0, headerHeight * 0.75]
),
},
{
scale: interpolate(
scrollOffset.value,
[-HEADER_HEIGHT, 0, HEADER_HEIGHT],
[-headerHeight, 0, headerHeight],
[2, 1, 1]
),
},
@@ -56,15 +58,29 @@ export const ParallaxScrollView: React.FC<Props> = ({
scrollEventThrottle={16}
>
{logo && (
<View className="absolute top-[250px] h-[130px] left-0 w-full z-40 px-4 flex justify-center items-center">
<View
style={{
top: headerHeight - 150,
height: 130,
}}
className="absolute left-0 w-full z-40 px-4 flex justify-center items-center"
>
{logo}
</View>
)}
{episodePoster && (
<View className="absolute top-[290px] h-[120px] w-full left-0 flex justify-center items-center z-50">
<View className="h-full aspect-video border border-neutral-800">
{episodePoster}
</View>
</View>
)}
<Animated.View
style={[
{
height: HEADER_HEIGHT,
height: headerHeight,
backgroundColor: "black",
},
headerAnimatedStyle,

View File

@@ -53,7 +53,7 @@ export const NextUp: React.FC<{ seriesId: string }> = ({ seriesId }) => {
key={item.Id}
className="flex flex-col w-44"
>
<ContinueWatchingPoster item={item} />
<ContinueWatchingPoster item={item} useEpisodePoster />
<ItemCardText item={item} />
</TouchableOpacity>
)}

View File

@@ -188,7 +188,11 @@ export const SeasonPicker: React.FC<Props> = ({ item }) => {
>
<View className="flex flex-row items-center mb-2">
<View className="w-32 aspect-video overflow-hidden mr-2">
<ContinueWatchingPoster item={e} width={128} />
<ContinueWatchingPoster
item={e}
width={128}
useEpisodePoster
/>
</View>
<View className="shrink">
<Text numberOfLines={2} className="">