diff --git a/src/components/home/ContinueWatchingSection.tsx b/src/components/home/ContinueWatchingSection.tsx index 01fb778a..f100ad92 100644 --- a/src/components/home/ContinueWatchingSection.tsx +++ b/src/components/home/ContinueWatchingSection.tsx @@ -39,6 +39,7 @@ interface ContinueWatchingItem extends StreamingContent { addonPoster?: string; addonName?: string; addonDescription?: string; + traktPlaybackId?: number; // Trakt playback ID for removal } // Define the ref interface @@ -652,6 +653,7 @@ const ContinueWatchingSection = React.forwardRef((props, re progress: item.progress, lastUpdated: pausedAt, addonId: undefined, + traktPlaybackId: item.id, // Store playback ID for removal } as ContinueWatchingItem); logger.log(`📺 [TraktPlayback] Adding movie ${item.movie.title} with ${item.progress.toFixed(1)}% progress`); @@ -680,6 +682,7 @@ const ContinueWatchingSection = React.forwardRef((props, re episode: item.episode.number, episodeTitle: item.episode.title || `Episode ${item.episode.number}`, addonId: undefined, + traktPlaybackId: item.id, // Store playback ID for removal } as ContinueWatchingItem); logger.log(`📺 [TraktPlayback] Adding ${item.show.title} S${item.episode.season}E${item.episode.number} with ${item.progress.toFixed(1)}% progress`); @@ -934,7 +937,7 @@ const ContinueWatchingSection = React.forwardRef((props, re }, [navigation, settings.useCachedStreams, settings.openMetadataScreenWhenCacheDisabled]); // Handle long press to delete (moved before renderContinueWatchingItem) - const handleLongPress = useCallback((item: ContinueWatchingItem) => { + const handleLongPress = useCallback(async (item: ContinueWatchingItem) => { try { // Trigger haptic feedback Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium); @@ -942,8 +945,17 @@ const ContinueWatchingSection = React.forwardRef((props, re // Ignore haptic errors } + const traktService = TraktService.getInstance(); + const isAuthed = await traktService.isAuthenticated(); + setAlertTitle('Remove from Continue Watching'); - setAlertMessage(`Remove "${item.name}" from your continue watching list?`); + + if (isAuthed) { + setAlertMessage(`Remove "${item.name}" from your continue watching list?\n\nThis will also remove it from your Trakt Continue Watching.`); + } else { + setAlertMessage(`Remove "${item.name}" from your continue watching list?`); + } + setAlertActions([ { label: 'Cancel', @@ -958,11 +970,13 @@ const ContinueWatchingSection = React.forwardRef((props, re try { Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); await storageService.removeAllWatchProgressForContent(item.id, item.type, { addBaseTombstone: true }); - const traktService = TraktService.getInstance(); - const isAuthed = await traktService.isAuthenticated(); + if (isAuthed) { let traktResult = false; - if (item.type === 'movie') { + // If we have a playback ID (from sync/playback), use that to remove from Continue Watching + if (item.traktPlaybackId) { + traktResult = await traktService.removePlaybackItem(item.traktPlaybackId); + } else if (item.type === 'movie') { traktResult = await traktService.removeMovieFromHistory(item.id); } else if (item.type === 'series' && item.season !== undefined && item.episode !== undefined) { traktResult = await traktService.removeEpisodeFromHistory(item.id, item.season, item.episode); diff --git a/src/screens/TraktSettingsScreen.tsx b/src/screens/TraktSettingsScreen.tsx index dff96880..06d70890 100644 --- a/src/screens/TraktSettingsScreen.tsx +++ b/src/screens/TraktSettingsScreen.tsx @@ -417,7 +417,7 @@ const TraktSettingsScreen: React.FC = () => { styles.infoText, { color: currentTheme.colors.mediumEmphasis } ]}> - When connected to Trakt, Continue Watching is sourced from Trakt. Account sync for watch progress is disabled to avoid conflicts. + When connected to Trakt, full history is synced directly from the API and is not written to local storage. Your Continue Watching list reflects your global Trakt progress. diff --git a/src/services/traktService.ts b/src/services/traktService.ts index ae97e2ec..fee8183d 100644 --- a/src/services/traktService.ts +++ b/src/services/traktService.ts @@ -2722,6 +2722,26 @@ export class TraktService { } } + /** + * Remove a playback item from Trakt (Continue Watching) by Playback ID + */ + public async removePlaybackItem(playbackId: number): Promise { + try { + logger.log(`🔍 [TraktService] removePlaybackItem called for playback ID: ${playbackId}`); + if (!playbackId) return false; + + // Use DELETE /sync/playback/{id} + // Note: The ID here is the playback ID, not the movie/episode ID + await this.apiRequest(`/sync/playback/${playbackId}`, 'DELETE'); + + logger.log(`✅ [TraktService] Successfully removed playback item ${playbackId}. Response: 204 No Content (Standard for DELETE)`); + return true; + } catch (error) { + logger.error(`[TraktService] Failed to remove playback item ${playbackId}:`, error); + return false; + } + } + /** * Remove entire show from watched history by IMDB ID */