Changed to TraktService.getInstance().isAuthenticated()

This commit is contained in:
tapframe 2025-12-25 13:03:04 +05:30
parent d2987ce0cc
commit 9375fab06c
3 changed files with 61 additions and 40 deletions

View file

@ -340,7 +340,10 @@ const KSPlayerCore: React.FC = () => {
const resumeTarget = routeInitialPosition || watchProgress.initialPosition || watchProgress.initialSeekTargetRef?.current;
if (resumeTarget && resumeTarget > 0 && !watchProgress.showResumeOverlay && data.duration > 0) {
setTimeout(() => {
controls.seekToTime(resumeTarget);
if (ksPlayerRef.current) {
logger.debug(`[KSPlayerCore] Auto-resuming to ${resumeTarget}`);
ksPlayerRef.current.seek(resumeTarget);
}
}, 500);
}
@ -373,15 +376,17 @@ const KSPlayerCore: React.FC = () => {
modals.setShowErrorModal(true);
};
const handleClose = async () => {
const handleClose = useCallback(() => {
if (isSyncingBeforeClose.current) return;
isSyncingBeforeClose.current = true;
await traktAutosync.handleProgressUpdate(currentTime, duration, true);
await traktAutosync.handlePlaybackEnd(currentTime, duration, 'user_close');
// Fire and forget - don't block navigation on async operations
// The useWatchProgress and useTraktAutosync hooks handle cleanup on unmount
traktAutosync.handleProgressUpdate(currentTime, duration, true);
traktAutosync.handlePlaybackEnd(currentTime, duration, 'user_close');
navigation.goBack();
};
}, [navigation, currentTime, duration, traktAutosync]);
// Stream selection handler
const handleSelectStream = async (newStream: any) => {

View file

@ -102,13 +102,17 @@ export const useWatchProgress = (
}
}, [id, type, paused, currentTime, duration]);
// Unmount Save
// Unmount Save - deferred to allow navigation to complete first
useEffect(() => {
return () => {
if (id && type && durationRef.current > 0) {
saveWatchProgress();
traktAutosync.handlePlaybackEnd(currentTimeRef.current, durationRef.current, 'unmount');
}
// Use setTimeout(0) to defer save operations to next event loop tick
// This allows navigation animations to complete smoothly
setTimeout(() => {
if (id && type && durationRef.current > 0) {
saveWatchProgress();
traktAutosync.handlePlaybackEnd(currentTimeRef.current, durationRef.current, 'unmount');
}
}, 0);
};
}, [id, type]);

View file

@ -55,12 +55,24 @@ export const EpisodesModal: React.FC<EpisodesModalProps> = ({
if (showEpisodesModal && metadata?.id) {
setIsLoadingProgress(true);
try {
const progress = await storageService.getShowProgress(metadata.id);
setEpisodeProgress(progress || {});
// Get all watch progress and filter for this show's episodes
const allProgress = await storageService.getAllWatchProgress();
const showPrefix = `series:${metadata.id}:`;
const progress: { [key: string]: any } = {};
for (const [key, value] of Object.entries(allProgress)) {
if (key.startsWith(showPrefix)) {
// Extract episode id from key (format: series:showId:episodeId)
const episodeId = key.replace(showPrefix, '');
progress[episodeId] = value;
}
}
setEpisodeProgress(progress);
// Trakt sync logic preserved
if (await TraktService.isAuthenticated()) {
// Optional: background sync logic
if (await TraktService.getInstance().isAuthenticated()) {
// Optional: background sync logic
}
} catch (err) {
logger.error('Failed to fetch episode progress', err);
@ -84,7 +96,7 @@ export const EpisodesModal: React.FC<EpisodesModalProps> = ({
const currentSeasonEpisodes = groupedEpisodes[selectedSeason] || [];
return (
<View style={StyleSheet.absoluteFill} zIndex={9999}>
<View style={[StyleSheet.absoluteFill, { zIndex: 9999 }]}>
<TouchableOpacity style={StyleSheet.absoluteFill} activeOpacity={1} onPress={() => setShowEpisodesModal(false)}>
<Animated.View entering={FadeIn.duration(200)} exiting={FadeOut.duration(150)} style={{ flex: 1, backgroundColor: 'rgba(0,0,0,0.5)' }} />
</TouchableOpacity>
@ -110,31 +122,31 @@ export const EpisodesModal: React.FC<EpisodesModalProps> = ({
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{ paddingBottom: 15, gap: 8 }}>
{[...seasons]
.sort((a, b) => {
if (a === 0) return 1;
if (b === 0) return -1;
return a - b;
}).map((season) => (
<TouchableOpacity
key={season}
onPress={() => setSelectedSeason(season)}
style={{
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
backgroundColor: selectedSeason === season ? 'white' : 'rgba(255,255,255,0.06)',
borderWidth: 1,
borderColor: selectedSeason === season ? 'white' : 'rgba(255,255,255,0.1)',
}}
>
<Text style={{
color: selectedSeason === season ? 'black' : 'white',
fontWeight: selectedSeason === season ? '700' : '500'
}}>
{season === 0 ? 'Specials' : `Season ${season}`}
</Text>
</TouchableOpacity>
))}
.sort((a, b) => {
if (a === 0) return 1;
if (b === 0) return -1;
return a - b;
}).map((season) => (
<TouchableOpacity
key={season}
onPress={() => setSelectedSeason(season)}
style={{
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
backgroundColor: selectedSeason === season ? 'white' : 'rgba(255,255,255,0.06)',
borderWidth: 1,
borderColor: selectedSeason === season ? 'white' : 'rgba(255,255,255,0.1)',
}}
>
<Text style={{
color: selectedSeason === season ? 'black' : 'white',
fontWeight: selectedSeason === season ? '700' : '500'
}}>
{season === 0 ? 'Specials' : `Season ${season}`}
</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>