an independent Bluesky client using Constellation, PDS Queries, and other services
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

profile query placeholder

+81 -36
+43 -35
src/routes/c.$did.tsx
··· 1 - import AtpAgent, { AtUri } from '@atproto/api' 2 - import type { ProfileViewDetailed } from '@atproto/api/dist/client/types/app/bsky/actor/defs'; 1 + import { AtUri } from '@atproto/api' 3 2 import { createFileRoute, Link, Outlet, useRouterState } from '@tanstack/react-router' 4 3 import { useAtom } from 'jotai'; 5 - import { useEffect, useState } from 'react'; 6 4 7 5 import { useAuth } from '~/providers/UnifiedAuthProvider'; 8 6 import { appviewUrlAtom } from '~/utils/atoms'; 7 + import { useProfileQuery } from '~/utils/useQuery'; 9 8 //import { useQueryGetProfiles } from '~/utils/useQuery'; 10 9 11 10 export const Route = createFileRoute('/c/$did')({ ··· 44 43 const state = useRouterState(); 45 44 46 45 // Local state for the manual fetch 47 - const [profile, setProfile] = useState<ProfileViewDetailed | null>(null); 48 - const [loading, setLoading] = useState(false); 49 - const [error, setError] = useState<string | null>(null); 46 + // const [profile, setProfile] = useState<ProfileViewDetailed | null>(null); 47 + // const [loading, setLoading] = useState(false); 48 + // const [error, setError] = useState<string | null>(null); 50 49 51 50 const pathParts = state.location.pathname.split("/"); 52 51 const c_did = pathParts[2]; ··· 58 57 // agent || undefined 59 58 // ); 60 59 61 - // shitty fallback im not sure why i even need this ??? but my hunch 62 - // is that the current agent is not built for public fetches? probably. im not sure. 63 - // blame the red dwarf dev 64 - useEffect(() => { 65 - async function fetchProfileManually() { 66 - if (!c_did) return; 60 + // // shitty fallback im not sure why i even need this ??? but my hunch 61 + // // is that the current agent is not built for public fetches? probably. im not sure. 62 + // // blame the red dwarf dev 63 + // useEffect(() => { 64 + // async function fetchProfileManually() { 65 + // if (!c_did) return; 67 66 68 - setLoading(true); 69 - setError(null); 70 - console.log("Manual fetch starting for:", c_did); 67 + // setLoading(true); 68 + // setError(null); 69 + // console.log("Manual fetch starting for:", c_did); 71 70 72 - try { 73 - // 2. FALLBACK: If authAgent is missing, create a temporary public one 74 - // This ensures a request happens even if signedOut 75 - const defaultagent = new AtpAgent({ service: 'https://public.api.bsky.app' }); 76 - const agent = status === "signedIn" ? authAgent || defaultagent : defaultagent; 71 + // try { 72 + // // 2. FALLBACK: If authAgent is missing, create a temporary public one 73 + // // This ensures a request happens even if signedOut 74 + // const defaultagent = new AtpAgent({ service: 'https://public.api.bsky.app' }); 75 + // const agent = status === "signedIn" ? authAgent || defaultagent : defaultagent; 77 76 78 - const res = await agent.app.bsky.actor.getProfile({ 79 - actor: decodeURIComponent(c_did) 80 - }); 77 + // const res = await agent.app.bsky.actor.getProfile({ 78 + // actor: decodeURIComponent(c_did) 79 + // }); 81 80 82 - console.log("Manual fetch success:", res.data); 83 - setProfile(res.data); 84 - } catch (err: any) { 85 - console.error("Manual fetch FAILED:", err); 86 - setError(err.message || "Unknown error"); 87 - } finally { 88 - setLoading(false); 89 - } 90 - } 81 + // console.log("Manual fetch success:", res.data); 82 + // setProfile(res.data); 83 + // } catch (err: any) { 84 + // console.error("Manual fetch FAILED:", err); 85 + // setError(err.message || "Unknown error"); 86 + // } finally { 87 + // setLoading(false); 88 + // } 89 + // } 91 90 92 - fetchProfileManually(); 93 - }, [c_did, authAgent, status]); // Re-run if DID or Auth status changes 91 + // fetchProfileManually(); 92 + // }, [c_did, authAgent, status]); // Re-run if DID or Auth status changes 93 + const { 94 + data: profile, 95 + error: error, 96 + refetch: refetchProfile, 97 + isLoading: loading, 98 + isPlaceholderData: isPlaceholderProfile, 99 + } = useProfileQuery({ 100 + did: decodeURIComponent(c_did), 101 + }) 94 102 95 103 // UI STATES 96 104 if (loading) return <div>⏳ Manual Loading Profile... (DID: {c_did})</div>; 97 105 98 106 if (error) return ( 99 107 <div className="bg-red-100 p-4 border border-red-400 text-red-700"> 100 - <strong>Fetch Error:</strong> {error} <br /> 108 + <strong>Fetch Error:</strong> {error.message} <br /> 101 109 <small>Check console for network logs.</small> 102 110 </div> 103 111 );
+38 -1
src/utils/useQuery.ts
··· 1690 1690 agent?: ATPAPI.Agent 1691 1691 ) { 1692 1692 return useQuery(constructGetProfilesQuery(disabled, ids, appviewdid, agent)); 1693 - } 1693 + } 1694 + 1695 + // modified from bluesky social-app /src/state/queries/profile.ts line 60 1696 + const RQKEY_ROOT = 'profile' 1697 + const RQKEY = (did: string) => [RQKEY_ROOT, did] 1698 + 1699 + export function useProfileQuery({ 1700 + did, 1701 + staleTime = 5 * 60 * 1000, 1702 + }: { 1703 + did: string | undefined 1704 + staleTime?: number 1705 + }) { 1706 + // same issue as the one in c.$did.tsx, you should really consider making the useAuth() hook handle unauthed agent calls 1707 + // todo dont make new public agents all the fucking time 1708 + const defaultagent = new ATPAPI.AtpAgent({ service: 'https://public.api.bsky.app' }); 1709 + const { agent: goodagent } = useAuth(); 1710 + const agent = goodagent || defaultagent; 1711 + //const {getUnstableProfile} = useUnstableProfileViewCache() 1712 + return useQuery<ATPAPI.AppBskyActorDefs.ProfileViewDetailed>({ 1713 + // WARNING 1714 + // this staleTime is load-bearing 1715 + // if you remove it, the UI infinite-loops 1716 + // -prf 1717 + staleTime, 1718 + refetchOnWindowFocus: true, 1719 + queryKey: RQKEY(did ?? ''), 1720 + queryFn: async () => { 1721 + const res = await agent.getProfile({actor: did ?? ''}) 1722 + return res.data 1723 + }, 1724 + // placeholderData: () => { 1725 + // if (!did) return 1726 + // return getUnstableProfile(did) as ATPAPI.AppBskyActorDefs.ProfileViewDetailed 1727 + // }, 1728 + enabled: !!did, 1729 + }) 1730 + }