import {useState} from 'react' import {View} from 'react-native' import {type AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useQueryClient} from '@tanstack/react-query' import {batchedUpdates} from '#/lib/batchedUpdates' import {isBlockedOrBlocking, isMuted} from '#/lib/moderation/blocked-and-muted' import {logger} from '#/logger' import {updateProfileShadow} from '#/state/cache/profile-shadow' import {getAllListMembers} from '#/state/queries/list-members' import {useAgent, useSession} from '#/state/session' import {bulkWriteFollows} from '#/screens/Onboarding/util' import {AvatarStack} from '#/screens/Search/components/StarterPackCard' import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check' import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import * as bsky from '#/types/bsky' const IGNORED_ACCOUNT = 'did:plc:pifkcjimdcfwaxkanzhwxufp' export function StarterPackCard({ view, }: { view: AppBskyGraphDefs.StarterPackView }) { const t = useTheme() const {_} = useLingui() const {currentAccount} = useSession() const {gtPhone} = useBreakpoints() const agent = useAgent() const queryClient = useQueryClient() const record = view.record const [isProcessing, setIsProcessing] = useState(false) const [isFollowingAll, setIsFollowingAll] = useState(false) const onFollowAll = async () => { if (!view.list) return setIsProcessing(true) let listItems: AppBskyGraphDefs.ListItemView[] = [] try { listItems = await getAllListMembers(agent, view.list.uri) } catch (e) { setIsProcessing(false) Toast.show(_(msg`An error occurred while trying to follow all`), { type: 'error', }) logger.error('Failed to get list members for starter pack', { safeMessage: e, }) return } const dids = listItems .filter( li => li.subject.did !== IGNORED_ACCOUNT && li.subject.did !== currentAccount?.did && !isBlockedOrBlocking(li.subject) && !isMuted(li.subject) && !li.subject.viewer?.following, ) .map(li => li.subject.did) let followUris: Map try { followUris = await bulkWriteFollows(agent, dids) } catch (e) { setIsProcessing(false) Toast.show(_(msg`An error occurred while trying to follow all`), { type: 'error', }) logger.error('Failed to follow all accounts', {safeMessage: e}) } setIsFollowingAll(true) setIsProcessing(false) batchedUpdates(() => { for (let did of dids) { updateProfileShadow(queryClient, did, { followingUri: followUris.get(did), }) } }) Toast.show(_(msg`All accounts have been followed!`), {type: 'success'}) logger.metric('starterPack:followAll', { logContext: 'Onboarding', starterPack: view.uri, count: dids.length, }) } if ( !bsky.dangerousIsType( record, AppBskyGraphStarterpack.isRecord, ) ) { return null } const profileCount = gtPhone ? 11 : 8 const profiles = view.listItemsSample ?.slice(0, profileCount) .map(item => item.subject) return ( {record.name} {record.description} ) }