diff --git a/src/components/episodelist/Episodelist.jsx b/src/components/episodelist/Episodelist.jsx index 00f50d6..857246a 100644 --- a/src/components/episodelist/Episodelist.jsx +++ b/src/components/episodelist/Episodelist.jsx @@ -137,9 +137,9 @@ function Episodelist({ }, [activeEpisodeId, episodes]); return ( -
-
-

Episodes

+
+
+

Episodes

{totalEpisodes > 100 && (
@@ -198,7 +198,7 @@ function Episodelist({
)}
-
+
30 diff --git a/src/components/sidecard/Sidecard.jsx b/src/components/sidecard/Sidecard.jsx index 0bcccd1..8baf4ef 100644 --- a/src/components/sidecard/Sidecard.jsx +++ b/src/components/sidecard/Sidecard.jsx @@ -9,10 +9,9 @@ import { Link, useNavigate } from "react-router-dom"; import useToolTipPosition from "@/src/hooks/useToolTipPosition"; import Qtip from "../qtip/Qtip"; -function Sidecard({ data, label, className, limit }) { +function Sidecard({ data, label, className }) { const { language } = useLanguage(); const navigate = useNavigate(); - const [showAll, setShowAll] = useState(false); const [hoverTimeout, setHoverTimeout] = useState(null); const handleMouseEnter = (item, index) => { const timeout = setTimeout(() => { @@ -24,116 +23,86 @@ function Sidecard({ data, label, className, limit }) { clearTimeout(hoverTimeout); setHoveredItem(null); }; - const toggleShowAll = () => { - setShowAll((prev) => !prev); - }; - const displayedData = limit - ? data.slice(0, limit) - : showAll - ? data - : data.slice(0, 6); const [hoveredItem, setHoveredItem] = useState(null); const { tooltipPosition, tooltipHorizontalPosition, cardRefs } = useToolTipPosition(hoveredItem, data); + return ( -
-

{label}

-
+
+
{data && - displayedData.map((item, index) => ( + data.map((item, index) => (
(cardRefs.current[index] = el)} > -
- {hoveredItem === item.id + index && - window.innerWidth > 1024 && ( -
- -
- )} +
+ {hoveredItem === item.id + index && window.innerWidth > 1024 && ( +
+ +
+ )} {item.title} navigate(`/watch/${item.id}`)} onMouseEnter={() => handleMouseEnter(item, index)} onMouseLeave={handleMouseLeave} /> -
+
- window.scrollTo({ top: 0, behavior: "smooth" }) - } + className="text-sm font-medium text-gray-200 hover:text-white transition-colors line-clamp-1" + onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })} > {language === "EN" ? item.title : item.japanese_title} -
+
{item.tvInfo?.sub && ( -
+
-

+ {item.tvInfo.sub} -

+
)} {item.tvInfo?.dub && ( -
+
-

+ {item.tvInfo.dub} -

+
)} {item.tvInfo?.showType && ( -
-
-

- {item.tvInfo.showType} -

-
+ + {item.tvInfo.showType} + )}
))} - {!limit && data.length > 6 && ( - - )}
); diff --git a/src/components/watchcontrols/Watchcontrols.jsx b/src/components/watchcontrols/Watchcontrols.jsx index c5ca17e..3b213d8 100644 --- a/src/components/watchcontrols/Watchcontrols.jsx +++ b/src/components/watchcontrols/Watchcontrols.jsx @@ -3,14 +3,17 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useEffect, useState } from "react"; const ToggleButton = ({ label, isActive, onClick }) => ( - ); @@ -42,25 +45,25 @@ export default function WatchControls({ }, [episodeId, episodes]); return ( -
-
+
+
setAutoPlay((prev) => !prev)} /> - setAutoSkipIntro((prev) => !prev)} - /> + /> setAutoNext((prev) => !prev)} />
-
+
diff --git a/src/pages/watch/Watch.jsx b/src/pages/watch/Watch.jsx index 4433730..5702804 100644 --- a/src/pages/watch/Watch.jsx +++ b/src/pages/watch/Watch.jsx @@ -72,6 +72,10 @@ export default function Watch() { autoNext, setAutoNext, } = useWatchControl(); + const playerRef = useRef(null); + const videoContainerRef = useRef(null); + const controlsRef = useRef(null); + const episodesRef = useRef(null); useEffect(() => { if (!episodes || episodes.length === 0) return; @@ -119,26 +123,66 @@ export default function Watch() { }, [streamInfo, episodeId, animeId, totalEpisodes, navigate]); useEffect(() => { + // Function to adjust the height of episodes list to match only video + controls const adjustHeight = () => { if (window.innerWidth > 1200) { - const player = document.querySelector(".player"); - const episodes = document.querySelector(".episodes"); - if (player && episodes) { - episodes.style.height = `${player.clientHeight}px`; + if (videoContainerRef.current && controlsRef.current && episodesRef.current) { + // Calculate combined height of video container and controls + const videoHeight = videoContainerRef.current.offsetHeight; + const controlsHeight = controlsRef.current.offsetHeight; + const totalHeight = videoHeight + controlsHeight; + + // Apply the combined height to episodes container + episodesRef.current.style.height = `${totalHeight}px`; } } else { - const episodes = document.querySelector(".episodes"); - if (episodes) { - episodes.style.height = "auto"; + if (episodesRef.current) { + episodesRef.current.style.height = 'auto'; } } }; - adjustHeight(); - window.addEventListener("resize", adjustHeight); + + // Initial adjustment with delay to ensure player is fully rendered + const initialTimer = setTimeout(() => { + adjustHeight(); + }, 500); + + // Set up resize listener + window.addEventListener('resize', adjustHeight); + + // Create MutationObserver to monitor player changes + const observer = new MutationObserver(() => { + setTimeout(adjustHeight, 100); + }); + + // Start observing both video container and controls + if (videoContainerRef.current) { + observer.observe(videoContainerRef.current, { + attributes: true, + childList: true, + subtree: true + }); + } + + if (controlsRef.current) { + observer.observe(controlsRef.current, { + attributes: true, + childList: true, + subtree: true + }); + } + + // Set up additional interval for continuous adjustments + const intervalId = setInterval(adjustHeight, 1000); + + // Clean up return () => { - window.removeEventListener("resize", adjustHeight); + clearTimeout(initialTimer); + clearInterval(intervalId); + observer.disconnect(); + window.removeEventListener('resize', adjustHeight); }; - }); + }, [buffering, activeServerType, activeServerName, episodeId, streamUrl, episodes]); function Tag({ bgColor, index, icon, text }) { return ( @@ -182,13 +226,13 @@ export default function Watch() { }, [animeId, animeInfo]); return (
-
+
{/* Left Column - Player, Controls, Servers */}
-
+
{/* Video Container */} -
+
{!buffering ? (["hd-1", "hd-4"].includes(activeServerName.toLowerCase()) ? {/* Controls Section */} -
+
{!buffering && ( -
+
- +
{animeInfo && animeInfo?.title ? ( -

- {language ? animeInfo?.title : animeInfo?.japanese_title} -

+ +

+ {language ? animeInfo?.title : animeInfo?.japanese_title} +

+
+ View Details + + + +
+ ) : ( )} @@ -366,12 +420,6 @@ export default function Watch() { )}

)} - - View Details -
@@ -380,22 +428,47 @@ export default function Watch() { {seasons?.length > 0 && (

More Seasons

-
+
{seasons.map((season, index) => ( -
-

+ {/* Dots Pattern Overlay */} +

')`, + backgroundSize: '3px 3px' + }} + /> + {/* Dark Gradient Overlay */} +
+ {/* Title Container */} +
+

{season.season}

@@ -404,22 +477,29 @@ export default function Watch() {
)} +
- {/* Recommended Section */} - {animeInfo?.recommended_data.length > 0 && ( -
-

Recommended

- + {/* Episodes Section */} +
+ {!episodes ? ( +
+ +
+ ) : ( + setEpisodeId(id)} + totalEpisodes={totalEpisodes} /> -
- )} + )} +
{/* Related Anime Section */} {animeInfo && animeInfo.related_data ? ( -
+

Related Anime

)}
- - {/* Right Column - Episodes */} -
- {!episodes ? ( -
- -
- ) : ( - setEpisodeId(id)} - totalEpisodes={totalEpisodes} - /> - )} -