aboutsummaryrefslogtreecommitdiff
path: root/pages/en/anime
diff options
context:
space:
mode:
authorFactiven <[email protected]>2023-08-09 15:11:53 +0700
committerGitHub <[email protected]>2023-08-09 15:11:53 +0700
commitbae1f53877c3447d3ba940f823e5a8a097f5b22c (patch)
tree98abb195bcad6f3e6c61c76c62fc238f227b0ead /pages/en/anime
parentUpdate package-lock.json (diff)
downloadmoopa-3.9.0.tar.xz
moopa-3.9.0.zip
Update v3.9.0 - Merged Beta to Main (#41)v3.9.0
* initial commit * Update_v.3.6.7-beta-v1.2 * Update_v.3.6.7-beta-v1.3 * Update_v.3.6.7-beta-v1.3 > update API * Fixed mediaList won't update * added .env disqus shortname * Update_v3.6.7-beta-v1.4 >Implementing database * Create main.yml * Update v3.6.7-beta-v1.5 small patch * title home page * Update content.js * Delete db-test.js * Update content.js * Update home page card * Update v3.7.0 * Update v3.7.1-beta > migrating backend to main code > fixed schedule component * Update v3.8.0 > Added dub options > Moved schedule backend * Update v.3.8.1 > Fixed episodes on watch page isn't dubbed * Update v3.8.1-patch-1 * Update v3.8.1-patch-2 > Another patch for dub * Update v3.8.2 > Removed prisma configuration for database since it's not stable yet * Update v3.8.3 > Fixed different provider have same id * Update v.3.8.3 > Fixed player bug where the controls won't hide after updating anilist progress * Update v3.8.4-patch-2 * Update v3.8.5 > Update readme.md > Update .env.example * Update next.config.js * small adjusment info page * Update v3.8.6 > Minor update for Android 13 user * Update v3.8.7 > Added prev and next button to mediaSession * Update v3.8.7-beta-v2 * Beta v2 (#37) * Update schema.prisma * Update schema.prisma * Update schema.prisma * Update 3.9.0-beta-v2.1 > Implemented database for storing user Watch List and settings > Added buttons to auto-play next episodes * Update v3.9.0-beta-v2.2 * Update README.md --------- Co-authored-by: Chitraksh Maheshwari <[email protected]>
Diffstat (limited to 'pages/en/anime')
-rw-r--r--pages/en/anime/[...id].js1
-rw-r--r--pages/en/anime/popular.js15
-rw-r--r--pages/en/anime/recently-watched.js159
-rw-r--r--pages/en/anime/trending.js15
-rw-r--r--pages/en/anime/watch/[...info].js29
5 files changed, 209 insertions, 10 deletions
diff --git a/pages/en/anime/[...id].js b/pages/en/anime/[...id].js
index 6c78955..5e4aed8 100644
--- a/pages/en/anime/[...id].js
+++ b/pages/en/anime/[...id].js
@@ -154,6 +154,7 @@ export default function Info({ info, color }) {
prg={progress}
max={info?.episodes}
image={info}
+ close={handleClose}
/>
)}
</div>
diff --git a/pages/en/anime/popular.js b/pages/en/anime/popular.js
index b8b19ba..8cbbeab 100644
--- a/pages/en/anime/popular.js
+++ b/pages/en/anime/popular.js
@@ -3,7 +3,6 @@ import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import Skeleton from "react-loading-skeleton";
-import Navbar from "../../../components/navbar";
import Footer from "../../../components/footer";
import { getServerSession } from "next-auth";
import { authOptions } from "../../api/auth/[...nextauth]";
@@ -98,7 +97,7 @@ export default function PopularAnime({ sessions }) {
<>
<MobileNav sessions={sessions} />
<div className="flex flex-col gap-2 items-center min-h-screen w-screen px-2 relative pb-10">
- <div className="z-50 bg-primary pt-5 pb-3 shadow-md shadow-primary w-full fixed left-3">
+ <div className="z-50 bg-primary pt-5 pb-3 shadow-md shadow-primary w-full fixed px-3">
<Link href="/en" className="flex gap-2 items-center font-karla">
<ChevronLeftIcon className="w-5 h-5" />
<h1 className="text-xl">Popular Anime</h1>
@@ -110,7 +109,11 @@ export default function PopularAnime({ sessions }) {
key={index}
className="flex flex-col items-center w-[150px] lg:w-[180px]"
>
- <Link href={`/en/anime/${i.id}`} className="p-2">
+ <Link
+ href={`/en/anime/${i.id}`}
+ className="p-2"
+ title={i.title.romaji}
+ >
<Image
src={i.coverImage.large}
alt={i.title.romaji}
@@ -119,7 +122,11 @@ export default function PopularAnime({ sessions }) {
className="w-[140px] h-[190px] lg:w-[170px] lg:h-[230px] object-cover rounded hover:scale-105 scale-100 transition-all duration-200 ease-out"
/>
</Link>
- <Link href={`/en/anime/${i.id}`} className="w-full px-2">
+ <Link
+ href={`/en/anime/${i.id}`}
+ className="w-full px-2"
+ title={i.title.romaji}
+ >
<h1 className="font-karla font-bold xl:text-base text-[15px] line-clamp-2">
{i.status === "RELEASING" ? (
<span className="dots bg-green-500" />
diff --git a/pages/en/anime/recently-watched.js b/pages/en/anime/recently-watched.js
new file mode 100644
index 0000000..0a7fbae
--- /dev/null
+++ b/pages/en/anime/recently-watched.js
@@ -0,0 +1,159 @@
+import { ChevronLeftIcon, PlayIcon } from "@heroicons/react/24/solid";
+import Image from "next/image";
+import Link from "next/link";
+import { useEffect, useState } from "react";
+import Skeleton from "react-loading-skeleton";
+import Footer from "../../../components/footer";
+import { getServerSession } from "next-auth";
+import { authOptions } from "../../api/auth/[...nextauth]";
+import MobileNav from "../../../components/home/mobileNav";
+
+export default function PopularAnime({ sessions }) {
+ const [data, setData] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ setLoading(true);
+ const fetchData = async () => {
+ let data;
+ if (sessions?.user?.name) {
+ data = await fetch(
+ `/api/user/profile?name=${sessions?.user?.name}`
+ ).then((res) => {
+ if (!res.ok) {
+ switch (res.status) {
+ case 404: {
+ return console.log("user not found");
+ }
+ case 500: {
+ return console.log("server error");
+ }
+ }
+ }
+ return res.json();
+ });
+ }
+ if (!data) {
+ const dat = JSON.parse(localStorage.getItem("artplayer_settings"));
+ if (dat) {
+ const arr = Object.keys(dat).map((key) => dat[key]);
+ setData(arr);
+ setLoading(false);
+ }
+ } else {
+ setData(data?.WatchListEpisode);
+ setLoading(false);
+ }
+ };
+ fetchData();
+ }, []);
+
+ return (
+ <>
+ <MobileNav sessions={sessions} />
+ <div className="flex flex-col gap-2 items-center min-h-screen w-screen px-2 relative pb-10">
+ <div className="z-50 bg-primary pt-5 pb-3 shadow-md shadow-primary w-full fixed left-0 px-3">
+ <Link href="/en" className="flex gap-2 items-center font-karla">
+ <ChevronLeftIcon className="w-5 h-5" />
+ <h1 className="text-xl">Recently Watched</h1>
+ </Link>
+ </div>
+ <div className="grid grid-cols-1 xs:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 2xl:grid-cols-4 gap-3 md:gap-7 pt-16">
+ {data
+ ?.filter((i) => i.title !== null)
+ .map((i) => {
+ const time = i.timeWatched;
+ const duration = i.duration;
+ let prog = (time / duration) * 100;
+ if (prog > 90) prog = 100;
+
+ return (
+ <Link
+ key={i.watchId}
+ className="flex flex-col gap-2 shrink-0 cursor-pointer"
+ href={`/en/anime/watch/${i.aniId}/${
+ i.provider
+ }?id=${encodeURIComponent(i.watchId)}&num=${i.episode}`}
+ >
+ <div className="relative md:w-[320px] aspect-video rounded-md overflow-hidden group">
+ <div className="w-full h-full bg-gradient-to-t from-black/70 from-20% to-transparent group-hover:to-black/40 transition-all duration-300 ease-out absolute z-30" />
+ <div className="absolute bottom-3 left-0 mx-2 text-white flex gap-2 items-center w-[80%] z-30">
+ <PlayIcon className="w-5 h-5 shrink-0" />
+ <h1
+ className="font-semibold text-sm md:text-base font-karla line-clamp-1"
+ title={i?.title || i.anititle}
+ >
+ {i?.title || i.anititle}
+ </h1>
+ </div>
+ <span
+ className={`absolute bottom-0 left-0 h-[2px] bg-red-600 z-30`}
+ style={{
+ width: `${prog}%`,
+ }}
+ />
+ {i?.image && (
+ <Image
+ src={i?.image}
+ width={200}
+ height={200}
+ alt="Episode Thumbnail"
+ className="w-fit group-hover:scale-[1.02] duration-300 ease-out z-10"
+ />
+ )}
+ </div>
+ <div className="flex flex-col font-karla w-full">
+ {/* <h1 className="font-semibold">{i.title}</h1> */}
+ <p className="flex items-center gap-1 text-sm text-gray-400 md:w-[320px]">
+ <span
+ className="text-white max-w-[150px] md:max-w-[220px]"
+ style={{
+ display: "inline-block",
+ overflow: "hidden",
+ textOverflow: "ellipsis",
+ whiteSpace: "nowrap",
+ }}
+ title={i.aniTitle}
+ >
+ {i.aniTitle}
+ </span>{" "}
+ | Episode {i.episode}
+ </p>
+ </div>
+ </Link>
+ );
+ })}
+
+ {loading && (
+ <>
+ {[1, 2, 4, 5, 6, 7, 8].map((item) => (
+ <div
+ key={item}
+ className="flex flex-col gap-2 items-center md:w-[320px] rounded-md overflow-hidden"
+ >
+ <div className="w-full">
+ <Skeleton className="w-fit aspect-video rounded" />
+ </div>
+ <div className="w-full">
+ <Skeleton width={80} height={20} />
+ </div>
+ </div>
+ ))}
+ </>
+ )}
+ </div>
+ </div>
+ <Footer />
+ </>
+ );
+}
+
+export async function getServerSideProps(context) {
+ const session = await getServerSession(context.req, context.res, authOptions);
+
+ return {
+ props: {
+ sessions: session,
+ },
+ };
+}
diff --git a/pages/en/anime/trending.js b/pages/en/anime/trending.js
index cbc30ab..9f8a187 100644
--- a/pages/en/anime/trending.js
+++ b/pages/en/anime/trending.js
@@ -3,7 +3,6 @@ import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import Skeleton from "react-loading-skeleton";
-import Navbar from "../../../components/navbar";
import Footer from "../../../components/footer";
import { getServerSession } from "next-auth";
import { authOptions } from "../../api/auth/[...nextauth]";
@@ -98,7 +97,7 @@ export default function TrendingAnime({ sessions }) {
<>
<MobileNav sessions={sessions} />
<div className="flex flex-col gap-2 items-center min-h-screen w-screen px-2 relative pb-10">
- <div className="z-50 bg-primary pt-5 pb-3 shadow-md shadow-primary w-full fixed left-3">
+ <div className="z-50 bg-primary pt-5 pb-3 shadow-md shadow-primary w-full fixed px-3">
<Link href="/en" className="flex gap-2 items-center font-karla">
<ChevronLeftIcon className="w-5 h-5" />
<h1 className="text-xl">Trending Now</h1>
@@ -110,7 +109,11 @@ export default function TrendingAnime({ sessions }) {
key={index}
className="flex flex-col items-center w-[150px] lg:w-[180px]"
>
- <Link href={`/en/anime/${i.id}`} className="p-2">
+ <Link
+ href={`/en/anime/${i.id}`}
+ className="p-2"
+ title={i.title.romaji}
+ >
<Image
src={i.coverImage.large}
alt={i.title.romaji}
@@ -119,7 +122,11 @@ export default function TrendingAnime({ sessions }) {
className="w-[140px] h-[190px] lg:w-[170px] lg:h-[230px] object-cover rounded hover:scale-105 scale-100 transition-all duration-200 ease-out"
/>
</Link>
- <Link href={`/en/anime/${i.id}`} className="w-full px-2">
+ <Link
+ href={`/en/anime/${i.id}`}
+ className="w-full px-2"
+ title={i.title.romaji}
+ >
<h1 className="font-karla font-bold xl:text-base text-[15px] line-clamp-2">
{i.status === "RELEASING" ? (
<span className="dots bg-green-500" />
diff --git a/pages/en/anime/watch/[...info].js b/pages/en/anime/watch/[...info].js
index 67e38c2..bc8851b 100644
--- a/pages/en/anime/watch/[...info].js
+++ b/pages/en/anime/watch/[...info].js
@@ -9,6 +9,8 @@ import Navigasi from "../../../../components/home/staticNav";
import PrimarySide from "../../../../components/anime/watch/primarySide";
import SecondarySide from "../../../../components/anime/watch/secondarySide";
import { GET_MEDIA_USER } from "../../../../queries";
+import { createList, createUser, getEpisode } from "../../../../prisma/user";
+// import { updateUser } from "../../../../prisma/user";
export default function Info({
sessions,
@@ -17,6 +19,7 @@ export default function Info({
provider,
epiNumber,
dub,
+ userData,
proxy,
disqus,
}) {
@@ -124,7 +127,7 @@ export default function Info({
}
}
}
-
+
setInfo(data.data.Media);
const response = await fetch(
@@ -156,12 +159,16 @@ export default function Info({
setLoading(false);
}
}
-
+
setArtStorage(JSON.parse(localStorage.getItem("artplayer_settings")));
// setEpiData(episodes);
setLoading(false);
}
getInfo();
+
+ return () => {
+ setCurrentEpisode(null);
+ };
}, [sessions?.user?.name, epiNumber, dub]);
// console.log(proxy);
@@ -190,6 +197,7 @@ export default function Info({
setOnList={setOnList}
setLoading={setLoading}
loading={loading}
+ timeWatched={userData?.timeWatched}
/>
<SecondarySide
info={info}
@@ -227,6 +235,22 @@ export async function getServerSideProps(context) {
const epiNumber = query.num;
const dub = query.dub;
+ let userData = null;
+
+ if (session) {
+ await createUser(session.user.name);
+ await createList(session.user.name, watchId);
+ const data = await getEpisode(session.user.name, watchId);
+ userData = JSON.parse(
+ JSON.stringify(data, (key, value) => {
+ if (key === "createdDate") {
+ return String(value);
+ }
+ return value;
+ })
+ );
+ }
+
return {
props: {
sessions: session,
@@ -235,6 +259,7 @@ export async function getServerSideProps(context) {
watchId: watchId || null,
epiNumber: epiNumber || null,
dub: dub || null,
+ userData: userData?.[0] || null,
proxy,
disqus,
},