import React from 'react' import { findNodeHandle, ListRenderItemInfo, StyleProp, View, ViewStyle, } from 'react-native' import {AppBskyGraphDefs, AppBskyGraphGetActorStarterPacks} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' import {InfiniteData, UseInfiniteQueryResult} from '@tanstack/react-query' import {logger} from '#/logger' import {useGenerateStarterPackMutation} from 'lib/generate-starterpack' import {useBottomBarOffset} from 'lib/hooks/useBottomBarOffset' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {NavigationProp} from 'lib/routes/types' import {parseStarterPackUri} from 'lib/strings/starter-pack' import {List, ListRef} from 'view/com/util/List' import {Text} from 'view/com/util/text/Text' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {useDialogControl} from '#/components/Dialog' import {LinearGradientBackground} from '#/components/LinearGradientBackground' import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' import {Default as StarterPackCard} from '#/components/StarterPack/StarterPackCard' import {PlusSmall_Stroke2_Corner0_Rounded as Plus} from '../icons/Plus' interface SectionRef { scrollToTop: () => void } interface ProfileFeedgensProps { starterPacksQuery: UseInfiniteQueryResult< InfiniteData, Error > scrollElRef: ListRef headerOffset: number enabled?: boolean style?: StyleProp testID?: string setScrollViewTag: (tag: number | null) => void isMe: boolean } function keyExtractor(item: AppBskyGraphDefs.StarterPackView) { return item.uri } export const ProfileStarterPacks = React.forwardRef< SectionRef, ProfileFeedgensProps >(function ProfileFeedgensImpl( { starterPacksQuery: query, scrollElRef, headerOffset, enabled, style, testID, setScrollViewTag, isMe, }, ref, ) { const t = useTheme() const bottomBarOffset = useBottomBarOffset(100) const [isPTRing, setIsPTRing] = React.useState(false) const {data, refetch, isFetching, hasNextPage, fetchNextPage} = query const {isTabletOrDesktop} = useWebMediaQueries() const items = data?.pages.flatMap(page => page.starterPacks) React.useImperativeHandle(ref, () => ({ scrollToTop: () => {}, })) const onRefresh = React.useCallback(async () => { setIsPTRing(true) try { await refetch() } catch (err) { logger.error('Failed to refresh starter packs', {message: err}) } setIsPTRing(false) }, [refetch, setIsPTRing]) const onEndReached = React.useCallback(async () => { if (isFetching || !hasNextPage) return try { await fetchNextPage() } catch (err) { logger.error('Failed to load more starter packs', {message: err}) } }, [isFetching, hasNextPage, fetchNextPage]) React.useEffect(() => { if (enabled && scrollElRef.current) { const nativeTag = findNodeHandle(scrollElRef.current) setScrollViewTag(nativeTag) } }, [enabled, scrollElRef, setScrollViewTag]) const renderItem = ({ item, index, }: ListRenderItemInfo) => { return ( ) } return ( ) }) function CreateAnother() { const {_} = useLingui() const t = useTheme() const navigation = useNavigation() return ( ) } function Empty() { const {_} = useLingui() const t = useTheme() const navigation = useNavigation() const confirmDialogControl = useDialogControl() const followersDialogControl = useDialogControl() const errorDialogControl = useDialogControl() const [isGenerating, setIsGenerating] = React.useState(false) const {mutate: generateStarterPack} = useGenerateStarterPackMutation({ onSuccess: ({uri}) => { const parsed = parseStarterPackUri(uri) if (parsed) { navigation.push('StarterPack', { name: parsed.name, rkey: parsed.rkey, }) } setIsGenerating(false) }, onError: e => { logger.error('Failed to generate starter pack', {safeMessage: e}) setIsGenerating(false) if (e.name === 'NOT_ENOUGH_FOLLOWERS') { followersDialogControl.open() } else { errorDialogControl.open() } }, }) const generate = () => { setIsGenerating(true) generateStarterPack() } return ( You haven't created a starter pack yet! Starter packs let you easily share your favorite feeds and people with your friends. Generate a starter pack Bluesky will choose a set of recommended accounts from people in your network. { navigation.navigate('StarterPackWizard') }} /> {}} showCancel={false} /> ) }