follow all button

This commit is contained in:
Hailey
2024-06-13 08:54:20 -07:00
parent a07cadd4d8
commit 25b4cb425f
2 changed files with 67 additions and 6 deletions
@@ -1,6 +1,6 @@
import React, {useCallback} from 'react' import React, {useCallback} from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import {AppBskyActorDefs} from '@atproto/api' import {AppBskyActorDefs, AtUri} from '@atproto/api'
import {useBottomBarOffset} from 'lib/hooks/useBottomBarOffset' import {useBottomBarOffset} from 'lib/hooks/useBottomBarOffset'
import {isNative} from 'platform/detection' import {isNative} from 'platform/detection'
@@ -37,9 +37,11 @@ export const ProfilesList = React.forwardRef<SectionRef, ProfilesListProps>(
const {data} = useListMembersQuery(listUri) const {data} = useListMembersQuery(listUri)
const profiles = data?.pages.flatMap(p => p.items.map(i => i.subject)) const profiles = data?.pages.flatMap(p => p.items.map(i => i.subject))
const isOwn = new AtUri(listUri).host === currentAccount?.did
const getSortedProfiles = () => { const getSortedProfiles = () => {
if (!profiles) return if (!profiles) return
if (!isOwn) return profiles
const myIndex = profiles.findIndex(p => p.did === currentAccount?.did) const myIndex = profiles.findIndex(p => p.did === currentAccount?.did)
return [ return [
profiles[myIndex], profiles[myIndex],
+64 -5
View File
@@ -5,25 +5,30 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native' import {useNavigation} from '@react-navigation/native'
import {NativeStackScreenProps} from '@react-navigation/native-stack' import {NativeStackScreenProps} from '@react-navigation/native-stack'
import {useQueryClient} from '@tanstack/react-query'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types' import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types'
import {shareUrl} from 'lib/sharing' import {shareUrl} from 'lib/sharing'
import {isWeb} from 'platform/detection' import {isWeb} from 'platform/detection'
import {useSetUsedStarterPack} from 'state/preferences/starter-pack' import {useSetUsedStarterPack} from 'state/preferences/starter-pack'
import {RQKEY} from 'state/queries/list-members'
import {useResolveDidQuery} from 'state/queries/resolve-uri' import {useResolveDidQuery} from 'state/queries/resolve-uri'
import {useStarterPackQuery} from 'state/queries/useStarterPackQuery' import {useStarterPackQuery} from 'state/queries/useStarterPackQuery'
import {useSession} from 'state/session' import {useAgent, useSession} from 'state/session'
import {useLoggedOutViewControls} from 'state/shell/logged-out' import {useLoggedOutViewControls} from 'state/shell/logged-out'
import * as Toast from '#/view/com/util/Toast'
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader' import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader' import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
import {CenteredView} from 'view/com/util/Views' import {CenteredView} from 'view/com/util/Views'
import {bulkWriteFollows} from '#/screens/Onboarding/util'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button' import {Button, ButtonText} from '#/components/Button'
import {useDialogControl} from '#/components/Dialog' import {useDialogControl} from '#/components/Dialog'
import {ArrowOutOfBox_Stroke2_Corner0_Rounded as ArrowOutOfBox} from '#/components/icons/ArrowOutOfBox' import {ArrowOutOfBox_Stroke2_Corner0_Rounded as ArrowOutOfBox} from '#/components/icons/ArrowOutOfBox'
import {QrCode_Stroke2_Corner0_Rounded as QrCode} from '#/components/icons/QrCode' import {QrCode_Stroke2_Corner0_Rounded as QrCode} from '#/components/icons/QrCode'
import {ListMaybePlaceholder} from '#/components/Lists' import {ListMaybePlaceholder} from '#/components/Lists'
import {Loader} from '#/components/Loader'
import * as Menu from '#/components/Menu' import * as Menu from '#/components/Menu'
import {FeedsList} from '#/components/StarterPack/Main/FeedsList' import {FeedsList} from '#/components/StarterPack/Main/FeedsList'
import {ProfilesList} from '#/components/StarterPack/Main/ProfilesList' import {ProfilesList} from '#/components/StarterPack/Main/ProfilesList'
@@ -111,12 +116,43 @@ function Header({
const t = useTheme() const t = useTheme()
const navigation = useNavigation<NavigationProp>() const navigation = useNavigation<NavigationProp>()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const agent = useAgent()
const queryClient = useQueryClient()
const qrCodeDialogControl = useDialogControl() const qrCodeDialogControl = useDialogControl()
const setUsedStarterPack = useSetUsedStarterPack() const setUsedStarterPack = useSetUsedStarterPack()
const {setShowLoggedOut} = useLoggedOutViewControls() const {setShowLoggedOut} = useLoggedOutViewControls()
const [isProcessing, setIsProcessing] = React.useState(false)
const {record, creator} = starterPack const {record, creator} = starterPack
const isOwn = creator.did === currentAccount?.did const isOwn = creator?.did === currentAccount?.did
const onFollowAll = async () => {
if (!starterPack.list) return
setIsProcessing(true)
try {
const list = await agent.app.bsky.graph.getList({
list: starterPack.list.uri,
})
const dids = list.data.items
.filter(li => !li.subject.viewer?.following)
.map(li => li.subject.did)
await bulkWriteFollows(agent, dids)
await queryClient.refetchQueries({
queryKey: RQKEY(starterPack.list.uri),
})
Toast.show(_(msg`All accounts have been followed!`))
} catch (e) {
Toast.show(_(msg`An error occurred while trying to follow all`))
} finally {
setIsProcessing(false)
}
}
if (!AppBskyGraphStarterpack.isRecord(record)) { if (!AppBskyGraphStarterpack.isRecord(record)) {
return null return null
@@ -165,11 +201,21 @@ function Header({
: t.palette.contrast_25, : t.palette.contrast_25,
}, },
(state.hovered || state.pressed) && { (state.hovered || state.pressed) && {
backgroundColor: t.palette.primary_600, backgroundColor: isOwn
? t.palette.primary_600
: t.palette.contrast_50,
}, },
]} ]}
{...props}> {...props}>
<Text style={[a.font_bold, {color: 'white'}]}> <Text
style={[
a.font_bold,
{
color: isOwn
? 'white'
: t.atoms.text_contrast_medium.color,
},
]}>
<Trans>Share</Trans> <Trans>Share</Trans>
</Text> </Text>
</Pressable> </Pressable>
@@ -200,7 +246,7 @@ function Header({
</Menu.Group> </Menu.Group>
</Menu.Outer> </Menu.Outer>
</Menu.Root> </Menu.Root>
{isOwn && ( {isOwn ? (
<Button <Button
label={_(msg`Edit`)} label={_(msg`Edit`)}
variant="solid" variant="solid"
@@ -213,6 +259,19 @@ function Header({
<Trans>Edit</Trans> <Trans>Edit</Trans>
</ButtonText> </ButtonText>
</Button> </Button>
) : (
<Button
label={_(msg`Follow all`)}
variant="solid"
color="primary"
size="small"
disabled={isProcessing}
onPress={onFollowAll}>
<ButtonText>
<Trans>Follow all</Trans>
{isProcessing && <Loader size="xs" />}
</ButtonText>
</Button>
)} )}
</View> </View>
</ProfileSubpageHeader> </ProfileSubpageHeader>