From 1eee181e219dfd993d396ac3169e7aad3dd285eb Mon Sep 17 00:00:00 2001 From: Factiven Date: Sun, 16 Jul 2023 22:35:39 +0700 Subject: Update v3.6.4 - Added Manga page with a working tracker for AniList user - Added schedule component to home page - Added disqus comment section so you can fight on each other (not recommended) - Added /id and /en route for english and indonesian subs (id route still work in progress) --- components/manga/panels/firstPanel.js | 200 +++++++++++++++++++++++++++++++++ components/manga/panels/secondPanel.js | 191 +++++++++++++++++++++++++++++++ components/manga/panels/thirdPanel.js | 171 ++++++++++++++++++++++++++++ 3 files changed, 562 insertions(+) create mode 100644 components/manga/panels/firstPanel.js create mode 100644 components/manga/panels/secondPanel.js create mode 100644 components/manga/panels/thirdPanel.js (limited to 'components/manga/panels') diff --git a/components/manga/panels/firstPanel.js b/components/manga/panels/firstPanel.js new file mode 100644 index 0000000..29484be --- /dev/null +++ b/components/manga/panels/firstPanel.js @@ -0,0 +1,200 @@ +import { useEffect, useRef, useState } from "react"; +import { + ArrowsPointingOutIcon, + ArrowsPointingInIcon, + ChevronLeftIcon, + ChevronRightIcon, +} from "@heroicons/react/24/outline"; +import Image from "next/image"; +import { useRouter } from "next/router"; +import { useAniList } from "../../../lib/anilist/useAnilist"; + +export default function FirstPanel({ + aniId, + data, + hasRun, + currentId, + seekPage, + setSeekPage, + visible, + setVisible, + chapter, + nextChapter, + prevChapter, + paddingX, + session, + mobileVisible, + setMobileVisible, + setCurrentPage, +}) { + const { markProgress } = useAniList(session); + const [currentImageIndex, setCurrentImageIndex] = useState(0); + const imageRefs = useRef([]); + const scrollContainerRef = useRef(); + + const router = useRouter(); + + useEffect(() => { + const handleScroll = () => { + const scrollTop = scrollContainerRef.current.scrollTop; + let index = 0; + + for (let i = 0; i < imageRefs.current.length; i++) { + const img = imageRefs.current[i]; + if ( + scrollTop >= img?.offsetTop - scrollContainerRef.current.offsetTop && + scrollTop < + img.offsetTop - + scrollContainerRef.current.offsetTop + + img.offsetHeight + ) { + index = i; + break; + } + } + + if (index === data.length - 3 && !hasRun.current) { + if (session) { + const currentChapter = chapter.chapters?.find( + (x) => x.id === currentId + ); + if (currentChapter) { + markProgress(aniId, currentChapter.number); + console.log("marking progress"); + } + } + hasRun.current = true; + } + + setCurrentPage(index + 1); + setCurrentImageIndex(index); + setSeekPage(index); + }; + + scrollContainerRef?.current?.addEventListener("scroll", handleScroll, { + passive: true, + }); + + return () => { + if (scrollContainerRef.current) { + scrollContainerRef.current.removeEventListener("scroll", handleScroll, { + passive: true, + }); + } + }; + }, [data, session, chapter]); + + useEffect(() => { + if (scrollContainerRef.current && seekPage !== currentImageIndex) { + const targetImageRef = imageRefs.current[seekPage]; + if (targetImageRef) { + scrollContainerRef.current.scrollTo({ + top: targetImageRef.offsetTop - scrollContainerRef.current.offsetTop, + behavior: "smooth", + }); + } + } + }, [seekPage, currentImageIndex]); + + useEffect(() => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollTo(0, 0); + } + }, [currentId]); + + useEffect(() => { + if (typeof window !== "undefined") { + const root = window.document.documentElement; + root.style.setProperty("--dynamic-padding", `${paddingX}px`); + } + }, [paddingX]); + + return ( +
+
+ {data && Array.isArray(data) && data?.length > 0 ? ( + data.map((i, index) => ( +
(imageRefs.current[index] = el)} + > + {i.index} setMobileVisible(!mobileVisible)} + className="w-screen lg:w-full h-auto bg-[#bbb]" + /> +
+ )) + ) : ( +
+ {data.error || "Not found"} :( +
+ )} +
+
+ + {visible ? ( + + ) : ( + + )} + +
+ + +
+
+ {`Page ${ + currentImageIndex + 1 + }/${data.length}`} +
+ ); +} diff --git a/components/manga/panels/secondPanel.js b/components/manga/panels/secondPanel.js new file mode 100644 index 0000000..6048fb4 --- /dev/null +++ b/components/manga/panels/secondPanel.js @@ -0,0 +1,191 @@ +import { useEffect, useRef, useState } from "react"; +import Image from "next/image"; +import { + ArrowsPointingOutIcon, + ArrowsPointingInIcon, +} from "@heroicons/react/24/outline"; +import { useAniList } from "../../../lib/anilist/useAnilist"; + +export default function SecondPanel({ + aniId, + data, + hasRun, + currentChapter, + currentId, + seekPage, + setSeekPage, + visible, + setVisible, + session, +}) { + const [index, setIndex] = useState(0); + const [image, setImage] = useState(null); + + const { markProgress } = useAniList(session); + + useEffect(() => { + setIndex(0); + setSeekPage(0); + }, [data, currentId]); + + const seekToIndex = (newIndex) => { + if (newIndex >= 0 && newIndex < data.length) { + // if newIndex is odd, decrease it by 1 to show the previous page + if (newIndex % 2 !== 0) { + newIndex = newIndex - 1; + } + setIndex(newIndex); + setSeekPage(newIndex); + } + }; + + useEffect(() => { + seekToIndex(seekPage); + }, [seekPage]); + + useEffect(() => { + if (data && Array.isArray(data) && data?.length > 0) { + setImage([...data].reverse()); // Create a copy of data before reversing + } + }, [data]); + + useEffect(() => { + const handleKeyDown = (event) => { + if (event.key === "ArrowRight") { + if (index > 0) { + setIndex(index - 2); + setSeekPage(index - 2); + } + } else if (event.key === "ArrowLeft") { + if (index < image.length - 2) { + setIndex(index + 2); + setSeekPage(index + 2); + } + + if (index + 1 >= image.length - 4 && !hasRun.current) { + let chapterNumber = currentChapter?.number; + if (chapterNumber % 1 !== 0) { + // If it's a decimal, round it + chapterNumber = Math.round(chapterNumber); + } + + markProgress(aniId, chapterNumber); + hasRun.current = true; + } + } + }; + + window.addEventListener("keydown", handleKeyDown); + + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, [index, image]); + + const handleNext = () => { + if (index < image.length - 2) { + setIndex(index + 2); + setSeekPage(index + 2); + } + + if (index + 1 >= image.length - 4 && !hasRun.current) { + console.log("marking progress"); + let chapterNumber = currentChapter?.number; + if (chapterNumber % 1 !== 0) { + // If it's a decimal, round it + chapterNumber = Math.round(chapterNumber); + } + + markProgress(aniId, chapterNumber); + hasRun.current = true; + } + }; + + const handlePrev = () => { + if (index > 0) { + setIndex(index - 2); + setSeekPage(index - 2); + } + }; + return ( +
+
+ {image && Array.isArray(image) && image?.length > 0 ? ( + <> +
+ {image[image.length - index - 2]?.url && ( + Manga Page + )} + Manga Page +
+
+ + +
+ + ) : ( +
+ {data.error || "Not found"} :( +
+ )} + + {visible ? ( + + ) : ( + + )} + + + Page {index + 1} + {index + 2 > data.length ? "" : `-${index + 2}`}/{data.length} + +
+
+ ); +} diff --git a/components/manga/panels/thirdPanel.js b/components/manga/panels/thirdPanel.js new file mode 100644 index 0000000..7dff76b --- /dev/null +++ b/components/manga/panels/thirdPanel.js @@ -0,0 +1,171 @@ +import { useEffect, useRef, useState } from "react"; +import Image from "next/image"; +import { + ArrowsPointingOutIcon, + ArrowsPointingInIcon, +} from "@heroicons/react/24/outline"; +import { useAniList } from "../../../lib/anilist/useAnilist"; + +export default function ThirdPanel({ + aniId, + data, + hasRun, + currentId, + currentChapter, + seekPage, + setSeekPage, + visible, + setVisible, + session, + scaleImg, + setMobileVisible, + mobileVisible, +}) { + const [index, setIndex] = useState(0); + const [image, setImage] = useState(null); + const { markProgress } = useAniList(session); + + useEffect(() => { + setIndex(0); + setSeekPage(0); + }, [data, currentId]); + + const seekToIndex = (newIndex) => { + if (newIndex >= 0 && newIndex < data.length) { + setIndex(newIndex); + setSeekPage(newIndex); + } + }; + + useEffect(() => { + seekToIndex(seekPage); + }, [seekPage]); + + useEffect(() => { + if (data && Array.isArray(data) && data?.length > 0) { + setImage([...data].reverse()); // Create a copy of data before reversing + } + }, [data]); + + useEffect(() => { + const handleKeyDown = (event) => { + if (event.key === "ArrowRight") { + if (index > 0) { + setIndex(index - 1); + setSeekPage(index - 1); + } + } else if (event.key === "ArrowLeft") { + if (index < image.length - 1) { + setIndex(index + 1); + setSeekPage(index + 1); + } + if (index + 1 >= image.length - 2 && !hasRun.current) { + let chapterNumber = currentChapter?.number; + if (chapterNumber % 1 !== 0) { + // If it's a decimal, round it + chapterNumber = Math.round(chapterNumber); + } + + markProgress(aniId, chapterNumber); + hasRun.current = true; + } + } + }; + + window.addEventListener("keydown", handleKeyDown); + + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, [index, image]); + + const handleNext = () => { + if (index < image.length - 1) { + setIndex(index + 1); + setSeekPage(index + 1); + } + if (index + 1 >= image.length - 2 && !hasRun.current) { + let chapterNumber = currentChapter?.number; + if (chapterNumber % 1 !== 0) { + // If it's a decimal, round it + chapterNumber = Math.round(chapterNumber); + } + + markProgress(aniId, chapterNumber); + hasRun.current = true; + } + }; + + const handlePrev = () => { + if (index > 0) { + setIndex(index - 1); + setSeekPage(index - 1); + } + }; + + return ( +
+
+ {image && Array.isArray(image) && image?.length > 0 ? ( + <> +
+ setMobileVisible(!mobileVisible)} + src={`https://img.moopa.live/image-proxy?url=${encodeURIComponent( + image[image.length - index - 1]?.url + )}&headers=${encodeURIComponent( + JSON.stringify({ + Referer: image[image.length - index - 1]?.headers.Referer, + }) + )}`} + alt="Manga Page" + style={{ + transform: `scale(${scaleImg})`, + transformOrigin: "top", + }} + /> +
+
+ + +
+ + ) : ( +
+ {data.error || "Not found"} :( +
+ )} + + {visible ? ( + + ) : ( + + )} + + + Page {index + 1}/{data.length} + +
+
+ ); +} -- cgit v1.2.3