New SP card
This commit is contained in:
@@ -6,22 +6,24 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
|||||||
import {useProfilesQuery} from '#/state/queries/profile'
|
import {useProfilesQuery} from '#/state/queries/profile'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
export function AvatarStack({
|
export function AvatarStack({
|
||||||
profiles,
|
profiles,
|
||||||
size = 26,
|
size = 26,
|
||||||
numPending,
|
numPending,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
spacing = 'normal',
|
||||||
}: {
|
}: {
|
||||||
profiles: bsky.profile.AnyProfileView[]
|
profiles: bsky.profile.AnyProfileView[]
|
||||||
size?: number
|
size?: number
|
||||||
numPending?: number
|
numPending?: number
|
||||||
backgroundColor?: string
|
backgroundColor?: string
|
||||||
|
spacing?: 'normal' | 'loose'
|
||||||
}) {
|
}) {
|
||||||
const halfSize = size / 2
|
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
|
const translateX = size / getSpacingValue(spacing)
|
||||||
|
|
||||||
const isPending = (numPending && profiles.length === 0) || !moderationOpts
|
const isPending = (numPending && profiles.length === 0) || !moderationOpts
|
||||||
|
|
||||||
@@ -43,7 +45,7 @@ export function AvatarStack({
|
|||||||
a.flex_row,
|
a.flex_row,
|
||||||
a.align_center,
|
a.align_center,
|
||||||
a.relative,
|
a.relative,
|
||||||
{width: size + (items.length - 1) * halfSize},
|
{width: size + (items.length - 1) * translateX},
|
||||||
]}>
|
]}>
|
||||||
{items.map((item, i) => (
|
{items.map((item, i) => (
|
||||||
<View
|
<View
|
||||||
@@ -54,7 +56,7 @@ export function AvatarStack({
|
|||||||
{
|
{
|
||||||
width: size,
|
width: size,
|
||||||
height: size,
|
height: size,
|
||||||
left: i * -halfSize,
|
left: i * -translateX,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: backgroundColor ?? t.atoms.bg.backgroundColor,
|
borderColor: backgroundColor ?? t.atoms.bg.backgroundColor,
|
||||||
borderRadius: 999,
|
borderRadius: 999,
|
||||||
@@ -75,6 +77,10 @@ export function AvatarStack({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSpacingValue(spacing: 'normal' | 'loose') {
|
||||||
|
return spacing === 'normal' ? 2 : 4
|
||||||
|
}
|
||||||
|
|
||||||
export function AvatarStackWithFetch({
|
export function AvatarStackWithFetch({
|
||||||
profiles,
|
profiles,
|
||||||
size,
|
size,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {precacheStarterPack} from '#/state/queries/starter-packs'
|
|||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {StarterPack as StarterPackIcon} from '#/components/icons/StarterPack'
|
import {StarterPack as StarterPackIcon} from '#/components/icons/StarterPack'
|
||||||
import {Link as BaseLink, LinkProps as BaseLinkProps} from '#/components/Link'
|
import {Link as BaseLink, type LinkProps as BaseLinkProps} from '#/components/Link'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import * as bsky from '#/types/bsky'
|
import * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
@@ -104,6 +104,32 @@ export function Card({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useStarterPackLink({
|
||||||
|
view,
|
||||||
|
}: {
|
||||||
|
view: bsky.starterPack.AnyStarterPackView
|
||||||
|
}) {
|
||||||
|
const {_} = useLingui()
|
||||||
|
const qc = useQueryClient()
|
||||||
|
const {rkey, handleOrDid} = React.useMemo(() => {
|
||||||
|
const rkey = new AtUri(view.uri).rkey
|
||||||
|
const {creator} = view
|
||||||
|
return {rkey, handleOrDid: creator.handle || creator.did}
|
||||||
|
}, [view])
|
||||||
|
const precache = () => {
|
||||||
|
precacheResolvedUri(qc, view.creator.handle, view.creator.did)
|
||||||
|
precacheStarterPack(qc, view)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
to: `/starter-pack/${handleOrDid}/${rkey}`,
|
||||||
|
label: AppBskyGraphStarterpack.isRecord(view.record)
|
||||||
|
? _(msg`Navigate to ${view.record.name}`)
|
||||||
|
: _(msg`Navigate to starter pack`),
|
||||||
|
precache,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function Link({
|
export function Link({
|
||||||
starterPack,
|
starterPack,
|
||||||
children,
|
children,
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import {useCallback, useMemo, useRef, useState} from 'react'
|
import {useCallback, useMemo, useRef, useState} from 'react'
|
||||||
import {View, type ViewabilityConfig, type ViewToken} from 'react-native'
|
import {View, type ViewabilityConfig, type ViewToken} from 'react-native'
|
||||||
import {type AppBskyActorDefs, type AppBskyFeedDefs, type AppBskyGraphDefs} from '@atproto/api'
|
import {
|
||||||
|
type AppBskyActorDefs,
|
||||||
|
type AppBskyFeedDefs,
|
||||||
|
type AppBskyGraphDefs,
|
||||||
|
} from '@atproto/api'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
@@ -13,19 +17,20 @@ import {useActorSearchPaginated} from '#/state/queries/actor-search'
|
|||||||
import {useGetPopularFeedsQuery} from '#/state/queries/feed'
|
import {useGetPopularFeedsQuery} from '#/state/queries/feed'
|
||||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||||
import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
|
import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
|
||||||
|
import {useSuggestedStarterPacksQuery} from '#/state/queries/useSuggestedStarterPacksQuery'
|
||||||
import {useProgressGuide} from '#/state/shell/progress-guide'
|
import {useProgressGuide} from '#/state/shell/progress-guide'
|
||||||
import {List} from '#/view/com/util/List'
|
import {List} from '#/view/com/util/List'
|
||||||
import {
|
import {
|
||||||
FeedFeedLoadingPlaceholder,
|
FeedFeedLoadingPlaceholder,
|
||||||
ProfileCardFeedLoadingPlaceholder,
|
ProfileCardFeedLoadingPlaceholder,
|
||||||
} from '#/view/com/util/LoadingPlaceholder'
|
} from '#/view/com/util/LoadingPlaceholder'
|
||||||
|
import {StarterPackCard} from '#/screens/Search/components/StarterPackCard'
|
||||||
import {ExploreRecommendations} from '#/screens/Search/modules/ExploreRecommendations'
|
import {ExploreRecommendations} from '#/screens/Search/modules/ExploreRecommendations'
|
||||||
import {ExploreTrendingTopics} from '#/screens/Search/modules/ExploreTrendingTopics'
|
import {ExploreTrendingTopics} from '#/screens/Search/modules/ExploreTrendingTopics'
|
||||||
import {ExploreTrendingVideos} from '#/screens/Search/modules/ExploreTrendingVideos'
|
import {ExploreTrendingVideos} from '#/screens/Search/modules/ExploreTrendingVideos'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Button} from '#/components/Button'
|
import {Button} from '#/components/Button'
|
||||||
import * as FeedCard from '#/components/FeedCard'
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
import {StarterPackCard} from '#/screens/Search/components/StarterPackCard'
|
|
||||||
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDownIcon} from '#/components/icons/Chevron'
|
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDownIcon} from '#/components/icons/Chevron'
|
||||||
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||||
import {type Props as SVGIconProps} from '#/components/icons/common'
|
import {type Props as SVGIconProps} from '#/components/icons/common'
|
||||||
@@ -40,7 +45,6 @@ import {
|
|||||||
SuggestedProfileCard,
|
SuggestedProfileCard,
|
||||||
useLoadEnoughProfiles,
|
useLoadEnoughProfiles,
|
||||||
} from './modules/ExploreSuggestedAccounts'
|
} from './modules/ExploreSuggestedAccounts'
|
||||||
import {useSuggestedStarterPacksQuery} from '#/state/queries/useSuggestedStarterPacksQuery'
|
|
||||||
|
|
||||||
function LoadMore({item}: {item: ExploreScreenItems & {type: 'loadMore'}}) {
|
function LoadMore({item}: {item: ExploreScreenItems & {type: 'loadMore'}}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
@@ -156,9 +160,9 @@ type ExploreScreenItems =
|
|||||||
error: string
|
error: string
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'starterPack',
|
type: 'starterPack'
|
||||||
key: string
|
key: string
|
||||||
view: AppBskyGraphDefs.StarterPackViewBasic
|
view: AppBskyGraphDefs.StarterPackView
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Explore({
|
export function Explore({
|
||||||
@@ -465,7 +469,7 @@ export function Explore({
|
|||||||
// error: cleanError(suggestedSPsError),
|
// error: cleanError(suggestedSPsError),
|
||||||
// })
|
// })
|
||||||
} else {
|
} else {
|
||||||
suggestedSPs.map(s => {
|
suggestedSPs.starterPacks.map(s => {
|
||||||
i.push({
|
i.push({
|
||||||
type: 'starterPack',
|
type: 'starterPack',
|
||||||
key: s.uri,
|
key: s.uri,
|
||||||
@@ -512,6 +516,9 @@ export function Explore({
|
|||||||
gate,
|
gate,
|
||||||
moderationOpts,
|
moderationOpts,
|
||||||
hasPressedLoadMoreFeeds,
|
hasPressedLoadMoreFeeds,
|
||||||
|
suggestedSPs,
|
||||||
|
isLoadingSuggestedSPs,
|
||||||
|
suggestedSPsError,
|
||||||
])
|
])
|
||||||
|
|
||||||
const renderItem = useCallback(
|
const renderItem = useCallback(
|
||||||
@@ -593,13 +600,7 @@ export function Explore({
|
|||||||
}
|
}
|
||||||
case 'starterPack': {
|
case 'starterPack': {
|
||||||
return (
|
return (
|
||||||
<View
|
<View style={[a.px_lg, a.py_sm]}>
|
||||||
style={[
|
|
||||||
a.border_b,
|
|
||||||
t.atoms.border_contrast_low,
|
|
||||||
a.px_lg,
|
|
||||||
a.py_lg,
|
|
||||||
]}>
|
|
||||||
<StarterPackCard view={item.view} />
|
<StarterPackCard view={item.view} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,57 +1,253 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {AppBskyGraphDefs} from '@atproto/api'
|
import {
|
||||||
import {Image} from 'expo-image'
|
type AppBskyGraphDefs,
|
||||||
|
AppBskyGraphStarterpack,
|
||||||
|
moderateProfile,
|
||||||
|
} from '@atproto/api'
|
||||||
|
import {msg,Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans, msg} from '@lingui/macro'
|
|
||||||
|
|
||||||
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import * as Card from '#/components/StarterPack/StarterPackCard'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {atoms as a, useTheme, useBreakpoints} from '#/alf'
|
import {useSession} from '#/state/session'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
|
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||||
|
import {ButtonText} from '#/components/Button'
|
||||||
|
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
||||||
|
import {Link} from '#/components/Link'
|
||||||
|
import {MediaInsetBorder} from '#/components/MediaInsetBorder'
|
||||||
|
import {useStarterPackLink} from '#/components/StarterPack/StarterPackCard'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
import * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
export function StarterPackCard({view}: {view: AppBskyGraphDefs.StarterPackViewBasic}) {
|
export function StarterPackCard({
|
||||||
|
view,
|
||||||
|
}: {
|
||||||
|
view: AppBskyGraphDefs.StarterPackView
|
||||||
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const imageUri = getStarterPackOgCard(view)
|
const {currentAccount} = useSession()
|
||||||
const {gtPhone} = useBreakpoints()
|
const {gtPhone} = useBreakpoints()
|
||||||
|
const link = useStarterPackLink({view})
|
||||||
|
|
||||||
|
if (
|
||||||
|
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
|
||||||
|
view.record,
|
||||||
|
AppBskyGraphStarterpack.isRecord,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const profileCount = gtPhone ? 11 : 8
|
||||||
|
const profiles = view.listItemsSample
|
||||||
|
?.slice(0, profileCount)
|
||||||
|
.map(item => item.subject)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
|
a.w_full,
|
||||||
|
a.p_lg,
|
||||||
|
a.gap_md,
|
||||||
a.border,
|
a.border,
|
||||||
a.rounded_sm,
|
a.rounded_sm,
|
||||||
a.overflow_hidden,
|
a.overflow_hidden,
|
||||||
t.atoms.border_contrast_low,
|
t.atoms.border_contrast_low,
|
||||||
]}>
|
]}>
|
||||||
<Card.Link starterPack={view}>
|
<View aria-hidden style={[a.absolute, a.inset_0, a.z_40]}>
|
||||||
<View style={[a.w_full, gtPhone && [
|
<Link
|
||||||
a.flex_row, a.gap_lg,
|
to={link.to}
|
||||||
]]}>
|
label={link.label}
|
||||||
<View style={[gtPhone && {
|
style={[a.absolute, a.inset_0]}
|
||||||
width: '50%',
|
onHoverIn={link.precache}
|
||||||
}]}>
|
onPress={link.precache}>
|
||||||
<Image
|
<View />
|
||||||
source={imageUri}
|
</Link>
|
||||||
style={[a.w_full, {aspectRatio: 1.91}]}
|
</View>
|
||||||
accessibilityIgnoresInvertColors={true}
|
|
||||||
|
<AvatarStack
|
||||||
|
profiles={profiles ?? []}
|
||||||
|
numPending={profileCount}
|
||||||
|
total={view.list?.listItemCount}
|
||||||
/>
|
/>
|
||||||
</View>
|
|
||||||
<View style={[a.flex_1, a.py_md, a.pr_md, !gtPhone && [a.px_md, a.flex_row, a.gap_sm, a.align_start]]}>
|
<View
|
||||||
|
style={[
|
||||||
|
a.w_full,
|
||||||
|
a.flex_row,
|
||||||
|
a.align_start,
|
||||||
|
a.gap_lg,
|
||||||
|
web({
|
||||||
|
position: 'static',
|
||||||
|
zIndex: 'unset',
|
||||||
|
}),
|
||||||
|
]}>
|
||||||
<View style={[a.flex_1]}>
|
<View style={[a.flex_1]}>
|
||||||
<Card.Card starterPack={view} noIcon />
|
<Text
|
||||||
|
emoji
|
||||||
|
style={[a.text_md, a.font_bold, a.leading_snug]}
|
||||||
|
numberOfLines={1}>
|
||||||
|
{view.record.name}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
emoji
|
||||||
|
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
||||||
|
numberOfLines={1}>
|
||||||
|
{view.creator?.did === currentAccount?.did
|
||||||
|
? _(msg`By you`)
|
||||||
|
: _(msg`By ${sanitizeHandle(view.creator.handle, '@')}`)}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Link
|
||||||
|
to={link.to}
|
||||||
|
label={link.label}
|
||||||
|
onHoverIn={link.precache}
|
||||||
|
onPress={link.precache}
|
||||||
|
variant="solid"
|
||||||
|
color="secondary"
|
||||||
|
size="small"
|
||||||
|
style={[a.z_50]}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Open pack</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Link>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AvatarStack({
|
||||||
|
profiles,
|
||||||
|
numPending,
|
||||||
|
total,
|
||||||
|
}: {
|
||||||
|
profiles: bsky.profile.AnyProfileView[]
|
||||||
|
numPending: number
|
||||||
|
total?: number
|
||||||
|
}) {
|
||||||
|
const t = useTheme()
|
||||||
|
const {gtPhone} = useBreakpoints()
|
||||||
|
const moderationOpts = useModerationOpts()
|
||||||
|
const circlesCount = numPending + 1 // add total at end
|
||||||
|
const widthPerc = 100 / circlesCount
|
||||||
|
const [size, setSize] = React.useState<number | null>(null)
|
||||||
|
|
||||||
|
const isPending = (numPending && profiles.length === 0) || !moderationOpts
|
||||||
|
|
||||||
|
const items = isPending
|
||||||
|
? Array.from({length: numPending ?? circlesCount}).map((_, i) => ({
|
||||||
|
key: i,
|
||||||
|
profile: null,
|
||||||
|
moderation: null,
|
||||||
|
}))
|
||||||
|
: profiles.map(item => ({
|
||||||
|
key: item.did,
|
||||||
|
profile: item,
|
||||||
|
moderation: moderateProfile(item, moderationOpts),
|
||||||
|
}))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.w_full,
|
||||||
|
a.flex_row,
|
||||||
|
a.align_center,
|
||||||
|
a.relative,
|
||||||
|
{width: `${100 - widthPerc * 0.2}%`},
|
||||||
|
]}>
|
||||||
|
{items.map((item, i) => (
|
||||||
|
<View
|
||||||
|
key={item.key}
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
width: `${widthPerc}%`,
|
||||||
|
zIndex: 100 - i,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.relative,
|
||||||
|
{
|
||||||
|
width: '120%',
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<View
|
||||||
|
onLayout={e => setSize(e.nativeEvent.layout.width)}
|
||||||
|
style={[
|
||||||
|
a.rounded_full,
|
||||||
|
t.atoms.bg_contrast_25,
|
||||||
|
{
|
||||||
|
paddingTop: '100%',
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
{size && item.profile ? (
|
||||||
|
<UserAvatar
|
||||||
|
size={size}
|
||||||
|
avatar={item.profile.avatar}
|
||||||
|
type={item.profile.associated?.labeler ? 'labeler' : 'user'}
|
||||||
|
moderation={item.moderation.ui('avatar')}
|
||||||
|
style={[a.absolute, a.inset_0]}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<MediaInsetBorder style={[a.rounded_full]} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
width: `${widthPerc}%`,
|
||||||
|
zIndex: 1,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.relative,
|
||||||
|
{
|
||||||
|
width: '120%',
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
paddingTop: '100%',
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.absolute,
|
||||||
|
a.inset_0,
|
||||||
|
a.rounded_full,
|
||||||
|
a.align_center,
|
||||||
|
a.justify_center,
|
||||||
|
{
|
||||||
|
backgroundColor: t.atoms.text_contrast_low.color,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
{total ? (
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
gtPhone ? a.text_md : a.text_sm,
|
||||||
|
a.font_bold,
|
||||||
|
a.leading_snug,
|
||||||
|
{color: 'white'},
|
||||||
|
]}>
|
||||||
|
<Trans comment="Indicates the number of additional profiles are in the Starter Pack e.g. +12">
|
||||||
|
+{total}
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<Plus fill="white" />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<Button
|
|
||||||
label={_(msg`Open pack`)}
|
|
||||||
variant='solid'
|
|
||||||
color='secondary'
|
|
||||||
size='small'
|
|
||||||
>
|
|
||||||
<ButtonText><Trans>Open pack</Trans></ButtonText>
|
|
||||||
</Button>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</Card.Link>
|
|
||||||
</View>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {useQuery} from '@tanstack/react-query'
|
import {useQuery} from '@tanstack/react-query'
|
||||||
import {AppBskyGraphDefs} from '@atproto/api'
|
|
||||||
|
|
||||||
import {useAgent} from '#/state/session'
|
import {useAgent} from '#/state/session'
|
||||||
|
|
||||||
@@ -13,90 +12,9 @@ export function useSuggestedStarterPacksQuery() {
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: createSuggestedStarterPacksQueryKey(),
|
queryKey: createSuggestedStarterPacksQueryKey(),
|
||||||
async queryFn() {
|
async queryFn() {
|
||||||
// // @ts-expect-error
|
// TODO interests
|
||||||
// const {data} = await agent.app.bsky.unspecced.getSuggestedStarterPacks()
|
const {data} = await agent.app.bsky.unspecced.getSuggestedStarterPacks()
|
||||||
// const {starterPacks} = data
|
return data
|
||||||
const {starterPacks} = {starterPacks: [temp]}
|
|
||||||
return starterPacks as AppBskyGraphDefs.StarterPackViewBasic[]
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const temp = {
|
|
||||||
uri: 'at://did:plc:dpajgwmnecpdyjyqzjzm6bnb/app.bsky.graph.starterpack/3l3bhtqkjfo2m',
|
|
||||||
cid: 'bafyreifvtjkrvuq3qcyz32p6lacdxbwhcmux5amnhokfputfarlpuyqqhu',
|
|
||||||
record: {
|
|
||||||
$type: 'app.bsky.graph.starterpack',
|
|
||||||
createdAt: '2024-09-03T18:44:43.158Z',
|
|
||||||
feeds: [
|
|
||||||
{
|
|
||||||
avatar:
|
|
||||||
'https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreieppnjpayqgjbyqnbeqzwj3pzqtiwbe5a4m6whzqnp3k7gpqs2gai@jpeg',
|
|
||||||
cid: 'bafyreigreonzn577vy6i4qh2so7aqfjztqrrj4jpssg2jczc27p6x4y6wi',
|
|
||||||
creator: {
|
|
||||||
associated: {
|
|
||||||
chat: {
|
|
||||||
allowIncoming: 'none',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
avatar:
|
|
||||||
'https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihagr2cmvl2jt4mgx3sppwe2it3fwolkrbtjrhcnwjk4jdijhsoze@jpeg',
|
|
||||||
createdAt: '2023-04-12T04:53:57.057Z',
|
|
||||||
description:
|
|
||||||
'official Bluesky account (check username👆)\n\nBugs, feature requests, feedback: support@bsky.app',
|
|
||||||
did: 'did:plc:z72i7hdynmk6r22z27h6tvur',
|
|
||||||
displayName: 'Bluesky',
|
|
||||||
handle: 'bsky.app',
|
|
||||||
indexedAt: '2024-12-18T07:43:57.513Z',
|
|
||||||
labels: [
|
|
||||||
{
|
|
||||||
cts: '2024-05-31T04:01:47.907Z',
|
|
||||||
src: 'did:plc:z3yk2cflhmn6vmzo3f5ixqh4',
|
|
||||||
uri: 'did:plc:z72i7hdynmk6r22z27h6tvur',
|
|
||||||
val: 'cornerstone',
|
|
||||||
ver: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
viewer: {
|
|
||||||
blockedBy: false,
|
|
||||||
muted: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description:
|
|
||||||
'A mix of popular content from accounts you follow and content that your follows like.',
|
|
||||||
did: 'did:web:discover.bsky.app',
|
|
||||||
displayName: 'Popular With Friends',
|
|
||||||
indexedAt: '2023-05-19T23:19:21.076Z',
|
|
||||||
labels: [],
|
|
||||||
likeCount: 33616,
|
|
||||||
uri: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/with-friends',
|
|
||||||
viewer: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: 'at://did:plc:dpajgwmnecpdyjyqzjzm6bnb/app.bsky.graph.list/3l3bhtqgyrn2e',
|
|
||||||
name: "Tom Sawyeeeeeee's Starter Pack",
|
|
||||||
updatedAt: '2024-12-19T22:44:58.411Z',
|
|
||||||
},
|
|
||||||
creator: {
|
|
||||||
did: 'did:plc:dpajgwmnecpdyjyqzjzm6bnb',
|
|
||||||
handle: 'test.esb.lol',
|
|
||||||
displayName: 'e',
|
|
||||||
avatar:
|
|
||||||
'https://cdn.bsky.app/img/avatar/plain/did:plc:dpajgwmnecpdyjyqzjzm6bnb/bafkreia6dx7fhoi6fxwfpgm7jrxijpqci7ap53wpilkpazojwvqlmgud2m@jpeg',
|
|
||||||
associated: {
|
|
||||||
chat: {
|
|
||||||
allowIncoming: 'all',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
viewer: {
|
|
||||||
muted: false,
|
|
||||||
blockedBy: false,
|
|
||||||
},
|
|
||||||
labels: [],
|
|
||||||
createdAt: '2023-07-17T15:57:52.014Z',
|
|
||||||
},
|
|
||||||
joinedAllTimeCount: 1,
|
|
||||||
joinedWeekCount: 0,
|
|
||||||
labels: [],
|
|
||||||
indexedAt: '2024-12-19T22:45:06.322Z',
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user