A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at fix/spotify 132 lines 3.4 kB view raw
1import { useQuery } from "@tanstack/react-query"; 2import { useSetAtom } from "jotai"; 3import { useEffect, useState } from "react"; 4import { 5 getProfileByDid, 6 getProfileStatsByDid, 7 getRecentTracksByDid, 8} from "../api/profile"; 9import { profileAtom } from "../atoms/profile"; 10import { API_URL } from "../consts"; 11 12export const useProfileByDidQuery = (did: string) => 13 useQuery({ 14 queryKey: ["profile", did], 15 queryFn: () => getProfileByDid(did), 16 }); 17 18export const useProfileStatsByDidQuery = (did: string) => 19 useQuery({ 20 queryKey: ["profile", "stats", did], 21 queryFn: () => getProfileStatsByDid(did), 22 enabled: !!did, 23 // refetchInterval: 4500, 24 }); 25 26export const useRecentTracksByDidQuery = (did: string, offset = 0, size = 10) => 27 useQuery({ 28 queryKey: ["profile", "recent-tracks", did, offset, size], 29 queryFn: () => getRecentTracksByDid(did, offset, size), 30 enabled: !!did, 31 }); 32 33function useProfile(token?: string | null) { 34 const setProfile = useSetAtom(profileAtom); 35 const [data, setData] = useState<string | null>(null); 36 const [error, setError] = useState<Error | null>(null); 37 const isLoading = !data && !error; 38 39 useEffect(() => { 40 if (!token) { 41 return; 42 } 43 44 const fetchProfile = async () => { 45 try { 46 const response = await fetch( 47 `${API_URL}/xrpc/app.rocksky.actor.getProfile`, 48 { 49 headers: { 50 Authorization: `Bearer ${token}`, 51 }, 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 if (Object.keys(profile).length === 0) { 68 localStorage.removeItem("token"); 69 window.location.href = "/"; 70 return; 71 } 72 setProfile({ 73 avatar: profile.avatar, 74 displayName: profile.displayName, 75 handle: profile.handle, 76 spotifyUser: { 77 isBeta: profile.spotifyUser?.isBetaUser, 78 }, 79 spotifyConnected: profile.spotifyConnected, 80 did: profile.did, 81 googledriveUser: { 82 isBeta: profile.googledrive?.isBetaUser, 83 }, 84 dropboxUser: { 85 isBeta: profile.dropbox?.isBetaUser, 86 }, 87 }); 88 } 89 90 if ( 91 !data || 92 data === "Unauthorized" || 93 data === "Internal Server Error" || 94 (error && localStorage.getItem("token")) 95 ) { 96 if (data === "Unauthorized") { 97 console.log(">> Unauthorized"); 98 localStorage.removeItem("token"); 99 } 100 } 101 102 // eslint-disable-next-line react-hooks/exhaustive-deps 103 }, [data]); 104 105 if ( 106 !data || 107 data === "Unauthorized" || 108 data === "Internal Server Error" || 109 (error && localStorage.getItem("token")) 110 ) { 111 if (data === "Unauthorized" && localStorage.getItem("token")) { 112 console.log(">> error", error, ">> data", data); // localStorage.clear(); 113 window.location.href = "/"; 114 } 115 return { 116 data: null, 117 error, 118 isLoading, 119 getProfileByDid, 120 getProfileStatsByDid, 121 getRecentTracksByDid, 122 }; 123 } 124 125 return { 126 data: JSON.parse(data), 127 error, 128 isLoading, 129 }; 130} 131 132export default useProfile;