forked from
rocksky.app/rocksky
A decentralized music tracking and discovery platform built on AT Protocol 馃幍
1import axios from "axios";
2import { useSetAtom } from "jotai";
3import { useEffect, useState } from "react";
4import { useNavigate } from "react-router";
5import { profileAtom } from "../atoms/profile";
6import { API_URL } from "../consts";
7import { Scrobble } from "../types/scrobble";
8
9function useProfile(token?: string | null) {
10 const setProfile = useSetAtom(profileAtom);
11 const navigate = useNavigate();
12 const [data, setData] = useState<string | null>(null);
13 const [error, setError] = useState<Error | null>(null);
14 const isLoading = !data && !error;
15
16 const getProfileByDid = async (did: string) => {
17 try {
18 const response = await axios.get(`${API_URL}/users/${did}`);
19 return response.data;
20 } catch {
21 navigate("/");
22 return null;
23 }
24 };
25
26 const getProfileStatsByDid = async (did: string) => {
27 const response = await axios.get(`${API_URL}/users/${did}/stats`);
28 return response.data;
29 };
30
31 const getRecentTracksByDid = async (
32 did: string,
33 offset = 0,
34 size = 10
35 ): Promise<Scrobble[]> => {
36 const response = await axios.get<Scrobble[]>(
37 `${API_URL}/users/${did}/scrobbles?size=${size}&offset=${offset}`
38 );
39 return response.data;
40 };
41
42 useEffect(() => {
43 if (!token) {
44 return;
45 }
46
47 const fetchProfile = async () => {
48 try {
49 const response = await fetch(`${API_URL}/profile`, {
50 headers: {
51 Authorization: `Bearer ${token}`,
52 },
53 }).then((res) => res.text());
54 setData(response);
55 setError(null);
56 } catch (e) {
57 setError(e as Error);
58 setData(null);
59 }
60 };
61 fetchProfile();
62 }, [token]);
63
64 useEffect(() => {
65 if (data !== "Unauthorized" && data !== "Internal Server Error" && data) {
66 const profile = JSON.parse(data);
67 setProfile({
68 avatar: `https://cdn.bsky.app/img/avatar/plain/${localStorage.getItem(
69 "did"
70 )}/${profile.avatar.ref["$link"]}@jpeg`,
71 displayName: profile.displayName,
72 handle: profile.handle,
73 spotifyUser: {
74 isBeta: profile.spotifyUser?.is_beta_user,
75 },
76 spotifyConnected: profile.spotifyConnected,
77 did: profile.did,
78 });
79 }
80
81 if (
82 !data ||
83 data === "Unauthorized" ||
84 data === "Internal Server Error" ||
85 (error && localStorage.getItem("token"))
86 ) {
87 if (data === "Unauthorized") {
88 localStorage.removeItem("token");
89 }
90 }
91
92 // eslint-disable-next-line react-hooks/exhaustive-deps
93 }, [data]);
94
95 if (
96 !data ||
97 data === "Unauthorized" ||
98 data === "Internal Server Error" ||
99 (error && localStorage.getItem("token"))
100 ) {
101 if (data === "Unauthorized" && localStorage.getItem("token")) {
102 localStorage.clear();
103 window.location.href = "/";
104 }
105 return {
106 data: null,
107 error,
108 isLoading,
109 getProfileByDid,
110 getProfileStatsByDid,
111 getRecentTracksByDid,
112 };
113 }
114
115 return {
116 data: JSON.parse(data),
117 error,
118 isLoading,
119 getProfileByDid,
120 getProfileStatsByDid,
121 getRecentTracksByDid,
122 };
123}
124
125export default useProfile;