A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

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

at trunk 2.1 kB View raw
1import type { Agent } from '@atproto/api'; 2 3/** The signed-in writer's identity, as shown in the home pill and editor bar. */ 4export interface ViewerProfile { 5 did: string; 6 handle: string | null; 7 displayName: string | null; 8 avatar: string | null; 9} 10 11/** 12 * Fetch the viewer's profile for display. Wraps a single `getProfile` call and 13 * never throws: on failure (e.g. the appview is unreachable) it returns the DID 14 * with null display fields, so callers always have something to render. 15 */ 16export async function fetchViewerProfile( agent: Agent, did: string ): Promise< ViewerProfile > { 17 try { 18 const { data } = await agent.getProfile( { actor: did } ); 19 return { 20 did, 21 handle: data.handle ?? null, 22 displayName: data.displayName ?? null, 23 avatar: data.avatar ?? null, 24 }; 25 } catch { 26 return { did, handle: null, displayName: null, avatar: null }; 27 } 28} 29 30/** Best display label for a viewer: real name, else handle, else the raw DID. */ 31export function displayNameFor( profile: ViewerProfile ): string { 32 return profile.displayName ?? profile.handle ?? profile.did; 33} 34 35/** 36 * Public author-page path for a handle (the `/[author]` route requires a leading 37 * `@` and resolves by handle). Returns null when no handle is known, so callers 38 * can omit the link rather than render a broken one. 39 */ 40export function authorPath( handle: string | null ): string | null { 41 return handle ? `/@${ handle }` : null; 42} 43 44/** One entry in the signed-in account dropdown. */ 45export interface MenuItem { 46 label: string; 47 href: string; 48} 49 50/** 51 * Dropdown items for a signed-in viewer: Dashboard, Write, then Profile. The 52 * Profile entry links to the public author page and is omitted when no handle 53 * is known (so we never render a broken link). 54 */ 55export function accountMenuItems( profile: ViewerProfile ): MenuItem[] { 56 const items: MenuItem[] = [ 57 { label: 'Dashboard', href: '/dashboard' }, 58 { label: 'Write', href: '/write' }, 59 ]; 60 const profileHref = authorPath( profile.handle ); 61 if ( profileHref ) { 62 items.push( { label: 'Profile', href: profileHref } ); 63 } 64 return items; 65}