diff --git a/README.md b/README.md index 548d224c..f2826a8b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Type the following commands into your terminal / command line to run Sudo-Flix locally ```bash git clone https://github.com/sussy-code/smov.git -cd sudo-flix +cd smov git pull pnpm install pnpm run dev @@ -40,7 +40,7 @@ Then you can visit the local instance [here](http://localhost:5173) or, at local To update a sudo-flix instance you can type the below commands into a terminal at the root of your project. ```bash git remote add upstream https://github.com/sussy-code/smov.git -git fetch sudo-flix # Grab the contents of the new remote source +git fetch upstream # Grab the contents of the new remote source git checkout # Most likely this would be `origin/main` git merge upstream/main # * Fix any conflicts present during merge * diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9baf93de..e34d9b8a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,7 +32,7 @@ dependencies: version: 1.0.3 '@movie-web/providers': specifier: github:sussy-code/providers - version: github.com/sussy-code/providers/30511f11e8bc3f8b26be356d0db59acc100cf92e + version: github.com/sussy-code/providers/ead928c5d09cad1c23aeab58687d3fae7f426dba '@noble/hashes': specifier: ^1.4.0 version: 1.4.0 @@ -286,7 +286,7 @@ devDependencies: version: 0.5.14(prettier@3.2.5) rollup-plugin-visualizer: specifier: ^5.12.0 - version: 5.12.0(@rollup/wasm-node@4.17.0) + version: 5.12.0(@rollup/wasm-node@4.17.1) tailwind-scrollbar: specifier: ^3.1.0 version: 3.1.0(tailwindcss@3.4.3) @@ -2060,7 +2060,7 @@ packages: engines: {node: '>=14.0.0'} dev: false - /@rollup/plugin-babel@5.3.1(@babel/core@7.24.4)(@rollup/wasm-node@4.17.0): + /@rollup/plugin-babel@5.3.1(@babel/core@7.24.4)(@rollup/wasm-node@4.17.1): resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} peerDependencies: @@ -2073,11 +2073,11 @@ packages: dependencies: '@babel/core': 7.24.4 '@babel/helper-module-imports': 7.24.3 - '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.17.0) - rollup: /@rollup/wasm-node@4.17.0 + '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.17.1) + rollup: /@rollup/wasm-node@4.17.1 dev: true - /@rollup/plugin-node-resolve@15.2.3(@rollup/wasm-node@4.17.0): + /@rollup/plugin-node-resolve@15.2.3(@rollup/wasm-node@4.17.1): resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2086,26 +2086,26 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.1.0(@rollup/wasm-node@4.17.0) + '@rollup/pluginutils': 5.1.0(@rollup/wasm-node@4.17.1) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.8 - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 dev: true - /@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.17.0): + /@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.17.1): resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} peerDependencies: rollup: npm:@rollup/wasm-node dependencies: - '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.17.0) + '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.17.1) magic-string: 0.25.9 - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 dev: true - /@rollup/plugin-terser@0.4.4(@rollup/wasm-node@4.17.0): + /@rollup/plugin-terser@0.4.4(@rollup/wasm-node@4.17.1): resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2114,13 +2114,13 @@ packages: rollup: optional: true dependencies: - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 serialize-javascript: 6.0.2 smob: 1.5.0 terser: 5.30.4 dev: true - /@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.17.0): + /@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.17.1): resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} peerDependencies: @@ -2129,10 +2129,10 @@ packages: '@types/estree': 0.0.39 estree-walker: 1.0.1 picomatch: 2.3.1 - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 dev: true - /@rollup/pluginutils@5.1.0(@rollup/wasm-node@4.17.0): + /@rollup/pluginutils@5.1.0(@rollup/wasm-node@4.17.1): resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2144,7 +2144,7 @@ packages: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 dev: true /@rollup/wasm-node@4.17.0: @@ -2155,6 +2155,16 @@ packages: '@types/estree': 1.0.5 optionalDependencies: fsevents: 2.3.3 + dev: true + + /@rollup/wasm-node@4.17.1: + resolution: {integrity: sha512-07J72z5LBQtNSFAunXeCSNEj7D72kfbeySMrOb7h1cswxKEFUqYjJ2gGLKfMuH1X42SrJ0zKx/i1K/hRbIIjHQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + fsevents: 2.3.3 /@scure/base@1.1.6: resolution: {integrity: sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==} @@ -5051,7 +5061,7 @@ packages: '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.4) '@babel/types': 7.24.0 kleur: 4.1.5 - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 unplugin: 1.10.1 transitivePeerDependencies: - supports-color @@ -5966,7 +5976,7 @@ packages: glob: 7.2.3 dev: true - /rollup-plugin-visualizer@5.12.0(@rollup/wasm-node@4.17.0): + /rollup-plugin-visualizer@5.12.0(@rollup/wasm-node@4.17.1): resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} engines: {node: '>=14'} hasBin: true @@ -5978,7 +5988,7 @@ packages: dependencies: open: 8.4.2 picomatch: 2.3.1 - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 source-map: 0.7.4 yargs: 17.7.2 dev: true @@ -6945,7 +6955,7 @@ packages: '@types/node': 20.12.7 esbuild: 0.20.2 postcss: 8.4.38 - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 optionalDependencies: fsevents: 2.3.3 dev: true @@ -7206,10 +7216,10 @@ packages: '@babel/core': 7.24.4 '@babel/preset-env': 7.24.4(@babel/core@7.24.4) '@babel/runtime': 7.24.4 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.4)(@rollup/wasm-node@4.17.0) - '@rollup/plugin-node-resolve': 15.2.3(@rollup/wasm-node@4.17.0) - '@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.17.0) - '@rollup/plugin-terser': 0.4.4(@rollup/wasm-node@4.17.0) + '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.4)(@rollup/wasm-node@4.17.1) + '@rollup/plugin-node-resolve': 15.2.3(@rollup/wasm-node@4.17.1) + '@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.17.1) + '@rollup/plugin-terser': 0.4.4(@rollup/wasm-node@4.17.1) '@surma/rollup-plugin-off-main-thread': 2.2.3 ajv: 8.12.0 common-tags: 1.8.2 @@ -7218,7 +7228,7 @@ packages: glob: 7.2.3 lodash: 4.17.21 pretty-bytes: 5.6.0 - rollup: /@rollup/wasm-node@4.17.0 + rollup: /@rollup/wasm-node@4.17.1 source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 @@ -7441,10 +7451,11 @@ packages: use-sync-external-store: 1.2.0(react@18.3.1) dev: false - github.com/sussy-code/providers/30511f11e8bc3f8b26be356d0db59acc100cf92e: - resolution: {tarball: https://codeload.github.com/sussy-code/providers/tar.gz/30511f11e8bc3f8b26be356d0db59acc100cf92e} + github.com/sussy-code/providers/ead928c5d09cad1c23aeab58687d3fae7f426dba: + resolution: {tarball: https://codeload.github.com/sussy-code/providers/tar.gz/ead928c5d09cad1c23aeab58687d3fae7f426dba} name: '@movie-web/providers' version: 2.3.0 + prepare: true requiresBuild: true dependencies: cheerio: 1.0.0-rc.12 diff --git a/public/placeholder.png b/public/placeholder.png new file mode 100644 index 00000000..8d00379f Binary files /dev/null and b/public/placeholder.png differ diff --git a/src/components/media/MediaCard.tsx b/src/components/media/MediaCard.tsx index 2152963a..e1da9d71 100644 --- a/src/components/media/MediaCard.tsx +++ b/src/components/media/MediaCard.tsx @@ -82,7 +82,7 @@ function MediaCardContent({ })} /> diff --git a/src/pages/Discover.tsx b/src/pages/Discover.tsx index f6f9fcf5..abd75354 100644 --- a/src/pages/Discover.tsx +++ b/src/pages/Discover.tsx @@ -4,6 +4,7 @@ import { Helmet } from "react-helmet-async"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; +import { get } from "@/backend/metadata/tmdb"; import { ThiccContainer } from "@/components/layout/ThinContainer"; import { Divider } from "@/components/utils/Divider"; import { Flare } from "@/components/utils/Flare"; @@ -20,7 +21,7 @@ import { import { SubPageLayout } from "./layouts/SubPageLayout"; import { PageTitle } from "./parts/util/PageTitle"; -import { get } from "../backend/metadata/tmdb"; +import placeholderImageLogo from "../../public/placeholder.png"; import { Icon, Icons } from "../components/Icon"; export function Discover() { @@ -56,6 +57,15 @@ export function Discover() { language: "en-US", }); + // Shuffle the movies + for (let i = data.results.length - 1; i > 0; i -= 1) { + const j = Math.floor(Math.random() * (i + 1)); + [data.results[i], data.results[j]] = [ + data.results[j], + data.results[i], + ]; + } + setCategoryMovies((prevCategoryMovies) => ({ ...prevCategoryMovies, [category.name]: data.results, @@ -78,6 +88,15 @@ export function Discover() { language: "en-US", }); + // Shuffle the TV shows + for (let i = data.results.length - 1; i > 0; i -= 1) { + const j = Math.floor(Math.random() * (i + 1)); + [data.results[i], data.results[j]] = [ + data.results[j], + data.results[i], + ]; + } + setCategoryShows((prevCategoryShows) => ({ ...prevCategoryShows, [category.name]: data.results, @@ -107,8 +126,8 @@ export function Discover() { [data.genres[i], data.genres[j]] = [data.genres[j], data.genres[i]]; } - // Fetch only the first 5 TV show genres - setTVGenres(data.genres.slice(0, 5)); + // Fetch only the first 6 TV show genres + setTVGenres(data.genres.slice(0, 6)); } catch (error) { console.error("Error fetching TV show genres:", error); } @@ -126,6 +145,16 @@ export function Discover() { with_genres: genreId.toString(), language: "en-US", }); + + // Shuffle the TV shows + for (let i = data.results.length - 1; i > 0; i -= 1) { + const j = Math.floor(Math.random() * (i + 1)); + [data.results[i], data.results[j]] = [ + data.results[j], + data.results[i], + ]; + } + setTVShowGenres((prevTVShowGenres) => ({ ...prevTVShowGenres, [genreId]: data.results, @@ -209,7 +238,7 @@ export function Discover() { if (movieElements.length > 0) { const posterWidth = movieElements[0].offsetWidth; const visibleMovies = Math.floor(carousel.offsetWidth / posterWidth); - const scrollAmount = posterWidth * visibleMovies * 0.6; + const scrollAmount = posterWidth * visibleMovies * 0.62; if (e.deltaY < 5) { carousel.scrollBy({ left: -scrollAmount, behavior: "smooth" }); } else { @@ -235,6 +264,13 @@ export function Discover() { 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 = @@ -245,6 +281,7 @@ export function Discover() { : isTVShow ? `${category} Shows` : `${category} Movies`; + // https://tailwindcss.com/docs/border-style return (

@@ -286,8 +323,12 @@ export function Discover() { className="rounded-xl bg-background-main group-hover:opacity-100" /> failed to fetch :( @@ -396,8 +437,8 @@ export function Discover() { const fetchMoviesForGenre = async (genreId: number) => { try { const movies: any[] = []; - for (let page = 1; page <= 5; page += 1) { - // Fetch only 5 pages + for (let page = 1; page <= 6; page += 1) { + // Fetch only 6 pages const data = await get("/discover/movie", { api_key: conf().TMDB_READ_API_KEY, with_genres: genreId.toString(), @@ -407,6 +448,13 @@ export function Discover() { 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,