mirror of
https://github.com/p-stream/p-stream.git
synced 2026-04-21 03:32:31 +00:00
use trakt lists for some genres and providers
This commit is contained in:
parent
33d6daba25
commit
6adfe7ede2
3 changed files with 159 additions and 23 deletions
|
|
@ -110,7 +110,7 @@ export const PROVIDER_TO_TRAKT_MAP = {
|
||||||
"10": "prime", // Prime Video
|
"10": "prime", // Prime Video
|
||||||
"15": "hulu", // Hulu
|
"15": "hulu", // Hulu
|
||||||
"337": "disney", // Disney+
|
"337": "disney", // Disney+
|
||||||
"384": "hbo", // HBO Max/Max
|
"1899": "hbo", // Max
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// Map genres to their Trakt endpoints
|
// Map genres to their Trakt endpoints
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ export function MoreContent({ onShowDetails }: MoreContentProps) {
|
||||||
<div className="animate-pulse">
|
<div className="animate-pulse">
|
||||||
<div className="h-8 bg-mediaCard-hoverBackground rounded w-1/4 mb-8" />
|
<div className="h-8 bg-mediaCard-hoverBackground rounded w-1/4 mb-8" />
|
||||||
<MediaGrid>
|
<MediaGrid>
|
||||||
{Array.from({ length: 20 }).map((_, i) => (
|
{Array.from({ length: 20 }).map((_, _i) => (
|
||||||
<div
|
<div
|
||||||
key={`loading-skeleton-${Math.random().toString(36).substring(7)}`}
|
key={`loading-skeleton-${Math.random().toString(36).substring(7)}`}
|
||||||
className="relative group cursor-default user-select-none rounded-xl p-2 bg-transparent"
|
className="relative group cursor-default user-select-none rounded-xl p-2 bg-transparent"
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,20 @@ import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { get } from "@/backend/metadata/tmdb";
|
import { get } from "@/backend/metadata/tmdb";
|
||||||
import {
|
import {
|
||||||
|
GENRE_TO_TRAKT_MAP,
|
||||||
|
PROVIDER_TO_TRAKT_MAP,
|
||||||
TraktLatestResponse,
|
TraktLatestResponse,
|
||||||
|
getActionReleases,
|
||||||
|
getAppleTVReleases,
|
||||||
|
getDisneyReleases,
|
||||||
|
getDramaReleases,
|
||||||
|
getHBOReleases,
|
||||||
|
getHuluReleases,
|
||||||
getLatest4KReleases,
|
getLatest4KReleases,
|
||||||
getLatestReleases,
|
getLatestReleases,
|
||||||
|
getNetflixMovies,
|
||||||
|
getNetflixTVShows,
|
||||||
|
getPrimeReleases,
|
||||||
paginateResults,
|
paginateResults,
|
||||||
} from "@/backend/metadata/traktApi";
|
} from "@/backend/metadata/traktApi";
|
||||||
import { conf } from "@/setup/config";
|
import { conf } from "@/setup/config";
|
||||||
|
|
@ -360,6 +371,56 @@ export function useDiscoverMedia({
|
||||||
[mediaType, formattedLanguage, page],
|
[mediaType, formattedLanguage, page],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Get Trakt function for provider
|
||||||
|
const getTraktProviderFunction = useCallback(
|
||||||
|
(providerId: string) => {
|
||||||
|
const trakt =
|
||||||
|
PROVIDER_TO_TRAKT_MAP[providerId as keyof typeof PROVIDER_TO_TRAKT_MAP];
|
||||||
|
if (!trakt) return null;
|
||||||
|
|
||||||
|
// Handle TV vs Movies for Netflix
|
||||||
|
if (trakt === "netflix" && mediaType === "tv") {
|
||||||
|
return getNetflixTVShows;
|
||||||
|
}
|
||||||
|
if (trakt === "netflix" && mediaType === "movie") {
|
||||||
|
return getNetflixMovies;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map provider to corresponding Trakt function
|
||||||
|
switch (trakt) {
|
||||||
|
case "appletv":
|
||||||
|
return getAppleTVReleases;
|
||||||
|
case "prime":
|
||||||
|
return getPrimeReleases;
|
||||||
|
case "hulu":
|
||||||
|
return getHuluReleases;
|
||||||
|
case "disney":
|
||||||
|
return getDisneyReleases;
|
||||||
|
case "hbo":
|
||||||
|
return getHBOReleases;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[mediaType],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get Trakt function for genre
|
||||||
|
const getTraktGenreFunction = useCallback((genreId: string) => {
|
||||||
|
const trakt =
|
||||||
|
GENRE_TO_TRAKT_MAP[genreId as keyof typeof GENRE_TO_TRAKT_MAP];
|
||||||
|
if (!trakt) return null;
|
||||||
|
|
||||||
|
switch (trakt) {
|
||||||
|
case "action":
|
||||||
|
return getActionReleases;
|
||||||
|
case "drama":
|
||||||
|
return getDramaReleases;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const fetchEditorPicks = useCallback(async () => {
|
const fetchEditorPicks = useCallback(async () => {
|
||||||
const picks =
|
const picks =
|
||||||
mediaType === "movie" ? EDITOR_PICKS_MOVIES : EDITOR_PICKS_TV_SHOWS;
|
mediaType === "movie" ? EDITOR_PICKS_MOVIES : EDITOR_PICKS_TV_SHOWS;
|
||||||
|
|
@ -395,6 +456,8 @@ export function useDiscoverMedia({
|
||||||
|
|
||||||
const attemptFetch = async (type: DiscoverContentType) => {
|
const attemptFetch = async (type: DiscoverContentType) => {
|
||||||
let data;
|
let data;
|
||||||
|
let traktGenreFunction;
|
||||||
|
let traktProviderFunction;
|
||||||
|
|
||||||
// Map content types to their endpoints and handling logic
|
// Map content types to their endpoints and handling logic
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
@ -438,31 +501,102 @@ export function useDiscoverMedia({
|
||||||
|
|
||||||
case "genre":
|
case "genre":
|
||||||
if (!id) throw new Error("Genre ID is required");
|
if (!id) throw new Error("Genre ID is required");
|
||||||
data = await fetchTMDBMedia(`/discover/${mediaType}`, {
|
|
||||||
with_genres: id,
|
// Try to use Trakt genre endpoint if available
|
||||||
});
|
traktGenreFunction = getTraktGenreFunction(id);
|
||||||
setSectionTitle(
|
if (traktGenreFunction) {
|
||||||
mediaType === "movie"
|
try {
|
||||||
? t("discover.carousel.title.movies", { category: genreName })
|
data = await fetchTraktMedia(traktGenreFunction);
|
||||||
: t("discover.carousel.title.tvshows", { category: genreName }),
|
setSectionTitle(
|
||||||
);
|
mediaType === "movie"
|
||||||
|
? t("discover.carousel.title.movies", { category: genreName })
|
||||||
|
: t("discover.carousel.title.tvshows", {
|
||||||
|
category: genreName,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} catch (traktErr) {
|
||||||
|
console.error(
|
||||||
|
"Trakt genre fetch failed, falling back to TMDB:",
|
||||||
|
traktErr,
|
||||||
|
);
|
||||||
|
// Fall back to TMDB
|
||||||
|
data = await fetchTMDBMedia(`/discover/${mediaType}`, {
|
||||||
|
with_genres: id,
|
||||||
|
});
|
||||||
|
setSectionTitle(
|
||||||
|
mediaType === "movie"
|
||||||
|
? t("discover.carousel.title.movies", { category: genreName })
|
||||||
|
: t("discover.carousel.title.tvshows", {
|
||||||
|
category: genreName,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use TMDB if no Trakt endpoint exists for this genre
|
||||||
|
data = await fetchTMDBMedia(`/discover/${mediaType}`, {
|
||||||
|
with_genres: id,
|
||||||
|
});
|
||||||
|
setSectionTitle(
|
||||||
|
mediaType === "movie"
|
||||||
|
? t("discover.carousel.title.movies", { category: genreName })
|
||||||
|
: t("discover.carousel.title.tvshows", { category: genreName }),
|
||||||
|
);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "provider":
|
case "provider":
|
||||||
if (!id) throw new Error("Provider ID is required");
|
if (!id) throw new Error("Provider ID is required");
|
||||||
data = await fetchTMDBMedia(`/discover/${mediaType}`, {
|
|
||||||
with_watch_providers: id,
|
// Try to use Trakt provider endpoint if available
|
||||||
watch_region: "US",
|
traktProviderFunction = getTraktProviderFunction(id);
|
||||||
});
|
if (traktProviderFunction) {
|
||||||
setSectionTitle(
|
try {
|
||||||
mediaType === "movie"
|
data = await fetchTraktMedia(traktProviderFunction);
|
||||||
? t("discover.carousel.title.moviesOn", {
|
setSectionTitle(
|
||||||
provider: providerName,
|
mediaType === "movie"
|
||||||
})
|
? t("discover.carousel.title.moviesOn", {
|
||||||
: t("discover.carousel.title.tvshowsOn", {
|
provider: providerName,
|
||||||
provider: providerName,
|
})
|
||||||
}),
|
: t("discover.carousel.title.tvshowsOn", {
|
||||||
);
|
provider: providerName,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} catch (traktErr) {
|
||||||
|
console.error(
|
||||||
|
"Trakt provider fetch failed, falling back to TMDB:",
|
||||||
|
traktErr,
|
||||||
|
);
|
||||||
|
// Fall back to TMDB
|
||||||
|
data = await fetchTMDBMedia(`/discover/${mediaType}`, {
|
||||||
|
with_watch_providers: id,
|
||||||
|
watch_region: "US",
|
||||||
|
});
|
||||||
|
setSectionTitle(
|
||||||
|
mediaType === "movie"
|
||||||
|
? t("discover.carousel.title.moviesOn", {
|
||||||
|
provider: providerName,
|
||||||
|
})
|
||||||
|
: t("discover.carousel.title.tvshowsOn", {
|
||||||
|
provider: providerName,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use TMDB if no Trakt endpoint exists for this provider
|
||||||
|
data = await fetchTMDBMedia(`/discover/${mediaType}`, {
|
||||||
|
with_watch_providers: id,
|
||||||
|
watch_region: "US",
|
||||||
|
});
|
||||||
|
setSectionTitle(
|
||||||
|
mediaType === "movie"
|
||||||
|
? t("discover.carousel.title.moviesOn", {
|
||||||
|
provider: providerName,
|
||||||
|
})
|
||||||
|
: t("discover.carousel.title.tvshowsOn", {
|
||||||
|
provider: providerName,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "recommendations":
|
case "recommendations":
|
||||||
|
|
@ -534,6 +668,8 @@ export function useDiscoverMedia({
|
||||||
fetchEditorPicks,
|
fetchEditorPicks,
|
||||||
t,
|
t,
|
||||||
page,
|
page,
|
||||||
|
getTraktGenreFunction,
|
||||||
|
getTraktProviderFunction,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue