diff options
Diffstat (limited to 'src/app/anime')
| -rw-r--r-- | src/app/anime/[id]/[...animeId]/page.jsx | 92 | ||||
| -rw-r--r-- | src/app/anime/[id]/[...animeId]/video.module.css | 70 | ||||
| -rw-r--r-- | src/app/anime/[id]/buttons.jsx | 88 | ||||
| -rw-r--r-- | src/app/anime/[id]/info.module.css | 63 | ||||
| -rw-r--r-- | src/app/anime/[id]/loading.jsx | 6 | ||||
| -rw-r--r-- | src/app/anime/[id]/loading.module.css | 24 | ||||
| -rw-r--r-- | src/app/anime/[id]/page.jsx | 23 | ||||
| -rw-r--r-- | src/app/anime/anime.module.css | 6 | ||||
| -rw-r--r-- | src/app/anime/page.jsx | 2 | ||||
| -rw-r--r-- | src/app/anime/recent/page.jsx | 2 | ||||
| -rw-r--r-- | src/app/anime/recent/recent.module.css | 30 | ||||
| -rw-r--r-- | src/app/anime/search/components/fetchedInfo.js | 8 | ||||
| -rw-r--r-- | src/app/anime/search/page.jsx | 13 | ||||
| -rw-r--r-- | src/app/anime/search/search.module.css (renamed from src/app/anime/search/search.css) | 15 | ||||
| -rw-r--r-- | src/app/anime/top-airing/page.jsx | 2 | ||||
| -rw-r--r-- | src/app/anime/top-airing/trending.module.css | 31 | ||||
| -rw-r--r-- | src/app/anime/videoLinkfetcher.js | 32 |
17 files changed, 274 insertions, 233 deletions
diff --git a/src/app/anime/[id]/[...animeId]/page.jsx b/src/app/anime/[id]/[...animeId]/page.jsx deleted file mode 100644 index f5505e5..0000000 --- a/src/app/anime/[id]/[...animeId]/page.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import { MediaPlayer, MediaProvider } from "@vidstack/react"; -import "@vidstack/react/player/styles/base.css"; -import "@vidstack/react/player/styles/plyr/theme.css"; -import { - PlyrLayout, - plyrLayoutIcons, -} from "@vidstack/react/player/layouts/plyr"; -import styles from "./video.module.css"; -import { redirect } from "next/navigation"; -import Link from "next/link"; - -export const runtime = 'edge'; - -export default async function Video({ params }) { - let link; - const id = params.animeId[0]; - const series = params.animeId[1]; - - // Getting the episode number and the anime name. Kindly ignore! - const words = id.split("-"); - const last_two = words.slice(-2).join(" "); - const remainingWords = words.slice(0, -2).join(" "); - - const data = await getVideoLink(id); - const animedata = await getAnimeInfo(series); - - if (data.message) { - redirect("/404"); - } - - try { - link = data.sources[4].url; - } catch (error) { - try { - link = data.sources[3].url; - } catch (error) { - console.log("Episode not found."); - redirect("/404"); - } - } - - return ( - <div className={styles.VideoMain}> - <div className={styles.VideoContainer}> - <p style={{ textAlign: "center", color: "white" }}> - {last_two} - {remainingWords} - </p> - <div className={styles.Video}> - <MediaPlayer - title={words} - src={link} - aspectRatio="16/9" - load="eager" - className={styles.VideoPlayer} - > - <MediaProvider /> - <PlyrLayout icons={plyrLayoutIcons} /> - </MediaPlayer> - <div className={styles.EpisodesButtons}> - {animedata && - animedata.episodes.map((item, index) => ( - // <p key={index}>Hello World</p> - <Link - href={`/anime/watch/${item.id}/${series}`} - key={index} - > - <button>{item.number}</button> - </Link> - ))} - </div> - </div> - </div> - </div> - ); -} - -async function getVideoLink(id) { - const res = await fetch( - "https://consumet-api-di2e.onrender.com/anime/gogoanime/watch/" + id - ); - const data = res.json(); - return data; -} - -async function getAnimeInfo(anime_id) { - const res = await fetch( - "https://anime-sensei-api.vercel.app/anime/gogoanime/info/" + anime_id, - { next: { revalidate: 7200 } } - ); - const data = await res.json(); - return data; -} diff --git a/src/app/anime/[id]/[...animeId]/video.module.css b/src/app/anime/[id]/[...animeId]/video.module.css deleted file mode 100644 index 0214e60..0000000 --- a/src/app/anime/[id]/[...animeId]/video.module.css +++ /dev/null @@ -1,70 +0,0 @@ -.Video { - display: flex; - justify-content: center; - align-items: center; -} - -.VideoPlayer { - border-radius: 10px; - width: 70%; - height: auto; -} - -.EpisodesButtons { - display: flex; - flex-direction: column; - margin-left: 10px; - height: 500px; - overflow-y: auto; - width: 100px; - scrollbar-width: thin; -} - -.EpisodesButtons button { - width: 70px; - margin: 5px; - outline: none; - border: none; - padding: 5px; - font-family: "Quicksand"; - font-size: 14px; - border-radius: 5px; - cursor: pointer; - color: white; - background-color: #3d3d3d; - transition: background-color 0.2s linear; -} - -.EpisodesButtons button:hover { - background-color: #1f1f1f; - transition: background-color 0.2s linear -} - -@media screen and (max-width: 768px) { - - .VideoMain { - max-width: 99%; - } - - .Video { - display: block; - } - - .VideoPlayer { - width: 100%; - } - - .EpisodesButtons { - display: flex; - flex-direction: row; - height: auto; - width: auto; - margin-top: 10px; - margin-left: 0px; - overflow-y: auto; - } - - .EpisodesButtons button { - width: 50px; - } -}
\ No newline at end of file diff --git a/src/app/anime/[id]/buttons.jsx b/src/app/anime/[id]/buttons.jsx new file mode 100644 index 0000000..eac1884 --- /dev/null +++ b/src/app/anime/[id]/buttons.jsx @@ -0,0 +1,88 @@ +"use client"; + +import styles from "./info.module.css"; +import { useState } from "react"; +import { fetch_video_link } from "../videoLinkfetcher"; +import { MediaPlayer, MediaProvider } from "@vidstack/react"; +import "@vidstack/react/player/styles/base.css"; +import "@vidstack/react/player/styles/plyr/theme.css"; +import { + PlyrLayout, + plyrLayoutIcons, +} from "@vidstack/react/player/layouts/plyr"; + +export default function Button({ data2: info }) { + const [videoLink, setVideoLink] = useState(null); + + async function video(id) { + const link = await fetch_video_link(id); + if (link === undefined) { + alert("Sorry, but not links were found"); + } else { + setVideoLink(link); + console.log(videoLink); + } + } + + return ( + <main> + <h2 className={styles.buttonHeader}>Episodes: </h2> + <div className={styles.buttonContainer}> + {info && + info.episodes && + info.episodes.map((item, index) => ( + <button + className={styles.dramaButton} + key={index} + onClick={(event) => { + event.target.style.backgroundColor = + "var(--soft-purple)"; + video(item.id); + }} + > + {item.number} + </button> + ))} + </div> + + {videoLink && ( + <div + className={styles.videoPopUp} + id="popup" + onKeyDown={(event) => { + if (event.code === "Escape") { + setVideoLink(""); + } + }} + > + <div className={styles.video}> + <MediaPlayer + title="dramaPlayer" + src={videoLink} + aspectRatio="16/9" + load="eager" + className={styles.VideoPlayer} + playsInline + id="videoPlayer" + volume={0.2} + onQualityChange={(event) => + console.log("changed qualities", event) + } + > + <MediaProvider /> + <PlyrLayout icons={plyrLayoutIcons} /> + </MediaPlayer> + <button + className={styles.closeButton} + onClick={() => { + setVideoLink(""); + }} + > + Close + </button> + </div> + </div> + )} + </main> + ); +} diff --git a/src/app/anime/[id]/info.module.css b/src/app/anime/[id]/info.module.css index e8bfc54..6299405 100644 --- a/src/app/anime/[id]/info.module.css +++ b/src/app/anime/[id]/info.module.css @@ -52,10 +52,15 @@ color: #ffffff81 } +.buttonContainer button { + transition: transform 200ms ease-in-out; + +} + .buttonContainer button:focus { opacity: 0.7; - transition: transform 0.2s linear; - background-color: var(--pastel-red); + transition: transform 200ms ease-in; + background-color: var(--soft-purple); transform: scale(0.9); } @@ -68,7 +73,7 @@ padding: 10px; font-family: "Quicksand"; font-size: 14px; - margin: 5px; + margin: 5px 5px 5px 5px; width: 55px; border-radius: 5px; text-align: center; @@ -76,13 +81,13 @@ outline: none; color: white; background-color: #3d3d3d; - transition: background-color 0.2s linear; + transition: background-color 200ms ease-in-out; cursor: pointer; } .dramaButton:hover { background-color: #1f1f1f; - transition: background-color 0.2s linear + transition: background-color 200ms ease-in } .infoPageContainer p { @@ -111,9 +116,57 @@ color: var(--soft-purple) } +.videoPopUp { + height: 100dvh; + width: 100dvw; + background-color: #1f1f1fd3; + position: fixed; + bottom: 0; + left: 0; + right: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 1; + overflow-y: auto; +} + +.video { + display: flex; + flex-direction: column; +} + +.closeButton { + font-family: "Poppins", serif; + font-size: 16px; + background-color: var(--pastel-red); + padding: 4px 10px; + border: 0; + outline: 0; + border-radius: 0.5rem; + cursor: pointer; + margin: 5px; + width: auto; +} + +.VideoPlayer { + width: 60dvw; + +} + + @media screen and (max-width: 768px) { + .titleContainer p { + font-size: 28px; + } + .animeDetails { font-size: 14px; } + + .VideoPlayer { + width: 100%; + } }
\ No newline at end of file diff --git a/src/app/anime/[id]/loading.jsx b/src/app/anime/[id]/loading.jsx index 71ff978..24e8c83 100644 --- a/src/app/anime/[id]/loading.jsx +++ b/src/app/anime/[id]/loading.jsx @@ -1,9 +1,9 @@ import styles from "./loading.module.css"; -export default function Loading() { +export default async function Loading() { return ( - <div className={styles.loadingContainer}> - <p className={styles.loadingText}>Hold tight...Arriving!!</p> + <div className={styles.Main}> + <div className={styles.LoadingContainer}></div> </div> ); } diff --git a/src/app/anime/[id]/loading.module.css b/src/app/anime/[id]/loading.module.css index 63604d5..14dfcf3 100644 --- a/src/app/anime/[id]/loading.module.css +++ b/src/app/anime/[id]/loading.module.css @@ -1,12 +1,22 @@ -.loadingContainer { +.Main { + height: 100vh; + width: 100vw; display: flex; - align-items: center; justify-content: center; - height: 100dvh; + align-items: center; +} + +.LoadingContainer { + width: 50px; + height: 50px; + border-radius: 50%; + border: 8px solid; + border-color: #F4F4F4 #0000; + animation: s1 1s infinite; } -.loadingText { - color: white; - font-family: "Lato"; - font-size: 20px; +@keyframes s1 { + to { + transform: rotate(.5turn) + } }
\ No newline at end of file diff --git a/src/app/anime/[id]/page.jsx b/src/app/anime/[id]/page.jsx index 598c8a7..14fb36a 100644 --- a/src/app/anime/[id]/page.jsx +++ b/src/app/anime/[id]/page.jsx @@ -1,14 +1,15 @@ import styles from "./info.module.css"; import Image from "next/image"; -import Link from "next/link"; - -export const runtime = 'edge'; +import Button from "./buttons"; +import { preFetchAnimeLinks } from "../videoLinkfetcher"; export default async function AnimeInfo({ params }) { let animeID = params.id; const info = await getAnimeInfo(animeID); + preFetchAnimeLinks(info); + return ( <div className={styles.dramaInfoContainer}> <div className={styles.dramaInfo}> @@ -50,21 +51,7 @@ export default async function AnimeInfo({ params }) { </p> </div> - <h2 className={styles.buttonHeader}>Episodes: </h2> - <div className={styles.buttonContainer}> - {info && - info.episodes && - info.episodes.map((item, index) => ( - <Link - href={`/anime/watch/${item.id}/${animeID}`} - key={index} - > - <button className={styles.dramaButton}> - {item.number} - </button> - </Link> - ))} - </div> + <Button data2={info} /> </div> </div> ); diff --git a/src/app/anime/anime.module.css b/src/app/anime/anime.module.css index 15695be..63f2993 100644 --- a/src/app/anime/anime.module.css +++ b/src/app/anime/anime.module.css @@ -1,4 +1,4 @@ -.Main { - max-width: 95%; - margin: 100px auto; +.main { + margin: 80px auto; + max-width: 98%; }
\ No newline at end of file diff --git a/src/app/anime/page.jsx b/src/app/anime/page.jsx index 3f893d1..7480ae2 100644 --- a/src/app/anime/page.jsx +++ b/src/app/anime/page.jsx @@ -5,7 +5,7 @@ import Input from "./search/page"; export default async function Anime() { return ( - <div className={styles.Main}> + <div className={styles.main}> <Input /> <Trending /> <Releases /> diff --git a/src/app/anime/recent/page.jsx b/src/app/anime/recent/page.jsx index 2bf4e86..b197899 100644 --- a/src/app/anime/recent/page.jsx +++ b/src/app/anime/recent/page.jsx @@ -6,7 +6,7 @@ export default async function Releases() { const data = await fetchRecentEpisodes(); return ( - <div className="trendingContainer"> + <div className={styles.RecentContainer}> <div className={styles.RecentText}> <p>Recent Releases</p> </div> diff --git a/src/app/anime/recent/recent.module.css b/src/app/anime/recent/recent.module.css index f9d5161..24774bd 100644 --- a/src/app/anime/recent/recent.module.css +++ b/src/app/anime/recent/recent.module.css @@ -8,6 +8,7 @@ margin: 5px; color: var(--soft-purple); font-family: "Poppins"; + font-weight: 500; } .RecentText span { @@ -17,11 +18,20 @@ .Recent { display: flex; overflow-x: auto; - margin: 5px; +} + +.RecentContainer:hover .RecentEntries { + opacity: 0.5; +} + +.RecentContainer:hover:hover .RecentEntries:hover { + opacity: 1; + transform: scale(1.02); } .Recent::-webkit-scrollbar { height: 5px; + width: 0px; } .Recent::-webkit-scrollbar-thumb { @@ -30,13 +40,12 @@ } .RecentEntries { - margin: 7px; - transition: transform 0.1s linear; -} + margin: 4px; + background-color: #353535a6; + padding: 0.5rem; + border-radius: 1rem; + transition: opacity 400ms ease, transform 400ms ease; -.RecentEntries:hover { - transition: transform 0.1s linear; - transform: scale(0.97); } .RecentEntries p { @@ -44,10 +53,13 @@ margin: 5px auto; width: 140px; font-family: "Atkinson Hyperlegible"; + height: 80px; + overflow-y: auto; + transition: font-size 400ms ease; } .RecentEntries p::-webkit-scrollbar { - width: 5px; + width: 2px; } .Recent p::-webkit-scrollbar-thumb { @@ -56,6 +68,6 @@ } .RecentImage { - border-radius: 5px; + border-radius: 1rem; aspect-ratio: auto; }
\ No newline at end of file diff --git a/src/app/anime/search/components/fetchedInfo.js b/src/app/anime/search/components/fetchedInfo.js index 17c9673..9a1d187 100644 --- a/src/app/anime/search/components/fetchedInfo.js +++ b/src/app/anime/search/components/fetchedInfo.js @@ -1,10 +1,10 @@ -import "../search.css"; +import styles from "../search.module.css"; import Link from "next/link"; import Image from "next/image"; export default async function fetchedInfo(data) { return ( - <div className="animeEntry"> + <div className={styles.animeEntry}> {data ? ( data.results && data.results.length > 0 ? ( data.results.map((item, index) => ( @@ -13,11 +13,11 @@ export default async function fetchedInfo(data) { href={`/anime/${item.id}`} style={{ textDecoration: "none" }} > - <div className="anime"> + <div className={styles.anime}> <p>{item.title}</p> <Image src={item.image} - className="animeImage" + className={styles.animeImage} width={120} height={160} alt="Drama Poster" diff --git a/src/app/anime/search/page.jsx b/src/app/anime/search/page.jsx index 3d63484..ce037cb 100644 --- a/src/app/anime/search/page.jsx +++ b/src/app/anime/search/page.jsx @@ -1,6 +1,6 @@ "use client"; -import "./search.css"; +import styles from "./search.module.css"; import { FaSearch } from "react-icons/fa"; // Import the search icon from react-icons library import { useState } from "react"; import Results from "./components/fetchInfo"; @@ -33,9 +33,9 @@ export default function Input() { return ( <div> - <div className="inputContainer"> - <div className="searchContainer"> - <FaSearch className="searchIcon" /> + <div className={styles.inputContainer}> + <div className={styles.searchContainer}> + <FaSearch className={styles.searchIcon} /> <input onChange={(event) => { if (event.target.value.trim() !== "") { @@ -44,14 +44,13 @@ export default function Input() { }} onKeyDown={(event) => handleKeyPress(event)} placeholder="Enter anime title" + className={styles.SearchInput} ></input> </div> </div> {loading && ( - <p className="waitWhileLoading" - - > + <p className={styles.waitWhileLoading}> Please wait while we crunch all the data for you </p> )} diff --git a/src/app/anime/search/search.css b/src/app/anime/search/search.module.css index 0a89a68..28fae6e 100644 --- a/src/app/anime/search/search.css +++ b/src/app/anime/search/search.module.css @@ -36,6 +36,14 @@ overflow-x: auto; } +.animeEntry:hover .anime { + opacity: 0.5; +} + +.animeEntry:hover .anime:hover { + opacity: 1; +} + .animeEntry::-webkit-scrollbar { height: 5px; } @@ -61,12 +69,15 @@ margin: 10px 10px 0px 0px; border-radius: 10px; border-width: 4px; + transition: opacity 400ms ease-in; + background-color: #353535a6; + } .anime p { color: white; - width: 25dvh; - font-family: "Lato"; + width: 20dvw; + font-family: "Atkinson"; font-size: 18px; } diff --git a/src/app/anime/top-airing/page.jsx b/src/app/anime/top-airing/page.jsx index 898b766..e385629 100644 --- a/src/app/anime/top-airing/page.jsx +++ b/src/app/anime/top-airing/page.jsx @@ -6,7 +6,7 @@ export default async function Trending() { const data = await test(); return ( - <div className="trendingContainer"> + <div className={styles.TrendingContainer}> <div className={styles.TrendingText}> <p>Trending</p> </div> diff --git a/src/app/anime/top-airing/trending.module.css b/src/app/anime/top-airing/trending.module.css index c3c55c5..33d00d3 100644 --- a/src/app/anime/top-airing/trending.module.css +++ b/src/app/anime/top-airing/trending.module.css @@ -8,6 +8,7 @@ margin: 5px; color: var(--soft-purple); font-family: "Poppins"; + font-weight: 500; } .TrendingText span { @@ -17,11 +18,20 @@ .trending { display: flex; overflow-x: auto; - margin: 5px; +} + +.TrendingContainer:hover .trendingEntries { + opacity: 0.5; +} + +.TrendingContainer:hover .trendingEntries:hover { + opacity: 1; + transform: scale(1.02); } .trending::-webkit-scrollbar { height: 5px; + width: 0px; } .trending::-webkit-scrollbar-thumb { @@ -30,13 +40,12 @@ } .trendingEntries { - margin: 7px; - transition: transform 0.2s linear; -} - -.trendingEntries:hover { - transition: transform 0.2s linear; - transform: scale(0.97); + margin: 4px; + transition: transform 400ms ease; + background-color: #353535a6; + padding: 0.5rem; + border-radius: 1rem; + transition: opacity 400ms ease, transform 400ms ease; } .trendingEntries p { @@ -44,10 +53,12 @@ margin: 5px auto; width: 140px; font-family: "Atkinson Hyperlegible"; + height: 80px; + overflow-y: auto; } .trendingEntries p::-webkit-scrollbar { - width: 5px; + width: 2px; } .trendingEntries p::-webkit-scrollbar-thumb { @@ -56,6 +67,6 @@ } .trendingImage { - border-radius: 5px; + border-radius: 1rem; aspect-ratio: auto; }
\ No newline at end of file diff --git a/src/app/anime/videoLinkfetcher.js b/src/app/anime/videoLinkfetcher.js new file mode 100644 index 0000000..3963bd3 --- /dev/null +++ b/src/app/anime/videoLinkfetcher.js @@ -0,0 +1,32 @@ +"use server"; +export async function fetch_video_link(id) { + try { + const res = await fetch( + `https://consumet-jade.vercel.app/anime/gogoanime/watch/${id}`, + { cache: "force-cache" } + ); + const data = await res.json(); + let vidLink = data.sources[data.sources.length - 2].url; + return vidLink; + } catch (error) { + console.log("Mehh Error", error); + } +} + +export async function preFetchAnimeLinks(data, n = 40) { + const limit = Math.min(n, data.episodes.length); + + try { + const fetchPromises = []; + for (let i = 0; i < limit; i++) { + const element = data.episodes[i]; + const link = `https://consumet-jade.vercel.app/anime/gogoanime/watch/${element.id}`; + fetchPromises.push(fetch(link, { cache: "force-cache" })); + } + + await Promise.all(fetchPromises); + console.log("Video links pre-fetched successfully!"); + } catch (error) { + console.error("Error occurred while pre-fetching video links:", error); + } +} |