Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@reduxjs/toolkit": "^2.8.2",
"@sentry/react": "^10.19.0",
"@studio-freight/lenis": "^1.0.42",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
Expand All @@ -17,6 +18,7 @@
"react-intersection-observer": "^9.16.0",
"react-redux": "^9.2.0",
"react-scripts": "5.0.1",
"react-toastify": "^11.0.5",
"web-vitals": "^2.1.4"
},
"scripts": {
Expand Down
9 changes: 5 additions & 4 deletions src/components/Browse.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
searchMovies,
searchTVShows
} from '../utils/vidsrcApi';
import { logger } from '../utils/logger';

// --- NEW: We will create this new component in the next step ---
import LazyLoadCarousel from './LazyLoadCarousel';
Expand Down Expand Up @@ -74,7 +75,7 @@ const Browse = () => {
}
}));
} catch (error) {
console.error('Error loading priority content:', error);
logger.error('Failed to load priority content', error, true);
} finally {
setInitialPageLoad(false); // The main page is now ready
}
Expand Down Expand Up @@ -110,7 +111,7 @@ const Browse = () => {
}
}));
} catch (error) {
console.error(`Error loading initial data for ${categoryKey}:`, error);
logger.error(`Failed to load initial data for ${categoryKey}`, error, true);
// Mark as loaded to prevent retrying on error
setContent(prev => ({ ...prev, [categoryKey]: { ...prev[categoryKey], loaded: true } }));
}
Expand Down Expand Up @@ -147,7 +148,7 @@ const Browse = () => {
}));

} catch (error) {
console.error(`Error loading more ${categoryKey}:`, error);
logger.error(`Failed to load more ${categoryKey}`, error, true);
setContent(prev => ({ ...prev, [categoryKey]: { ...prev[categoryKey], loadingMore: false, hasMore: false } }));
}
}, [content]);
Expand All @@ -170,7 +171,7 @@ const Browse = () => {

setSearchResults(combinedResults);
} catch (error) {
console.error('Search error:', error);
logger.error('Search failed', error, true);
setSearchResults([]);
} finally {
setIsSearching(false);
Expand Down
9 changes: 5 additions & 4 deletions src/components/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
updateProfile,
} from "firebase/auth";
import { useNavigate, useLocation } from "react-router-dom";
import { logger } from "../utils/logger";

// Enhanced Login component with better responsiveness and animations
const Login = () => {
Expand Down Expand Up @@ -66,8 +67,8 @@ const Login = () => {
} catch (error) {
const errorCode = error.code;
const errorMessage = error.message;
console.error("Sign up error:", errorCode, errorMessage);
logger.error(`Sign up failed: ${errorCode}`, { errorCode, errorMessage }, true);

// Provide user-friendly error messages
let friendlyMessage = "";
switch (errorCode) {
Expand Down Expand Up @@ -111,8 +112,8 @@ const Login = () => {
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.error("Sign In error:", errorCode, errorMessage);
logger.error(`Sign in failed: ${errorCode}`, { errorCode, errorMessage }, true);

// Provide user-friendly error messages
let friendlyMessage = "";
switch (errorCode) {
Expand Down
5 changes: 3 additions & 2 deletions src/components/MovieCard.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { memo } from 'react';
import { getImageUrl, getYear, getBackupImageUrl } from '../utils/vidsrcApi';
import { logger } from '../utils/logger';

const MovieCard = memo(({ movie, onClick, isTV = false, customBadge = null }) => {
const title = isTV ? movie.name : movie.title;
Expand All @@ -8,11 +9,11 @@ const MovieCard = memo(({ movie, onClick, isTV = false, customBadge = null }) =>

// Debug logging to see what data we're getting
if (!title) {
console.log('🔍 MovieCard Debug - Movie data:', movie);
logger.debug('MovieCard: Missing title', { movie });
}

const handleImageError = (e) => {
console.log('🖼️ Image failed to load:', e.target.src);
logger.debug('MovieCard: Image failed to load', { src: e.target.src });
// Try alternative poster sizes first
if (e.target.src.includes('w500')) {
e.target.src = getImageUrl(posterPath, 'w342');
Expand Down
7 changes: 4 additions & 3 deletions src/components/MovieDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useParams, useNavigate } from 'react-router-dom';
import { getMovieDetails, getMovieCredits, getMovieVideos, getMovieRecommendations } from '../utils/vidsrcApi';
import { safeOpenExternal } from '../utils/safeNavigation';
import VideoPlayer from './VideoPlayer';
import { logger } from '../utils/logger';

const MovieDetails = () => {
const { id } = useParams();
Expand Down Expand Up @@ -58,7 +59,7 @@ const MovieDetails = () => {
}, 300);
}
} catch (error) {
console.error('Error loading movie details:', error);
logger.error('Error loading movie details', error, true);
setCredits({ cast: [], crew: [] });
setVideos([]);
setRecommendations([]);
Expand Down Expand Up @@ -335,7 +336,7 @@ const MovieDetails = () => {
const url = `https://www.youtube.com/watch?v=${encodeURIComponent(trailer.key)}`;
const success = safeOpenExternal(url);
if (!success) {
console.warn('Failed to open trailer safely');
logger.warn('Failed to open trailer safely');
}
}}
className="border-2 border-gray-500 text-gray-300 hover:border-red-500 hover:text-red-400 px-6 sm:px-8 py-4 sm:py-3 rounded-lg font-['JetBrains_Mono',monospace] font-bold flex items-center justify-center transition-all duration-300 w-full sm:w-auto order-3"
Expand Down Expand Up @@ -409,7 +410,7 @@ const MovieDetails = () => {
className="bg-gray-900/50 rounded-lg p-4 text-center cursor-pointer hover:bg-gray-800/50 transition-all duration-300 transform hover:scale-105"
onClick={() => {
// You can add navigation to actor details page here if you have one
console.log('Navigate to actor:', actor.name);
logger.debug('Navigate to actor:', actor.name);
}}
>
<div className="relative mb-3">
Expand Down
32 changes: 21 additions & 11 deletions src/components/Movies.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { fetchPopularMovies, fetchTopRatedMovies, fetchTrendingMovies, searchContent } from '../utils/vidsrcApi';
import { detectDevice, mobileCache } from '../utils/mobileApiHelper';
import { logger } from '../utils/logger';
import MovieCard from './MovieCard';
import VideoPlayer from './VideoPlayer';

Expand Down Expand Up @@ -35,21 +36,21 @@ const Movies = () => {
if (device.isMobile) {
const handleOnline = () => {
setMobileStatus(prev => ({ ...prev, isOffline: false }));
console.log('📱 Mobile device came online, refreshing movie data...');
logger.mobileEvent('device_online', { action: 'refreshing_movie_data' });
};

const handleOffline = () => {
setMobileStatus(prev => ({ ...prev, isOffline: true }));
console.log('📱 Mobile device went offline, using cached movie data...');
logger.mobileEvent('device_offline', { action: 'using_cached_data' });
};

const handleConnectionChange = () => {
if (navigator.connection) {
setMobileStatus(prev => ({
...prev,
connectionType: navigator.connection.effectiveType
setMobileStatus(prev => ({
...prev,
connectionType: navigator.connection.effectiveType
}));
console.log('📱 Mobile connection changed to:', navigator.connection.effectiveType);
logger.mobileEvent('connection_change', { type: navigator.connection.effectiveType });
}
};

Expand Down Expand Up @@ -100,23 +101,32 @@ const Movies = () => {

// Show user feedback for mobile fallback data
if (response.isMockData && mobileStatus.isMobile) {
console.log('📱 Using offline movie content for mobile device');
logger.mobileEvent('using_offline_content', { filter: currentFilter });
}



setMovies(movieData);
setFilteredMovies(movieData);


// Cache data for mobile devices
if (mobileStatus.isMobile && movieData.length > 0) {
mobileCache.set(`movies_${currentFilter}`, movieData, 600000); // 10 minutes
}

} catch (error) {

logger.error('Failed to load movies', error, true);

console.error('Error loading movies:', error);
setHasMore(false); // Disable load more on error


// Mobile fallback - try to use any cached data
if (mobileStatus.isMobile) {
const cachedData = mobileCache.get(`movies_${currentFilter}`);
if (cachedData && cachedData.length > 0) {
console.log('📱 Using emergency movie cache for mobile');
logger.mobileEvent('using_emergency_cache', { filter: currentFilter });
setMovies(cachedData);
setFilteredMovies(cachedData);
} else {
Expand Down Expand Up @@ -199,7 +209,7 @@ const Movies = () => {
: [];
setFilteredMovies(movieResults);
} catch (error) {
console.error('Search error:', error);
logger.error('Search failed', error, true);
setFilteredMovies([]);
} finally {
setIsSearching(false);
Expand Down
Loading