|
|
@ -35,6 +35,7 @@ export default function Video() { |
|
|
const [playlists, setPlaylists] = useState([]); |
|
|
const [playlists, setPlaylists] = useState([]); |
|
|
const [isAddToPlaylistOpen, setIsAddToPlaylistOpen] = useState(false); |
|
|
const [isAddToPlaylistOpen, setIsAddToPlaylistOpen] = useState(false); |
|
|
const [currentPlaylist, setCurrentPlaylist] = useState(null); |
|
|
const [currentPlaylist, setCurrentPlaylist] = useState(null); |
|
|
|
|
|
const [isCommentVisible, setIsCommentVisible] = useState(window.innerWidth >= 1024); // Show comments by default on large screens |
|
|
|
|
|
|
|
|
const fetchVideo = useCallback(async () => { |
|
|
const fetchVideo = useCallback(async () => { |
|
|
// Fetch video data and similar videos based on the video ID from the URL |
|
|
// Fetch video data and similar videos based on the video ID from the URL |
|
|
@ -307,11 +308,11 @@ export default function Video() { |
|
|
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient"> |
|
|
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient"> |
|
|
<Navbar isSearchPage={false} alerts={alerts} onCloseAlert={onCloseAlert} /> |
|
|
<Navbar isSearchPage={false} alerts={alerts} onCloseAlert={onCloseAlert} /> |
|
|
|
|
|
|
|
|
<main className="px-36 w-full flex justify-between pt-[118px]"> |
|
|
<main className="px-5 lg:px-36 w-full lg:flex justify-between pt-[48px] lg:pt-[118px]"> |
|
|
{video ? ( |
|
|
{video ? ( |
|
|
<> |
|
|
<> |
|
|
{/* Video player section */} |
|
|
{/* Video player section */} |
|
|
<div className="w-1280/1920"> |
|
|
<div className="lg:w-1280/1920"> |
|
|
|
|
|
|
|
|
<div |
|
|
<div |
|
|
className="relative w-full aspect-video mx-auto rounded-lg overflow-hidden" |
|
|
className="relative w-full aspect-video mx-auto rounded-lg overflow-hidden" |
|
|
@ -326,6 +327,8 @@ export default function Video() { |
|
|
onTimeUpdate={handleTimeUpdate} |
|
|
onTimeUpdate={handleTimeUpdate} |
|
|
onLoadedMetadata={handleLoadedMetadata} |
|
|
onLoadedMetadata={handleLoadedMetadata} |
|
|
onEnded={passToNextVideo} |
|
|
onEnded={passToNextVideo} |
|
|
|
|
|
className="w-full h-full object-cover" |
|
|
|
|
|
controls={window.innerWidth < 1024} // Show native controls on small screens |
|
|
> |
|
|
> |
|
|
<source src={`${video.file}`} type="video/mp4" /> |
|
|
<source src={`${video.file}`} type="video/mp4" /> |
|
|
Your browser does not support the video tag. |
|
|
Your browser does not support the video tag. |
|
|
@ -333,7 +336,7 @@ export default function Video() { |
|
|
|
|
|
|
|
|
{/* Video controls */} |
|
|
{/* Video controls */} |
|
|
<div |
|
|
<div |
|
|
className={`absolute bottom-4 left-4 right-4 glassmorphism-rounded-md p-4 flex items-center transition-opacity duration-300 ${ |
|
|
className={`absolute bottom-4 left-4 right-4 glassmorphism-rounded-md p-4 hidden lg:flex items-center transition-opacity duration-300 ${ |
|
|
showControls ? 'opacity-100' : 'opacity-0' |
|
|
showControls ? 'opacity-100' : 'opacity-0' |
|
|
}`} |
|
|
}`} |
|
|
ref={controllerRef} |
|
|
ref={controllerRef} |
|
|
@ -367,54 +370,63 @@ export default function Video() { |
|
|
<h1 className="mt-3 font-montserrat font-bold text-2xl text-white">{video.title}</h1> |
|
|
<h1 className="mt-3 font-montserrat font-bold text-2xl text-white">{video.title}</h1> |
|
|
|
|
|
|
|
|
{/* Channel and like */} |
|
|
{/* Channel and like */} |
|
|
<div className="flex items-center mt-4"> |
|
|
<div className="lg:flex items-center mt-4"> |
|
|
<img |
|
|
<div className="flex"> |
|
|
|
|
|
<img |
|
|
src={video.creator?.profile_picture || "https://placehold.co/48"} |
|
|
src={video.creator?.profile_picture || "https://placehold.co/48"} |
|
|
alt={video.creator?.name || "Creator"} |
|
|
alt={video.creator?.name || "Creator"} |
|
|
className="w-12 h-12 rounded-full object-cover mr-3" |
|
|
className="w-12 h-12 rounded-full object-cover mr-3" |
|
|
/> |
|
|
/> |
|
|
<div> |
|
|
<div> |
|
|
<p className="text-white font-bold font-montserrat">{video.creator?.name}</p> |
|
|
<p className="text-white font-bold font-montserrat">{video.creator?.name}</p> |
|
|
<p className="text-gray-300 text-sm">{video.creator?.subscribers || 0} abonnés</p> |
|
|
<p className="text-gray-300 text-sm">{video.creator?.subscribers || 0} abonnés</p> |
|
|
|
|
|
</div> |
|
|
|
|
|
<button className="ml-14 bg-primary text-white font-montserrat font-bold px-4 py-2 rounded-md cursor-pointer" onClick={handleSubscribe} > |
|
|
|
|
|
s'abonner |
|
|
|
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
<button className="ml-14 bg-primary text-white font-montserrat font-bold px-4 py-2 rounded-md cursor-pointer" onClick={handleSubscribe} > |
|
|
|
|
|
s'abonner |
|
|
|
|
|
</button> |
|
|
|
|
|
<button className="ml-4 cursor-pointer" onClick={handleLike}> |
|
|
|
|
|
<svg width="32" height="32" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg"> |
|
|
|
|
|
<path d="M6 31.5H7.5V12H6C5.20435 12 4.44129 12.3161 3.87868 12.8787C3.31607 13.4413 3 14.2044 3 15V28.5C3 29.2956 3.31607 30.0587 3.87868 30.6213C4.44129 31.1839 5.20435 31.5 6 31.5ZM30 12H19.5L21.183 6.948C21.3332 6.49712 21.3741 6.01702 21.3024 5.54723C21.2306 5.07745 21.0483 4.63142 20.7705 4.24589C20.4926 3.86036 20.1271 3.54636 19.7041 3.32975C19.2811 3.11314 18.8127 3.00012 18.3375 3H18L10.5 11.157V31.5H27L32.868 18.606L33 18V15C33 14.2044 32.6839 13.4413 32.1213 12.8787C31.5587 12.3161 30.7956 12 30 12Z" fill="white"/> |
|
|
|
|
|
</svg> |
|
|
|
|
|
</button> |
|
|
|
|
|
<p className="font-montserrat text-white ml-2" >{video.likes}</p> |
|
|
|
|
|
|
|
|
|
|
|
<button className="relative ml-14"> |
|
|
|
|
|
<div className="bg-primary cursor-pointer px-4 py-2 rounded-md flex items-center gap-4" onClick={() => setIsAddToPlaylistOpen(!isAddToPlaylistOpen)} > |
|
|
|
|
|
<p className="text-white font-montserrat font-bold" >playlist</p> |
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="fill-white"><path d="M19 11h-6V5h-2v6H5v2h6v6h2v-6h6z"></path></svg> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="flex items-center lg:ml-auto mt-4 lg:mt-0"> |
|
|
{ |
|
|
<button className="lg:ml-4 cursor-pointer" onClick={handleLike}> |
|
|
playlists.length > 0 && isAddToPlaylistOpen && ( |
|
|
<svg width="32" height="32" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg"> |
|
|
<div className="absolute inset-0 w-max h-max z-40 glassmorphism top-1/1 mt-2 left-0 rounded-2xl px-4 py-2 cursor-default"> |
|
|
<path d="M6 31.5H7.5V12H6C5.20435 12 4.44129 12.3161 3.87868 12.8787C3.31607 13.4413 3 14.2044 3 15V28.5C3 29.2956 3.31607 30.0587 3.87868 30.6213C4.44129 31.1839 5.20435 31.5 6 31.5ZM30 12H19.5L21.183 6.948C21.3332 6.49712 21.3741 6.01702 21.3024 5.54723C21.2306 5.07745 21.0483 4.63142 20.7705 4.24589C20.4926 3.86036 20.1271 3.54636 19.7041 3.32975C19.2811 3.11314 18.8127 3.00012 18.3375 3H18L10.5 11.157V31.5H27L32.868 18.606L33 18V15C33 14.2044 32.6839 13.4413 32.1213 12.8787C31.5587 12.3161 30.7956 12 30 12Z" fill="white"/> |
|
|
<ul className="flex flex-col gap-2"> |
|
|
</svg> |
|
|
{playlists.map((playlist) => ( |
|
|
</button> |
|
|
<li |
|
|
<p className="font-montserrat text-white ml-2" >{video.likes}</p> |
|
|
key={playlist.id} |
|
|
|
|
|
className="text-white font-montserrat font-medium text-sm cursor-pointer hover:underline flex items-center justify-between gap-4" |
|
|
{ |
|
|
onClick={() => handleAddToPlaylist(playlist.id)} |
|
|
isAuthenticated && ( |
|
|
> |
|
|
<button className="relative ml-14"> |
|
|
<p className="text-start">{playlist.name}</p> |
|
|
<div className="bg-primary cursor-pointer px-4 py-2 rounded-md flex items-center gap-4" onClick={() => { setIsAddToPlaylistOpen(!isAddToPlaylistOpen) }} > |
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="fill-white"><path d="M19 11h-6V5h-2v6H5v2h6v6h2v-6h6z"></path></svg> |
|
|
<p className="text-white font-montserrat font-bold" >playlist</p> |
|
|
</li> |
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="fill-white"><path d="M19 11h-6V5h-2v6H5v2h6v6h2v-6h6z"></path></svg> |
|
|
))} |
|
|
</div> |
|
|
</ul> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
playlists.length > 0 && isAddToPlaylistOpen && ( |
|
|
|
|
|
<div className="absolute inset-0 w-max h-max z-40 glassmorphism top-1/1 mt-2 left-0 rounded-2xl px-4 py-2 cursor-default"> |
|
|
|
|
|
<ul className="flex flex-col gap-2"> |
|
|
|
|
|
{playlists.map((playlist) => ( |
|
|
|
|
|
<li |
|
|
|
|
|
key={playlist.id} |
|
|
|
|
|
className="text-white font-montserrat font-medium text-sm cursor-pointer hover:underline flex items-center justify-between gap-4" |
|
|
|
|
|
onClick={() => handleAddToPlaylist(playlist.id)} |
|
|
|
|
|
> |
|
|
|
|
|
<p className="text-start">{playlist.name}</p> |
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="fill-white"><path d="M19 11h-6V5h-2v6H5v2h6v6h2v-6h6z"></path></svg> |
|
|
|
|
|
</li> |
|
|
|
|
|
))} |
|
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
</div> |
|
|
</div> |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
</button> |
|
|
</button> |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
{/* Video details */} |
|
|
{/* Video details */} |
|
|
@ -436,7 +448,12 @@ export default function Video() { |
|
|
|
|
|
|
|
|
{/* Comments section */} |
|
|
{/* Comments section */} |
|
|
<div> |
|
|
<div> |
|
|
<h2 className="font-montserrat text-white text-2xl mt-8">Commentaires</h2> |
|
|
<div className="flex justify-between items-center mt-8 mb-2"> |
|
|
|
|
|
<h2 className="font-montserrat text-white text-2xl">Commentaires</h2> |
|
|
|
|
|
<button className="text-white lg:hidden" onClick={() => setIsCommentVisible(!isCommentVisible)} > |
|
|
|
|
|
Voir {isCommentVisible ? "moins" : "plus"} |
|
|
|
|
|
</button> |
|
|
|
|
|
</div> |
|
|
<textarea |
|
|
<textarea |
|
|
className="glassmorphism h-[100px] w-full font-inter text-white placeholder:text-[#9f9f9f] focus:outline-none py-4 px-6" |
|
|
className="glassmorphism h-[100px] w-full font-inter text-white placeholder:text-[#9f9f9f] focus:outline-none py-4 px-6" |
|
|
placeholder="Ajouter un commentaire..." |
|
|
placeholder="Ajouter un commentaire..." |
|
|
@ -449,15 +466,19 @@ export default function Video() { |
|
|
</button> |
|
|
</button> |
|
|
|
|
|
|
|
|
{/* Comments list */} |
|
|
{/* Comments list */} |
|
|
<div className="mt-4"> |
|
|
{ |
|
|
{video.comments && video.comments.length > 0 ? ( |
|
|
isCommentVisible && ( |
|
|
video.comments.map((comment, index) => ( |
|
|
<div className="mt-4"> |
|
|
<Comment comment={comment} index={index} videoId={id} key={index} refetchVideo={fetchVideo} addAlert={addAlert} /> |
|
|
{video.comments && video.comments.length > 0 ? ( |
|
|
)) |
|
|
video.comments.map((comment, index) => ( |
|
|
) : ( |
|
|
<Comment comment={comment} index={index} videoId={id} key={index} refetchVideo={fetchVideo} addAlert={addAlert} /> |
|
|
<p className="text-gray-400">Aucun commentaire pour le moment. Soyez le premier à en publier !</p> |
|
|
)) |
|
|
)} |
|
|
) : ( |
|
|
</div> |
|
|
<p className="text-gray-400">Aucun commentaire pour le moment. Soyez le premier à en publier !</p> |
|
|
|
|
|
)} |
|
|
|
|
|
</div> |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
@ -469,15 +490,16 @@ export default function Video() { |
|
|
{ |
|
|
{ |
|
|
!isPlaylist ? ( |
|
|
!isPlaylist ? ( |
|
|
<div className="flex flex-col items-center gap-2"> |
|
|
<div className="flex flex-col items-center gap-2"> |
|
|
|
|
|
<h2 className="font-montserrat w-full lg:w-9/10 mt-8 text-white text-2xl">Recommandations</h2> |
|
|
{similarVideos.map((video, index) => ( |
|
|
{similarVideos.map((video, index) => ( |
|
|
<div className="w-9/10" key={index}> |
|
|
<div className="w-full lg:w-9/10" key={index}> |
|
|
<VideoCard video={video} /> |
|
|
<VideoCard video={video} /> |
|
|
</div> |
|
|
</div> |
|
|
))} |
|
|
))} |
|
|
</div> |
|
|
</div> |
|
|
) : ( |
|
|
) : ( |
|
|
<div className="flex flex-col items-center gap-2"> |
|
|
<div className="flex flex-col items-center gap-2"> |
|
|
<div className="glassmorphism w-9/10 py-4 px-2" > |
|
|
<div className="glassmorphism w-full lg:w-9/10 py-4 px-2" > |
|
|
<h2 className="font-montserrat text-white text-2xl">{currentPlaylist?.name}</h2> |
|
|
<h2 className="font-montserrat text-white text-2xl">{currentPlaylist?.name}</h2> |
|
|
{ |
|
|
{ |
|
|
currentPlaylist?.videos && currentPlaylist.videos.length > 0 ? ( |
|
|
currentPlaylist?.videos && currentPlaylist.videos.length > 0 ? ( |
|
|
|