mirror of https://github.com/sussy-code/smov.git
add that skids improvments for discover page
This commit is contained in:
parent
495c52ed76
commit
525b30012d
9444
pnpm-lock.yaml
9444
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
// 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 { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
@ -21,7 +21,6 @@ import {
|
|||
|
||||
import { SubPageLayout } from "./layouts/SubPageLayout";
|
||||
import { PageTitle } from "./parts/util/PageTitle";
|
||||
import placeholderImageLogo from "../../public/placeholder.png";
|
||||
import { Icon, Icons } from "../components/Icon";
|
||||
|
||||
export function Discover() {
|
||||
|
@ -167,6 +166,66 @@ export function Discover() {
|
|||
tvGenres.forEach((genre) => fetchTVShowsForGenre(genre.id));
|
||||
}, [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
|
||||
function scrollCarousel(categorySlug: string, direction: string) {
|
||||
const carousel = carouselRefs.current[categorySlug];
|
||||
|
@ -176,6 +235,7 @@ export function Discover() {
|
|||
const movieWidth = movieElements[0].offsetWidth;
|
||||
const visibleMovies = Math.floor(carousel.offsetWidth / movieWidth);
|
||||
const scrollAmount = movieWidth * visibleMovies * 0.69; // Silly number :3
|
||||
|
||||
if (direction === "left") {
|
||||
if (carousel.scrollLeft <= 5) {
|
||||
carousel.scrollBy({
|
||||
|
@ -254,23 +314,21 @@ export function Discover() {
|
|||
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isHovered) {
|
||||
document.body.style.overflow = "auto";
|
||||
}
|
||||
}, [isHovered]);
|
||||
|
||||
const handleMouseEnter = () => {
|
||||
document.body.style.overflow = "hidden";
|
||||
setIsHovered(true);
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
document.body.style.overflow = "auto";
|
||||
setIsHovered(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("mouseleave", handleMouseLeave);
|
||||
return () => {
|
||||
window.removeEventListener("mouseleave", handleMouseLeave);
|
||||
};
|
||||
}, []);
|
||||
|
||||
function renderMovies(medias: Media[], category: string, isTVShow = false) {
|
||||
const categorySlug = `${category.toLowerCase().replace(/ /g, "-")}${Math.random()}`; // Convert the category to a slug
|
||||
const displayCategory =
|
||||
|
@ -281,6 +339,7 @@ export function Discover() {
|
|||
: isTVShow
|
||||
? `${category} Shows`
|
||||
: `${category} Movies`;
|
||||
|
||||
// https://tailwindcss.com/docs/border-style
|
||||
return (
|
||||
<div className="relative overflow-hidden mt-2">
|
||||
|
@ -302,48 +361,58 @@ export function Discover() {
|
|||
onMouseLeave={handleMouseLeave}
|
||||
onWheel={(e) => handleWheel(e, categorySlug)}
|
||||
>
|
||||
{medias.slice(0, 20).map((media) => (
|
||||
<a
|
||||
key={media.id}
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`/media/tmdb-${isTVShow ? "tv" : "movie"}-${media.id}-${
|
||||
isTVShow ? media.name : media.title
|
||||
}`,
|
||||
{medias
|
||||
.filter((media, index, self) => {
|
||||
return (
|
||||
index ===
|
||||
self.findIndex(
|
||||
(m) => m.id === media.id && m.title === 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
|
||||
>
|
||||
<Flare.Base className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-300 bg-transparent">
|
||||
<Flare.Light
|
||||
flareSize={300}
|
||||
cssColorVar="--colors-mediaCard-hoverAccent"
|
||||
backgroundClass="bg-mediaCard-hoverBackground duration-200"
|
||||
className="rounded-xl bg-background-main group-hover:opacity-100"
|
||||
/>
|
||||
<img
|
||||
src={
|
||||
media.poster_path
|
||||
? `https://image.tmdb.org/t/p/w500${media.poster_path}`
|
||||
: placeholderImageLogo
|
||||
}
|
||||
alt={media.poster_path ? "" : "failed to fetch :("}
|
||||
loading="lazy"
|
||||
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>
|
||||
))}
|
||||
);
|
||||
})
|
||||
.slice(0, 20)
|
||||
.map((media) => (
|
||||
<a
|
||||
key={media.id}
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`/media/tmdb-${isTVShow ? "tv" : "movie"}-${media.id}-${
|
||||
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
|
||||
>
|
||||
<Flare.Base className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-300 bg-transparent">
|
||||
<Flare.Light
|
||||
flareSize={300}
|
||||
cssColorVar="--colors-mediaCard-hoverAccent"
|
||||
backgroundClass="bg-mediaCard-hoverBackground duration-200"
|
||||
className="rounded-xl bg-background-main group-hover:opacity-100"
|
||||
/>
|
||||
<img
|
||||
src={
|
||||
media.poster_path
|
||||
? `https://image.tmdb.org/t/p/w500${media.poster_path}`
|
||||
: "/placeholder.png"
|
||||
}
|
||||
alt={media.poster_path ? "" : "failed to fetch :("}
|
||||
loading="lazy"
|
||||
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 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(() => {
|
||||
let countdownInterval: NodeJS.Timeout;
|
||||
if (countdown !== null && countdown > 0) {
|
||||
|
@ -554,7 +563,7 @@ export function Discover() {
|
|||
))}
|
||||
{genres.map((genre) => (
|
||||
<div
|
||||
key={genre.id}
|
||||
key={`${genre.id}|${genre.name}`}
|
||||
id={`carousel-${genre.name.toLowerCase().replace(/ /g, "-")}`}
|
||||
className="mt-8"
|
||||
>
|
||||
|
@ -581,7 +590,7 @@ export function Discover() {
|
|||
))}
|
||||
{tvGenres.map((genre) => (
|
||||
<div
|
||||
key={genre.id}
|
||||
key={`${genre.id}|${genre.name}`}
|
||||
id={`carousel-${genre.name.toLowerCase().replace(/ /g, "-")}`}
|
||||
className="mt-8"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue