mirror of
https://github.com/p-stream/p-stream.git
synced 2026-03-31 01:58:44 +00:00
clean up details modal
This commit is contained in:
parent
743f5ffabc
commit
ede3613112
6 changed files with 23 additions and 1177 deletions
|
|
@ -212,7 +212,8 @@
|
|||
"season": "Season",
|
||||
"episode": "Episode",
|
||||
"airs": "Airs",
|
||||
"endsAt": "Ends at {{time}}"
|
||||
"endsAt": "Ends at {{time}}",
|
||||
"trailer": "Trailer"
|
||||
},
|
||||
"migration": {
|
||||
"loginRequired": "You must be logged in to migrate your data! Please go back and login to continue.",
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import { IconPatch } from "@/components/buttons/IconPatch";
|
|||
import { Icon, Icons } from "@/components/Icon";
|
||||
import { MediaBookmarkButton } from "@/components/media/MediaBookmark";
|
||||
|
||||
import { DetailsHeaderProps } from "./types";
|
||||
import { DetailsBodyProps } from "./types";
|
||||
|
||||
export function DetailsHeader({
|
||||
export function DetailsBody({
|
||||
data,
|
||||
onPlayClick,
|
||||
onTrailerClick,
|
||||
|
|
@ -24,7 +24,7 @@ export function DetailsHeader({
|
|||
releaseDate,
|
||||
seasons,
|
||||
imdbData,
|
||||
}: DetailsHeaderProps) {
|
||||
}: DetailsBodyProps) {
|
||||
const [releaseInfo, setReleaseInfo] = useState<TraktReleaseResponse | null>(
|
||||
null,
|
||||
);
|
||||
|
|
@ -44,7 +44,7 @@ export function DetailsHeader({
|
|||
}, [data.id]);
|
||||
|
||||
const getQualityIndicator = () => {
|
||||
if (!releaseInfo) return null;
|
||||
if (!releaseInfo || data.type === "show") return null;
|
||||
|
||||
const hasDigitalRelease = !!releaseInfo.digital_release_date;
|
||||
const hasTheatricalRelease = !!releaseInfo.theatrical_release_date;
|
||||
|
|
@ -176,17 +176,19 @@ export function DetailsHeader({
|
|||
</span>
|
||||
</Button>
|
||||
<div className="flex items-center gap-1 flex-shrink-0">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onTrailerClick}
|
||||
className="p-2 opacity-75 transition-opacity duration-300 hover:scale-110 hover:cursor-pointer hover:opacity-95"
|
||||
title={t("details.trailer")}
|
||||
>
|
||||
<IconPatch
|
||||
icon={Icons.FILM}
|
||||
className="transition-transform duration-300 hover:scale-110 hover:cursor-pointer"
|
||||
/>
|
||||
</button>
|
||||
{imdbData?.trailer_url && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onTrailerClick}
|
||||
className="p-2 opacity-75 transition-opacity duration-300 hover:scale-110 hover:cursor-pointer hover:opacity-95"
|
||||
title={t("details.trailer")}
|
||||
>
|
||||
<IconPatch
|
||||
icon={Icons.FILM}
|
||||
className="transition-transform duration-300 hover:scale-110 hover:cursor-pointer"
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
<MediaBookmarkButton
|
||||
media={{
|
||||
id: data.id?.toString() || "",
|
||||
|
|
@ -12,7 +12,7 @@ import { scrapeIMDb } from "@/utils/imdbScraper";
|
|||
import { getTmdbLanguageCode } from "@/utils/language";
|
||||
import { scrapeRottenTomatoes } from "@/utils/rottenTomatoesScraper";
|
||||
|
||||
import { DetailsHeader } from "./DetailsHeader";
|
||||
import { DetailsBody } from "./DetailsBody";
|
||||
import { DetailsInfo } from "./DetailsInfo";
|
||||
import { EpisodeCarousel } from "./EpisodeCarousel";
|
||||
import { CastCarousel } from "./PeopleCarousel";
|
||||
|
|
@ -205,7 +205,7 @@ export function DetailsContent({ data, minimal = false }: DetailsContentProps) {
|
|||
|
||||
{/* Content */}
|
||||
<div className="px-6 pb-6 mt-[-70px] flex-grow relative z-30">
|
||||
<DetailsHeader
|
||||
<DetailsBody
|
||||
data={data}
|
||||
onPlayClick={handlePlayClick}
|
||||
onTrailerClick={() => setShowTrailer(true)}
|
||||
|
|
|
|||
|
|
@ -6,29 +6,11 @@ import { getRTIcon } from "@/utils/rottenTomatoesScraper";
|
|||
import { DetailsRatingsProps } from "./types";
|
||||
|
||||
export function DetailsRatings({
|
||||
voteAverage,
|
||||
voteCount,
|
||||
imdbData,
|
||||
rtData,
|
||||
mediaId,
|
||||
mediaType,
|
||||
imdbId,
|
||||
}: DetailsRatingsProps) {
|
||||
const formatVoteCount = (count?: number) => {
|
||||
if (!count) return "0";
|
||||
if (count >= 1000) {
|
||||
return `${Math.floor(count / 1000)}K+`;
|
||||
}
|
||||
return count.toString();
|
||||
};
|
||||
|
||||
const getRatingColor = (rating: number) => {
|
||||
if (rating >= 8) return "bg-green-500";
|
||||
if (rating >= 6) return "bg-yellow-500";
|
||||
if (rating >= 4) return "bg-orange-500";
|
||||
return "bg-red-500";
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
{/* External Links */}
|
||||
|
|
@ -90,27 +72,6 @@ export function DetailsRatings({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="pt-4">
|
||||
{voteAverage !== undefined &&
|
||||
voteCount !== undefined &&
|
||||
voteCount > 0 && (
|
||||
<>
|
||||
{/* Rating Progress Bar */}
|
||||
<div className="w-full h-2 bg-white/10 rounded-full overflow-hidden">
|
||||
<div
|
||||
className={`h-full ${getRatingColor(imdbData?.imdb_rating || voteAverage)} transition-all duration-500`}
|
||||
style={{
|
||||
width: `${((imdbData?.imdb_rating || voteAverage) / 10) * 100}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-white/60 text-[10px] text-right">
|
||||
{formatVoteCount(imdbData?.votes || voteCount)}{" "}
|
||||
{t("details.votes")}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -99,7 +99,7 @@ export interface EpisodeCarouselProps {
|
|||
mediaTitle?: string;
|
||||
}
|
||||
|
||||
export interface DetailsHeaderProps {
|
||||
export interface DetailsBodyProps {
|
||||
data: DetailsContent;
|
||||
onPlayClick: () => void;
|
||||
onTrailerClick: () => void;
|
||||
|
|
@ -112,6 +112,7 @@ export interface DetailsHeaderProps {
|
|||
imdbData?: {
|
||||
rating: number;
|
||||
votes: number;
|
||||
trailer_url?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue