watch page progress

This commit is contained in:
Tejas Panchal
2025-07-30 20:55:12 +05:30
parent c0c1e93660
commit ef1746a716
4 changed files with 196 additions and 156 deletions

View File

@@ -137,9 +137,9 @@ function Episodelist({
}, [activeEpisodeId, episodes]);
return (
<div className="relative flex flex-col w-full h-full max-[1200px]:max-h-[500px]">
<div className="sticky top-0 z-10 flex flex-col gap-y-[5px] justify-start px-4 py-5 bg-[#1a1a1a] border-b border-[#2a2a2a]">
<h1 className="text-[14px] font-semibold text-white mb-2">Episodes</h1>
<div className="flex flex-col w-full h-full">
<div className="sticky top-0 z-10 flex flex-col gap-y-[5px] justify-start px-4 py-3 bg-[#1a1a1a] border-b border-[#2a2a2a]">
<h1 className="text-[14px] font-semibold text-white mb-1">Episodes</h1>
{totalEpisodes > 100 && (
<div className="w-full flex gap-x-4 items-center max-[1200px]:justify-between">
<div className="min-w-fit flex text-[13px]">
@@ -198,7 +198,7 @@ function Episodelist({
</div>
)}
</div>
<div ref={listContainerRef} className="w-full h-full overflow-y-auto bg-[#1a1a1a]">
<div ref={listContainerRef} className="w-full flex-1 overflow-y-auto bg-[#1a1a1a]">
<div
className={`${
totalEpisodes > 30

View File

@@ -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 (
<div className={`flex flex-col space-y-6 ${className}`}>
<h1 className="font-bold text-2xl text-[#ffbade]">{label}</h1>
<div className="flex flex-col space-y-4 bg-[#2B2A3C] p-4 pt-8">
<div className={`flex flex-col ${className}`}>
<div className="flex flex-col space-y-2 max-h-[600px] overflow-y-auto pr-2 scrollbar-thin scrollbar-track-[#1a1a1a] scrollbar-thumb-[#2a2a2a] hover:scrollbar-thumb-[#333] scrollbar-thumb-rounded">
{data &&
displayedData.map((item, index) => (
data.map((item, index) => (
<div
key={index}
className="flex items-center gap-x-4"
className="group"
ref={(el) => (cardRefs.current[index] = el)}
>
<div
style={{
borderBottom:
index + 1 < displayedData.length
? "1px solid rgba(255, 255, 255, .075)"
: "none",
}}
className="flex pb-4 relative container items-center"
>
{hoveredItem === item.id + index &&
window.innerWidth > 1024 && (
<div
className={`absolute ${tooltipPosition} ${tooltipHorizontalPosition} ${
tooltipPosition === "top-1/2"
? "translate-y-[50px]"
: "translate-y-[-50px]"
} z-[100000] transform transition-all duration-300 ease-in-out ${
hoveredItem === item.id + index
? "opacity-100 translate-y-0"
: "opacity-0 translate-y-2"
}`}
>
<Qtip id={item.id} />
</div>
)}
<div className="flex items-start gap-3 p-2 rounded-lg transition-colors hover:bg-[#1f1f1f]">
{hoveredItem === item.id + index && window.innerWidth > 1024 && (
<div
className={`absolute ${tooltipPosition} ${tooltipHorizontalPosition} ${
tooltipPosition === "top-1/2"
? "translate-y-[50px]"
: "translate-y-[-50px]"
} z-[100000] transform transition-all duration-300 ease-in-out ${
hoveredItem === item.id + index
? "opacity-100 translate-y-0"
: "opacity-0 translate-y-2"
}`}
>
<Qtip id={item.id} />
</div>
)}
<img
src={`${item.poster}`}
alt={item.title}
className="flex-shrink-0 w-[60px] h-[75px] rounded-md object-cover cursor-pointer"
className="w-[50px] h-[70px] rounded object-cover cursor-pointer transition-transform group-hover:scale-105"
onClick={() => navigate(`/watch/${item.id}`)}
onMouseEnter={() => handleMouseEnter(item, index)}
onMouseLeave={handleMouseLeave}
/>
<div className="flex flex-col ml-4 space-y-2">
<div className="flex flex-col gap-1.5 flex-1 min-w-0">
<Link
to={`/${item.id}`}
className="text-[1em] font-[500] hover:cursor-pointer hover:text-[#ffbade] transform transition-all ease-out line-clamp-1 max-[478px]:line-clamp-2 max-[478px]:text-[14px]"
onClick={() =>
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}
</Link>
<div className="flex flex-wrap items-center w-fit space-x-1 max-[320px]:gap-y-2">
<div className="flex flex-wrap items-center gap-2">
{item.tvInfo?.sub && (
<div className="flex space-x-1 justify-center items-center bg-[#B0E3AF] rounded-[4px] px-[4px] text-black py-[2px]">
<div className="flex items-center gap-1 px-1.5 py-0.5 bg-[#2a2a2a] rounded text-gray-300">
<FontAwesomeIcon
icon={faClosedCaptioning}
className="text-[12px]"
className="text-[10px]"
/>
<p className="text-[12px] font-bold">
<span className="text-[10px] font-medium">
{item.tvInfo.sub}
</p>
</span>
</div>
)}
{item.tvInfo?.dub && (
<div className="flex space-x-1 justify-center items-center bg-[#B9E7FF] rounded-[4px] px-[8px] text-black py-[2px]">
<div className="flex items-center gap-1 px-1.5 py-0.5 bg-[#2a2a2a] rounded text-gray-300">
<FontAwesomeIcon
icon={faMicrophone}
className="text-[12px]"
className="text-[10px]"
/>
<p className="text-[12px] font-bold">
<span className="text-[10px] font-medium">
{item.tvInfo.dub}
</p>
</span>
</div>
)}
{item.tvInfo?.showType && (
<div className="flex items-center gap-x-2">
<div className="dot ml-[4px]"></div>
<p className="text-[15px] font-light">
{item.tvInfo.showType}
</p>
</div>
<span className="text-xs text-gray-400">
{item.tvInfo.showType}
</span>
)}
</div>
</div>
</div>
</div>
))}
{!limit && data.length > 6 && (
<button
className="w-full bg-[#555462d3] py-3 mt-4 hover:bg-[#555462] rounded-md font-bold transform transition-all ease-out"
onClick={toggleShowAll}
>
{showAll ? "Show less" : "Show more"}
</button>
)}
</div>
</div>
);

View File

@@ -3,14 +3,17 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useEffect, useState } from "react";
const ToggleButton = ({ label, isActive, onClick }) => (
<button className="flex gap-x-2" onClick={onClick}>
<h1 className="capitalize text-[13px]">{label}</h1>
<button
className="flex items-center text-xs px-2 py-0.5 rounded transition-colors hover:bg-[#2a2a2a]"
onClick={onClick}
>
<span className="text-gray-300">{label}</span>
<span
className={`capitalize text-[13px] ${
isActive ? "text-[#ffbade]" : "text-red-500"
className={`ml-1.5 ${
isActive ? "text-white" : "text-gray-500"
}`}
>
{isActive ? "on" : "off"}
{isActive ? "ON" : "OFF"}
</span>
</button>
);
@@ -42,25 +45,25 @@ export default function WatchControls({
}, [episodeId, episodes]);
return (
<div className="bg-[#11101A] w-full flex justify-between flex-wrap px-4 pt-4 max-[1200px]:bg-[#14151A] max-[375px]:flex-col max-[375px]:gap-y-2">
<div className="flex gap-x-4 flex-wrap">
<div className="w-full flex justify-between items-center px-3 py-2 border-b border-gray-800">
<div className="flex gap-x-2">
<ToggleButton
label="auto play"
label="Auto Play"
isActive={autoPlay}
onClick={() => setAutoPlay((prev) => !prev)}
/>
<ToggleButton
label="auto skip intro"
<ToggleButton
label="Skip Intro"
isActive={autoSkipIntro}
onClick={() => setAutoSkipIntro((prev) => !prev)}
/>
/>
<ToggleButton
label="auto next"
label="Auto Next"
isActive={autoNext}
onClick={() => setAutoNext((prev) => !prev)}
/>
</div>
<div className="flex gap-x-6 max-[575px]:gap-x-4 max-[375px]:justify-end">
<div className="flex items-center gap-x-2">
<button
onClick={() => {
if (currentEpisodeIndex > 0) {
@@ -70,11 +73,13 @@ export default function WatchControls({
}
}}
disabled={currentEpisodeIndex <= 0}
className={`w-7 h-7 flex items-center justify-center rounded transition-colors ${
currentEpisodeIndex <= 0
? "text-gray-600 cursor-not-allowed"
: "text-gray-300 hover:text-white"
}`}
>
<FontAwesomeIcon
icon={faBackward}
className="text-[20px] max-[575px]:text-[16px] text-white"
/>
<FontAwesomeIcon icon={faBackward} className="text-[14px]" />
</button>
<button
onClick={() => {
@@ -85,11 +90,13 @@ export default function WatchControls({
}
}}
disabled={currentEpisodeIndex >= episodes?.length - 1}
className={`w-7 h-7 flex items-center justify-center rounded transition-colors ${
currentEpisodeIndex >= episodes?.length - 1
? "text-gray-600 cursor-not-allowed"
: "text-gray-300 hover:text-white"
}`}
>
<FontAwesomeIcon
icon={faForward}
className="text-[20px] max-[575px]:text-[16px] text-white"
/>
<FontAwesomeIcon icon={faForward} className="text-[14px]" />
</button>
</div>
</div>