Teal.fm frontend powered by slices.network tealfm-slices.wisp.place
tealfm slices
1import { graphql, useLazyLoadQuery } from "react-relay"; 2import { useParams } from "react-router-dom"; 3import type { ProfileTopAlbumsQuery } from "./__generated__/ProfileTopAlbumsQuery.graphql"; 4import AlbumItem from "./AlbumItem"; 5import { useDateRangeFilter } from "./useDateRangeFilter"; 6import { useMemo } from "react"; 7 8export default function ProfileTopAlbums() { 9 const { handle, period } = useParams<{ handle: string; period?: string }>(); 10 const dateRangeVariables = useDateRangeFilter(period); 11 12 const queryVariables = useMemo(() => { 13 return { 14 where: { 15 ...dateRangeVariables.where, 16 actorHandle: { eq: handle }, 17 }, 18 }; 19 }, [handle, dateRangeVariables]); 20 21 const data = useLazyLoadQuery<ProfileTopAlbumsQuery>( 22 graphql` 23 query ProfileTopAlbumsQuery($where: FmTealAlphaFeedPlayWhereInput) { 24 fmTealAlphaFeedPlaysAggregated( 25 groupBy: [{ field: releaseMbId }, { field: releaseName }, { field: artists }] 26 orderBy: { count: desc } 27 limit: 50 28 where: $where 29 ) { 30 releaseMbId 31 releaseName 32 artists 33 count 34 } 35 } 36 `, 37 queryVariables, 38 { fetchKey: `${handle}-${period || "all"}`, fetchPolicy: "store-or-network" } 39 ); 40 41 const albums = [...(data.fmTealAlphaFeedPlaysAggregated || [])]; 42 43 // Deduplicate by release name, keeping the one with highest count 44 // Prefer entries with artist data 45 const seenNames = new Set<string>(); 46 const dedupedAlbums = albums 47 .sort((a, b) => { 48 // First sort by count (already sorted from query) 49 if (b.count !== a.count) return b.count - a.count; 50 // Then prefer entries with artists data 51 if (a.artists && !b.artists) return -1; 52 if (!a.artists && b.artists) return 1; 53 return 0; 54 }) 55 .filter((album) => { 56 const name = album.releaseName || "Unknown Album"; 57 if (seenNames.has(name)) { 58 return false; 59 } 60 seenNames.add(name); 61 return true; 62 }) 63 .slice(0, 10); 64 65 const maxCount = dedupedAlbums.length > 0 ? dedupedAlbums[0].count : 0; 66 67 return ( 68 <div className="space-y-1"> 69 {dedupedAlbums.map((album, index) => ( 70 <AlbumItem 71 key={album.releaseMbId || index} 72 releaseName={album.releaseName || "Unknown Album"} 73 releaseMbId={album.releaseMbId} 74 artists={album.artists} 75 count={album.count} 76 rank={index + 1} 77 maxCount={maxCount} 78 /> 79 ))} 80 </div> 81 ); 82}