Skip to content

Commit 339aad5

Browse files
(UPDATE): enhance watched episodes tracking by audio type in DetailsPage component
1 parent 7389bbc commit 339aad5

File tree

1 file changed

+53
-20
lines changed

1 file changed

+53
-20
lines changed

app/(tabs)/details.tsx

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { AnimeItem } from "../../types/anime";
2525
// Context hooks for watchlist and watch history management
2626
import { useWatchlist } from '../../contexts/WatchlistContext';
2727
import { useWatchHistory } from '../../contexts/WatchHistoryContext';
28+
import type { WatchHistoryItem } from '../../contexts/WatchHistoryContext';
2829

2930
// AsyncStorage for local data persistence
3031
import AsyncStorage from '@react-native-async-storage/async-storage';
@@ -81,7 +82,10 @@ export default function DetailsPage() {
8182
const [loading, setLoading] = useState(true); // Data loading state
8283
const [error, setError] = useState<string | null>(null); // Error state for API failures
8384
const [animeData, setAnimeData] = useState<AnimeDetailsResponse['result'] | null>(null); // Main anime data
84-
const [watchedEpisode, setWatchedEpisode] = useState<string>(''); // Most recently watched episode
85+
const [mostRecentEpisodeByAudio, setMostRecentEpisodeByAudio] = useState<Record<'sub' | 'dub', string>>(() => ({
86+
sub: '',
87+
dub: '',
88+
}));
8589

8690
// Context hooks for watchlist and watch history functionality
8791
const { isInWatchlist, toggleWatchlist } = useWatchlist();
@@ -166,7 +170,10 @@ export default function DetailsPage() {
166170
const { getWatchedEpisodes } = useWatchHistory();
167171

168172
// State for tracking all watched episodes (used for UI indicators)
169-
const [watchedEpisodes, setWatchedEpisodes] = useState<Set<string>>(new Set());
173+
const [watchedEpisodesByAudio, setWatchedEpisodesByAudio] = useState<Record<'sub' | 'dub', Set<string>>>(() => ({
174+
sub: new Set<string>(),
175+
dub: new Set<string>(),
176+
}));
170177

171178
/**
172179
* Watch History Loading Effect
@@ -183,23 +190,46 @@ export default function DetailsPage() {
183190
try {
184191
// Get all watched episodes for this anime
185192
const historyEpisodes = getWatchedEpisodes(id as string);
186-
193+
187194
if (historyEpisodes.length > 0) {
188-
// Create a set of all watched episode numbers
189-
const episodeSet = new Set(historyEpisodes.map(ep => ep.episodeNumber));
190-
setWatchedEpisodes(episodeSet);
191-
192-
// Find the most recently watched episode for the main indicator
193-
const mostRecentEpisode = historyEpisodes.reduce((latest, current) =>
194-
current.watchedAt > latest.watchedAt ? current : latest
195-
);
196-
197-
// Set the most recently watched episode
198-
setWatchedEpisode(mostRecentEpisode.episodeNumber);
195+
const subEpisodes = new Set<string>();
196+
const dubEpisodes = new Set<string>();
197+
const latestByAudio: Record<'sub' | 'dub', WatchHistoryItem | null> = {
198+
sub: null,
199+
dub: null,
200+
};
201+
202+
historyEpisodes.forEach((entry) => {
203+
const entryAudioType: 'sub' | 'dub' = entry.audioType || 'sub';
204+
205+
if (entryAudioType === 'sub') {
206+
subEpisodes.add(entry.episodeNumber);
207+
} else if (entryAudioType === 'dub') {
208+
dubEpisodes.add(entry.episodeNumber);
209+
}
210+
211+
const currentLatest = latestByAudio[entryAudioType];
212+
if (!currentLatest || entry.watchedAt > currentLatest.watchedAt) {
213+
latestByAudio[entryAudioType] = entry;
214+
}
215+
});
216+
217+
setWatchedEpisodesByAudio({
218+
sub: subEpisodes,
219+
dub: dubEpisodes,
220+
});
221+
222+
setMostRecentEpisodeByAudio({
223+
sub: latestByAudio.sub?.episodeNumber || '',
224+
dub: latestByAudio.dub?.episodeNumber || '',
225+
});
199226
} else {
200227
// Clear the states if no history
201-
setWatchedEpisodes(new Set());
202-
setWatchedEpisode('');
228+
setWatchedEpisodesByAudio({
229+
sub: new Set<string>(),
230+
dub: new Set<string>(),
231+
});
232+
setMostRecentEpisodeByAudio({ sub: '', dub: '' });
203233
}
204234
} catch (err) {
205235
console.error('Error loading watched episode data:', err);
@@ -322,6 +352,9 @@ export default function DetailsPage() {
322352
// Check watchlist status using context for real-time updates
323353
const isInWatchlistCache = isInWatchlist(animeData.id);
324354

355+
const watchedEpisodesForAudio = watchedEpisodesByAudio[audioType];
356+
const mostRecentEpisodeForAudio = mostRecentEpisodeByAudio[audioType];
357+
325358
/**
326359
* Main Details Page Render
327360
*
@@ -496,8 +529,8 @@ export default function DetailsPage() {
496529
key={`episode-${episode}`}
497530
style={[
498531
styles.episodeBox,
499-
watchedEpisodes.has(episode) && styles.watchedEpisodeBox, // Watched episode styling
500-
episode === watchedEpisode && styles.currentEpisodeBox // Most recent episode styling
532+
watchedEpisodesForAudio.has(episode) && styles.watchedEpisodeBox, // Watched episode styling
533+
episode === mostRecentEpisodeForAudio && styles.currentEpisodeBox // Most recent episode styling
501534
]}
502535
onPress={() => router.push({
503536
pathname: "/streaming",
@@ -513,10 +546,10 @@ export default function DetailsPage() {
513546
{/* Episode number */}
514547
<Text style={[
515548
styles.episodeNumber,
516-
watchedEpisodes.has(episode) && styles.watchedEpisodeText
549+
watchedEpisodesForAudio.has(episode) && styles.watchedEpisodeText
517550
]}>{episode}</Text>
518551
{/* Watched indicator checkmark */}
519-
{watchedEpisodes.has(episode) && (
552+
{watchedEpisodesForAudio.has(episode) && (
520553
<View style={styles.watchedIndicator}>
521554
<MaterialCommunityIcons name="check" size={10} color="#fff" />
522555
</View>

0 commit comments

Comments
 (0)