diff --git a/app/(auth)/(tabs)/home/index.tsx b/app/(auth)/(tabs)/home/index.tsx index 6d145340..f79056e2 100644 --- a/app/(auth)/(tabs)/home/index.tsx +++ b/app/(auth)/(tabs)/home/index.tsx @@ -33,6 +33,8 @@ import { Ionicons } from "@expo/vector-icons"; import MoviePoster from "@/components/MoviePoster"; import { ScrollingCollectionList } from "@/components/home/ScrollingCollectionList"; import { useSettings } from "@/utils/atoms/settings"; +import { LargeMovieCarousel } from "@/components/home/LargeMovieCarousel"; +import { MediaListSection } from "@/components/medialists/MediaListSection"; export default function index() { const router = useRouter(); @@ -102,7 +104,7 @@ export default function index() { return -1; }); - return data.Items || []; + return cs || []; }, enabled: !!api && !!user?.Id, staleTime: 0, @@ -178,44 +180,6 @@ export default function index() { staleTime: 60 * 1000, }); - const { data: mediaListCollection } = useQuery({ - queryKey: ["mediaListCollection", user?.Id], - queryFn: async () => { - if (!api || !user?.Id) return null; - - const response = await getItemsApi(api).getItems({ - userId: user.Id, - tags: ["medialist", "promoted"], - recursive: true, - fields: ["Tags"], - includeItemTypes: ["BoxSet"], - }); - - return response.data.Items?.[0].Id || null; - }, - enabled: !!api && !!user?.Id && settings?.usePopularPlugin === true, - staleTime: 60 * 1000, - }); - - const { data: popularItems, isLoading: isLoadingPopular } = useQuery< - BaseItemDto[] - >({ - queryKey: ["popular", user?.Id], - queryFn: async () => { - if (!api || !user?.Id || !mediaListCollection) return []; - - const response = await getItemsApi(api).getItems({ - userId: user.Id, - parentId: mediaListCollection, - limit: 10, - }); - - return response.data.Items || []; - }, - enabled: !!api && !!user?.Id && !!mediaListCollection, - staleTime: 60 * 1000, - }); - const refetch = useCallback(async () => { setLoading(true); await queryClient.refetchQueries({ queryKey: ["resumeItems", user?.Id] }); @@ -243,6 +207,36 @@ export default function index() { }; }, []); + const { data: mediaListCollections } = useQuery({ + queryKey: [ + "mediaListCollections-home", + user?.Id, + settings?.mediaListCollectionIds, + ], + queryFn: async () => { + if (!api || !user?.Id) return []; + + const response = await getItemsApi(api).getItems({ + userId: user.Id, + tags: ["medialist", "promoted"], + recursive: true, + fields: ["Tags"], + includeItemTypes: ["BoxSet"], + }); + + const ids = + response.data.Items?.filter( + (c) => + c.Name !== "cf_carousel" && + settings?.mediaListCollectionIds?.includes(c.Id!), + ) ?? []; + + return ids; + }, + enabled: !!api && !!user?.Id && settings?.usePopularPlugin === true, + staleTime: 0, + }); + if (isConnected === false) { return ( @@ -292,6 +286,8 @@ export default function index() { } > + + - - + {mediaListCollections?.map((ml) => ( + + ))} + { }, [playing, progress, item, sessionData]); useEffect(() => { - console.log("Full screen changed", fullScreen); if (fullScreen === true) { videoRef.current?.presentFullscreenPlayer(); } else { diff --git a/components/ItemCardText.tsx b/components/ItemCardText.tsx index 98aa9e42..75b9c232 100644 --- a/components/ItemCardText.tsx +++ b/components/ItemCardText.tsx @@ -36,7 +36,7 @@ export const ItemCardText: React.FC = ({ item }) => { ) : ( <> - {item.Name} + {item.Name} {item.ProductionYear} )} diff --git a/components/MoviePoster.tsx b/components/MoviePoster.tsx index 6ea71a48..c1e7a10d 100644 --- a/components/MoviePoster.tsx +++ b/components/MoviePoster.tsx @@ -53,6 +53,7 @@ const MoviePoster: React.FC = ({ contentFit="cover" style={{ aspectRatio: "10/15", + width: "100%", }} /> diff --git a/components/SubtitleTrackSelector.tsx b/components/SubtitleTrackSelector.tsx index 6531490e..349feb3d 100644 --- a/components/SubtitleTrackSelector.tsx +++ b/components/SubtitleTrackSelector.tsx @@ -37,11 +37,7 @@ export const SubtitleTrackSelector: React.FC = ({ if (index !== undefined && index !== null) { onChange(index); } else { - // Get first subtitle stream - const firstSubtitle = subtitleStreams.find((x) => x.Index !== undefined); - if (firstSubtitle?.Index !== undefined) { - onChange(firstSubtitle.Index); - } + onChange(-1); } }, []); @@ -56,7 +52,9 @@ export const SubtitleTrackSelector: React.FC = ({ - {tc(selectedSubtitleSteam?.DisplayTitle, 13)} + {selectedSubtitleSteam + ? tc(selectedSubtitleSteam?.DisplayTitle, 13) + : "None"} @@ -72,6 +70,14 @@ export const SubtitleTrackSelector: React.FC = ({ sideOffset={8} > Subtitles + { + onChange(-1); + }} + > + None + {subtitleStreams?.map((subtitle, idx: number) => ( = ({ setJellyfin( () => new Jellyfin({ - clientInfo: { name: "Streamyfin", version: "0.6.0" }, + clientInfo: { name: "Streamyfin", version: "0.6.1" }, deviceInfo: { name: Platform.OS === "ios" ? "iOS" : "Android", id }, }), ); diff --git a/utils/atoms/queue.ts b/utils/atoms/queue.ts index 968cada0..09bccb37 100644 --- a/utils/atoms/queue.ts +++ b/utils/atoms/queue.ts @@ -46,7 +46,6 @@ export const useJobProcessor = () => { const [isProcessing, setProcessing] = useAtom(isProcessingAtom); useEffect(() => { - console.info("Queue changed", queue, isProcessing); if (queue.length > 0 && !isProcessing) { console.info("Processing queue", queue); queueActions.processJob(queue, setQueue, setProcessing); diff --git a/utils/atoms/settings.ts b/utils/atoms/settings.ts index a558facf..eabf9284 100644 --- a/utils/atoms/settings.ts +++ b/utils/atoms/settings.ts @@ -9,6 +9,7 @@ type Settings = { usePopularPlugin?: boolean; deviceProfile?: "Expo" | "Native" | "Old"; forceDirectPlay?: boolean; + mediaListCollectionIds?: string[]; }; /** @@ -31,6 +32,7 @@ const loadSettings = async (): Promise => { usePopularPlugin: false, deviceProfile: "Expo", forceDirectPlay: false, + mediaListCollectionIds: [], }; }; diff --git a/utils/jellyfin/image/getLogoImageUrlById.ts b/utils/jellyfin/image/getLogoImageUrlById.ts index 5cdb410f..a801b1b7 100644 --- a/utils/jellyfin/image/getLogoImageUrlById.ts +++ b/utils/jellyfin/image/getLogoImageUrlById.ts @@ -11,9 +11,11 @@ import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; export const getLogoImageUrlById = ({ api, item, + height = 130, }: { api?: Api | null; item?: BaseItemDto | null; + height?: number; }) => { if (!api || !item) { return null; @@ -27,7 +29,7 @@ export const getLogoImageUrlById = ({ params.append("tag", imageTags); params.append("quality", "90"); - params.append("fillHeight", "130"); + params.append("fillHeight", height.toString()); return `${api.basePath}/Items/${item.Id}/Images/Logo?${params.toString()}`; };