Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed dtuff #61

Merged
merged 15 commits into from
Jun 21, 2024
16 changes: 15 additions & 1 deletion src/backend/metadata/tmdb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,28 @@
export function formatTMDBMetaToMediaItem(media: TMDBMediaResult): MediaItem {
const type = TMDBMediaToMediaItemType(media.object_type);

return {
// Define the basic structure of MediaItem
const mediaItem: MediaItem = {
title: media.title,
id: media.id.toString(),
year: media.original_release_date?.getFullYear() ?? 0,
release_date: media.original_release_date,
poster: media.poster,
type,
seasons: undefined,

Check failure on line 102 in src/backend/metadata/tmdb.ts

View workflow job for this annotation

GitHub Actions / Build project

Type 'undefined' is not assignable to type 'any[]'.
};

// If it's a TV show, include the seasons information
if (type === "show") {
const seasons = media.seasons?.map((season) => ({
title: season.title,
id: season.id.toString(),
number: season.season_number,
}));
mediaItem.seasons = seasons as MWSeasonMeta[];
}

return mediaItem;
}

export function TMDBIdToUrlId(
Expand Down
35 changes: 22 additions & 13 deletions src/components/media/ModalEpisodeSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";

import { get } from "@/backend/metadata/tmdb";
import { Flare } from "@/components/utils/Flare";
import { conf } from "@/setup/config";

interface ModalEpisodeSelectorProps {
Expand Down Expand Up @@ -57,8 +58,8 @@ export function EpisodeSelector({
}, [handleSeasonSelect, tmdbId]);

return (
<div className="flex flex-row">
<div className="sm:w-96 w-96 sm:block cursor-pointer overflow-y-scroll overflow-x-hidden max-h-60 max-w-24">
<div className="flex flex-row relative">
<div className="w-24 sm:w-96 cursor-pointer overflow-y-auto overflow-x-hidden max-h-60 z-10">
{seasonsData.map((season) => (
<div
key={season.season_number}
Expand All @@ -76,8 +77,8 @@ export function EpisodeSelector({
</div>
))}
</div>
<div className="flex-auto mt-4 cursor-pointer sm:mt-0 sm:ml-4 overflow-y-auto overflow-x-hidden max-h-60 order-1 sm:order-2">
<div className="grid grid-cols-3 gap-2">
<div className="flex-auto mt-4 sm:mt-0 sm:ml-4 cursor-pointer overflow-x-auto overflow-y-hidden sm:overflow-y-auto sm:overflow-x-hidden max-h-60 max-w-[70vw] z-0">
<div className="flex sm:grid sm:grid-cols-3 sm:gap-2">
{selectedSeason ? (
selectedSeason.episodes.map(
(episode: {
Expand All @@ -87,23 +88,31 @@ export function EpisodeSelector({
show_id: number;
id: number;
}) => (
<div
<Flare.Base
key={episode.episode_number}
onClick={() =>
navigate(
`/media/tmdb-tv-${tmdbId}-${mediaTitle}/${episode.show_id}/${episode.id}`,
)
}
className="bg-mediaCard-hoverBackground rounded p-2 hover:scale-95 transition-transform transition-border-color duration-[0.28s] ease-in-out transform-origin-center"
className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-[0.28s] flex-shrink-0 w-48 sm:w-auto mr-2 sm:mr-0"
>
<img
src={`https://image.tmdb.org/t/p/w500/${episode.still_path}`}
className="w-full h-auto rounded"
<Flare.Light
flareSize={300}
cssColorVar="--colors-mediaCard-hoverAccent"
backgroundClass="bg-mediaCard-hoverBackground duration-200"
className="rounded-xl bg-background-main group-hover:opacity-100"
/>
<p className="text-center text-[0.95em] mt-2">
{episode.name}
</p>
</div>
<div className="relative z-10">
<img
src={`https://image.tmdb.org/t/p/w500/${episode.still_path}`}
className="w-full h-auto rounded"
/>
<p className="text-center text-[0.95em] mt-2">
{episode.name}
</p>
</div>
</Flare.Base>
),
)
) : (
Expand Down
77 changes: 44 additions & 33 deletions src/components/media/PopupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,29 @@ interface PopupModalProps {
media: MediaItem;
}

interface MediaData {
backdrop_path?: string;
title?: string;
name?: string;
runtime?: number;
release_date?: string;
first_air_date?: string;
vote_average?: number;
genres?: Array<{ name: string }>;
overview?: string;
}

interface MediaInfo {
results?: Array<{
iso_3166_1: string;
rating?: string;
release_dates?: Array<{
certification: string;
release_date: string;
}>;
}>;
}

type StyleState = {
opacity: number;
visibility: "visible" | "hidden" | undefined;
Expand All @@ -46,11 +69,10 @@ export function PopupModal({
opacity: 0,
visibility: "hidden",
});
const [data, setData] = useState<any>(null);
const [mediaInfo, setMediaInfo] = useState<any>(null);
const [data, setData] = useState<MediaData | null>(null);
const [mediaInfo, setMediaInfo] = useState<MediaInfo | null>(null);
const [error, setError] = useState<string | null>(null);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [menuOpen, setMenuOpen] = useState<boolean>(false); // Added definition for menuOpen
// const [menuOpen, setMenuOpen] = useState<boolean>(false);
const navigate = useNavigate();

useEffect(() => {
Expand All @@ -62,7 +84,6 @@ export function PopupModal({
onClose();
}
}

document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
Expand All @@ -83,7 +104,7 @@ export function PopupModal({

try {
const mediaTypePath = media.type === "show" ? "tv" : media.type;
const result = await get<any>(`/${mediaTypePath}/${media.id}`, {
const result = await get<MediaData>(`/${mediaTypePath}/${media.id}`, {
api_key: conf().TMDB_READ_API_KEY,
language: "en-US",
});
Expand All @@ -107,7 +128,7 @@ export function PopupModal({
const mediaTypeForAPI = media.type === "show" ? "tv" : media.type;
const endpointSuffix =
media.type === "show" ? "content_ratings" : "release_dates";
const result = await get<any>(
const result = await get<MediaInfo>(
`/${mediaTypeForAPI}/${media.id}/${endpointSuffix}`,
{
api_key: conf().TMDB_READ_API_KEY,
Expand All @@ -126,10 +147,7 @@ export function PopupModal({
}, [media.id, media.type, isVisible]);

if (!isVisible && style.visibility === "hidden") return null;

if (error) {
return <div>Error: {error}</div>;
}
if (error) return <div>Error: {error}</div>;

const isTVShow = media.type === "show";
const usReleaseInfo = mediaInfo?.results?.find(
Expand Down Expand Up @@ -158,11 +176,7 @@ export function PopupModal({
<div
ref={modalRef}
className="rounded-xl bg-modal-background flex flex-col justify-center items-center transition-opacity duration-100 max-w-full sm:max-w-xl w-full sm:w-auto sm:h-auto overflow-y-auto p-4"
style={{
opacity: style.opacity,
maxHeight: "90vh",
height: "auto",
}}
style={{ opacity: style.opacity, maxHeight: "90vh", height: "auto" }}
>
<div className="aspect-w-16 aspect-h-9 w-full sm:w-auto">
<div className="rounded-xl">
Expand All @@ -172,9 +186,7 @@ export function PopupModal({
alt={media.poster ? "" : "failed to fetch :("}
className="rounded-xl object-cover w-full h-full"
loading="lazy"
style={{
maxHeight: "60vh",
}}
style={{ maxHeight: "60vh" }}
/>
) : (
<Skeleton />
Expand Down Expand Up @@ -239,28 +251,27 @@ export function PopupModal({
</div>
<div className="flex flex-row gap-3 pb-3 pt-2">
<div className="flex items-center space-x-[2px] font-semibold">
{Array.from({ length: 5 }, (_, index) => {
return (
<span key={index}>
{index < Math.round(Number(data?.vote_average) / 2) ? (
<Icon icon={Icons.STAR} />
) : (
<Icon icon={Icons.STAR_BORDER} />
)}
</span>
);
})}
{Array.from({ length: 5 }, (_, index) => (
<span key={index}>
{index < Math.round(Number(data?.vote_average) / 2) ? (
<Icon icon={Icons.STAR} />
) : (
<Icon icon={Icons.STAR_BORDER} />
)}
</span>
))}
</div>
{data?.genres?.length > 0
{data?.genres && data.genres.length > 0
? data.genres.map((genre: { name: string }) => (
<div key={genre.name} className="inline-block">
<div className="px-2 py-1 bg-mediaCard-hoverBackground rounded hover:bg-search-background cursor-default duration-200 transition-colors transform hover:scale-110">
{genre.name}
</div>
</div>
))
: Array.from({ length: 3 }).map((_) => (
<div className="inline-block">
: Array.from({ length: 3 }).map((_, idx) => (
// eslint-disable-next-line react/no-array-index-key
<div className="inline-block" key={idx}>
<Skeleton />
</div>
))}
Expand Down
2 changes: 0 additions & 2 deletions src/components/player/atoms/Episodes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ function EpisodesView({
const newData = setPlayerMeta(loadingState.value.fullData, episodeId);
if (newData) onChange?.(newData);
}
// prevent router clear here, otherwise its done double
// player already switches route after meta change
router.close(true);
},
[setPlayerMeta, loadingState, router, onChange],
Expand Down
1 change: 1 addition & 0 deletions src/setup/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ function App() {
</LegacyUrlView>
}
/>

<Route path="/browse/:query?" element={<HomePage />} />
<Route path="/" element={<HomePage />} />
<Route path="/register" element={<RegisterPage />} />
Expand Down
1 change: 1 addition & 0 deletions src/utils/mediaTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface MediaItem {
seasons: import("c:/Users/huzei/OneDrive/Desktop/Sudo-Flix/src/backend/metadata/types/mw").MWSeasonMeta[];
id: string;
title: string;
year?: number;
Expand Down
Loading