A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at main 125 lines 3.2 kB view raw
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;