A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz

Use all-time fallback for TopTrack

Fetch all-time top track and fall back to it when the 7-day query is
empty. Wait for both queries to finish before rendering and use the
first available track for title, artist and album art.

+41 -33
+41 -33
apps/web/src/pages/profile/toptrack/TopTrack.tsx
··· 5 5 function TopTrack() { 6 6 const { did } = useParams({ strict: false }); 7 7 const { data, isLoading } = useTracksQuery(did!, 0, 1, ...getLastDays(7)); 8 + const { data: allTimeTopTracks, isLoading: allTimeTopTracksLoading } = 9 + useTracksQuery(did!, 0, 1); 8 10 9 11 return ( 10 12 <> 11 - {!isLoading && data.length > 0 && ( 12 - <div className="flex"> 13 - <div className="flex flex-col items-end pr-[15px]"> 14 - <h4 15 - className="text-[12px] opacity-60 m-[0px]" 16 - style={{ fontWeight: "bold" }} 17 - > 18 - TOP TRACK 19 - </h4> 20 - <Link 21 - to={data[0].uri?.split("at:/")[1]?.replace("app.rocksky.", "")} 22 - className="!text-[var(--color-text)] no-underline hover:underline" 23 - > 24 - <b className="text-[18px] truncate max-w-[500px]"> 25 - {data[0].title} 26 - </b> 27 - </Link> 13 + {!isLoading && 14 + !allTimeTopTracksLoading && 15 + (data.length > 0 || allTimeTopTracks.length > 0) && ( 16 + <div className="flex"> 17 + <div className="flex flex-col items-end pr-[15px]"> 18 + <h4 19 + className="text-[12px] opacity-60 m-[0px]" 20 + style={{ fontWeight: "bold" }} 21 + > 22 + TOP TRACK 23 + </h4> 24 + <Link 25 + to={(data[0] || allTimeTopTracks[0])?.uri 26 + ?.split("at:/")[1] 27 + ?.replace("app.rocksky.", "")} 28 + className="!text-[var(--color-text)] no-underline hover:underline" 29 + > 30 + <b className="text-[18px] truncate max-w-[500px]"> 31 + {(data[0] || allTimeTopTracks[0])?.title} 32 + </b> 33 + </Link> 28 34 35 + <Link 36 + to={(data[0] || allTimeTopTracks[0])?.artistUri 37 + ?.split("at:/")[1] 38 + ?.replace("app.rocksky.", "")} 39 + className="text-[var(--color-text)] no-underline hover:underline" 40 + > 41 + <span className="opacity-90 text-[18px] truncate max-w-[500px]"> 42 + {(data[0] || allTimeTopTracks[0])?.albumArtist} 43 + </span> 44 + </Link> 45 + </div> 29 46 <Link 30 - to={data[0].artistUri 47 + to={(data[0] || allTimeTopTracks[0])?.albumUri 31 48 ?.split("at:/")[1] 32 49 ?.replace("app.rocksky.", "")} 33 - className="text-[var(--color-text)] no-underline hover:underline" 34 50 > 35 - <span className="opacity-90 text-[18px] truncate max-w-[500px]"> 36 - {data[0].albumArtist} 37 - </span> 51 + <img 52 + src={(data[0] || allTimeTopTracks[0])?.albumArt} 53 + alt={"Addicted"} 54 + className="w-[70px] h-[70px]" 55 + /> 38 56 </Link> 39 57 </div> 40 - <Link 41 - to={data[0].albumUri?.split("at:/")[1]?.replace("app.rocksky.", "")} 42 - > 43 - <img 44 - src={data[0].albumArt} 45 - alt={"Addicted"} 46 - className="w-[70px] h-[70px]" 47 - /> 48 - </Link> 49 - </div> 50 - )} 58 + )} 51 59 </> 52 60 ); 53 61 }