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 SaveButtonzio/stable
parent
58a97db5b8
commit
1a037d3542
|
@ -18,7 +18,7 @@ import {
|
||||||
useRemoveFeedMutation,
|
useRemoveFeedMutation,
|
||||||
} from '#/state/queries/preferences'
|
} from '#/state/queries/preferences'
|
||||||
import {sanitizeHandle} from 'lib/strings/handles'
|
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 {useSession} from 'state/session'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import * as Toast from 'view/com/util/Toast'
|
import * as Toast from 'view/com/util/Toast'
|
||||||
|
@ -33,45 +33,31 @@ import * as Prompt from '#/components/Prompt'
|
||||||
import {RichText} from '#/components/RichText'
|
import {RichText} from '#/components/RichText'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
type Props =
|
type Props = {
|
||||||
| {
|
view: AppBskyFeedDefs.GeneratorView
|
||||||
type: 'feed'
|
}
|
||||||
view: AppBskyFeedDefs.GeneratorView
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'list'
|
|
||||||
view: AppBskyGraphDefs.ListView
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Default(props: Props) {
|
export function Default(props: Props) {
|
||||||
const {type, view} = props
|
const {view} = props
|
||||||
const displayName = type === 'feed' ? view.displayName : view.name
|
|
||||||
const purpose = type === 'list' ? view.purpose : undefined
|
|
||||||
return (
|
return (
|
||||||
<Link label={displayName} {...props}>
|
<Link label={view.displayName} {...props}>
|
||||||
<Outer>
|
<Outer>
|
||||||
<Header>
|
<Header>
|
||||||
<Avatar src={view.avatar} />
|
<Avatar src={view.avatar} />
|
||||||
<TitleAndByline
|
<TitleAndByline title={view.displayName} creator={view.creator} />
|
||||||
title={displayName}
|
<SaveButton view={view} pin />
|
||||||
creator={view.creator}
|
|
||||||
type={type}
|
|
||||||
purpose={purpose}
|
|
||||||
/>
|
|
||||||
<Action uri={view.uri} pin type={type} purpose={purpose} />
|
|
||||||
</Header>
|
</Header>
|
||||||
<Description description={view.description} />
|
<Description description={view.description} />
|
||||||
{type === 'feed' && <Likes count={view.likeCount || 0} />}
|
<Likes count={view.likeCount || 0} />
|
||||||
</Outer>
|
</Outer>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Link({
|
export function Link({
|
||||||
type,
|
|
||||||
view,
|
view,
|
||||||
label,
|
|
||||||
children,
|
children,
|
||||||
|
...props
|
||||||
}: Props & Omit<LinkProps, 'to'>) {
|
}: Props & Omit<LinkProps, 'to'>) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
@ -79,17 +65,12 @@ export function Link({
|
||||||
return createProfileFeedHref({feed: view})
|
return createProfileFeedHref({feed: view})
|
||||||
}, [view])
|
}, [view])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
precacheFeedFromGeneratorView(queryClient, view)
|
||||||
|
}, [view, queryClient])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InternalLink
|
<InternalLink to={href} {...props}>
|
||||||
to={href}
|
|
||||||
label={label}
|
|
||||||
onPress={() => {
|
|
||||||
if (type === 'feed') {
|
|
||||||
precacheFeedFromGeneratorView(queryClient, view)
|
|
||||||
} else {
|
|
||||||
precacheList(queryClient, view)
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
{children}
|
{children}
|
||||||
</InternalLink>
|
</InternalLink>
|
||||||
)
|
)
|
||||||
|
@ -132,13 +113,9 @@ export function AvatarPlaceholder({size = 40}: Omit<AvatarProps, 'src'>) {
|
||||||
export function TitleAndByline({
|
export function TitleAndByline({
|
||||||
title,
|
title,
|
||||||
creator,
|
creator,
|
||||||
type,
|
|
||||||
purpose,
|
|
||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
creator?: AppBskyActorDefs.ProfileViewBasic
|
creator?: AppBskyActorDefs.ProfileViewBasic
|
||||||
type: 'feed' | 'list'
|
|
||||||
purpose?: AppBskyGraphDefs.ListView['purpose']
|
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|
||||||
|
@ -151,15 +128,7 @@ export function TitleAndByline({
|
||||||
<Text
|
<Text
|
||||||
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
||||||
numberOfLines={1}>
|
numberOfLines={1}>
|
||||||
{type === 'list' && purpose === 'app.bsky.graph.defs#curatelist' ? (
|
<Trans>Feed by {sanitizeHandle(creator.handle, '@')}</Trans>
|
||||||
<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>
|
|
||||||
)}
|
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
@ -221,34 +190,24 @@ export function Likes({count}: {count: number}) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Action({
|
export function SaveButton({
|
||||||
uri,
|
view,
|
||||||
pin,
|
pin,
|
||||||
type,
|
|
||||||
purpose,
|
|
||||||
}: {
|
}: {
|
||||||
uri: string
|
view: AppBskyFeedDefs.GeneratorView | AppBskyGraphDefs.ListView
|
||||||
pin?: boolean
|
pin?: boolean
|
||||||
type: 'feed' | 'list'
|
|
||||||
purpose?: AppBskyGraphDefs.ListView['purpose']
|
|
||||||
}) {
|
}) {
|
||||||
const {hasSession} = useSession()
|
const {hasSession} = useSession()
|
||||||
if (
|
if (!hasSession) return null
|
||||||
!hasSession ||
|
return <SaveButtonInner view={view} pin={pin} />
|
||||||
(type === 'list' && purpose !== 'app.bsky.graph.defs#curatelist')
|
|
||||||
)
|
|
||||||
return null
|
|
||||||
return <ActionInner uri={uri} pin={pin} type={type} />
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ActionInner({
|
function SaveButtonInner({
|
||||||
uri,
|
view,
|
||||||
pin,
|
pin,
|
||||||
type,
|
|
||||||
}: {
|
}: {
|
||||||
uri: string
|
view: AppBskyFeedDefs.GeneratorView | AppBskyGraphDefs.ListView
|
||||||
pin?: boolean
|
pin?: boolean
|
||||||
type: 'feed' | 'list'
|
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const {data: preferences} = usePreferencesQuery()
|
const {data: preferences} = usePreferencesQuery()
|
||||||
|
@ -256,6 +215,10 @@ function ActionInner({
|
||||||
useAddSavedFeedsMutation()
|
useAddSavedFeedsMutation()
|
||||||
const {isPending: isRemovePending, mutateAsync: removeFeed} =
|
const {isPending: isRemovePending, mutateAsync: removeFeed} =
|
||||||
useRemoveFeedMutation()
|
useRemoveFeedMutation()
|
||||||
|
|
||||||
|
const uri = view.uri
|
||||||
|
const type = view.uri.includes('app.bsky.feed.generator') ? 'feed' : 'list'
|
||||||
|
|
||||||
const savedFeedConfig = React.useMemo(() => {
|
const savedFeedConfig = React.useMemo(() => {
|
||||||
return preferences?.savedFeeds?.find(feed => feed.value === uri)
|
return preferences?.savedFeeds?.find(feed => feed.value === uri)
|
||||||
}, [preferences?.savedFeeds, uri])
|
}, [preferences?.savedFeeds, uri])
|
||||||
|
@ -332,12 +295,9 @@ function ActionInner({
|
||||||
export function createProfileFeedHref({
|
export function createProfileFeedHref({
|
||||||
feed,
|
feed,
|
||||||
}: {
|
}: {
|
||||||
feed: AppBskyFeedDefs.GeneratorView | AppBskyGraphDefs.ListView
|
feed: AppBskyFeedDefs.GeneratorView
|
||||||
}) {
|
}) {
|
||||||
const urip = new AtUri(feed.uri)
|
const urip = new AtUri(feed.uri)
|
||||||
const type = urip.collection === 'app.bsky.feed.generator' ? 'feed' : 'list'
|
|
||||||
const handleOrDid = feed.creator.handle || feed.creator.did
|
const handleOrDid = feed.creator.handle || feed.creator.did
|
||||||
return `/profile/${handleOrDid}/${type === 'feed' ? 'feed' : 'lists'}/${
|
return `/profile/${handleOrDid}/feed/${urip.rkey}`
|
||||||
urip.rkey
|
|
||||||
}`
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 (
|
||||||
|
<Link label={view.name} {...props}>
|
||||||
|
<Outer>
|
||||||
|
<Header>
|
||||||
|
<Avatar src={view.avatar} />
|
||||||
|
<TitleAndByline
|
||||||
|
title={view.name}
|
||||||
|
creator={view.creator}
|
||||||
|
purpose={view.purpose}
|
||||||
|
/>
|
||||||
|
{showPinButton && view.purpose === CURATELIST && (
|
||||||
|
<SaveButton view={view} pin />
|
||||||
|
)}
|
||||||
|
</Header>
|
||||||
|
<Description description={view.description} />
|
||||||
|
</Outer>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Link({
|
||||||
|
view,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: Props & Omit<LinkProps, 'to'>) {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
const href = React.useMemo(() => {
|
||||||
|
return createProfileListHref({list: view})
|
||||||
|
}, [view])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
precacheList(queryClient, view)
|
||||||
|
}, [view, queryClient])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InternalLink to={href} {...props}>
|
||||||
|
{children}
|
||||||
|
</InternalLink>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TitleAndByline({
|
||||||
|
title,
|
||||||
|
creator,
|
||||||
|
purpose = CURATELIST,
|
||||||
|
}: {
|
||||||
|
title: string
|
||||||
|
creator?: AppBskyActorDefs.ProfileViewBasic
|
||||||
|
purpose?: AppBskyGraphDefs.ListView['purpose']
|
||||||
|
}) {
|
||||||
|
const t = useTheme()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.flex_1]}>
|
||||||
|
<Text style={[a.text_md, a.font_bold, a.leading_snug]} numberOfLines={1}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
{creator && (
|
||||||
|
<Text
|
||||||
|
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
||||||
|
numberOfLines={1}>
|
||||||
|
{purpose === MODLIST ? (
|
||||||
|
<Trans>
|
||||||
|
Moderation list by {sanitizeHandle(creator.handle, '@')}
|
||||||
|
</Trans>
|
||||||
|
) : (
|
||||||
|
<Trans>List by {sanitizeHandle(creator.handle, '@')}</Trans>
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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}`
|
||||||
|
}
|
|
@ -45,7 +45,7 @@ export const FeedsList = React.forwardRef<SectionRef, ProfilesListProps>(
|
||||||
(isWeb || index !== 0) && a.border_t,
|
(isWeb || index !== 0) && a.border_t,
|
||||||
t.atoms.border_contrast_low,
|
t.atoms.border_contrast_low,
|
||||||
]}>
|
]}>
|
||||||
<FeedCard.Default type="feed" view={item} />
|
<FeedCard.Default view={item} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -316,7 +316,7 @@ function LandingScreenLoaded({
|
||||||
t.atoms.border_contrast_low,
|
t.atoms.border_contrast_low,
|
||||||
]}
|
]}
|
||||||
key={feed.uri}>
|
key={feed.uri}>
|
||||||
<FeedCard.Default type="feed" view={feed} />
|
<FeedCard.Default view={feed} />
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -163,7 +163,7 @@ export const ProfileFeedgens = React.forwardRef<
|
||||||
a.px_lg,
|
a.px_lg,
|
||||||
a.py_lg,
|
a.py_lg,
|
||||||
]}>
|
]}>
|
||||||
<FeedCard.Default type="feed" view={item} />
|
<FeedCard.Default view={item} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {useAnalytics} from 'lib/analytics/analytics'
|
||||||
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
||||||
import {EmptyState} from 'view/com/util/EmptyState'
|
import {EmptyState} from 'view/com/util/EmptyState'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import * as FeedCard from '#/components/FeedCard'
|
import * as ListCard from '#/components/ListCard'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {List, ListRef} from '../util/List'
|
import {List, ListRef} from '../util/List'
|
||||||
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
||||||
|
@ -172,7 +172,7 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
|
||||||
a.px_lg,
|
a.px_lg,
|
||||||
a.py_lg,
|
a.py_lg,
|
||||||
]}>
|
]}>
|
||||||
<FeedCard.Default type="list" view={item} />
|
<ListCard.Default view={item} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,6 +41,7 @@ import hairlineWidth = StyleSheet.hairlineWidth
|
||||||
import {Divider} from '#/components/Divider'
|
import {Divider} from '#/components/Divider'
|
||||||
import * as FeedCard from '#/components/FeedCard'
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
|
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
|
||||||
|
import * as ListCard from '#/components/ListCard'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Feeds'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Feeds'>
|
||||||
|
|
||||||
|
@ -495,7 +496,7 @@ export function FeedsScreen(_props: Props) {
|
||||||
} else if (item.type === 'popularFeed') {
|
} else if (item.type === 'popularFeed') {
|
||||||
return (
|
return (
|
||||||
<View style={[a.px_lg, a.pt_lg, a.gap_lg]}>
|
<View style={[a.px_lg, a.pt_lg, a.gap_lg]}>
|
||||||
<FeedCard.Default type="feed" view={item.feed} />
|
<FeedCard.Default view={item.feed} />
|
||||||
<Divider />
|
<Divider />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
@ -627,7 +628,7 @@ function FollowingFeed() {
|
||||||
fill={t.palette.white}
|
fill={t.palette.white}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<FeedCard.TitleAndByline title={_(msg`Following`)} type="feed" />
|
<FeedCard.TitleAndByline title={_(msg`Following`)} />
|
||||||
</FeedCard.Header>
|
</FeedCard.Header>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
@ -639,34 +640,45 @@ function SavedFeed({
|
||||||
savedFeed: SavedFeedItem & {type: 'feed' | 'list'}
|
savedFeed: SavedFeedItem & {type: 'feed' | 'list'}
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {view: feed} = savedFeed
|
|
||||||
const displayName =
|
|
||||||
savedFeed.type === 'feed' ? savedFeed.view.displayName : savedFeed.view.name
|
|
||||||
|
|
||||||
return (
|
const commonStyle = [
|
||||||
<FeedCard.Link testID={`saved-feed-${feed.displayName}`} {...savedFeed}>
|
a.flex_1,
|
||||||
|
a.px_lg,
|
||||||
|
a.py_md,
|
||||||
|
a.border_b,
|
||||||
|
t.atoms.border_contrast_low,
|
||||||
|
]
|
||||||
|
|
||||||
|
return savedFeed.type === 'feed' ? (
|
||||||
|
<FeedCard.Link
|
||||||
|
testID={`saved-feed-${savedFeed.view.displayName}`}
|
||||||
|
{...savedFeed}>
|
||||||
{({hovered, pressed}) => (
|
{({hovered, pressed}) => (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[commonStyle, (hovered || pressed) && t.atoms.bg_contrast_25]}>
|
||||||
a.flex_1,
|
|
||||||
a.px_lg,
|
|
||||||
a.py_md,
|
|
||||||
a.border_b,
|
|
||||||
t.atoms.border_contrast_low,
|
|
||||||
(hovered || pressed) && t.atoms.bg_contrast_25,
|
|
||||||
]}>
|
|
||||||
<FeedCard.Header>
|
<FeedCard.Header>
|
||||||
<FeedCard.Avatar src={feed.avatar} size={28} />
|
<FeedCard.Avatar src={savedFeed.view.avatar} size={28} />
|
||||||
<FeedCard.TitleAndByline
|
<FeedCard.TitleAndByline title={savedFeed.view.displayName} />
|
||||||
title={displayName}
|
|
||||||
type={savedFeed.type}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ChevronRight size="sm" fill={t.atoms.text_contrast_low.color} />
|
<ChevronRight size="sm" fill={t.atoms.text_contrast_low.color} />
|
||||||
</FeedCard.Header>
|
</FeedCard.Header>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</FeedCard.Link>
|
</FeedCard.Link>
|
||||||
|
) : (
|
||||||
|
<ListCard.Link testID={`saved-feed-${savedFeed.view.name}`} {...savedFeed}>
|
||||||
|
{({hovered, pressed}) => (
|
||||||
|
<View
|
||||||
|
style={[commonStyle, (hovered || pressed) && t.atoms.bg_contrast_25]}>
|
||||||
|
<ListCard.Header>
|
||||||
|
<ListCard.Avatar src={savedFeed.view.avatar} size={28} />
|
||||||
|
<ListCard.TitleAndByline title={savedFeed.view.name} />
|
||||||
|
|
||||||
|
<ChevronRight size="sm" fill={t.atoms.text_contrast_low.color} />
|
||||||
|
</ListCard.Header>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</ListCard.Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -505,7 +505,7 @@ export function Explore() {
|
||||||
a.px_lg,
|
a.px_lg,
|
||||||
a.py_lg,
|
a.py_lg,
|
||||||
]}>
|
]}>
|
||||||
<FeedCard.Default type="feed" view={item.feed} />
|
<FeedCard.Default view={item.feed} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,7 +306,7 @@ let SearchScreenFeedsResults = ({
|
||||||
a.px_lg,
|
a.px_lg,
|
||||||
a.py_lg,
|
a.py_lg,
|
||||||
]}>
|
]}>
|
||||||
<FeedCard.Default type="feed" view={item} />
|
<FeedCard.Default view={item} />
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
keyExtractor={item => item.uri}
|
keyExtractor={item => item.uri}
|
||||||
|
|
Loading…
Reference in New Issue