This commit is contained in:
Fredrik Burmester
2024-09-01 17:10:33 +02:00
parent ffea51ccb0
commit 3d73f604ac
5 changed files with 88 additions and 10 deletions

View File

@@ -1,8 +1,10 @@
import { ItemImage } from "@/components/common/ItemImage";
import { Text } from "@/components/common/Text";
import { TouchableItemRouter } from "@/components/common/TouchableItemRouter";
import { FilterButton } from "@/components/filters/FilterButton";
import { ResetFiltersButton } from "@/components/filters/ResetFiltersButton";
import { ItemCardText } from "@/components/ItemCardText";
import { ItemPoster } from "@/components/posters/ItemPoster";
import MoviePoster from "@/components/posters/MoviePoster";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import {
@@ -194,7 +196,8 @@ const page: React.FC = () => {
width: "89%",
}}
>
<MoviePoster item={item} />
<ItemPoster item={item} />
{/* <MoviePoster item={item} /> */}
<ItemCardText item={item} />
</View>
</MemoizedTouchableItemRouter>

View File

@@ -46,6 +46,7 @@ import { FlashList } from "@shopify/flash-list";
import { Loader } from "@/components/Loader";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { orientationAtom } from "@/utils/atoms/orientation";
import { ItemPoster } from "@/components/posters/ItemPoster";
const MemoizedTouchableItemRouter = React.memo(TouchableItemRouter);
@@ -208,7 +209,8 @@ const Page = () => {
width: "89%",
}}
>
<MoviePoster item={item} />
{/* <MoviePoster item={item} /> */}
<ItemPoster item={item} />
<ItemCardText item={item} />
</View>
</MemoizedTouchableItemRouter>

View File

@@ -1,20 +1,31 @@
import { useImageColors } from "@/hooks/useImageColors";
import { apiAtom } from "@/providers/JellyfinProvider";
import { Ionicons } from "@expo/vector-icons";
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { Image, ImageProps, ImageSource } from "expo-image";
import { useAtom } from "jotai";
import { useMemo } from "react";
import { View } from "react-native";
interface Props extends ImageProps {
item: BaseItemDto;
variant?: "Backdrop" | "Primary" | "Thumb" | "Logo";
variant?:
| "Primary"
| "Backdrop"
| "ParentBackdrop"
| "ParentLogo"
| "Logo"
| "AlbumPrimary"
| "SeriesPrimary"
| "Screenshot"
| "Thumb";
quality?: number;
width?: number;
}
export const ItemImage: React.FC<Props> = ({
item,
variant,
variant = "Primary",
quality = 90,
width = 1000,
...props
@@ -28,6 +39,8 @@ export const ItemImage: React.FC<Props> = ({
let blurhash: string | null | undefined;
let src: ImageSource | null = null;
console.log("ImageItem ~ " + variant, item.Name, item.ImageTags);
switch (variant) {
case "Backdrop":
if (item.Type === "Episode") {
@@ -35,7 +48,7 @@ export const ItemImage: React.FC<Props> = ({
if (!tag) break;
blurhash = item.ImageBlurHashes?.Backdrop?.[tag];
src = {
uri: `${api.basePath}/Items/${item.ParentBackdropItemId}/Images/Backdrop/0?quality=${quality}&tag=${tag}`,
uri: `${api.basePath}/Items/${item.ParentBackdropItemId}/Images/Backdrop/0?quality=${quality}&tag=${tag}&width=${width}`,
blurhash,
};
break;
@@ -45,7 +58,7 @@ export const ItemImage: React.FC<Props> = ({
if (!tag) break;
blurhash = item.ImageBlurHashes?.Backdrop?.[tag];
src = {
uri: `${api.basePath}/Items/${item.Id}/Images/Backdrop/0?quality=${quality}&tag=${tag}`,
uri: `${api.basePath}/Items/${item.Id}/Images/Backdrop/0?quality=${quality}&tag=${tag}&width=${width}`,
blurhash,
};
break;
@@ -55,7 +68,7 @@ export const ItemImage: React.FC<Props> = ({
blurhash = item.ImageBlurHashes?.Primary?.[tag];
src = {
uri: `${api.basePath}/Items/${item.Id}/Images/Primary?quality=${quality}&tag=${tag}`,
uri: `${api.basePath}/Items/${item.Id}/Images/Primary?quality=${quality}&tag=${tag}&width=${width}`,
blurhash,
};
break;
@@ -65,29 +78,42 @@ export const ItemImage: React.FC<Props> = ({
blurhash = item.ImageBlurHashes?.Thumb?.[tag];
src = {
uri: `${api.basePath}/Items/${item.Id}/Images/Backdrop?quality=${quality}&tag=${tag}`,
uri: `${api.basePath}/Items/${item.Id}/Images/Backdrop?quality=${quality}&tag=${tag}&width=${width}`,
blurhash,
};
break;
default:
tag = item.ImageTags?.["Primary"];
src = {
uri: `${api.basePath}/Items/${item.Id}/Images/Primary?quality=${quality}&tag=${tag}`,
uri: `${api.basePath}/Items/${item.Id}/Images/Primary?quality=${quality}&tag=${tag}&width=${width}`,
};
break;
}
console.log("src: ", src?.uri?.slice(0, 30));
return src;
}, [item.ImageTags]);
useImageColors(source?.uri);
// return placeholder icon if no source
if (!source?.uri) return;
<View {...props}>
<Ionicons name="image-outline" size={24} color="white" />;
</View>;
return (
<Image
cachePolicy={"memory-disk"}
transition={300}
placeholder={{
blurhash: source?.blurhash,
}}
style={{
width: "100%",
height: "100%",
}}
source={{
uri: source?.uri,
}}

View File

@@ -55,7 +55,7 @@ export const TouchableItemRouter: React.FC<PropsWithChildren<Props>> = ({
}
if (item.Type === "UserView") {
Alert.alert("Not implemented");
router.push(`/(auth)/(tabs)/${from}/collections/${item.Id}`);
return;
}

View File

@@ -0,0 +1,47 @@
import { View, ViewProps } from "react-native";
import { Text } from "@/components/common/Text";
import {
BaseItemDto,
BaseItemKind,
} from "@jellyfin/sdk/lib/generated-client/models";
import { ItemImage } from "../common/ItemImage";
import { WatchedIndicator } from "../WatchedIndicator";
import { useState } from "react";
interface Props extends ViewProps {
item: BaseItemDto;
showProgress?: boolean;
}
export const ItemPoster: React.FC<Props> = ({
item,
showProgress,
...props
}) => {
const [progress, setProgress] = useState(
item.UserData?.PlayedPercentage || 0
);
if (item.Type === "Movie" || item.Type === "Series" || item.Type === "BoxSet")
return (
<View className="relative rounded-lg overflow-hidden border border-neutral-900">
<ItemImage
style={{
aspectRatio: "10/15",
width: "100%",
}}
item={item}
/>
<WatchedIndicator item={item} />
{showProgress && progress > 0 && (
<View className="h-1 bg-red-600 w-full"></View>
)}
</View>
);
return (
<View className="rounded-lg w-full aspect-square overflow-hidden border border-neutral-900">
<ItemImage className="w-full aspect-square" item={item} />
</View>
);
};