A decentralized music tracking and discovery platform built on AT Protocol 馃幍
rocksky.app
spotify
atproto
lastfm
musicbrainz
scrobbling
listenbrainz
1import { v4 } from "uuid";
2import Header from "../components/Header";
3import type { Profile } from "../types/profile";
4import type { Scrobble } from "../types/scrobble";
5import dayjs from "dayjs";
6import relativeTime from "dayjs/plugin/relativeTime";
7
8dayjs.extend(relativeTime);
9
10export type RecentScrobblesEmbedPageProps = {
11 profile: Profile;
12 scrobbles: Scrobble[];
13};
14
15export function RecentScrobblesEmbedPage(props: RecentScrobblesEmbedPageProps) {
16 return (
17 <div className="p-[15px]">
18 <Header profile={props.profile} />
19 <h2 className="m-[0px] mb-[10px]">Recent Listens</h2>
20
21 <div className="w-full overflow-x-auto">
22 <table className="table-borderless table">
23 <tbody>
24 {props.scrobbles.map((scrobble, index) => (
25 <tr key={v4()}>
26 <td className="pl-[0px] pr-[0px]">
27 <div className="flex flex-row items-center">
28 <a
29 href={`https://rocksky.app/${scrobble.uri?.split("at://")[1]?.replace("app.rocksky.", "")}`}
30 target="_blank"
31 className="flex flex-row items-center no-underline text-inherit"
32 >
33 {scrobble.albumArt && (
34 <img
35 className="max-w-[60px] max-h-[60px] mr-[20px] rounded-[5px]"
36 src={scrobble.albumArt!}
37 />
38 )}
39 {!scrobble.albumArt && (
40 <div className="w-[60px] h-[60px] bg-[var(--color-avatar-background)] flex items-center justify-center mr-[20px]">
41 <div className="h-[30px] w-[30px]"></div>
42 </div>
43 )}
44 <div>
45 <div>{scrobble.title}</div>
46 <a
47 href={`https://rocksky.app/${scrobble.artistUri?.split("at://")[1]?.replace("app.rocksky.", "")}`}
48 target="_blank"
49 className="no-underline text-inherit"
50 >
51 <div className="font-rockford-light opacity-60">
52 {scrobble.albumArtist}
53 </div>
54 </a>
55 </div>
56 </a>
57 </div>
58 </td>
59 <td className="font-rockford-light opacity-60">
60 {dayjs(
61 scrobble.createdAt.endsWith("Z")
62 ? scrobble.createdAt
63 : `${scrobble.createdAt}Z`,
64 ).fromNow()}
65 </td>
66 </tr>
67 ))}
68 </tbody>
69 </table>
70 </div>
71 </div>
72 );
73}