A decentralized music tracking and discovery platform built on AT Protocol 🎵

Add top tracks table and date range params

Render top tracks as a responsive table in the embed page, using v4
Link tracks and artists to rocksky; show album art with fallback UI
Update API call to include startDate/endDate using getLastDays(7)

+50
+46
apps/embed/src/embeds/TopTracksEmbedPage.tsx
··· 1 + import { v4 } from "uuid"; 1 2 import Header from "../components/Header"; 2 3 import type { Profile } from "../types/profile"; 3 4 import type { Track } from "../types/track"; ··· 12 13 <div className="p-[15px]"> 13 14 <Header profile={props.profile} /> 14 15 <h2 className="m-[0px]">Top Tracks</h2> 16 + 17 + <div className="w-full overflow-x-auto"> 18 + <table className="table-borderless table"> 19 + <tbody> 20 + {props.tracks.map((track, index) => ( 21 + <tr key={v4()}> 22 + <td> 23 + <div className="flex flex-row items-center"> 24 + <div className="mr-[20px] min-w-[30px]">{index + 1}</div> 25 + <a 26 + href={`https://rocksky.app/${track.uri?.split("at://")[1]?.replace("app.rocksky.", "")}`} 27 + target="_blank" 28 + className="flex flex-row items-center no-underline text-inherit" 29 + > 30 + {track.albumArt && ( 31 + <img 32 + className="max-w-[60px] max-h-[60px] mr-[20px] rounded-[5px]" 33 + src={track.albumArt!} 34 + /> 35 + )} 36 + {!track.albumArt && ( 37 + <div className="w-[60px] h-[60px] bg-[var(--color-avatar-background)] flex items-center justify-center mr-[20px]"> 38 + <div className="h-[30px] w-[30px]"></div> 39 + </div> 40 + )} 41 + <div> 42 + <div>{track.title}</div> 43 + <a 44 + href={`https://rocksky.app/${track.artistUri.split("at://")[1]?.replace("app.rocksky.", "")}`} 45 + target="_blank" 46 + className="no-underline text-inherit" 47 + > 48 + <div className="font-rockford-light opacity-60"> 49 + {track.albumArtist} 50 + </div> 51 + </a> 52 + </div> 53 + </a> 54 + </div> 55 + </td> 56 + </tr> 57 + ))} 58 + </tbody> 59 + </table> 60 + </div> 15 61 </div> 16 62 ); 17 63 }
+4
apps/embed/src/xrpc/getTopTracks.ts
··· 1 1 import { ROCKSKY_API_URL } from "../consts"; 2 + import getLastDays from "../lib/getLastDays"; 2 3 import type { Track } from "../types/track"; 3 4 4 5 export default async function getTopAlbums(handle: string) { 6 + const [start, end] = getLastDays(7); 5 7 const url = new URL( 6 8 `${ROCKSKY_API_URL}/xrpc/app.rocksky.actor.getActorSongs`, 7 9 ); 8 10 url.searchParams.append("did", handle); 11 + url.searchParams.append("startDate", start.toISOString()); 12 + url.searchParams.append("endDate", end.toISOString()); 9 13 url.searchParams.append("limit", "20"); 10 14 11 15 const res = await fetch(url);