add that skids improvments for discover page

This commit is contained in:
sussy-code 2024-05-28 20:08:16 +00:00
parent 495c52ed76
commit 525b30012d
2 changed files with 5332 additions and 4347 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
// Based mfs only use only one 500 line file instead of ten 50 line files. // Based mfs only use only one 500 line file instead of ten 50 line files.
import React, { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { Helmet } from "react-helmet-async"; import { Helmet } from "react-helmet-async";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
@ -21,7 +21,6 @@ import {
import { SubPageLayout } from "./layouts/SubPageLayout"; import { SubPageLayout } from "./layouts/SubPageLayout";
import { PageTitle } from "./parts/util/PageTitle"; import { PageTitle } from "./parts/util/PageTitle";
import placeholderImageLogo from "../../public/placeholder.png";
import { Icon, Icons } from "../components/Icon"; import { Icon, Icons } from "../components/Icon";
export function Discover() { export function Discover() {
@ -167,6 +166,66 @@ export function Discover() {
tvGenres.forEach((genre) => fetchTVShowsForGenre(genre.id)); tvGenres.forEach((genre) => fetchTVShowsForGenre(genre.id));
}, [tvGenres]); }, [tvGenres]);
// Fetch Movie genres
useEffect(() => {
const fetchGenres = async () => {
try {
const data = await get<any>("/genre/movie/list", {
api_key: conf().TMDB_READ_API_KEY,
language: "en-US",
});
// Shuffle the array of genres
for (let i = data.genres.length - 1; i > 0; i -= 1) {
const j = Math.floor(Math.random() * (i + 1));
[data.genres[i], data.genres[j]] = [data.genres[j], data.genres[i]];
}
// Fetch only the first 4 genres
setGenres(data.genres.slice(0, 4));
} catch (error) {
console.error("Error fetching genres:", error);
}
};
fetchGenres();
}, []);
// Fetch movies for each genre
useEffect(() => {
const fetchMoviesForGenre = async (genreId: number) => {
try {
const movies: any[] = [];
for (let page = 1; page <= 6; page += 1) {
// Fetch only 6 pages
const data = await get<any>("/discover/movie", {
api_key: conf().TMDB_READ_API_KEY,
with_genres: genreId.toString(),
language: "en-US",
page: page.toString(),
});
movies.push(...data.results);
}
// Shuffle the movies
for (let i = movies.length - 1; i > 0; i -= 1) {
const j = Math.floor(Math.random() * (i + 1));
[movies[i], movies[j]] = [movies[j], movies[i]];
}
setGenreMovies((prevGenreMovies) => ({
...prevGenreMovies,
[genreId]: movies,
}));
} catch (error) {
console.error(`Error fetching movies for genre ${genreId}:`, error);
}
};
genres.forEach((genre) => fetchMoviesForGenre(genre.id));
}, [genres]);
// Update the scrollCarousel function to use the new ref map // Update the scrollCarousel function to use the new ref map
function scrollCarousel(categorySlug: string, direction: string) { function scrollCarousel(categorySlug: string, direction: string) {
const carousel = carouselRefs.current[categorySlug]; const carousel = carouselRefs.current[categorySlug];
@ -176,6 +235,7 @@ export function Discover() {
const movieWidth = movieElements[0].offsetWidth; const movieWidth = movieElements[0].offsetWidth;
const visibleMovies = Math.floor(carousel.offsetWidth / movieWidth); const visibleMovies = Math.floor(carousel.offsetWidth / movieWidth);
const scrollAmount = movieWidth * visibleMovies * 0.69; // Silly number :3 const scrollAmount = movieWidth * visibleMovies * 0.69; // Silly number :3
if (direction === "left") { if (direction === "left") {
if (carousel.scrollLeft <= 5) { if (carousel.scrollLeft <= 5) {
carousel.scrollBy({ carousel.scrollBy({
@ -254,23 +314,21 @@ export function Discover() {
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
useEffect(() => {
if (!isHovered) {
document.body.style.overflow = "auto";
}
}, [isHovered]);
const handleMouseEnter = () => { const handleMouseEnter = () => {
document.body.style.overflow = "hidden"; document.body.style.overflow = "hidden";
setIsHovered(true); setIsHovered(true);
}; };
const handleMouseLeave = () => { const handleMouseLeave = () => {
document.body.style.overflow = "auto";
setIsHovered(false); setIsHovered(false);
}; };
useEffect(() => {
window.addEventListener("mouseleave", handleMouseLeave);
return () => {
window.removeEventListener("mouseleave", handleMouseLeave);
};
}, []);
function renderMovies(medias: Media[], category: string, isTVShow = false) { function renderMovies(medias: Media[], category: string, isTVShow = false) {
const categorySlug = `${category.toLowerCase().replace(/ /g, "-")}${Math.random()}`; // Convert the category to a slug const categorySlug = `${category.toLowerCase().replace(/ /g, "-")}${Math.random()}`; // Convert the category to a slug
const displayCategory = const displayCategory =
@ -281,6 +339,7 @@ export function Discover() {
: isTVShow : isTVShow
? `${category} Shows` ? `${category} Shows`
: `${category} Movies`; : `${category} Movies`;
// https://tailwindcss.com/docs/border-style // https://tailwindcss.com/docs/border-style
return ( return (
<div className="relative overflow-hidden mt-2"> <div className="relative overflow-hidden mt-2">
@ -302,48 +361,58 @@ export function Discover() {
onMouseLeave={handleMouseLeave} onMouseLeave={handleMouseLeave}
onWheel={(e) => handleWheel(e, categorySlug)} onWheel={(e) => handleWheel(e, categorySlug)}
> >
{medias.slice(0, 20).map((media) => ( {medias
<a .filter((media, index, self) => {
key={media.id} return (
onClick={() => index ===
navigate( self.findIndex(
`/media/tmdb-${isTVShow ? "tv" : "movie"}-${media.id}-${ (m) => m.id === media.id && m.title === media.title,
isTVShow ? media.name : media.title
}`,
) )
} );
className="text-center relative mt-3 mx-[0.285em] mb-3 transition-transform hover:scale-105 duration-[0.45s]" })
style={{ flex: `0 0 ${movieWidth}` }} // Set a fixed width for each movie .slice(0, 20)
> .map((media) => (
<Flare.Base className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-300 bg-transparent"> <a
<Flare.Light key={media.id}
flareSize={300} onClick={() =>
cssColorVar="--colors-mediaCard-hoverAccent" navigate(
backgroundClass="bg-mediaCard-hoverBackground duration-200" `/media/tmdb-${isTVShow ? "tv" : "movie"}-${media.id}-${
className="rounded-xl bg-background-main group-hover:opacity-100" isTVShow ? media.name : media.title
/> }`,
<img )
src={ }
media.poster_path className="text-center relative mt-3 mx-[0.285em] mb-3 transition-transform hover:scale-105 duration-[0.45s]"
? `https://image.tmdb.org/t/p/w500${media.poster_path}` style={{ flex: `0 0 ${movieWidth}` }} // Set a fixed width for each movie
: placeholderImageLogo >
} <Flare.Base className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-300 bg-transparent">
alt={media.poster_path ? "" : "failed to fetch :("} <Flare.Light
loading="lazy" flareSize={300}
className="rounded-xl relative" cssColorVar="--colors-mediaCard-hoverAccent"
/> backgroundClass="bg-mediaCard-hoverBackground duration-200"
<h1 className="group relative pt-2 text-[13.5px] whitespace-normal duration-[0.35s] font-semibold text-white opacity-0 group-hover:opacity-100"> className="rounded-xl bg-background-main group-hover:opacity-100"
{isTVShow />
? (media.name?.length ?? 0) > 32 <img
? `${media.name?.slice(0, 32)}...` src={
: media.name media.poster_path
: (media.title?.length ?? 0) > 32 ? `https://image.tmdb.org/t/p/w500${media.poster_path}`
? `${media.title?.slice(0, 32)}...` : "/placeholder.png"
: media.title} }
</h1> alt={media.poster_path ? "" : "failed to fetch :("}
</Flare.Base> loading="lazy"
</a> className="rounded-xl relative"
))} />
<h1 className="group relative pt-2 text-[13.5px] whitespace-normal duration-[0.35s] font-semibold text-white opacity-0 group-hover:opacity-100">
{isTVShow
? (media.name?.length ?? 0) > 32
? `${media.name?.slice(0, 32)}...`
: media.name
: (media.title?.length ?? 0) > 32
? `${media.title?.slice(0, 32)}...`
: media.title}
</h1>
</Flare.Base>
</a>
))}
</div> </div>
<div className="flex items-center justify-center"> <div className="flex items-center justify-center">
@ -407,66 +476,6 @@ export function Discover() {
} }
}; };
// Fetch Movie genres
useEffect(() => {
const fetchGenres = async () => {
try {
const data = await get<any>("/genre/movie/list", {
api_key: conf().TMDB_READ_API_KEY,
language: "en-US",
});
// Shuffle the array of genres
for (let i = data.genres.length - 1; i > 0; i -= 1) {
const j = Math.floor(Math.random() * (i + 1));
[data.genres[i], data.genres[j]] = [data.genres[j], data.genres[i]];
}
// Fetch only the first 4 genres
setGenres(data.genres.slice(0, 4));
} catch (error) {
console.error("Error fetching genres:", error);
}
};
fetchGenres();
}, []);
// Fetch movies for each genre
useEffect(() => {
const fetchMoviesForGenre = async (genreId: number) => {
try {
const movies: any[] = [];
for (let page = 1; page <= 6; page += 1) {
// Fetch only 6 pages
const data = await get<any>("/discover/movie", {
api_key: conf().TMDB_READ_API_KEY,
with_genres: genreId.toString(),
language: "en-US",
page: page.toString(),
});
movies.push(...data.results);
}
// Shuffle the movies
for (let i = movies.length - 1; i > 0; i -= 1) {
const j = Math.floor(Math.random() * (i + 1));
[movies[i], movies[j]] = [movies[j], movies[i]];
}
setGenreMovies((prevGenreMovies) => ({
...prevGenreMovies,
[genreId]: movies,
}));
} catch (error) {
console.error(`Error fetching movies for genre ${genreId}:`, error);
}
};
genres.forEach((genre) => fetchMoviesForGenre(genre.id));
}, [genres]);
useEffect(() => { useEffect(() => {
let countdownInterval: NodeJS.Timeout; let countdownInterval: NodeJS.Timeout;
if (countdown !== null && countdown > 0) { if (countdown !== null && countdown > 0) {
@ -554,7 +563,7 @@ export function Discover() {
))} ))}
{genres.map((genre) => ( {genres.map((genre) => (
<div <div
key={genre.id} key={`${genre.id}|${genre.name}`}
id={`carousel-${genre.name.toLowerCase().replace(/ /g, "-")}`} id={`carousel-${genre.name.toLowerCase().replace(/ /g, "-")}`}
className="mt-8" className="mt-8"
> >
@ -581,7 +590,7 @@ export function Discover() {
))} ))}
{tvGenres.map((genre) => ( {tvGenres.map((genre) => (
<div <div
key={genre.id} key={`${genre.id}|${genre.name}`}
id={`carousel-${genre.name.toLowerCase().replace(/ /g, "-")}`} id={`carousel-${genre.name.toLowerCase().replace(/ /g, "-")}`}
className="mt-8" className="mt-8"
> >