forked from
rocksky.app/rocksky
A decentralized music tracking and discovery platform built on AT Protocol 馃幍
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;