mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-11 17:45:38 +00:00
CP, calender changes
This commit is contained in:
parent
93e80d9720
commit
fe8489fa18
4 changed files with 192 additions and 31 deletions
|
|
@ -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<NavigationProp<RootStackParamList>>();
|
||||
const { libraryItems, loading: libraryLoading } = useLibrary();
|
||||
const {
|
||||
isAuthenticated: traktAuthenticated,
|
||||
isLoading: traktLoading,
|
||||
watchedShows,
|
||||
watchlistShows,
|
||||
continueWatching,
|
||||
loadAllCollections
|
||||
} = useTraktContext();
|
||||
const [episodes, setEpisodes] = useState<ThisWeekEpisode[]>([]);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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<NavigationProp<RootStackParamList>>();
|
||||
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<CalendarSection[]>([]);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -913,7 +913,20 @@ const LibraryScreen = () => {
|
|||
<View style={styles.headerSpacer} />
|
||||
</>
|
||||
) : (
|
||||
<Text style={[styles.headerTitle, { color: currentTheme.colors.white }]}>Library</Text>
|
||||
<>
|
||||
<Text style={[styles.headerTitle, { color: currentTheme.colors.white }]}>Library</Text>
|
||||
<TouchableOpacity
|
||||
style={[styles.calendarButton, { backgroundColor: currentTheme.colors.primary }]}
|
||||
onPress={() => navigation.navigate('Calendar')}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<MaterialIcons
|
||||
name="event"
|
||||
size={24}
|
||||
color={currentTheme.colors.white}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
|
@ -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;
|
||||
|
|
@ -401,13 +401,6 @@ const SettingsScreen: React.FC = () => {
|
|||
renderControl={ChevronRight}
|
||||
onPress={() => navigation.navigate('PlayerSettings')}
|
||||
/>
|
||||
<SettingItem
|
||||
title="Calendar"
|
||||
description="Episode tracking"
|
||||
icon="event"
|
||||
renderControl={ChevronRight}
|
||||
onPress={() => navigation.navigate('Calendar')}
|
||||
/>
|
||||
<SettingItem
|
||||
title="Notifications"
|
||||
description="Episode reminders"
|
||||
|
|
|
|||
Loading…
Reference in a new issue