From 1a037d35429b119d1751930068dfcf3b2b94dbde Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 28 Jun 2024 08:27:54 -0500 Subject: FeedCard & ListCard cleanups (#4644) * Extract ListCard from FeedCard * Export FeedCard.Action and optionally include in ListCard * Remove list dual usage from most of FeedCard * Update usages of FeedCard and ListCard * Add back list purpose logic * Make Action comp easier to use, clarify list purpose * Rename Action to SaveButton --- src/components/ListCard.tsx | 129 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 src/components/ListCard.tsx (limited to 'src/components/ListCard.tsx') diff --git a/src/components/ListCard.tsx b/src/components/ListCard.tsx new file mode 100644 index 000000000..c0e0d0e25 --- /dev/null +++ b/src/components/ListCard.tsx @@ -0,0 +1,129 @@ +import React from 'react' +import {View} from 'react-native' +import {AppBskyActorDefs, AppBskyGraphDefs, AtUri} from '@atproto/api' +import {Trans} from '@lingui/macro' +import {useQueryClient} from '@tanstack/react-query' + +import {sanitizeHandle} from 'lib/strings/handles' +import {precacheList} from 'state/queries/feed' +import {useTheme} from '#/alf' +import {atoms as a} from '#/alf' +import { + Avatar, + Description, + Header, + Outer, + SaveButton, +} from '#/components/FeedCard' +import {Link as InternalLink, LinkProps} from '#/components/Link' +import {Text} from '#/components/Typography' + +/* + * This component is based on `FeedCard` and is tightly coupled with that + * component. Please refer to `FeedCard` for more context. + */ + +export { + Avatar, + AvatarPlaceholder, + Description, + Header, + Outer, + SaveButton, + TitleAndBylinePlaceholder, +} from '#/components/FeedCard' + +const CURATELIST = 'app.bsky.graph.defs#curatelist' +const MODLIST = 'app.bsky.graph.defs#modlist' + +type Props = { + view: AppBskyGraphDefs.ListView + showPinButton?: boolean +} + +export function Default(props: Props) { + const {view, showPinButton} = props + return ( + + +
+ + + {showPinButton && view.purpose === CURATELIST && ( + + )} +
+ +
+ + ) +} + +export function Link({ + view, + children, + ...props +}: Props & Omit) { + const queryClient = useQueryClient() + + const href = React.useMemo(() => { + return createProfileListHref({list: view}) + }, [view]) + + React.useEffect(() => { + precacheList(queryClient, view) + }, [view, queryClient]) + + return ( + + {children} + + ) +} + +export function TitleAndByline({ + title, + creator, + purpose = CURATELIST, +}: { + title: string + creator?: AppBskyActorDefs.ProfileViewBasic + purpose?: AppBskyGraphDefs.ListView['purpose'] +}) { + const t = useTheme() + + return ( + + + {title} + + {creator && ( + + {purpose === MODLIST ? ( + + Moderation list by {sanitizeHandle(creator.handle, '@')} + + ) : ( + List by {sanitizeHandle(creator.handle, '@')} + )} + + )} + + ) +} + +export function createProfileListHref({ + list, +}: { + list: AppBskyGraphDefs.ListView +}) { + const urip = new AtUri(list.uri) + const handleOrDid = list.creator.handle || list.creator.did + return `/profile/${handleOrDid}/lists/${urip.rkey}` +} -- cgit 1.4.1