diff options
Diffstat (limited to 'src/app/anime')
| -rw-r--r-- | src/app/anime/[id]/[animeId]/page.jsx | 56 | ||||
| -rw-r--r-- | src/app/anime/[id]/[animeId]/video.css | 30 | ||||
| -rw-r--r-- | src/app/anime/[id]/info.css | 83 | ||||
| -rw-r--r-- | src/app/anime/[id]/loading.css | 346 | ||||
| -rw-r--r-- | src/app/anime/[id]/loading.jsx | 9 | ||||
| -rw-r--r-- | src/app/anime/[id]/page.jsx | 50 | ||||
| -rw-r--r-- | src/app/anime/page.jsx | 6 | ||||
| -rw-r--r-- | src/app/anime/recent/page.jsx | 45 | ||||
| -rw-r--r-- | src/app/anime/recent/recent.css | 66 | ||||
| -rw-r--r-- | src/app/anime/search/components/fetchInfo.js | 14 | ||||
| -rw-r--r-- | src/app/anime/search/components/fetchedInfo.js | 44 | ||||
| -rw-r--r-- | src/app/anime/search/page.jsx | 67 | ||||
| -rw-r--r-- | src/app/anime/search/search.css | 80 | ||||
| -rw-r--r-- | src/app/anime/top-airing/page.jsx | 45 | ||||
| -rw-r--r-- | src/app/anime/top-airing/trending.css | 0 | ||||
| -rw-r--r-- | src/app/anime/video/loading.css | 346 | ||||
| -rw-r--r-- | src/app/anime/video/loading.jsx | 9 |
17 files changed, 1293 insertions, 3 deletions
diff --git a/src/app/anime/[id]/[animeId]/page.jsx b/src/app/anime/[id]/[animeId]/page.jsx new file mode 100644 index 0000000..d59b0a0 --- /dev/null +++ b/src/app/anime/[id]/[animeId]/page.jsx @@ -0,0 +1,56 @@ +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 "./video.css"; +import { redirect } from "next/navigation"; + +export default async function Video({ params }) { + const id = params.animeId; + + // 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); + + if (data.message) { + redirect("/404"); + } + + const link = data.sources[4].url; + + return ( + <div> + <div className="video2"> + <p> + {last_two} - {remainingWords} + </p> + <MediaPlayer + title={words} + src={link} + className="testPlayer" + playsInline + aspectRatio="16/9" + load="eager" + > + <MediaProvider /> + <PlyrLayout icons={plyrLayoutIcons} /> + </MediaPlayer> + </div> + </div> + ); +} + +async function getVideoLink(id) { + const res = await fetch( + "https://consumet-api-di2e.onrender.com/anime/gogoanime/watch/" + id, + { next: { revalidate: 3600 } } // Video links are revalidated after an hour + ); + const data = res.json(); + return data; +} diff --git a/src/app/anime/[id]/[animeId]/video.css b/src/app/anime/[id]/[animeId]/video.css new file mode 100644 index 0000000..5ccb58f --- /dev/null +++ b/src/app/anime/[id]/[animeId]/video.css @@ -0,0 +1,30 @@ +.video2 { + display: flex; + flex-direction: column; + align-items: center; + margin: 0px auto; + width: 50%; +} + +.testPlayer { + border-radius: 10px; +} + +.video2 p { + color: white; + font-family: "Lato"; + font-size: 20px; + text-align: center; +} + +@media (prefers-color-scheme: light) { + .video2 p { + color: black; + } +} + +@media screen and (max-width: 768px) { + .video2 { + width: 100%; + } +}
\ No newline at end of file diff --git a/src/app/anime/[id]/info.css b/src/app/anime/[id]/info.css new file mode 100644 index 0000000..2b070d0 --- /dev/null +++ b/src/app/anime/[id]/info.css @@ -0,0 +1,83 @@ +.dramaInfoContainer { + display: flex; + flex-direction: column; +} + +.dramaInfo { + display: flex; + flex-direction: column; + width: 95%; + margin: 0px auto; +} + +.titleContainer { + display: flex; + justify-content: space-between; + align-items: center; +} + +.titleContainer p { + color: var(--neon-green); + width: 60%; + font-family: "Kanit"; + font-size: 24px; +} + +.titleContainer img { + border-radius: 10px; +} + +.animeDescription { + color: #ffffff81; + font-family: "Lato"; + font-size: 16px; + max-height: 120px; + margin: 20px auto; + text-align: center; + overflow-y: auto; +} + +.buttonContainer { + margin: 5px auto; + text-align: center; + max-height: 200px; + overflow-y: auto; +} + +.dramaButton { + padding: 8px; + font-family: "Atkinson Hyperlegible"; + font-size: 18px; + margin: 5px; + width: 50px; + border-radius: 5px; + border: none; + background-color: var(--light-green); + cursor: pointer; +} + +.dramaButton:hover { + background-color: var(--soft-purple); +} + +.infoPageContainer { + display: flex; + height: 100dvh; + justify-content: center; + align-items: center; +} + +.infoPageContainer p { + color: white; +} + +@media (prefers-color-scheme: light) { + .animeDescription { + color: black; + } + + .infoPageContainer p { + color: black; + } + +}
\ No newline at end of file diff --git a/src/app/anime/[id]/loading.css b/src/app/anime/[id]/loading.css new file mode 100644 index 0000000..aa3a519 --- /dev/null +++ b/src/app/anime/[id]/loading.css @@ -0,0 +1,346 @@ +.loadingContainer { + color: white; + display: flex; + justify-content: center; + align-items: center; + height: 80dvh; +} + + +.text-flicker-in-glow { + -webkit-animation: text-flicker-in-glow 4s linear both; + animation: text-flicker-in-glow 4s linear both; + font-size: 36px; + font-family: "Kanit"; +} + +/* ---------------------------------------------- + * Generated by Animista on 2024-3-21 9:58:16 + * Licensed under FreeBSD License. + * See http://animista.net/license for more info. + * w: http://animista.net, t: @cssanimista + * ---------------------------------------------- */ + +/** + * ---------------------------------------- + * animation text-flicker-in-glow + * ---------------------------------------- + */ + +@-webkit-keyframes text-flicker-in-glow { + 0% { + opacity: 0; + } + + 10% { + opacity: 0; + text-shadow: none; + } + + 10.1% { + opacity: 1; + text-shadow: none; + } + + 10.2% { + opacity: 0; + text-shadow: none; + } + + 20% { + opacity: 0; + text-shadow: none; + } + + 20.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.25); + } + + 20.6% { + opacity: 0; + text-shadow: none; + } + + 30% { + opacity: 0; + text-shadow: none; + } + + 30.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.5% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.6% { + opacity: 0; + text-shadow: none; + } + + 45% { + opacity: 0; + text-shadow: none; + } + + 45.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 50% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55.1% { + opacity: 0; + text-shadow: none; + } + + 57% { + opacity: 0; + text-shadow: none; + } + + 57.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60.1% { + opacity: 0; + text-shadow: none; + } + + 65% { + opacity: 0; + text-shadow: none; + } + + 65.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75.1% { + opacity: 0; + text-shadow: none; + } + + 77% { + opacity: 0; + text-shadow: none; + } + + 77.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85.1% { + opacity: 0; + text-shadow: none; + } + + 86% { + opacity: 0; + text-shadow: none; + } + + 86.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 100% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } +} + +@keyframes text-flicker-in-glow { + 0% { + opacity: 0; + } + + 10% { + opacity: 0; + text-shadow: none; + } + + 10.1% { + opacity: 1; + text-shadow: none; + } + + 10.2% { + opacity: 0; + text-shadow: none; + } + + 20% { + opacity: 0; + text-shadow: none; + } + + 20.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.25); + } + + 20.6% { + opacity: 0; + text-shadow: none; + } + + 30% { + opacity: 0; + text-shadow: none; + } + + 30.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.5% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.6% { + opacity: 0; + text-shadow: none; + } + + 45% { + opacity: 0; + text-shadow: none; + } + + 45.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 50% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55.1% { + opacity: 0; + text-shadow: none; + } + + 57% { + opacity: 0; + text-shadow: none; + } + + 57.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60.1% { + opacity: 0; + text-shadow: none; + } + + 65% { + opacity: 0; + text-shadow: none; + } + + 65.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75.1% { + opacity: 0; + text-shadow: none; + } + + 77% { + opacity: 0; + text-shadow: none; + } + + 77.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85.1% { + opacity: 0; + text-shadow: none; + } + + 86% { + opacity: 0; + text-shadow: none; + } + + 86.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 100% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } +} + +@media (prefers-color-scheme: light) { + .loadingContainer { + color: black; + } +}
\ No newline at end of file diff --git a/src/app/anime/[id]/loading.jsx b/src/app/anime/[id]/loading.jsx new file mode 100644 index 0000000..dfa397c --- /dev/null +++ b/src/app/anime/[id]/loading.jsx @@ -0,0 +1,9 @@ +import "./loading.css"; + +export default function Loading() { + return ( + <div className="loadingContainer"> + <p className="text-flicker-in-glow">Loading</p> + </div> + ); +} diff --git a/src/app/anime/[id]/page.jsx b/src/app/anime/[id]/page.jsx new file mode 100644 index 0000000..3e2b1f0 --- /dev/null +++ b/src/app/anime/[id]/page.jsx @@ -0,0 +1,50 @@ +import "./info.css"; +import Image from "next/image"; +import Link from "next/link"; + +export default async function AnimeInfo({ params }) { + let animeID = params.id; + + const info = await getAnimeInfo(animeID); + + return ( + <div className="dramaInfoContainer"> + <div className="dramaInfo"> + {info && ( + <div> + <div className="titleContainer"> + <p>{info.title}</p> + <Image + src={info.image} + width={140} + height={190} + alt="Drama" + /> + </div> + <p className="animeDescription">{info.description}</p> + </div> + )} + + <div className="buttonContainer"> + {info && + info.episodes.map((item, index) => ( + <Link href={`/anime/watch/${item.id}`} key={index}> + <button className="dramaButton"> + {item.number} + </button> + </Link> + ))} + </div> + </div> + </div> + ); +} + +async function getAnimeInfo(anime_id) { + const res = await fetch( + "https://anime-sensei-api.vercel.app/anime/gogoanime/info/" + anime_id, + { next: { revalidate: 1800 } } + ); + const data = res.json(); + return data; +} diff --git a/src/app/anime/page.jsx b/src/app/anime/page.jsx index 759619d..625dd83 100644 --- a/src/app/anime/page.jsx +++ b/src/app/anime/page.jsx @@ -1,7 +1,7 @@ import "./anime.css"; -import Trending from "../top-airing/page"; -import Releases from "../recent/page"; -import Input from "../search/page"; +import Trending from "./top-airing/page"; +import Releases from "./recent/page"; +import Input from "./search/page"; export default async function Anime() { return ( diff --git a/src/app/anime/recent/page.jsx b/src/app/anime/recent/page.jsx new file mode 100644 index 0000000..779f0d4 --- /dev/null +++ b/src/app/anime/recent/page.jsx @@ -0,0 +1,45 @@ +import "./recent.css"; +import Image from "next/image"; +import Link from "next/link"; + +export default async function Releases() { + const data = await test(); + + return ( + <div className="trendingContainer"> + <p className="trendingText">Recent Releases</p> + + <div className="trending"> + {data && + data.results.map((item, index) => ( + <Link + key={index} + href={`/anime/${item.id}`} + style={{ textDecoration: "none" }} + > + <div className="trendingEntries"> + <Image + src={item.image} + className="{trendingImage}" + width={160} + height={220} + alt="Drama" + priority + /> + <p>{item.title}</p> + </div> + </Link> + ))} + </div> + </div> + ); +} + +async function test() { + const res = await fetch( + "https://consumet-api-di2e.onrender.com/anime/gogoanime/recent-episodes", + { cache: "force-cache" } + ); + const data = res.json(); + return data; +} diff --git a/src/app/anime/recent/recent.css b/src/app/anime/recent/recent.css new file mode 100644 index 0000000..7d17143 --- /dev/null +++ b/src/app/anime/recent/recent.css @@ -0,0 +1,66 @@ +.trendingContainer { + display: flex; + flex-direction: column; +} + +.trendingText { + color: #FEFFAC; + font-family: "Open Sans"; + font-size: 26px; + margin: 10px; +} + +.trending { + width: 98%; + display: flex; + flex-direction: row; + overflow-x: auto; + margin: 0px auto; +} + +/* Customize scrollbar here */ +.trending::-webkit-scrollbar { + height: 5px; +} + +.trendingEntries { + margin: 10px 10px 5px 5px; + text-align: center; + cursor: pointer; + transition: transform 0.2s ease; + +} + +.trendingEntries:hover { + transform: scale(1.03); +} + +.trendingEntries img { + border-radius: 10px; + width: 150px; + height: 210px; +} + +.trendingEntries p { + color: white; + max-height: 60px; + max-width: 150px; + overflow-y: auto; + font-family: "Lato"; + margin: 10px auto; + font-size: 16px; +} + +.trendingEntries p::-webkit-scrollbar { + width: 5px; +} + +@media (prefers-color-scheme: light) { + .trendingText { + color: black; + } + + .trendingEntries p { + color: black; + } +}
\ No newline at end of file diff --git a/src/app/anime/search/components/fetchInfo.js b/src/app/anime/search/components/fetchInfo.js new file mode 100644 index 0000000..07b203d --- /dev/null +++ b/src/app/anime/search/components/fetchInfo.js @@ -0,0 +1,14 @@ +"use server"; + +export default async function Results(id) { + return await testFunction(id); +} + +async function testFunction(title) { + const res = await fetch( + "https://consumet-api-di2e.onrender.com/anime/gogoanime/" + title, + { cache: "force-cache" } + ); + const data = await res.json(); + return data; +} diff --git a/src/app/anime/search/components/fetchedInfo.js b/src/app/anime/search/components/fetchedInfo.js new file mode 100644 index 0000000..17c9673 --- /dev/null +++ b/src/app/anime/search/components/fetchedInfo.js @@ -0,0 +1,44 @@ +import "../search.css"; +import Link from "next/link"; +import Image from "next/image"; + +export default async function fetchedInfo(data) { + return ( + <div className="animeEntry"> + {data ? ( + data.results && data.results.length > 0 ? ( + data.results.map((item, index) => ( + <Link + key={index} + href={`/anime/${item.id}`} + style={{ textDecoration: "none" }} + > + <div className="anime"> + <p>{item.title}</p> + <Image + src={item.image} + className="animeImage" + width={120} + height={160} + alt="Drama Poster" + /> + </div> + </Link> + )) + ) : ( + <div style={{ margin: "0px auto" }}> + <p + style={{ + color: "white", + fontFamily: "Kanit", + fontSize: 18, + }} + > + No results found + </p> + </div> + ) + ) : null} + </div> + ); +} diff --git a/src/app/anime/search/page.jsx b/src/app/anime/search/page.jsx new file mode 100644 index 0000000..75f09bd --- /dev/null +++ b/src/app/anime/search/page.jsx @@ -0,0 +1,67 @@ +"use client"; + +import "./search.css"; +import { FaSearch } from "react-icons/fa"; // Import the search icon from react-icons library +import { useState } from "react"; +import Results from "./components/fetchInfo"; +import fetchedInfo from "./components/fetchedInfo"; + +export default function Input() { + const [searchedAnime, setSearchedAnime] = useState(null); + const [loading, setLoading] = useState(null); + const [info, setInfo] = useState(null); + + const handleKeyPress = async (event) => { + if ( + (event.code === "Enter" || + event.key === "Enter" || + event.code === 13) && + searchedAnime !== "" + ) { + setLoading(true); + setInfo(await fetchedInfo(await Results(searchedAnime))); + setLoading(false); + } else if ( + (event.code === "Enter" || + event.key === "Enter" || + event.code === 13) && + searchedAnime === "" + ) { + alert("Input cannot be empty"); + } + }; + + return ( + <div> + <div className="inputContainer"> + <div className="searchContainer"> + <FaSearch className="searchIcon" /> + <input + onChange={(event) => { + if (event.target.value.trim() !== "") { + setSearchedAnime(event.target.value); + } + }} + onKeyDown={(event) => handleKeyPress(event)} + placeholder="Enter anime title" + ></input> + </div> + </div> + + {loading && ( + <p + style={{ + textAlign: "center", + fontFamily: "Kanit", + fontSize: 18, + color: "white", + }} + > + Please wait while we crunch all the data for you + </p> + )} + + {info} + </div> + ); +} diff --git a/src/app/anime/search/search.css b/src/app/anime/search/search.css new file mode 100644 index 0000000..8afb508 --- /dev/null +++ b/src/app/anime/search/search.css @@ -0,0 +1,80 @@ +.inputContainer { + display: flex; + margin: 30px auto; +} + +.searchContainer input { + border: none; + border-radius: 5px; + color: white; + outline: none; + background: none; + width: 100%; + font-family: "Lato"; + font-size: 16px; +} + +.searchContainer { + display: flex; + align-items: center; + margin: 0px auto; + background-color: #2c2c2c; + padding: 8px; + border-radius: 5px; + width: 20%; +} + +.searchIcon { + color: white; + margin-right: 5px; +} + +.animeEntry { + display: flex; + overflow-x: auto; +} + +.animeEntry::-webkit-scrollbar { + height: 7px; +} + +.animeEntry::-webkit-scrollbar-track { + background-color: #636363; + border-radius: 5px; +} + +.animeEntry::-webkit-scrollbar-thumb { + background-color: rgba(196, 196, 196, 0.692); + border-radius: 5px; + +} + +.anime { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px; + border-style: dotted; + border-color: #636363; + margin: 10px; + border-radius: 10px; + border-width: 4px; +} + +.anime p { + color: white; + width: 25dvh; + font-family: "Lato"; + font-size: 18px; +} + +.animeImage { + border-radius: 10px; + margin-left: 20px; +} + +@media screen and (max-width: 768px) { + .searchContainer { + width: 70%; + } +}
\ No newline at end of file diff --git a/src/app/anime/top-airing/page.jsx b/src/app/anime/top-airing/page.jsx new file mode 100644 index 0000000..5536870 --- /dev/null +++ b/src/app/anime/top-airing/page.jsx @@ -0,0 +1,45 @@ +import "./trending.css"; +import Image from "next/image"; +import Link from "next/link"; + +export default async function Trending() { + const data = await test(); + + return ( + <div className="trendingContainer"> + <p className="trendingText">Trending</p> + + <div className="trending"> + {data && + data.results.map((item, index) => ( + <Link + key={index} + href={`/anime/${item.id}`} + style={{ textDecoration: "none" }} + > + <div className="trendingEntries"> + <Image + src={item.image} + className="{trendingImage}" + width={160} + height={220} + alt="Drama" + priority + /> + <p>{item.title}</p> + </div> + </Link> + ))} + </div> + </div> + ); +} + +async function test() { + const res = await fetch( + "https://consumet-api-di2e.onrender.com/anime/gogoanime/top-airing", + { cache: "force-cache" } + ); + const data = res.json(); + return data; +} diff --git a/src/app/anime/top-airing/trending.css b/src/app/anime/top-airing/trending.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/app/anime/top-airing/trending.css diff --git a/src/app/anime/video/loading.css b/src/app/anime/video/loading.css new file mode 100644 index 0000000..aa3a519 --- /dev/null +++ b/src/app/anime/video/loading.css @@ -0,0 +1,346 @@ +.loadingContainer { + color: white; + display: flex; + justify-content: center; + align-items: center; + height: 80dvh; +} + + +.text-flicker-in-glow { + -webkit-animation: text-flicker-in-glow 4s linear both; + animation: text-flicker-in-glow 4s linear both; + font-size: 36px; + font-family: "Kanit"; +} + +/* ---------------------------------------------- + * Generated by Animista on 2024-3-21 9:58:16 + * Licensed under FreeBSD License. + * See http://animista.net/license for more info. + * w: http://animista.net, t: @cssanimista + * ---------------------------------------------- */ + +/** + * ---------------------------------------- + * animation text-flicker-in-glow + * ---------------------------------------- + */ + +@-webkit-keyframes text-flicker-in-glow { + 0% { + opacity: 0; + } + + 10% { + opacity: 0; + text-shadow: none; + } + + 10.1% { + opacity: 1; + text-shadow: none; + } + + 10.2% { + opacity: 0; + text-shadow: none; + } + + 20% { + opacity: 0; + text-shadow: none; + } + + 20.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.25); + } + + 20.6% { + opacity: 0; + text-shadow: none; + } + + 30% { + opacity: 0; + text-shadow: none; + } + + 30.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.5% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.6% { + opacity: 0; + text-shadow: none; + } + + 45% { + opacity: 0; + text-shadow: none; + } + + 45.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 50% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55.1% { + opacity: 0; + text-shadow: none; + } + + 57% { + opacity: 0; + text-shadow: none; + } + + 57.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60.1% { + opacity: 0; + text-shadow: none; + } + + 65% { + opacity: 0; + text-shadow: none; + } + + 65.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75.1% { + opacity: 0; + text-shadow: none; + } + + 77% { + opacity: 0; + text-shadow: none; + } + + 77.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85.1% { + opacity: 0; + text-shadow: none; + } + + 86% { + opacity: 0; + text-shadow: none; + } + + 86.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 100% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } +} + +@keyframes text-flicker-in-glow { + 0% { + opacity: 0; + } + + 10% { + opacity: 0; + text-shadow: none; + } + + 10.1% { + opacity: 1; + text-shadow: none; + } + + 10.2% { + opacity: 0; + text-shadow: none; + } + + 20% { + opacity: 0; + text-shadow: none; + } + + 20.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.25); + } + + 20.6% { + opacity: 0; + text-shadow: none; + } + + 30% { + opacity: 0; + text-shadow: none; + } + + 30.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.5% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.6% { + opacity: 0; + text-shadow: none; + } + + 45% { + opacity: 0; + text-shadow: none; + } + + 45.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 50% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55.1% { + opacity: 0; + text-shadow: none; + } + + 57% { + opacity: 0; + text-shadow: none; + } + + 57.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60.1% { + opacity: 0; + text-shadow: none; + } + + 65% { + opacity: 0; + text-shadow: none; + } + + 65.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75.1% { + opacity: 0; + text-shadow: none; + } + + 77% { + opacity: 0; + text-shadow: none; + } + + 77.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85.1% { + opacity: 0; + text-shadow: none; + } + + 86% { + opacity: 0; + text-shadow: none; + } + + 86.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 100% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } +} + +@media (prefers-color-scheme: light) { + .loadingContainer { + color: black; + } +}
\ No newline at end of file diff --git a/src/app/anime/video/loading.jsx b/src/app/anime/video/loading.jsx new file mode 100644 index 0000000..dfa397c --- /dev/null +++ b/src/app/anime/video/loading.jsx @@ -0,0 +1,9 @@ +import "./loading.css"; + +export default function Loading() { + return ( + <div className="loadingContainer"> + <p className="text-flicker-in-glow">Loading</p> + </div> + ); +} |