tangled
alpha
login
or
join now
t1c.dev
/
rocksky
forked from
rocksky.app/rocksky
2
fork
atom
A decentralized music tracking and discovery platform built on AT Protocol 🎵
2
fork
atom
overview
issues
pulls
pipelines
display spotify link
tsiry-sandratraina.com
1 year ago
5cc92be1
8250c4a9
+83
-24
7 changed files
expand all
collapse all
unified
split
rockskyweb
src
atoms
artist.ts
song.ts
layouts
ExternalLinks
ExternalLinks.tsx
index.tsx
Main.tsx
pages
artist
Artist.tsx
song
Song.tsx
+15
rockskyweb/src/atoms/artist.ts
···
1
1
+
import { atom } from "jotai";
2
2
+
3
3
+
export const artistAtom = atom<{
4
4
+
id: string;
5
5
+
name: string;
6
6
+
born?: string;
7
7
+
bornIn?: string;
8
8
+
died?: string;
9
9
+
listeners: number;
10
10
+
scrobbles: number;
11
11
+
picture?: string;
12
12
+
tags: string[];
13
13
+
uri: string;
14
14
+
spotifyLink?: string;
15
15
+
} | null>(null);
+14
rockskyweb/src/atoms/song.ts
···
1
1
+
import { atom } from "jotai";
2
2
+
3
3
+
export const songAtom = atom<{
4
4
+
title: string;
5
5
+
albumArtist: string;
6
6
+
cover: string;
7
7
+
listeners: number;
8
8
+
scrobbles: number;
9
9
+
tags: string[];
10
10
+
lyrics?: string;
11
11
+
artistUri?: string;
12
12
+
albumUri?: string;
13
13
+
spotifyLink?: string;
14
14
+
} | null>(null);
+38
rockskyweb/src/layouts/ExternalLinks/ExternalLinks.tsx
···
1
1
+
import styled from "@emotion/styled";
2
2
+
import { Spotify } from "@styled-icons/boxicons-logos";
3
3
+
import { LabelLarge } from "baseui/typography";
4
4
+
import { useAtomValue } from "jotai";
5
5
+
import { useLocation } from "react-router";
6
6
+
import { artistAtom } from "../../atoms/artist";
7
7
+
8
8
+
const Link = styled.a`
9
9
+
text-decoration: none;
10
10
+
color: #000;
11
11
+
&:hover {
12
12
+
text-decoration: underline;
13
13
+
}
14
14
+
`;
15
15
+
16
16
+
function ExternalLinks() {
17
17
+
const artist = useAtomValue(artistAtom);
18
18
+
const location = useLocation();
19
19
+
const { pathname } = location;
20
20
+
const display =
21
21
+
pathname.includes("app.rocksky.scrobble") ||
22
22
+
pathname.includes("app.rocksky.song");
23
23
+
return (
24
24
+
<>
25
25
+
{display && artist?.spotifyLink && (
26
26
+
<div style={{ marginTop: 50 }}>
27
27
+
<LabelLarge marginBottom={"10px"}>External Links</LabelLarge>
28
28
+
<Link href={artist?.spotifyLink} target="_blank">
29
29
+
<Spotify size={25} color="#1dd05d" />
30
30
+
<span style={{ marginLeft: 10 }}>Spotify</span>
31
31
+
</Link>
32
32
+
</div>
33
33
+
)}
34
34
+
</>
35
35
+
);
36
36
+
}
37
37
+
38
38
+
export default ExternalLinks;
+3
rockskyweb/src/layouts/ExternalLinks/index.tsx
···
1
1
+
import ExternalLinks from "./ExternalLinks";
2
2
+
3
3
+
export default ExternalLinks;
+3
rockskyweb/src/layouts/Main.tsx
···
9
9
import { profileAtom } from "../atoms/profile";
10
10
import { API_URL } from "../consts";
11
11
import useProfile from "../hooks/useProfile";
12
12
+
import ExternalLinks from "./ExternalLinks";
12
13
import Navbar from "./Navbar";
13
14
import Search from "./Search";
14
15
import SpotifyLogin from "./SpotifyLogin";
···
202
203
</div>
203
204
</div>
204
205
)}
206
206
+
207
207
+
<ExternalLinks />
205
208
</div>
206
209
</RightPane>
207
210
</Container>
+5
-12
rockskyweb/src/pages/artist/Artist.tsx
···
1
1
import styled from "@emotion/styled";
2
2
import { Avatar } from "baseui/avatar";
3
3
import { HeadingMedium, HeadingXSmall, LabelMedium } from "baseui/typography";
4
4
+
import { useAtomValue, useSetAtom } from "jotai";
4
5
import numeral from "numeral";
5
6
import { useEffect, useState } from "react";
6
7
import { useParams } from "react-router";
8
8
+
import { artistAtom } from "../../atoms/artist";
7
9
import ArtistIcon from "../../components/Icons/Artist";
8
10
import Shout from "../../components/Shout/Shout";
9
11
import useLibrary from "../../hooks/useLibrary";
···
21
23
const Artist = () => {
22
24
const { did, rkey } = useParams<{ did: string; rkey: string }>();
23
25
const { getArtist, getArtistTracks, getArtistAlbums } = useLibrary();
24
24
-
const [artist, setArtist] = useState<{
25
25
-
id: string;
26
26
-
name: string;
27
27
-
born?: string;
28
28
-
bornIn?: string;
29
29
-
died?: string;
30
30
-
listeners: number;
31
31
-
scrobbles: number;
32
32
-
picture?: string;
33
33
-
tags: string[];
34
34
-
uri: string;
35
35
-
} | null>(null);
26
26
+
const artist = useAtomValue(artistAtom);
27
27
+
const setArtist = useSetAtom(artistAtom);
36
28
const [topTracks, setTopTracks] = useState<
37
29
{
38
30
id: string;
···
74
66
picture: data.picture,
75
67
tags: data.tags,
76
68
uri: data.uri,
69
69
+
spotifyLink: data.spotify_link,
77
70
});
78
71
};
79
72
fetchArtist();
+5
-12
rockskyweb/src/pages/song/Song.tsx
···
6
6
LabelLarge,
7
7
LabelMedium,
8
8
} from "baseui/typography";
9
9
+
import { useAtomValue, useSetAtom } from "jotai";
9
10
import numeral from "numeral";
10
10
-
import { useEffect, useState } from "react";
11
11
+
import { useEffect } from "react";
11
12
import ContentLoader from "react-content-loader";
12
13
import { Link as DefaultLink, useParams } from "react-router";
14
14
+
import { songAtom } from "../../atoms/song";
13
15
import Disc from "../../components/Icons/Disc";
14
16
import Shout from "../../components/Shout/Shout";
15
17
import SongCover from "../../components/SongCover";
···
35
37
const { did, rkey } = useParams<{ did: string; rkey: string }>();
36
38
const { getFeedByUri } = useFeed();
37
39
const { getSongByUri } = useLibrary();
38
38
-
const [song, setSong] = useState<{
39
39
-
title: string;
40
40
-
albumArtist: string;
41
41
-
cover: string;
42
42
-
listeners: number;
43
43
-
scrobbles: number;
44
44
-
tags: string[];
45
45
-
lyrics?: string;
46
46
-
artistUri?: string;
47
47
-
albumUri?: string;
48
48
-
} | null>(null);
40
40
+
const song = useAtomValue(songAtom);
41
41
+
const setSong = useSetAtom(songAtom);
49
42
useEffect(() => {
50
43
const getSong = async () => {
51
44
// if path contains app.rocksky.scrobble, get the song