personal web client for Bluesky
typescript solidjs bluesky atcute
at trunk 1.8 kB view raw
1import { createMemo } from 'solid-js'; 2 3import type { Did } from '@atcute/lexicons'; 4 5import { createProfileFollowingQuery } from '~/api/queries/profile-following'; 6 7import { useParams, useTitle } from '~/lib/navigation/router'; 8 9import * as Page from '~/components/page'; 10import PagedList from '~/components/paged-list'; 11import ProfileFollowButton from '~/components/profiles/profile-follow-button'; 12import ProfileItem from '~/components/profiles/profile-item'; 13import VirtualItem from '~/components/virtual-item'; 14 15const ProfileFollowingPage = () => { 16 const { did } = useParams<{ did: Did }>(); 17 18 const following = createProfileFollowingQuery(() => did); 19 const subject = createMemo(() => following.data?.pages[0].subject); 20 21 useTitle(() => { 22 const data = subject(); 23 if (data) { 24 const handle = data.handle.toLowerCase(); 25 26 return `Users followed by @${handle}${import.meta.env.VITE_APP_NAME}`; 27 } 28 29 return `Users followed by — ${import.meta.env.VITE_APP_NAME}`; 30 }); 31 32 return ( 33 <> 34 <Page.Header> 35 <Page.HeaderAccessory> 36 <Page.Back to={`/${did}`} /> 37 </Page.HeaderAccessory> 38 39 <Page.Heading 40 title="Following" 41 subtitle={(() => { 42 const $subject = subject(); 43 if ($subject) { 44 return '@' + $subject.handle.toLowerCase(); 45 } 46 })()} 47 /> 48 </Page.Header> 49 50 <PagedList 51 data={following.data?.pages.map((page) => page.profiles)} 52 error={following.error} 53 render={(item) => { 54 return ( 55 <VirtualItem estimateHeight={64}> 56 <ProfileItem item={item} AsideComponent={<ProfileFollowButton profile={item} />} /> 57 </VirtualItem> 58 ); 59 }} 60 hasNextPage={following.hasNextPage} 61 isFetchingNextPage={following.isFetching} 62 onEndReached={() => following.fetchNextPage()} 63 /> 64 </> 65 ); 66}; 67 68export default ProfileFollowingPage;