A decentralized music tracking and discovery platform built on AT Protocol 🎵
listenbrainz spotify atproto lastfm musicbrainz scrobbling

Guard profile.did usage and fix related bugs

Add null checks and early returns in Handle to avoid using an undefined
profile.did. Add profile.data?.did to effect deps and use "" fallbacks
when checking Set membership. Fix useActorCompatibilityQuery type
(undefined) and remove unused LabelMedium import. Use empty-string
fallback when calling useFollowersInfiniteQuery.

Changed files
+19 -6
apps
web
src
components
Handle
Stats
hooks
pages
profile
followers
+16 -3
apps/web/src/components/Handle/Handle.tsx
··· 50 50 setIsSignInOpen(true); 51 51 return; 52 52 } 53 + if (!profile.data?.did) { 54 + return; 55 + } 53 56 setFollows((prev) => new Set(prev).add(profile.data?.did)); 54 57 followAccount(profile.data?.did); 55 58 }; ··· 59 62 setIsSignInOpen(true); 60 63 return; 61 64 } 65 + if (!profile.data?.did) { 66 + return; 67 + } 68 + 62 69 setFollows((prev) => { 70 + if (!profile.data?.did) { 71 + return prev; 72 + } 63 73 const newSet = new Set(prev); 64 74 newSet.delete(profile.data?.did); 65 75 return newSet; ··· 73 83 } 74 84 setFollows((prev) => { 75 85 const newSet = new Set(prev); 86 + if (!profile.data?.did) { 87 + return newSet; 88 + } 76 89 if ( 77 90 data.followers.some( 78 91 (follower: { did: string }) => follower.did === currentDid, ··· 84 97 } 85 98 return newSet; 86 99 }); 87 - }, [data, isLoading]); 100 + }, [data, isLoading, currentDid, setFollows, profile.data?.did]); 88 101 89 102 useEffect(() => { 90 103 if (profile.isLoading || profile.isError) { ··· 169 182 {(profile.data?.did !== localStorage.getItem("did") || 170 183 !localStorage.getItem("did")) && ( 171 184 <div className="ml-auto mt-[10px]"> 172 - {!follows.has(profile.data?.did) && !isLoading && ( 185 + {!follows.has(profile.data?.did || "") && !isLoading && ( 173 186 <Button 174 187 shape="pill" 175 188 size="mini" ··· 193 206 Follow 194 207 </Button> 195 208 )} 196 - {follows.has(profile.data?.did) && !isLoading && ( 209 + {follows.has(profile.data?.did || "") && !isLoading && ( 197 210 <Button 198 211 shape="pill" 199 212 size="mini"
+1 -1
apps/web/src/components/Stats/Stats.tsx
··· 1 1 import { css } from "@emotion/react"; 2 2 import styled from "@emotion/styled"; 3 - import { HeadingSmall, LabelMedium } from "baseui/typography"; 3 + import { HeadingSmall } from "baseui/typography"; 4 4 import numeral from "numeral"; 5 5 6 6 const Group = styled.div<{ mb?: number }>`
+1 -1
apps/web/src/hooks/useProfile.tsx
··· 39 39 enabled: !!did, 40 40 }); 41 41 42 - export const useActorCompatibilityQuery = (did: string | undefine) => 42 + export const useActorCompatibilityQuery = (did: string | undefined) => 43 43 useQuery({ 44 44 queryKey: ["profile", "compatibility", did], 45 45 queryFn: () => getActorCompatibility(did!),
+1 -1
apps/web/src/pages/profile/followers/Followers.tsx
··· 25 25 const { did } = useParams({ strict: false }); 26 26 const profile = useProfileByDidQuery(did!); 27 27 const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = 28 - useFollowersInfiniteQuery(profile.data?.did, 20); 28 + useFollowersInfiniteQuery(profile.data?.did || "", 20); 29 29 const { mutate: followAccount } = useFollowAccountMutation(); 30 30 const { mutate: unfollowAccount } = useUnfollowAccountMutation(); 31 31