diff --git a/app/(auth)/(tabs)/(search)/index.tsx b/app/(auth)/(tabs)/(search)/index.tsx index 979119a6..ac3d83fe 100644 --- a/app/(auth)/(tabs)/(search)/index.tsx +++ b/app/(auth)/(tabs)/(search)/index.tsx @@ -30,15 +30,15 @@ import React, { import { Platform, ScrollView, TouchableOpacity, View } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { useDebounce } from "use-debounce"; -import {useJellyseerr} from "@/hooks/useJellyseerr"; -import {MovieResult, TvResult} from "@/utils/jellyseerr/server/models/Search"; -import {MediaType} from "@/utils/jellyseerr/server/constants/media"; +import { useJellyseerr } from "@/hooks/useJellyseerr"; +import { MovieResult, TvResult } from "@/utils/jellyseerr/server/models/Search"; +import { MediaType } from "@/utils/jellyseerr/server/constants/media"; import JellyseerrPoster from "@/components/posters/JellyseerrPoster"; -import {Tag} from "@/components/GenreTags"; +import { Tag } from "@/components/GenreTags"; import DiscoverSlide from "@/components/jellyseerr/DiscoverSlide"; -import {sortBy} from "lodash"; +import { sortBy } from "lodash"; -type SearchType = 'Library' | 'Discover'; +type SearchType = "Library" | "Discover"; const exampleSearches = [ "Lord of the rings", @@ -153,29 +153,41 @@ export default function search() { const response = await jellyseerrApi?.search({ query: new URLSearchParams(debouncedSearch).toString(), page: 1, // todo: maybe rework page & page-size if first results are not enough... - language: 'en' - }) + language: "en", + }); return response?.results; }, - enabled: !!jellyseerrApi && searchType === "Discover" && debouncedSearch.length > 0, + enabled: + !!jellyseerrApi && + searchType === "Discover" && + debouncedSearch.length > 0, }); const { data: jellyseerrDiscoverSettings, isFetching: j2 } = useQuery({ queryKey: ["search", "jellyseerrDiscoverSettings", debouncedSearch], queryFn: async () => jellyseerrApi?.discoverSettings(), - enabled: !!jellyseerrApi && searchType === "Discover" && debouncedSearch.length == 0, + enabled: + !!jellyseerrApi && + searchType === "Discover" && + debouncedSearch.length == 0, }); - const jellyseerrMovieResults: MovieResult[] | undefined = useMemo(() => - jellyseerrResults?.filter(r => r.mediaType === MediaType.MOVIE) as MovieResult[], + const jellyseerrMovieResults: MovieResult[] | undefined = useMemo( + () => + jellyseerrResults?.filter( + (r) => r.mediaType === MediaType.MOVIE + ) as MovieResult[], [jellyseerrResults] - ) + ); - const jellyseerrTvResults: TvResult[] | undefined = useMemo(() => - jellyseerrResults?.filter(r => r.mediaType === MediaType.TV) as TvResult[], + const jellyseerrTvResults: TvResult[] | undefined = useMemo( + () => + jellyseerrResults?.filter( + (r) => r.mediaType === MediaType.TV + ) as TvResult[], [jellyseerrResults] - ) + ); const { data: series, isFetching: l2 } = useQuery({ queryKey: ["search", "series", debouncedSearch], @@ -260,7 +272,17 @@ export default function search() { jellyseerrMovieResults?.length || jellyseerrTvResults?.length ); - }, [artists, episodes, albums, songs, movies, series, collections, actors, jellyseerrResults]); + }, [ + artists, + episodes, + albums, + songs, + movies, + series, + collections, + actors, + jellyseerrResults, + ]); const loading = useMemo(() => { return l1 || l2 || l3 || l4 || l5 || l6 || l7 || l8 || j1 || j2; @@ -290,14 +312,24 @@ export default function search() { )} {jellyseerrApi && ( - - setSearchType('Library')}> - + + setSearchType("Library")}> + - setSearchType('Discover')}> - + setSearchType("Discover")}> + )} @@ -319,7 +351,7 @@ export default function search() { className="flex flex-col w-28 mr-2" item={item} > - + {item.Name} @@ -338,7 +370,7 @@ export default function search() { item={item} className="flex flex-col w-28 mr-2" > - + {item.Name} @@ -357,8 +389,8 @@ export default function search() { key={item.Id} className="flex flex-col w-44 mr-2" > - - + + )} /> @@ -371,7 +403,7 @@ export default function search() { item={item} className="flex flex-col w-28 mr-2" > - + {item.Name} @@ -387,8 +419,8 @@ export default function search() { key={item.Id} className="flex flex-col w-28 mr-2" > - - + + )} /> @@ -401,8 +433,8 @@ export default function search() { key={item.Id} className="flex flex-col w-28 mr-2" > - - + + )} /> @@ -415,8 +447,8 @@ export default function search() { key={item.Id} className="flex flex-col w-28 mr-2" > - - + + )} /> @@ -429,8 +461,8 @@ export default function search() { key={item.Id} className="flex flex-col w-28 mr-2" > - - + + )} /> @@ -442,14 +474,14 @@ export default function search() { header="Request Movies" items={jellyseerrMovieResults} renderItem={(item: MovieResult) => ( - + )} /> ( - + )} /> @@ -468,7 +500,7 @@ export default function search() { "{debouncedSearch}" - ) : debouncedSearch.length === 0 && searchType === 'Library' ? ( + ) : debouncedSearch.length === 0 && searchType === "Library" ? ( {exampleSearches.map((e) => ( ))} - ) : debouncedSearch.length === 0 && searchType === 'Discover' ? ( + ) : debouncedSearch.length === 0 && searchType === "Discover" ? ( - {sortBy?.(jellyseerrDiscoverSettings?.filter(s => s.enabled), 'order') - .map((slide) => ) - } + {sortBy?.( + jellyseerrDiscoverSettings?.filter((s) => s.enabled), + "order" + ).map((slide) => ( + + ))} ) : null} @@ -500,7 +535,12 @@ type Props = { header?: string; }; -const SearchItemWrapper = ({ ids, items, renderItem, header }: PropsWithChildren>) => { +const SearchItemWrapper = ({ + ids, + items, + renderItem, + header, +}: PropsWithChildren>) => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); @@ -540,14 +580,11 @@ const SearchItemWrapper = ({ ids, items, renderItem, header className="px-4 mb-2" showsHorizontalScrollIndicator={false} > - { - data && data?.length > 0 - ? data.map((item) => renderItem(item)) - : - items && items?.length > 0 - ? items.map(i => renderItem(i)) - : undefined - } + {data && data?.length > 0 + ? data.map((item) => renderItem(item)) + : items && items?.length > 0 + ? items.map((i) => renderItem(i)) + : undefined} ); diff --git a/components/jellyseerr/DiscoverSlide.tsx b/components/jellyseerr/DiscoverSlide.tsx index ca0f1d6e..7e566630 100644 --- a/components/jellyseerr/DiscoverSlide.tsx +++ b/components/jellyseerr/DiscoverSlide.tsx @@ -1,26 +1,31 @@ -import React, {useMemo} from "react"; +import React, { useMemo } from "react"; import DiscoverSlider from "@/utils/jellyseerr/server/entity/DiscoverSlider"; -import {DiscoverSliderType} from "@/utils/jellyseerr/server/constants/discover"; -import {DiscoverEndpoint, Endpoints, useJellyseerr} from "@/hooks/useJellyseerr"; -import {useInfiniteQuery} from "@tanstack/react-query"; -import {MovieResult, TvResult} from "@/utils/jellyseerr/server/models/Search"; +import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover"; +import { + DiscoverEndpoint, + Endpoints, + useJellyseerr, +} from "@/hooks/useJellyseerr"; +import { useInfiniteQuery } from "@tanstack/react-query"; +import { MovieResult, TvResult } from "@/utils/jellyseerr/server/models/Search"; import JellyseerrPoster from "@/components/posters/JellyseerrPoster"; -import {Text} from "@/components/common/Text"; -import {FlashList} from "@shopify/flash-list"; +import { Text } from "@/components/common/Text"; +import { FlashList } from "@shopify/flash-list"; +import { View } from "react-native"; interface Props { - slide: DiscoverSlider + slide: DiscoverSlider; } -const DiscoverSlide: React.FC = ({slide}) => { - const {jellyseerrApi} = useJellyseerr(); +const DiscoverSlide: React.FC = ({ slide }) => { + const { jellyseerrApi } = useJellyseerr(); - const {data, isFetching, fetchNextPage, hasNextPage} = useInfiniteQuery({ + const { data, isFetching, fetchNextPage, hasNextPage } = useInfiniteQuery({ queryKey: ["jellyseerr", "discover", slide.id], queryFn: async ({ pageParam }) => { let endpoint: DiscoverEndpoint | undefined = undefined; let params: any = { - page: Number(pageParam) - } + page: Number(pageParam), + }; switch (slide.type) { case DiscoverSliderType.TRENDING: @@ -28,48 +33,68 @@ const DiscoverSlide: React.FC = ({slide}) => { break; case DiscoverSliderType.POPULAR_MOVIES: case DiscoverSliderType.UPCOMING_MOVIES: - endpoint = Endpoints.DISCOVER_MOVIES + endpoint = Endpoints.DISCOVER_MOVIES; if (slide.type === DiscoverSliderType.UPCOMING_MOVIES) - params = { ...params, primaryReleaseDateGte: new Date().toISOString().split('T')[0]} + params = { + ...params, + primaryReleaseDateGte: new Date().toISOString().split("T")[0], + }; break; case DiscoverSliderType.POPULAR_TV: case DiscoverSliderType.UPCOMING_TV: - endpoint = Endpoints.DISCOVER_TV + endpoint = Endpoints.DISCOVER_TV; if (slide.type === DiscoverSliderType.UPCOMING_TV) - params = {...params, firstAirDateGte: new Date().toISOString().split('T')[0]} + params = { + ...params, + firstAirDateGte: new Date().toISOString().split("T")[0], + }; break; } return endpoint ? jellyseerrApi?.discover(endpoint, params) : null; }, initialPageParam: 1, - getNextPageParam: (lastPage, pages) => ((lastPage?.page || pages?.findLast(p => p?.results.length)?.page) || 1) + 1, + getNextPageParam: (lastPage, pages) => + (lastPage?.page || pages?.findLast((p) => p?.results.length)?.page || 1) + + 1, enabled: !!jellyseerrApi, - staleTime: 0 + staleTime: 0, }); - const flatData = useMemo(() => data?.pages?.filter(p => p?.results.length).flatMap(p => p?.results), [data]) + const flatData = useMemo( + () => + data?.pages?.filter((p) => p?.results.length).flatMap((p) => p?.results), + [data] + ); return ( - (flatData && flatData?.length > 0) && <> - {DiscoverSliderType[slide.type].toString().toTitle()} - item!!.id.toString()} - estimatedItemSize={250} - data={flatData} - onEndReachedThreshold={1} - onEndReached={() => { - if (hasNextPage) - fetchNextPage() - }} - renderItem={({item}) => - (item ? : <>) - } - /> - - ) -} + flatData && + flatData?.length > 0 && ( + + + {DiscoverSliderType[slide.type].toString().toTitle()} + + item!!.id.toString()} + estimatedItemSize={250} + data={flatData} + onEndReachedThreshold={1} + onEndReached={() => { + if (hasNextPage) fetchNextPage(); + }} + renderItem={({ item }) => + item ? ( + + ) : ( + <> + ) + } + /> + + ) + ); +}; -export default DiscoverSlide; \ No newline at end of file +export default DiscoverSlide;