mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-04-27 11:04:42 +01:00
93 lines
2.2 KiB
TypeScript
93 lines
2.2 KiB
TypeScript
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
|
import { Image } from "expo-image";
|
|
import { useAtom } from "jotai";
|
|
import { useMemo } from "react";
|
|
import { View } from "react-native";
|
|
import {
|
|
GlassPosterView,
|
|
isGlassEffectAvailable,
|
|
} from "@/modules/glass-poster";
|
|
import { apiAtom } from "@/providers/JellyfinProvider";
|
|
import { getPrimaryImageUrl } from "@/utils/jellyfin/image/getPrimaryImageUrl";
|
|
|
|
export const TV_POSTER_WIDTH = 260;
|
|
|
|
type SeriesPosterProps = {
|
|
item: BaseItemDto;
|
|
showProgress?: boolean;
|
|
};
|
|
|
|
const SeriesPoster: React.FC<SeriesPosterProps> = ({ item }) => {
|
|
const [api] = useAtom(apiAtom);
|
|
|
|
const url = useMemo(() => {
|
|
if (item.Type === "Episode") {
|
|
return `${api?.basePath}/Items/${item.SeriesId}/Images/Primary?fillHeight=780&quality=80&tag=${item.SeriesPrimaryImageTag}`;
|
|
}
|
|
return getPrimaryImageUrl({
|
|
api,
|
|
item,
|
|
width: 520, // 2x for quality on large screens
|
|
});
|
|
}, [api, item]);
|
|
|
|
const blurhash = useMemo(() => {
|
|
const key = item.ImageTags?.Primary as string;
|
|
return item.ImageBlurHashes?.Primary?.[key];
|
|
}, [item]);
|
|
|
|
// Use glass effect on tvOS 26+
|
|
const useGlass = isGlassEffectAvailable();
|
|
|
|
if (useGlass) {
|
|
return (
|
|
<GlassPosterView
|
|
imageUrl={url ?? null}
|
|
aspectRatio={10 / 15}
|
|
cornerRadius={24}
|
|
progress={0}
|
|
showWatchedIndicator={false}
|
|
isFocused={false}
|
|
width={TV_POSTER_WIDTH}
|
|
style={{ width: TV_POSTER_WIDTH }}
|
|
/>
|
|
);
|
|
}
|
|
|
|
// Fallback for older tvOS versions
|
|
return (
|
|
<View
|
|
style={{
|
|
width: TV_POSTER_WIDTH,
|
|
aspectRatio: 10 / 15,
|
|
position: "relative",
|
|
borderRadius: 24,
|
|
overflow: "hidden",
|
|
}}
|
|
>
|
|
<Image
|
|
placeholder={{
|
|
blurhash,
|
|
}}
|
|
key={item.Id}
|
|
id={item.Id}
|
|
source={
|
|
url
|
|
? {
|
|
uri: url,
|
|
}
|
|
: null
|
|
}
|
|
cachePolicy={"memory-disk"}
|
|
contentFit='cover'
|
|
style={{
|
|
height: "100%",
|
|
width: "100%",
|
|
}}
|
|
/>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default SeriesPoster;
|