From 1a037d35429b119d1751930068dfcf3b2b94dbde Mon Sep 17 00:00:00 2001
From: Eric Bailey <git@esb.lol>
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/FeedCard.tsx | 100 +++++++++++++-------------------------------
 1 file changed, 30 insertions(+), 70 deletions(-)

(limited to 'src/components/FeedCard.tsx')

diff --git a/src/components/FeedCard.tsx b/src/components/FeedCard.tsx
index e0fc7ef54..b1200d9c4 100644
--- a/src/components/FeedCard.tsx
+++ b/src/components/FeedCard.tsx
@@ -18,7 +18,7 @@ import {
   useRemoveFeedMutation,
 } from '#/state/queries/preferences'
 import {sanitizeHandle} from 'lib/strings/handles'
-import {precacheFeedFromGeneratorView, precacheList} from 'state/queries/feed'
+import {precacheFeedFromGeneratorView} from 'state/queries/feed'
 import {useSession} from 'state/session'
 import {UserAvatar} from '#/view/com/util/UserAvatar'
 import * as Toast from 'view/com/util/Toast'
@@ -33,45 +33,31 @@ import * as Prompt from '#/components/Prompt'
 import {RichText} from '#/components/RichText'
 import {Text} from '#/components/Typography'
 
-type Props =
-  | {
-      type: 'feed'
-      view: AppBskyFeedDefs.GeneratorView
-    }
-  | {
-      type: 'list'
-      view: AppBskyGraphDefs.ListView
-    }
+type Props = {
+  view: AppBskyFeedDefs.GeneratorView
+}
 
 export function Default(props: Props) {
-  const {type, view} = props
-  const displayName = type === 'feed' ? view.displayName : view.name
-  const purpose = type === 'list' ? view.purpose : undefined
+  const {view} = props
   return (
-    <Link label={displayName} {...props}>
+    <Link label={view.displayName} {...props}>
       <Outer>
         <Header>
           <Avatar src={view.avatar} />
-          <TitleAndByline
-            title={displayName}
-            creator={view.creator}
-            type={type}
-            purpose={purpose}
-          />
-          <Action uri={view.uri} pin type={type} purpose={purpose} />
+          <TitleAndByline title={view.displayName} creator={view.creator} />
+          <SaveButton view={view} pin />
         </Header>
         <Description description={view.description} />
-        {type === 'feed' && <Likes count={view.likeCount || 0} />}
+        <Likes count={view.likeCount || 0} />
       </Outer>
     </Link>
   )
 }
 
 export function Link({
-  type,
   view,
-  label,
   children,
+  ...props
 }: Props & Omit<LinkProps, 'to'>) {
   const queryClient = useQueryClient()
 
@@ -79,17 +65,12 @@ export function Link({
     return createProfileFeedHref({feed: view})
   }, [view])
 
+  React.useEffect(() => {
+    precacheFeedFromGeneratorView(queryClient, view)
+  }, [view, queryClient])
+
   return (
-    <InternalLink
-      to={href}
-      label={label}
-      onPress={() => {
-        if (type === 'feed') {
-          precacheFeedFromGeneratorView(queryClient, view)
-        } else {
-          precacheList(queryClient, view)
-        }
-      }}>
+    <InternalLink to={href} {...props}>
       {children}
     </InternalLink>
   )
@@ -132,13 +113,9 @@ export function AvatarPlaceholder({size = 40}: Omit<AvatarProps, 'src'>) {
 export function TitleAndByline({
   title,
   creator,
-  type,
-  purpose,
 }: {
   title: string
   creator?: AppBskyActorDefs.ProfileViewBasic
-  type: 'feed' | 'list'
-  purpose?: AppBskyGraphDefs.ListView['purpose']
 }) {
   const t = useTheme()
 
@@ -151,15 +128,7 @@ export function TitleAndByline({
         <Text
           style={[a.leading_snug, t.atoms.text_contrast_medium]}
           numberOfLines={1}>
-          {type === 'list' && purpose === 'app.bsky.graph.defs#curatelist' ? (
-            <Trans>List by {sanitizeHandle(creator.handle, '@')}</Trans>
-          ) : type === 'list' && purpose === 'app.bsky.graph.defs#modlist' ? (
-            <Trans>
-              Moderation list by {sanitizeHandle(creator.handle, '@')}
-            </Trans>
-          ) : (
-            <Trans>Feed by {sanitizeHandle(creator.handle, '@')}</Trans>
-          )}
+          <Trans>Feed by {sanitizeHandle(creator.handle, '@')}</Trans>
         </Text>
       )}
     </View>
@@ -221,34 +190,24 @@ export function Likes({count}: {count: number}) {
   )
 }
 
-export function Action({
-  uri,
+export function SaveButton({
+  view,
   pin,
-  type,
-  purpose,
 }: {
-  uri: string
+  view: AppBskyFeedDefs.GeneratorView | AppBskyGraphDefs.ListView
   pin?: boolean
-  type: 'feed' | 'list'
-  purpose?: AppBskyGraphDefs.ListView['purpose']
 }) {
   const {hasSession} = useSession()
-  if (
-    !hasSession ||
-    (type === 'list' && purpose !== 'app.bsky.graph.defs#curatelist')
-  )
-    return null
-  return <ActionInner uri={uri} pin={pin} type={type} />
+  if (!hasSession) return null
+  return <SaveButtonInner view={view} pin={pin} />
 }
 
-function ActionInner({
-  uri,
+function SaveButtonInner({
+  view,
   pin,
-  type,
 }: {
-  uri: string
+  view: AppBskyFeedDefs.GeneratorView | AppBskyGraphDefs.ListView
   pin?: boolean
-  type: 'feed' | 'list'
 }) {
   const {_} = useLingui()
   const {data: preferences} = usePreferencesQuery()
@@ -256,6 +215,10 @@ function ActionInner({
     useAddSavedFeedsMutation()
   const {isPending: isRemovePending, mutateAsync: removeFeed} =
     useRemoveFeedMutation()
+
+  const uri = view.uri
+  const type = view.uri.includes('app.bsky.feed.generator') ? 'feed' : 'list'
+
   const savedFeedConfig = React.useMemo(() => {
     return preferences?.savedFeeds?.find(feed => feed.value === uri)
   }, [preferences?.savedFeeds, uri])
@@ -332,12 +295,9 @@ function ActionInner({
 export function createProfileFeedHref({
   feed,
 }: {
-  feed: AppBskyFeedDefs.GeneratorView | AppBskyGraphDefs.ListView
+  feed: AppBskyFeedDefs.GeneratorView
 }) {
   const urip = new AtUri(feed.uri)
-  const type = urip.collection === 'app.bsky.feed.generator' ? 'feed' : 'list'
   const handleOrDid = feed.creator.handle || feed.creator.did
-  return `/profile/${handleOrDid}/${type === 'feed' ? 'feed' : 'lists'}/${
-    urip.rkey
-  }`
+  return `/profile/${handleOrDid}/feed/${urip.rkey}`
 }
-- 
cgit 1.4.1

