87da619aaa
* migrate to #/screens * rm unneeded import * block drawer gesture on recent profiles * rm recommendations (#8056) * [Explore] Disable Trending videos (#8054) * remove giant header * disable * [Explore] Dynamic module ordering (#8066) * Dynamic module ordering * [Explore] New headers, metrics (#8067) * new sticky headers * improve spacing between modules * view metric on modules * update metrics names * [Explore] Suggested accounts module (#8072) * use modern profile card, update load more * add tab bar * tabbed suggested accounts * [Explore] Discover feeds module (#8073) * cap number of feeds to 3 * change feed pin button * Apply suggestions from code review Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * restore statsig to log events * filter out followed profiles, make suer enough are loaded (#8090) * [Explore] Trending topics (#8055) * redesigned trending topics * rm borders on web * get post count / age / ranking from api * spacing tweaks * fetch more topics then slice * use api data for avis/category * rm top border * Integrate new SDK, part out components * Clean up * Use status field * Bump SDK * Send up interests and langs --------- Co-authored-by: Eric Bailey <git@esb.lol> * Clean up module spacing and borders (cherry picked from commit 63d19b6c2d67e226e0e14709b1047a1f88b3ce1c) (cherry picked from commit 62d7d394ab1dc31b40b9c2cf59075adbf94737a1) * Switch back border ordering (cherry picked from commit 34e3789f8b410132c1390df3c2bb8257630ebdd9) * [Explore] Starter Packs (#8095) * Temp WIP (cherry picked from commit 43b5d7b1e64b3adb1ed162262d0310e0bf026c18) * New SP card * Load state * Revert change * Cleanup * Interests and caching * Count total * Format * Caching * [Explore] Feed previews module (#8075) * wip new hook * get fetching working, maybe * get feed previews rendering! * fix header height * working pin button * extract out FeedLink * add loader * only make preview:header sticky * Fix headers * Header tweaks * Fix moderation filter * Fix threading --------- Co-authored-by: Eric Bailey <git@esb.lol> * Space it out * Fix query key * Mock new endpoint, filter saved feeds * Make sure we're pinning, lower cache time * add news category * Remove log * Improve suggested accounts load state * Integrate new app view endpoint * fragment * Update src/screens/Search/modules/ExploreTrendingTopics.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/screens/Search/modules/ExploreTrendingTopics.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * lint * maybe fix this --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Eric Bailey <git@esb.lol> Co-authored-by: Hailey <me@haileyok.com>
205 lines
5.4 KiB
TypeScript
205 lines
5.4 KiB
TypeScript
import React from 'react'
|
|
import {View} from 'react-native'
|
|
import {Image} from 'expo-image'
|
|
import {AppBskyGraphStarterpack, AtUri} from '@atproto/api'
|
|
import {msg, Plural, Trans} from '@lingui/macro'
|
|
import {useLingui} from '@lingui/react'
|
|
import {useQueryClient} from '@tanstack/react-query'
|
|
|
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
|
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
|
import {precacheResolvedUri} from '#/state/queries/resolve-uri'
|
|
import {precacheStarterPack} from '#/state/queries/starter-packs'
|
|
import {useSession} from '#/state/session'
|
|
import {atoms as a, useTheme} from '#/alf'
|
|
import {StarterPack as StarterPackIcon} from '#/components/icons/StarterPack'
|
|
import {
|
|
Link as BaseLink,
|
|
type LinkProps as BaseLinkProps,
|
|
} from '#/components/Link'
|
|
import {Text} from '#/components/Typography'
|
|
import * as bsky from '#/types/bsky'
|
|
|
|
export function Default({
|
|
starterPack,
|
|
}: {
|
|
starterPack?: bsky.starterPack.AnyStarterPackView
|
|
}) {
|
|
if (!starterPack) return null
|
|
return (
|
|
<Link starterPack={starterPack}>
|
|
<Card starterPack={starterPack} />
|
|
</Link>
|
|
)
|
|
}
|
|
|
|
export function Notification({
|
|
starterPack,
|
|
}: {
|
|
starterPack?: bsky.starterPack.AnyStarterPackView
|
|
}) {
|
|
if (!starterPack) return null
|
|
return (
|
|
<Link starterPack={starterPack}>
|
|
<Card starterPack={starterPack} noIcon={true} noDescription={true} />
|
|
</Link>
|
|
)
|
|
}
|
|
|
|
export function Card({
|
|
starterPack,
|
|
noIcon,
|
|
noDescription,
|
|
}: {
|
|
starterPack: bsky.starterPack.AnyStarterPackView
|
|
noIcon?: boolean
|
|
noDescription?: boolean
|
|
}) {
|
|
const {record, creator, joinedAllTimeCount} = starterPack
|
|
|
|
const {_} = useLingui()
|
|
const t = useTheme()
|
|
const {currentAccount} = useSession()
|
|
|
|
if (
|
|
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
|
|
record,
|
|
AppBskyGraphStarterpack.isRecord,
|
|
)
|
|
) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<View style={[a.w_full, a.gap_md]}>
|
|
<View style={[a.flex_row, a.gap_sm, a.w_full]}>
|
|
{!noIcon ? <StarterPackIcon width={40} gradient="sky" /> : null}
|
|
<View style={[a.flex_1]}>
|
|
<Text
|
|
emoji
|
|
style={[a.text_md, a.font_bold, a.leading_snug]}
|
|
numberOfLines={2}>
|
|
{record.name}
|
|
</Text>
|
|
<Text
|
|
emoji
|
|
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
|
numberOfLines={1}>
|
|
{creator?.did === currentAccount?.did
|
|
? _(msg`Starter pack by you`)
|
|
: _(msg`Starter pack by ${sanitizeHandle(creator.handle, '@')}`)}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
{!noDescription && record.description ? (
|
|
<Text emoji numberOfLines={3} style={[a.leading_snug]}>
|
|
{record.description}
|
|
</Text>
|
|
) : null}
|
|
{!!joinedAllTimeCount && joinedAllTimeCount >= 50 && (
|
|
<Text style={[a.font_bold, t.atoms.text_contrast_medium]}>
|
|
<Trans comment="Number of users (always at least 50) who have joined Bluesky using a specific starter pack">
|
|
<Plural value={joinedAllTimeCount} other="# users have" /> joined!
|
|
</Trans>
|
|
</Text>
|
|
)}
|
|
</View>
|
|
)
|
|
}
|
|
|
|
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({
|
|
starterPack,
|
|
children,
|
|
}: {
|
|
starterPack: bsky.starterPack.AnyStarterPackView
|
|
onPress?: () => void
|
|
children: BaseLinkProps['children']
|
|
}) {
|
|
const {_} = useLingui()
|
|
const queryClient = useQueryClient()
|
|
const {record} = starterPack
|
|
const {rkey, handleOrDid} = React.useMemo(() => {
|
|
const rkey = new AtUri(starterPack.uri).rkey
|
|
const {creator} = starterPack
|
|
return {rkey, handleOrDid: creator.handle || creator.did}
|
|
}, [starterPack])
|
|
|
|
if (!AppBskyGraphStarterpack.isRecord(record)) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<BaseLink
|
|
action="push"
|
|
to={`/starter-pack/${handleOrDid}/${rkey}`}
|
|
label={_(msg`Navigate to ${record.name}`)}
|
|
onPress={() => {
|
|
precacheResolvedUri(
|
|
queryClient,
|
|
starterPack.creator.handle,
|
|
starterPack.creator.did,
|
|
)
|
|
precacheStarterPack(queryClient, starterPack)
|
|
}}
|
|
style={[a.flex_col, a.align_start]}>
|
|
{children}
|
|
</BaseLink>
|
|
)
|
|
}
|
|
|
|
export function Embed({
|
|
starterPack,
|
|
}: {
|
|
starterPack: bsky.starterPack.AnyStarterPackView
|
|
}) {
|
|
const t = useTheme()
|
|
const imageUri = getStarterPackOgCard(starterPack)
|
|
|
|
return (
|
|
<View
|
|
style={[
|
|
a.border,
|
|
a.rounded_sm,
|
|
a.overflow_hidden,
|
|
t.atoms.border_contrast_low,
|
|
]}>
|
|
<Link starterPack={starterPack}>
|
|
<Image
|
|
source={imageUri}
|
|
style={[a.w_full, {aspectRatio: 1.91}]}
|
|
accessibilityIgnoresInvertColors={true}
|
|
/>
|
|
<View style={[a.px_sm, a.py_md]}>
|
|
<Card starterPack={starterPack} />
|
|
</View>
|
|
</Link>
|
|
</View>
|
|
)
|
|
}
|