Enhance ContinueWatchingSection and MetadataScreen with improved logging and Trakt integration

This update refines the ContinueWatchingSection by removing excessive console logging, enhancing error handling with a logger, and optimizing the loading process for continue watching items. Additionally, the MetadataScreen now fetches and logs Trakt progress data, providing detailed insights into playback progress for movies and series. This enhancement improves user experience by ensuring accurate tracking of watched content and streamlining the logging process.
This commit is contained in:
tapframe 2025-06-20 02:21:29 +05:30
parent 3816435e01
commit 00491c83e5
2 changed files with 119 additions and 81 deletions

View file

@ -80,13 +80,10 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
// Modified loadContinueWatching to be more efficient
const loadContinueWatching = useCallback(async () => {
try {
console.log('[ContinueWatching] Starting to load continue watching items...');
setLoading(true);
const allProgress = await storageService.getAllWatchProgress();
console.log(`[ContinueWatching] Found ${Object.keys(allProgress).length} progress items in storage`);
if (Object.keys(allProgress).length === 0) {
console.log('[ContinueWatching] No progress items found, setting empty array');
setContinueWatchingItems([]);
return;
}
@ -97,24 +94,16 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
// Process each saved progress
for (const key in allProgress) {
console.log(`[ContinueWatching] Raw key from storage: "${key}"`);
// Parse the key to get type and id
const keyParts = key.split(':');
console.log(`[ContinueWatching] Key parts:`, keyParts);
const [type, id, ...episodeIdParts] = keyParts;
const episodeId = episodeIdParts.length > 0 ? episodeIdParts.join(':') : undefined;
const progress = allProgress[key];
console.log(`[ContinueWatching] Parsed - type: "${type}", id: "${id}", episodeId: "${episodeId}"`);
// Skip items that are more than 95% complete (effectively finished)
const progressPercent = (progress.currentTime / progress.duration) * 100;
console.log(`[ContinueWatching] Progress for ${key}: ${progressPercent.toFixed(1)}%`);
if (progressPercent >= 95) {
console.log(`[ContinueWatching] Skipping ${key} - too high progress (${progressPercent.toFixed(1)}%)`);
continue;
}
@ -122,34 +111,27 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
try {
// Validate IMDB ID format before attempting to fetch
if (!isValidImdbId(id)) {
console.log(`[ContinueWatching] Skipping ${type}:${id} - invalid IMDB ID format`);
return;
}
console.log(`[ContinueWatching] Fetching content details for ${type}:${id}`);
let content: StreamingContent | null = null;
// Get content details using catalogService
content = await catalogService.getContentDetails(type, id);
if (content) {
console.log(`[ContinueWatching] Successfully fetched content: ${content.name}`);
// Extract season and episode info from episodeId if available
let season: number | undefined;
let episode: number | undefined;
let episodeTitle: string | undefined;
if (episodeId && type === 'series') {
console.log(`[ContinueWatching] Parsing episode ID: ${episodeId}`);
// Try different episode ID formats
let match = episodeId.match(/s(\d+)e(\d+)/i); // Format: s1e1
if (match) {
season = parseInt(match[1], 10);
episode = parseInt(match[2], 10);
episodeTitle = `Episode ${episode}`;
console.log(`[ContinueWatching] Parsed s1e1 format: S${season}E${episode}`);
} else {
// Try format: seriesId:season:episode (e.g., tt0108778:4:6)
const parts = episodeId.split(':');
@ -164,14 +146,9 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
season = seasonNum;
episode = episodeNum;
episodeTitle = `Episode ${episode}`;
console.log(`[ContinueWatching] Parsed colon format: S${season}E${episode}`);
}
}
}
if (!season || !episode) {
console.log(`[ContinueWatching] Failed to parse episode details from: ${episodeId}`);
}
}
const continueWatchingItem: ContinueWatchingItem = {
@ -183,31 +160,18 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
episodeTitle
};
console.log(`[ContinueWatching] Created item for ${content.name}:`, {
type,
season,
episode,
episodeTitle,
episodeId,
originalKey: key
});
if (type === 'series') {
// For series, keep only the latest watched episode for each show
if (!latestEpisodes[id] || latestEpisodes[id].lastUpdated < progress.lastUpdated) {
latestEpisodes[id] = continueWatchingItem;
console.log(`[ContinueWatching] Updated latest episode for series ${id}`);
}
} else {
// For movies, add to the list directly
progressItems.push(continueWatchingItem);
console.log(`[ContinueWatching] Added movie to progress items`);
}
} else {
console.log(`[ContinueWatching] Failed to fetch content details for ${type}:${id}`);
}
} catch (error) {
console.error(`[ContinueWatching] Failed to get content details for ${type}:${id}`, error);
logger.error(`Failed to get content details for ${type}:${id}`, error);
}
})();
@ -215,35 +179,20 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
}
// Wait for all content to be processed
console.log(`[ContinueWatching] Waiting for ${contentPromises.length} content promises...`);
await Promise.all(contentPromises);
// Add the latest episodes for each series to the items list
progressItems.push(...Object.values(latestEpisodes));
console.log(`[ContinueWatching] Total items after processing: ${progressItems.length}`);
// Sort by last updated time (most recent first)
progressItems.sort((a, b) => b.lastUpdated - a.lastUpdated);
// Limit to 10 items
const finalItems = progressItems.slice(0, 10);
console.log(`[ContinueWatching] Final continue watching items: ${finalItems.length}`);
// Debug: Log the final items with their episode details
finalItems.forEach((item, index) => {
console.log(`[ContinueWatching] Item ${index}:`, {
name: item.name,
type: item.type,
season: item.season,
episode: item.episode,
episodeTitle: item.episodeTitle,
progress: item.progress
});
});
setContinueWatchingItems(finalItems);
} catch (error) {
console.error('[ContinueWatching] Failed to load continue watching items:', error);
logger.error('Failed to load continue watching items:', error);
} finally {
setLoading(false);
}
@ -308,11 +257,9 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
// Properly expose the refresh method
React.useImperativeHandle(ref, () => ({
refresh: async () => {
console.log('[ContinueWatching] Refresh method called');
await loadContinueWatching();
// Return whether there are items to help parent determine visibility
const hasItems = continueWatchingItems.length > 0;
console.log(`[ContinueWatching] Refresh returning hasItems: ${hasItems}, items count: ${continueWatchingItems.length}`);
return hasItems;
}
}));
@ -379,32 +326,23 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
{/* Episode Info or Year */}
{(() => {
console.log(`[ContinueWatching] Rendering item:`, {
name: item.name,
type: item.type,
season: item.season,
episode: item.episode,
episodeTitle: item.episodeTitle,
hasSeasonAndEpisode: !!(item.season && item.episode)
});
if (item.type === 'series' && item.season && item.episode) {
return (
<View style={styles.episodeRow}>
<Text style={[styles.episodeText, { color: currentTheme.colors.mediumEmphasis }]}>
Season {item.season}
</Text>
{item.episodeTitle && (
<Text
style={[styles.episodeTitle, { color: currentTheme.colors.mediumEmphasis }]}
numberOfLines={1}
>
{item.episodeTitle}
</Text>
)}
</View>
);
} else {
if (item.type === 'series' && item.season && item.episode) {
return (
<View style={styles.episodeRow}>
<Text style={[styles.episodeText, { color: currentTheme.colors.mediumEmphasis }]}>
Season {item.season}
</Text>
{item.episodeTitle && (
<Text
style={[styles.episodeTitle, { color: currentTheme.colors.mediumEmphasis }]}
numberOfLines={1}
>
{item.episodeTitle}
</Text>
)}
</View>
);
} else {
return (
<Text style={[styles.yearText, { color: currentTheme.colors.mediumEmphasis }]}>
{item.year} {item.type === 'movie' ? 'Movie' : 'Series'}

View file

@ -40,6 +40,7 @@ import MetadataDetails from '../components/metadata/MetadataDetails';
import { useMetadataAnimations } from '../hooks/useMetadataAnimations';
import { useMetadataAssets } from '../hooks/useMetadataAssets';
import { useWatchProgress } from '../hooks/useWatchProgress';
import { TraktService, TraktPlaybackItem } from '../services/traktService';
const { height } = Dimensions.get('window');
@ -84,6 +85,105 @@ const MetadataScreen: React.FC = () => {
const assetData = useMetadataAssets(metadata, id, type, imdbId, settings, setMetadata);
const animations = useMetadataAnimations(safeAreaTop, watchProgressData.watchProgress);
// Fetch and log Trakt progress data when entering the screen
useEffect(() => {
const fetchTraktProgress = async () => {
try {
const traktService = TraktService.getInstance();
const isAuthenticated = await traktService.isAuthenticated();
console.log(`[MetadataScreen] === TRAKT PROGRESS DATA FOR ${type.toUpperCase()}: ${metadata?.name || id} ===`);
console.log(`[MetadataScreen] IMDB ID: ${id}`);
console.log(`[MetadataScreen] Trakt authenticated: ${isAuthenticated}`);
if (!isAuthenticated) {
console.log(`[MetadataScreen] Not authenticated with Trakt, no progress data available`);
return;
}
// Get all playback progress from Trakt
const allProgress = await traktService.getPlaybackProgress();
console.log(`[MetadataScreen] Total Trakt progress items: ${allProgress.length}`);
if (allProgress.length === 0) {
console.log(`[MetadataScreen] No Trakt progress data found`);
return;
}
// Filter progress for current content
let relevantProgress: TraktPlaybackItem[] = [];
if (type === 'movie') {
relevantProgress = allProgress.filter(item =>
item.type === 'movie' &&
item.movie?.ids.imdb === id.replace('tt', '')
);
} else if (type === 'series') {
relevantProgress = allProgress.filter(item =>
item.type === 'episode' &&
item.show?.ids.imdb === id.replace('tt', '')
);
}
console.log(`[MetadataScreen] Relevant progress items for this ${type}: ${relevantProgress.length}`);
if (relevantProgress.length === 0) {
console.log(`[MetadataScreen] No Trakt progress found for this ${type}`);
return;
}
// Log detailed progress information
relevantProgress.forEach((item, index) => {
console.log(`[MetadataScreen] --- Progress Item ${index + 1} ---`);
console.log(`[MetadataScreen] Type: ${item.type}`);
console.log(`[MetadataScreen] Progress: ${item.progress.toFixed(2)}%`);
console.log(`[MetadataScreen] Paused at: ${item.paused_at}`);
console.log(`[MetadataScreen] Trakt ID: ${item.id}`);
if (item.movie) {
console.log(`[MetadataScreen] Movie: ${item.movie.title} (${item.movie.year})`);
console.log(`[MetadataScreen] Movie IMDB: tt${item.movie.ids.imdb}`);
console.log(`[MetadataScreen] Movie TMDB: ${item.movie.ids.tmdb}`);
}
if (item.episode && item.show) {
console.log(`[MetadataScreen] Show: ${item.show.title} (${item.show.year})`);
console.log(`[MetadataScreen] Show IMDB: tt${item.show.ids.imdb}`);
console.log(`[MetadataScreen] Episode: S${item.episode.season}E${item.episode.number} - ${item.episode.title}`);
console.log(`[MetadataScreen] Episode IMDB: ${item.episode.ids.imdb || 'N/A'}`);
console.log(`[MetadataScreen] Episode TMDB: ${item.episode.ids.tmdb || 'N/A'}`);
}
console.log(`[MetadataScreen] Raw item:`, JSON.stringify(item, null, 2));
});
// Find most recent progress if multiple episodes
if (type === 'series' && relevantProgress.length > 1) {
const mostRecent = relevantProgress.sort((a, b) =>
new Date(b.paused_at).getTime() - new Date(a.paused_at).getTime()
)[0];
console.log(`[MetadataScreen] === MOST RECENT EPISODE PROGRESS ===`);
if (mostRecent.episode && mostRecent.show) {
console.log(`[MetadataScreen] Most recent: S${mostRecent.episode.season}E${mostRecent.episode.number} - ${mostRecent.episode.title}`);
console.log(`[MetadataScreen] Progress: ${mostRecent.progress.toFixed(2)}%`);
console.log(`[MetadataScreen] Watched on: ${new Date(mostRecent.paused_at).toLocaleString()}`);
}
}
console.log(`[MetadataScreen] === END TRAKT PROGRESS DATA ===`);
} catch (error) {
console.error(`[MetadataScreen] Failed to fetch Trakt progress:`, error);
}
};
// Only fetch when we have metadata loaded
if (metadata && id) {
fetchTraktProgress();
}
}, [metadata, id, type]);
// Memoized derived values for performance
const isReady = useMemo(() => !loading && metadata && !metadataError, [loading, metadata, metadataError]);