diff --git a/src/backend/metadata/traktApi.ts b/src/backend/metadata/traktApi.ts index fe3835c1..fd489927 100644 --- a/src/backend/metadata/traktApi.ts +++ b/src/backend/metadata/traktApi.ts @@ -19,10 +19,33 @@ export interface TraktReleaseResponse { digital_release_date?: string; } +export interface PaginatedTraktResponse { + tmdb_ids: number[]; + hasMore: boolean; + totalCount: number; +} + export type TraktContentType = "movie" | "episode"; export const TRAKT_BASE_URL = "https://fed-airdate.pstream.org"; +// Pagination utility +export function paginateResults( + results: TraktLatestResponse, + page: number, + pageSize: number = 20, +): PaginatedTraktResponse { + const startIndex = (page - 1) * pageSize; + const endIndex = startIndex + pageSize; + const paginatedIds = results.tmdb_ids.slice(startIndex, endIndex); + + return { + tmdb_ids: paginatedIds, + hasMore: endIndex < results.tmdb_ids.length, + totalCount: results.tmdb_ids.length, + }; +} + // Base function to fetch from Trakt API async function fetchFromTrakt(endpoint: string): Promise { const response = await fetch(`${TRAKT_BASE_URL}${endpoint}`); diff --git a/src/pages/discover/components/MediaCarousel.tsx b/src/pages/discover/components/MediaCarousel.tsx index 63ab3a4c..90d853bb 100644 --- a/src/pages/discover/components/MediaCarousel.tsx +++ b/src/pages/discover/components/MediaCarousel.tsx @@ -503,7 +503,7 @@ export function MediaCarousel({
{media.length > 0 - ? media.slice(0, 20).map((item) => ( + ? media.map((item) => (
) => e.preventDefault() diff --git a/src/pages/discover/hooks/useDiscoverMedia.ts b/src/pages/discover/hooks/useDiscoverMedia.ts index 5dc51dc3..fb1f0d7f 100644 --- a/src/pages/discover/hooks/useDiscoverMedia.ts +++ b/src/pages/discover/hooks/useDiscoverMedia.ts @@ -6,6 +6,7 @@ import { TraktLatestResponse, getLatest4KReleases, getLatestReleases, + paginateResults, } from "@/backend/metadata/traktApi"; import { conf } from "@/setup/config"; import { useLanguageStore } from "@/stores/language"; @@ -325,10 +326,13 @@ export function useDiscoverMedia({ }); // Race between the Trakt request and timeout - const { tmdb_ids: tmdbIds } = await Promise.race([ - traktFunction(), - timeoutPromise, - ]); + const response = await Promise.race([traktFunction(), timeoutPromise]); + + // Paginate the results + const { tmdb_ids: tmdbIds, hasMore: hasMoreResults } = paginateResults( + response, + page, + ); // Fetch details for each TMDB ID const mediaPromises = tmdbIds.map(async (tmdbId: number) => { @@ -346,14 +350,14 @@ export function useDiscoverMedia({ const results = await Promise.all(mediaPromises); return { results, - hasMore: false, // Trakt endpoints don't support pagination + hasMore: hasMoreResults, }; } catch (err) { console.error("Error fetching Trakt media:", err); throw err; } }, - [mediaType, formattedLanguage], + [mediaType, formattedLanguage, page], ); const fetchEditorPicks = useCallback(async () => {