diff --git a/85f7f045f99c649f87f9d0baa67c7663.txt b/85f7f045f99c649f87f9d0baa67c7663.txt deleted file mode 100644 index 8b13789..0000000 --- a/85f7f045f99c649f87f9d0baa67c7663.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Asset 1.svg b/Asset 1.svg deleted file mode 100644 index e62f7bb..0000000 --- a/Asset 1.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/Asset 1chrome.png b/Asset 1chrome.png deleted file mode 100644 index e538bbe..0000000 Binary files a/Asset 1chrome.png and /dev/null differ diff --git a/image.png b/image.png deleted file mode 100644 index 2f98760..0000000 Binary files a/image.png and /dev/null differ diff --git a/src/components/ContentTabs.js b/src/components/ContentTabs.js index 090a26e..37296a2 100644 --- a/src/components/ContentTabs.js +++ b/src/components/ContentTabs.js @@ -1,7 +1,6 @@ import React from 'react'; -//import { motion } from 'framer-motion'; import { Tab } from '@headlessui/react'; -//import { User, Star } from 'react-feather'; +import { useDarkMode } from './DarkModeContext'; const ContentTabs = ({ item, @@ -14,38 +13,49 @@ const ContentTabs = ({ similar, handleListItemClick }) => { + const { isDarkMode } = useDarkMode(); + return ( - + - `w-full rounded-lg py-2.5 text-sm font-medium leading-5 + `w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all ${selected - ? 'bg-[#02c39a] text-white dark:text-black shadow' - : 'text-gray-600 dark:text-gray-400 hover:bg-white/[0.12] hover:text-gray-900 dark:hover:text-white'}` + ? 'bg-[#02c39a] text-white shadow' + : isDarkMode + ? 'text-gray-400 hover:bg-white/[0.12] hover:text-white' + : 'text-gray-600 hover:bg-gray-200 hover:text-gray-900' + }` }> Overview - `w-full rounded-lg py-2.5 text-sm font-medium leading-5 + `w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all ${selected - ? 'bg-[#02c39a] text-white dark:text-black shadow' - : 'text-gray-600 dark:text-gray-400 hover:bg-white/[0.12] hover:text-gray-900 dark:hover:text-white'}` + ? 'bg-[#02c39a] text-white shadow' + : isDarkMode + ? 'text-gray-400 hover:bg-white/[0.12] hover:text-white' + : 'text-gray-600 hover:bg-gray-200 hover:text-gray-900' + }` }> Cast & Crew - `w-full rounded-lg py-2.5 text-sm font-medium leading-5 + `w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all ${selected - ? 'bg-[#02c39a] text-white dark:text-black shadow' - : 'text-gray-600 dark:text-gray-400 hover:bg-white/[0.12] hover:text-gray-900 dark:hover:text-white'}` + ? 'bg-[#02c39a] text-white shadow' + : isDarkMode + ? 'text-gray-400 hover:bg-white/[0.12] hover:text-white' + : 'text-gray-600 hover:bg-gray-200 hover:text-gray-900' + }` }> Reviews -
-

+

+

{detailedOverview}

{detailedOverview?.length > 200 && ( @@ -61,31 +71,42 @@ const ContentTabs = ({ {cast.map((person) => (
- {person.name} -

{person.name}

-

{person.character}

+
+ {person.name} { + e.target.src = '/fallback-poster.jpg'; + }} + /> +
+

+ {person.name} +

+

+ {person.character} +

))}
- + ); }; -const ReviewsTab = ({ reviews }) => ( +const ReviewsTab = ({ reviews, isDarkMode }) => (
{reviews.length > 0 ? ( reviews.map((review) => (
@@ -95,30 +116,36 @@ const ReviewsTab = ({ reviews }) => (
-

{review.author}

-

+

+ {review.author} +

+

{new Date(review.created_at).toLocaleDateString()}

{review.author_details?.rating && ( -
+
- + {review.author_details.rating}
)}
-

+

{review.content}

)) ) : ( -
+
No reviews available yet
)} diff --git a/src/components/EpisodeGrid.js b/src/components/EpisodeGrid.js index 6dca9b1..a1884c7 100644 --- a/src/components/EpisodeGrid.js +++ b/src/components/EpisodeGrid.js @@ -1,6 +1,10 @@ import React from 'react'; +import { motion } from 'framer-motion'; +import { useDarkMode } from './DarkModeContext'; const EpisodeGrid = ({ type, mediaData, episodes, seasons, currentEpisode, handleInputChange }) => { + const { isDarkMode } = useDarkMode(); + if (type !== 'tv') return null; return ( @@ -29,14 +33,18 @@ const EpisodeGrid = ({ type, mediaData, episodes, seasons, currentEpisode, handl
{episodes.map((episode) => ( - + ))}
diff --git a/src/components/EpisodeNavigation.js b/src/components/EpisodeNavigation.js index 3e14b29..132f5e5 100644 --- a/src/components/EpisodeNavigation.js +++ b/src/components/EpisodeNavigation.js @@ -2,15 +2,18 @@ import React from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/solid'; import { Tooltip } from 'react-tooltip'; +import { useDarkMode } from './DarkModeContext'; const EpisodeNavigation = ({ episodes, currentEpisodeNo, season, onEpisodeChange, - isDarkMode, + isDarkMode: parentIsDarkMode, isLoading }) => { + const { isDarkMode } = useDarkMode(); + const actualIsDarkMode = parentIsDarkMode ?? isDarkMode; const currentEpisodeIndex = episodes.findIndex(ep => ep.episode_number === parseInt(currentEpisodeNo)); const hasPrevious = currentEpisodeIndex > 0; const hasNext = currentEpisodeIndex < episodes.length - 1; @@ -28,13 +31,13 @@ const EpisodeNavigation = ({ return (
{ + const { isDarkMode } = useDarkMode(); + const handleImageError = (e) => { e.target.src = '/fallback-poster.jpg'; }; @@ -14,10 +17,10 @@ const Recommendations = ({ recommendations, handleListItemClick }) => { transition={{ staggerChildren: 0.1 }} >
-
{recommendations.map((item, index) => ( @@ -42,7 +45,7 @@ const Recommendations = ({ recommendations, handleListItemClick }) => { opacity-0 group-hover:opacity-100 transition-opacity duration-200">
@@ -52,18 +55,19 @@ const Recommendations = ({ recommendations, handleListItemClick }) => {
-

{item.title || item.name}

{(item.release_date || item.first_air_date) && (
-

+

{new Date(item.release_date || item.first_air_date).getFullYear()}

{item.vote_average > 0 && ( -
+
{item.vote_average.toFixed(1)} diff --git a/src/components/UseBrave.js b/src/components/UseBrave.js index 3e3e3c4..712aeec 100644 --- a/src/components/UseBrave.js +++ b/src/components/UseBrave.js @@ -1,24 +1,58 @@ import React from 'react'; +import { motion } from 'framer-motion'; import { useDarkMode } from './DarkModeContext'; const UseBrave = () => { const { isDarkMode } = useDarkMode(); + const isBrave = navigator?.brave?.isBrave?.name === 'isBrave'; + + if (isBrave) return null; return ( -
- - For an ad-free experience and better privacy, consider using - - Brave Browser - . - -
- - Make Sure you enable Ad blocker and Popup blocker in the settings. - -
+ +
+
+ + + +
+
+

+ For the best streaming experience, we recommend using{' '} + + Brave Browser + + . It has built-in popup and ad blocking features that enhance your viewing experience. +

+
+ +
+
); }; diff --git a/src/components/UserListsSidebar.js b/src/components/UserListsSidebar.js index ab38fb3..0a05405 100644 --- a/src/components/UserListsSidebar.js +++ b/src/components/UserListsSidebar.js @@ -1,92 +1,95 @@ -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; +import { motion, AnimatePresence } from 'framer-motion'; +import { Link } from 'react-router-dom'; import { useDarkMode } from './DarkModeContext'; -import ListSection from './ListSection'; -const UserListsSidebar = ({ - showUserLists, - setShowUserLists, - watchHistory, - watchlist, - favorites, - handleListItemClick -}) => { - useDarkMode(); - const sidebarRef = useRef(null); - - // Add state for tracking minimized sections - const [minimizedSections, setMinimizedSections] = useState({ - history: false, - watchlist: false, - favorites: false - }); - - const handleClose = useCallback(() => { - setShowUserLists(false); - }, [setShowUserLists]); - - // Handle focus trap and keyboard navigation - useEffect(() => { - if (!showUserLists) return; - - const sidebar = sidebarRef.current; - const focusableElements = sidebar.querySelectorAll( - 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' +const ListSection = ({ items, onItemClick, emptyMessage }) => { + const { isDarkMode } = useDarkMode(); + + if (!items?.length) { + return ( +

+ {emptyMessage} +

); - const firstElement = focusableElements[0]; - const lastElement = focusableElements[focusableElements.length - 1]; - - function handleKeyDown(e) { - if (e.key === 'Escape') { - handleClose(); - return; - } - if (e.key === 'Tab') { - if (e.shiftKey && document.activeElement === firstElement) { - e.preventDefault(); - lastElement.focus(); - } else if (!e.shiftKey && document.activeElement === lastElement) { - e.preventDefault(); - firstElement.focus(); - } - } - } - - sidebar.addEventListener('keydown', handleKeyDown); - firstElement.focus(); + } - return () => { - sidebar.removeEventListener('keydown', handleKeyDown); - }; - }, [showUserLists, handleClose]); - - const toggleSection = (section) => { - setMinimizedSections(prev => ({ - ...prev, - [section]: !prev[section] - })); - }; + return ( +
+ {items.map((item) => ( + onItemClick(item)} + className={`flex items-center p-2 rounded-lg cursor-pointer ${ + isDarkMode + ? 'hover:bg-white/5' + : 'hover:bg-gray-50' + } transition-colors duration-200`} + whileHover={{ scale: 1.02 }} + whileTap={{ scale: 0.98 }} + > +
+ {item.title +
+
+

+ {item.title || item.name} +

+

+ {item.media_type === 'movie' ? 'Movie' : 'TV Series'} + {item.watchedAt && ( + + • {new Date(item.watchedAt.seconds * 1000).toLocaleDateString()} + + )} +

+
+
+ ))} +
+ ); +}; - const SectionTitle = ({ icon, title, count, section, isMinimized }) => ( -
toggleSection(section)} - className="flex items-center justify-between w-full cursor-pointer group" - > -
+const SectionTitle = ({ section, isMinimized, icon, title, count, onToggle }) => { + const { isDarkMode } = useDarkMode(); + + return ( +
+
{icon} - {title} - - ({count || 0}) - +

+ {title} +

+ {count > 0 && ( + + {count} + + )}
); +}; + +const UserListsSidebar = ({ + showUserLists, + setShowUserLists, + watchHistory, + watchlist, + favorites, + handleListItemClick +}) => { + const { isDarkMode } = useDarkMode(); + const [minimizedSections, setMinimizedSections] = useState({ + history: false, + watchlist: false, + favorites: false + }); + + const toggleSection = (section) => { + setMinimizedSections(prev => ({ + ...prev, + [section]: !prev[section] + })); + }; return ( <> - {/* Overlay with improved dark mode blur */} - {showUserLists && ( -