pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

update favorite episodes so they populate immediately

Pas 752e8cad 7c9f3c75

+44 -23
+17 -19
src/components/overlays/detailsModal/components/carousels/EpisodeCarousel.tsx
··· 9 9 import { Modal, ModalCard, useModal } from "@/components/overlays/Modal"; 10 10 import { hasAired } from "@/components/player/utils/aired"; 11 11 import { useBookmarkStore } from "@/stores/bookmarks"; 12 - // eslint-disable-next-line import/no-cycle 13 - import { 14 - ProgressEpisodeItem, 15 - getProgressPercentage, 16 - useProgressStore, 17 - } from "@/stores/progress"; 12 + import { getProgressPercentage, useProgressStore } from "@/stores/progress"; 18 13 19 14 import { EpisodeCarouselProps } from "../../types"; 15 + 16 + const EMPTY_ARRAY: string[] = []; 20 17 21 18 export function EpisodeCarousel({ 22 19 episodes, ··· 221 218 (s) => s.toggleFavoriteEpisode, 222 219 ); 223 220 const bookmarks = useBookmarkStore((s) => s.bookmarks); 224 - const getFavoriteEpisodes = useBookmarkStore((s) => s.getFavoriteEpisodes); 225 221 226 222 const toggleFavoriteStatus = (episodeId: number, event: React.MouseEvent) => { 227 223 event.preventDefault(); ··· 252 248 ); 253 249 254 250 // Get favorite episodes for this show 255 - const favoriteEpisodeIds = useMemo( 256 - () => (mediaId ? getFavoriteEpisodes(mediaId.toString()) : []), 257 - [mediaId, getFavoriteEpisodes], 251 + const favoriteEpisodeIds = useBookmarkStore((s) => 252 + mediaId 253 + ? (s.bookmarks[mediaId.toString()]?.favoriteEpisodes ?? EMPTY_ARRAY) 254 + : EMPTY_ARRAY, 258 255 ); 259 256 260 257 // Calculate watched episodes count and percentage 261 258 const watchedStats = useMemo(() => { 262 259 if (!mediaId || !totalEpisodes) return { watched: 0, percentage: 0 }; 263 260 264 - const item = progress[mediaId.toString()]; 265 - if (!item?.episodes) return { watched: 0, percentage: 0 }; 266 - 267 261 let watchedCount = 0; 268 - Object.values<ProgressEpisodeItem>(item.episodes).forEach((episode) => { 269 - const percentage = getProgressPercentage( 270 - episode.progress.watched, 271 - episode.progress.duration, 272 - ); 262 + episodes.forEach((episode) => { 263 + const episodeProgress = 264 + progress[mediaId.toString()]?.episodes?.[episode.id]; 265 + const percentage = episodeProgress 266 + ? getProgressPercentage( 267 + episodeProgress.progress.watched, 268 + episodeProgress.progress.duration, 269 + ) 270 + : 0; 273 271 if (percentage > 90) { 274 272 watchedCount += 1; 275 273 } ··· 278 276 const percentage = Math.round((watchedCount / totalEpisodes) * 100); 279 277 280 278 return { watched: watchedCount, percentage }; 281 - }, [progress, mediaId, totalEpisodes]); 279 + }, [episodes, progress, mediaId, totalEpisodes]); 282 280 283 281 // Load favorite episodes when favorites is selected 284 282 useEffect(() => {
+12 -4
src/components/player/atoms/Episodes.tsx
··· 24 24 25 25 import { hasAired } from "../utils/aired"; 26 26 27 + const EMPTY_ARRAY: string[] = []; 28 + 27 29 function CenteredText(props: { children: React.ReactNode }) { 28 30 return ( 29 31 <div className="h-full w-full flex justify-center items-center p-8 text-center"> ··· 504 506 meta?.tmdbId ?? "", 505 507 selectedSeason, 506 508 ); 507 - const getFavoriteEpisodes = useBookmarkStore((s) => s.getFavoriteEpisodes); 508 - const favoriteEpisodes = meta?.tmdbId ? getFavoriteEpisodes(meta.tmdbId) : []; 509 + const favoriteEpisodes = useBookmarkStore((s) => 510 + meta?.tmdbId 511 + ? (s.bookmarks[meta.tmdbId]?.favoriteEpisodes ?? EMPTY_ARRAY) 512 + : EMPTY_ARRAY, 513 + ); 509 514 510 515 let content: ReactNode = null; 511 516 if (seasons) { ··· 574 579 ); 575 580 const progress = useProgressStore(); 576 581 const updateItem = useProgressStore((s) => s.updateItem); 577 - const getFavoriteEpisodes = useBookmarkStore((s) => s.getFavoriteEpisodes); 578 - const favoriteEpisodes = meta?.tmdbId ? getFavoriteEpisodes(meta.tmdbId) : []; 582 + const favoriteEpisodes = useBookmarkStore((s) => 583 + meta?.tmdbId 584 + ? (s.bookmarks[meta.tmdbId]?.favoriteEpisodes ?? EMPTY_ARRAY) 585 + : EMPTY_ARRAY, 586 + ); 579 587 const bookmarks = useBookmarkStore((s) => s.bookmarks); 580 588 581 589 // Load all seasons for favorites view
+11
src/stores/bookmarks/BookmarkSyncer.tsx
··· 126 126 }, 127 127 }); 128 128 129 + // Override toggleFavoriteEpisode to trigger immediate sync 130 + const originalToggleFavoriteEpisode = 131 + useBookmarkStore.getState().toggleFavoriteEpisode; 132 + useBookmarkStore.setState({ 133 + toggleFavoriteEpisode: (...args) => { 134 + originalToggleFavoriteEpisode(...args); 135 + // Trigger debounced sync after toggling favorite episode 136 + debouncedSync(); 137 + }, 138 + }); 139 + 129 140 return () => { 130 141 if (syncTimeout) { 131 142 clearTimeout(syncTimeout);
+4
src/stores/bookmarks/index.ts
··· 186 186 action: "add", 187 187 tmdbId: showId, 188 188 favoriteEpisodes: bookmark.favoriteEpisodes, 189 + title: bookmark.title, 190 + year: bookmark.year, 191 + poster: bookmark.poster, 192 + type: bookmark.type, 189 193 }); 190 194 }); 191 195 },