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 media card skeleton and on recomented carousel

Pas ac722880 02291a3e

+42 -20
+11 -5
src/components/media/MediaCard.tsx
··· 49 49 } 50 50 51 51 // Skeleton Component 52 - function MediaCardSkeleton() { 52 + export function MediaCardSkeleton() { 53 53 return ( 54 - <div className="group -m-[0.705em] rounded-xl bg-background-main transition-colors duration-300"> 55 - <div className="pointer-events-auto relative mb-2 p-[0.4em] transition-transform duration-300"> 54 + <Flare.Base className="group -m-[0.705em] rounded-xl bg-background-main transition-colors duration-300"> 55 + <Flare.Light 56 + flareSize={300} 57 + cssColorVar="--colors-mediaCard-hoverAccent" 58 + backgroundClass="bg-mediaCard-hoverBackground duration-100" 59 + className="rounded-xl bg-background-main group-hover:opacity-100" 60 + /> 61 + <Flare.Child className="pointer-events-auto relative mb-2 p-[0.4em] transition-transform duration-300 opacity-60"> 56 62 <div className="animate-pulse"> 57 63 {/* Poster skeleton - matches MediaCard poster dimensions exactly */} 58 64 <div className="relative mb-4 pb-[150%] w-full overflow-hidden rounded-xl bg-mediaCard-hoverBackground" /> ··· 71 77 <div className="h-3 bg-mediaCard-hoverBackground rounded w-8" /> 72 78 </div> 73 79 </div> 74 - </div> 75 - </div> 80 + </Flare.Child> 81 + </Flare.Base> 76 82 ); 77 83 } 78 84
+31 -15
src/components/overlays/detailsModal/components/carousels/SimilarMediaCarousel.tsx
··· 3 3 4 4 import { getMediaPoster, getRelatedMedia } from "@/backend/metadata/tmdb"; 5 5 import { TMDBContentTypes } from "@/backend/metadata/types/tmdb"; 6 - import { MediaCard } from "@/components/media/MediaCard"; 6 + import { MediaCard, MediaCardSkeleton } from "@/components/media/MediaCard"; 7 7 import { useIsMobile } from "@/hooks/useIsMobile"; 8 8 import { CarouselNavButtons } from "@/pages/discover/components/CarouselNavButtons"; 9 9 import { useOverlayStack } from "@/stores/interface/overlayStack"; ··· 22 22 const { isMobile } = useIsMobile(); 23 23 const { showModal } = useOverlayStack(); 24 24 const [similarMedia, setSimilarMedia] = useState<MediaItem[]>([]); 25 + const [isLoading, setIsLoading] = useState(true); 25 26 const carouselRef = useRef<HTMLDivElement>(null); 26 27 const carouselRefs = useRef<{ [key: string]: HTMLDivElement | null }>({ 27 28 similar: null, ··· 29 30 30 31 useEffect(() => { 31 32 const loadSimilarMedia = async () => { 33 + setIsLoading(true); 32 34 try { 33 35 const results = await getRelatedMedia(mediaId, mediaType, 12); 34 36 const mediaItems: MediaItem[] = results.map((result) => { ··· 57 59 setSimilarMedia(mediaItems); 58 60 } catch (err) { 59 61 console.error("Failed to load similar media:", err); 62 + } finally { 63 + setIsLoading(false); 60 64 } 61 65 }; 62 66 ··· 76 80 }); 77 81 }; 78 82 79 - if (similarMedia.length === 0) return null; 83 + if (!isLoading && similarMedia.length === 0) return null; 80 84 81 85 return ( 82 86 <div className="space-y-4 pt-8"> ··· 96 100 > 97 101 <div className="md:w-12" /> 98 102 99 - {similarMedia.map((media) => ( 100 - <div 101 - key={media.id} 102 - className="relative mt-4 group cursor-pointer user-select-none rounded-xl p-2 bg-transparent transition-colors duration-300 w-[10rem] md:w-[11.5rem] h-auto" 103 - style={{ scrollSnapAlign: "start" }} 104 - > 105 - <MediaCard 106 - media={media} 107 - linkable 108 - onShowDetails={handleShowDetails} 109 - /> 110 - </div> 111 - ))} 103 + {isLoading 104 + ? // Show skeleton cards while loading 105 + Array.from({ length: 12 }, (_, i) => ( 106 + <div 107 + key={`skeleton-${i}`} 108 + className="relative mt-4 group cursor-pointer user-select-none rounded-xl p-2 bg-transparent transition-colors duration-300 w-[10rem] md:w-[11.5rem] h-auto" 109 + style={{ scrollSnapAlign: "start" }} 110 + > 111 + <MediaCardSkeleton /> 112 + </div> 113 + )) 114 + : // Show actual media cards when loaded 115 + similarMedia.map((media) => ( 116 + <div 117 + key={media.id} 118 + className="relative mt-4 group cursor-pointer user-select-none rounded-xl p-2 bg-transparent transition-colors duration-300 w-[10rem] md:w-[11.5rem] h-auto" 119 + style={{ scrollSnapAlign: "start" }} 120 + > 121 + <MediaCard 122 + media={media} 123 + linkable 124 + onShowDetails={handleShowDetails} 125 + /> 126 + </div> 127 + ))} 112 128 113 129 <div className="md:w-12" /> 114 130 </div>