this repo has no description
0
fork

Configure Feed

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

header: add profile

Clément b3b80623 d55de0ff

+80 -7
+62
app/src/contexts/profile.tsx
··· 1 + import type { AppBskyActorGetProfile } from '@atcute/bluesky'; 2 + import { Client, simpleFetchHandler } from '@atcute/client'; 3 + import type { Did } from '@atcute/lexicons'; 4 + import { useQuery } from '@tanstack/solid-query'; 5 + import { createContext, useContext } from 'solid-js'; 6 + import type { JSX } from 'solid-js'; 7 + 8 + import { useAuth } from './auth'; 9 + 10 + export type Profile = Pick< 11 + AppBskyActorGetProfile.$output, 12 + 'did' | 'handle' | 'displayName' | 'avatar' | 'description' 13 + >; 14 + type ProfileContextType = { 15 + profile: () => Profile | null; 16 + isLoading: () => boolean; 17 + refetch: () => void; 18 + }; 19 + 20 + async function fn(did: Did): Promise<Profile | undefined> { 21 + const rpc = new Client({ 22 + handler: simpleFetchHandler({ service: 'https://public.api.bsky.app' }), 23 + }); 24 + const res = await rpc.get('app.bsky.actor.getProfile', { 25 + params: { actor: did }, 26 + }); 27 + if (res.ok) { 28 + return res.data; 29 + } 30 + return undefined; 31 + } 32 + 33 + const ProfileContext = createContext<ProfileContextType | undefined>(undefined); 34 + 35 + export function ProfileProvider(props: { children: JSX.Element }) { 36 + const auth = useAuth(); 37 + 38 + const did = auth.did(); 39 + 40 + const query = useQuery(() => ({ 41 + queryKey: ['currentUserProfile', did], 42 + queryFn: () => (did ? fn(did) : null), 43 + })); 44 + 45 + const profile = () => query.data ?? null; 46 + const isLoading = () => query.isLoading; 47 + const refetch = () => query.refetch(); 48 + 49 + return ( 50 + <ProfileContext.Provider value={{ profile, isLoading, refetch }}> 51 + {props.children} 52 + </ProfileContext.Provider> 53 + ); 54 + } 55 + 56 + export function useProfile() { 57 + const context = useContext(ProfileContext); 58 + if (!context) { 59 + throw new Error('useProfile must be used within ProfileProvider'); 60 + } 61 + return context; 62 + }
+11 -5
app/src/lib/header/Header.tsx
··· 1 - import type { Did } from '@atcute/lexicons'; 2 1 import { Link } from '@tanstack/solid-router'; 3 2 import { Show } from 'solid-js'; 4 3 5 4 import { useAuth } from '~/contexts/auth'; 5 + import { useProfile } from '~/contexts/profile'; 6 + import type { Profile } from '~/contexts/profile'; 6 7 7 8 import { Avatar } from '@/Avatar'; 8 9 ··· 10 11 11 12 export function Header() { 12 13 const auth = useAuth(); 14 + const profile = useProfile(); 13 15 14 16 return ( 15 17 <header class="p-4 flex items-center shadow-mini h-18 justify-between border-b border-border"> ··· 21 23 </Show> 22 24 </div> 23 25 <Show when={auth.did()} fallback={<SignInDialog />}> 24 - {(did) => <HeaderLoggedIn did={did()} />} 26 + <Show when={profile.profile()} fallback={<p>loading...</p>}> 27 + {(p) => <HeaderLoggedIn profile={p()} />} 28 + </Show> 25 29 </Show> 26 30 </header> 27 31 ); 28 32 } 29 33 30 - function HeaderLoggedIn(props: { did: Did }) { 34 + function HeaderLoggedIn(props: { profile: Profile }) { 31 35 return ( 32 36 <div class="flex flex-row gap-4 items-center"> 33 - <p>logged in as</p> 34 - <Avatar user={{ did: props.did }} /> 37 + <p> 38 + logged in as <span>@{props.profile.handle}</span> 39 + </p> 40 + <Avatar user={{ did: props.profile.did }} /> 35 41 </div> 36 42 ); 37 43 }
+7 -2
app/src/routes/__root.tsx
··· 1 + import { SolidQueryDevtools } from '@tanstack/solid-query-devtools'; 1 2 import { 2 3 HeadContent, 3 4 Outlet, ··· 9 10 import { HydrationScript } from 'solid-js/web'; 10 11 11 12 import { AuthProvider } from '~/contexts/auth'; 13 + import { ProfileProvider } from '~/contexts/profile'; 12 14 import styleCss from '~/styles.css?url'; 13 15 14 16 import { Header } from '$/header/Header'; ··· 34 36 <HeadContent /> 35 37 <Suspense> 36 38 <AuthProvider> 37 - <Header /> 38 - <Outlet /> 39 + <ProfileProvider> 40 + <Header /> 41 + <Outlet /> 42 + </ProfileProvider> 39 43 </AuthProvider> 40 44 41 45 <Toaster /> 46 + <SolidQueryDevtools /> 42 47 <TanStackRouterDevtools /> 43 48 </Suspense> 44 49 <Scripts />