From fe8489fa18be5f8c8ef6eff3ef442b3f645d25b7 Mon Sep 17 00:00:00 2001 From: tapframe Date: Mon, 7 Jul 2025 18:41:13 +0530 Subject: [PATCH] CP, calender changes --- src/components/home/ThisWeekSection.tsx | 85 ++++++++++++++++--- src/screens/CalendarScreen.tsx | 105 +++++++++++++++++++++--- src/screens/LibraryScreen.tsx | 26 +++++- src/screens/SettingsScreen.tsx | 7 -- 4 files changed, 192 insertions(+), 31 deletions(-) diff --git a/src/components/home/ThisWeekSection.tsx b/src/components/home/ThisWeekSection.tsx index aa78aa43..42a45d60 100644 --- a/src/components/home/ThisWeekSection.tsx +++ b/src/components/home/ThisWeekSection.tsx @@ -14,6 +14,7 @@ import { Image } from 'expo-image'; import { LinearGradient } from 'expo-linear-gradient'; import { MaterialIcons } from '@expo/vector-icons'; import { useTheme } from '../../contexts/ThemeContext'; +import { useTraktContext } from '../../contexts/TraktContext'; import { stremioService } from '../../services/stremioService'; import { tmdbService } from '../../services/tmdbService'; import { useLibrary } from '../../hooks/useLibrary'; @@ -44,23 +45,75 @@ interface ThisWeekEpisode { export const ThisWeekSection = React.memo(() => { const navigation = useNavigation>(); const { libraryItems, loading: libraryLoading } = useLibrary(); + const { + isAuthenticated: traktAuthenticated, + isLoading: traktLoading, + watchedShows, + watchlistShows, + continueWatching, + loadAllCollections + } = useTraktContext(); const [episodes, setEpisodes] = useState([]); const [loading, setLoading] = useState(true); const { currentTheme } = useTheme(); const fetchThisWeekEpisodes = useCallback(async () => { - if (libraryItems.length === 0) { - setLoading(false); - return; - } - setLoading(true); try { - const seriesItems = libraryItems.filter(item => item.type === 'series'); + // Combine library series with Trakt series + const librarySeries = libraryItems.filter(item => item.type === 'series'); + let allSeries = [...librarySeries]; + + // Add Trakt watchlist and continue watching shows if authenticated + if (traktAuthenticated) { + const traktSeriesIds = new Set(); + + // Add watchlist shows + if (watchlistShows) { + for (const item of watchlistShows) { + if (item.show && item.show.ids.imdb) { + const imdbId = item.show.ids.imdb; + if (!librarySeries.some(s => s.id === imdbId)) { + traktSeriesIds.add(imdbId); + allSeries.push({ + id: imdbId, + name: item.show.title, + type: 'series', + poster: '', // Will try to fetch from TMDB + year: item.show.year, + traktSource: 'watchlist' + }); + } + } + } + } + + // Add continue watching shows + if (continueWatching) { + for (const item of continueWatching) { + if (item.type === 'episode' && item.show && item.show.ids.imdb) { + const imdbId = item.show.ids.imdb; + if (!librarySeries.some(s => s.id === imdbId) && !traktSeriesIds.has(imdbId)) { + traktSeriesIds.add(imdbId); + allSeries.push({ + id: imdbId, + name: item.show.title, + type: 'series', + poster: '', // Will try to fetch from TMDB + year: item.show.year, + traktSource: 'continue-watching' + }); + } + } + } + } + } + + console.log(`[ThisWeekSection] Checking ${allSeries.length} series (Library: ${librarySeries.length}, Trakt: ${allSeries.length - librarySeries.length})`); let allEpisodes: ThisWeekEpisode[] = []; - for (const series of seriesItems) { + for (const series of allSeries) { try { const metadata = await stremioService.getMetaDetails(series.type, series.id); @@ -125,15 +178,23 @@ export const ThisWeekSection = React.memo(() => { } finally { setLoading(false); } - }, [libraryItems]); + }, [libraryItems, traktAuthenticated, watchlistShows, continueWatching]); - // Load episodes when library items change + // Load episodes when library items or Trakt data changes useEffect(() => { - if (!libraryLoading) { - console.log('[ThisWeekSection] Library items changed, refreshing episodes. Items count:', libraryItems.length); + if (!libraryLoading && !traktLoading) { + if (traktAuthenticated && (!watchlistShows || !continueWatching)) { + console.log('[ThisWeekSection] Loading Trakt collections for this week data'); + loadAllCollections(); + } else { + console.log('[ThisWeekSection] Data ready, refreshing episodes. Library items:', libraryItems.length); + fetchThisWeekEpisodes(); + } + } else if (!libraryLoading && !traktAuthenticated) { + console.log('[ThisWeekSection] Not authenticated with Trakt, using library only. Items count:', libraryItems.length); fetchThisWeekEpisodes(); } - }, [libraryLoading, libraryItems, fetchThisWeekEpisodes]); + }, [libraryLoading, traktLoading, traktAuthenticated, libraryItems, watchlistShows, continueWatching, fetchThisWeekEpisodes, loadAllCollections]); const handleEpisodePress = (episode: ThisWeekEpisode) => { // For upcoming episodes, go to the metadata screen diff --git a/src/screens/CalendarScreen.tsx b/src/screens/CalendarScreen.tsx index cf61468a..c07018b7 100644 --- a/src/screens/CalendarScreen.tsx +++ b/src/screens/CalendarScreen.tsx @@ -22,6 +22,7 @@ import { useTheme } from '../contexts/ThemeContext'; import { RootStackParamList } from '../navigation/AppNavigator'; import { stremioService } from '../services/stremioService'; import { useLibrary } from '../hooks/useLibrary'; +import { useTraktContext } from '../contexts/TraktContext'; import { format, parseISO, isThisWeek, isAfter, startOfToday, addWeeks, isBefore, isSameDay } from 'date-fns'; import Animated, { FadeIn } from 'react-native-reanimated'; import { CalendarSection } from '../components/calendar/CalendarSection'; @@ -55,6 +56,15 @@ const CalendarScreen = () => { const navigation = useNavigation>(); const { libraryItems, loading: libraryLoading } = useLibrary(); const { currentTheme } = useTheme(); + const { + isAuthenticated: traktAuthenticated, + isLoading: traktLoading, + watchedShows, + watchlistShows, + continueWatching, + loadAllCollections + } = useTraktContext(); + logger.log(`[Calendar] Initial load - Library has ${libraryItems?.length || 0} items, loading: ${libraryLoading}`); const [calendarData, setCalendarData] = useState([]); const [loading, setLoading] = useState(true); @@ -67,15 +77,83 @@ const CalendarScreen = () => { setLoading(true); try { - // Filter for only series in library - const seriesItems = libraryItems.filter(item => item.type === 'series'); - logger.log(`[Calendar] Library items: ${libraryItems.length}, Series items: ${seriesItems.length}`); + // Combine library series with Trakt series + const librarySeries = libraryItems.filter(item => item.type === 'series'); + let allSeries = [...librarySeries]; + + // Add Trakt watchlist and watched shows if authenticated + if (traktAuthenticated) { + const traktSeriesIds = new Set(); + + // Add watchlist shows + if (watchlistShows) { + for (const item of watchlistShows) { + if (item.show && item.show.ids.imdb) { + const imdbId = item.show.ids.imdb; + if (!librarySeries.some(s => s.id === imdbId)) { + traktSeriesIds.add(imdbId); + allSeries.push({ + id: imdbId, + name: item.show.title, + type: 'series', + poster: '', // Will try to fetch from TMDB + year: item.show.year, + traktSource: 'watchlist' + }); + } + } + } + } + + // Add continue watching shows + if (continueWatching) { + for (const item of continueWatching) { + if (item.type === 'episode' && item.show && item.show.ids.imdb) { + const imdbId = item.show.ids.imdb; + if (!librarySeries.some(s => s.id === imdbId) && !traktSeriesIds.has(imdbId)) { + traktSeriesIds.add(imdbId); + allSeries.push({ + id: imdbId, + name: item.show.title, + type: 'series', + poster: '', // Will try to fetch from TMDB + year: item.show.year, + traktSource: 'continue-watching' + }); + } + } + } + } + + // Add watched shows (only recent ones to avoid too much data) + if (watchedShows) { + const recentWatched = watchedShows.slice(0, 20); // Limit to recent 20 + for (const item of recentWatched) { + if (item.show && item.show.ids.imdb) { + const imdbId = item.show.ids.imdb; + if (!librarySeries.some(s => s.id === imdbId) && !traktSeriesIds.has(imdbId)) { + traktSeriesIds.add(imdbId); + allSeries.push({ + id: imdbId, + name: item.show.title, + type: 'series', + poster: '', // Will try to fetch from TMDB + year: item.show.year, + traktSource: 'watched' + }); + } + } + } + } + } + + logger.log(`[Calendar] Total series to check: ${allSeries.length} (Library: ${librarySeries.length}, Trakt: ${allSeries.length - librarySeries.length})`); let allEpisodes: CalendarEpisode[] = []; let seriesWithoutEpisodes: CalendarEpisode[] = []; // For each series, fetch upcoming episodes - for (const series of seriesItems) { + for (const series of allSeries) { try { logger.log(`[Calendar] Fetching episodes for series: ${series.name} (${series.id})`); const metadata = await stremioService.getMetaDetails(series.type, series.id); @@ -215,17 +293,22 @@ const CalendarScreen = () => { setLoading(false); setRefreshing(false); } - }, [libraryItems]); + }, [libraryItems, traktAuthenticated, watchlistShows, continueWatching, watchedShows]); useEffect(() => { - if (libraryItems.length > 0 && !libraryLoading) { - logger.log(`[Calendar] Library loaded with ${libraryItems.length} items, fetching calendar data`); + if (!libraryLoading && !traktLoading) { + if (traktAuthenticated && (!watchlistShows || !continueWatching || !watchedShows)) { + logger.log(`[Calendar] Loading Trakt collections for calendar data`); + loadAllCollections(); + } else { + logger.log(`[Calendar] Data ready, fetching calendar data - Library: ${libraryItems.length} items`); + fetchCalendarData(); + } + } else if (!libraryLoading && !traktAuthenticated) { + logger.log(`[Calendar] Not authenticated with Trakt, using library only (${libraryItems.length} items)`); fetchCalendarData(); - } else if (!libraryLoading) { - logger.log(`[Calendar] Library loaded but empty (${libraryItems.length} items)`); - setLoading(false); } - }, [libraryItems, libraryLoading, fetchCalendarData]); + }, [libraryItems, libraryLoading, traktLoading, traktAuthenticated, watchlistShows, continueWatching, watchedShows, fetchCalendarData, loadAllCollections]); const onRefresh = useCallback(() => { setRefreshing(true); diff --git a/src/screens/LibraryScreen.tsx b/src/screens/LibraryScreen.tsx index ef80caff..25fffa2e 100644 --- a/src/screens/LibraryScreen.tsx +++ b/src/screens/LibraryScreen.tsx @@ -913,7 +913,20 @@ const LibraryScreen = () => { ) : ( - Library + <> + Library + navigation.navigate('Calendar')} + activeOpacity={0.7} + > + + + )} @@ -1224,6 +1237,17 @@ const styles = StyleSheet.create({ justifyContent: 'space-between', paddingHorizontal: 16, }, + calendarButton: { + width: 44, + height: 44, + borderRadius: 22, + justifyContent: 'center', + alignItems: 'center', + elevation: 3, + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.2, + shadowRadius: 4, + }, }); export default LibraryScreen; \ No newline at end of file diff --git a/src/screens/SettingsScreen.tsx b/src/screens/SettingsScreen.tsx index cfdd7b9b..abfa960b 100644 --- a/src/screens/SettingsScreen.tsx +++ b/src/screens/SettingsScreen.tsx @@ -401,13 +401,6 @@ const SettingsScreen: React.FC = () => { renderControl={ChevronRight} onPress={() => navigation.navigate('PlayerSettings')} /> - navigation.navigate('Calendar')} - />