Migrate FeedSourceCard

This commit is contained in:
Eric Bailey
2024-04-22 11:13:34 -05:00
parent b99be94442
commit f9d8370a30
2 changed files with 56 additions and 74 deletions
+20 -9
View File
@@ -249,7 +249,11 @@ export function useSaveFeedMutation() {
return useMutation<void, unknown, {uri: string}>({ return useMutation<void, unknown, {uri: string}>({
mutationFn: async ({uri}) => { mutationFn: async ({uri}) => {
await getAgent().addSavedFeed(uri) await getAgent().addSavedFeedV2({
type: 'feed',
value: uri,
pinned: false,
})
track('CustomFeed:Save') track('CustomFeed:Save')
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
@@ -262,9 +266,9 @@ export function useSaveFeedMutation() {
export function useRemoveFeedMutation() { export function useRemoveFeedMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
return useMutation<void, unknown, {uri: string}>({ return useMutation<void, unknown, Pick<AppBskyActorDefs.SavedFeed, 'id'>>({
mutationFn: async ({uri}) => { mutationFn: async ({id}) => {
await getAgent().removeSavedFeed(uri) await getAgent().removeSavedFeedV2(id)
track('CustomFeed:Unsave') track('CustomFeed:Unsave')
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
@@ -279,7 +283,11 @@ export function usePinFeedMutation() {
return useMutation<void, unknown, {uri: string}>({ return useMutation<void, unknown, {uri: string}>({
mutationFn: async ({uri}) => { mutationFn: async ({uri}) => {
await getAgent().addPinnedFeed(uri) await getAgent().addSavedFeedV2({
type: 'feed',
value: uri,
pinned: true,
})
track('CustomFeed:Pin', {uri}) track('CustomFeed:Pin', {uri})
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
@@ -292,10 +300,13 @@ export function usePinFeedMutation() {
export function useUnpinFeedMutation() { export function useUnpinFeedMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
return useMutation<void, unknown, {uri: string}>({ return useMutation<void, unknown, AppBskyActorDefs.SavedFeed>({
mutationFn: async ({uri}) => { mutationFn: async feed => {
await getAgent().removePinnedFeed(uri) await getAgent().updateSavedFeed({
track('CustomFeed:Unpin', {uri}) ...feed,
pinned: false,
})
track('CustomFeed:Unpin', {uri: feed.value})
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
+36 -65
View File
@@ -5,7 +5,6 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useGate} from '#/lib/statsig/statsig'
import {logger} from '#/logger' import {logger} from '#/logger'
import {FeedSourceInfo, useFeedSourceInfoQuery} from '#/state/queries/feed' import {FeedSourceInfo, useFeedSourceInfoQuery} from '#/state/queries/feed'
import { import {
@@ -24,9 +23,6 @@ import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import * as Toast from 'view/com/util/Toast' import * as Toast from 'view/com/util/Toast'
import {useTheme} from '#/alf' import {useTheme} from '#/alf'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
import {PrimaryAlgoNoticeDialog} from '#/components/PrimaryAlgoNoticeDialog'
import * as Prompt from '#/components/Prompt' import * as Prompt from '#/components/Prompt'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
@@ -93,8 +89,6 @@ export function FeedSourceCardLoaded({
const {_} = useLingui() const {_} = useLingui()
const removePromptControl = Prompt.usePromptControl() const removePromptControl = Prompt.usePromptControl()
const navigation = useNavigationDeduped() const navigation = useNavigationDeduped()
const gate = useGate()
const primaryAlgoDialogControl = Prompt.usePromptControl()
const {isPending: isSavePending, mutateAsync: saveFeed} = const {isPending: isSavePending, mutateAsync: saveFeed} =
useSaveFeedMutation() useSaveFeedMutation()
@@ -102,7 +96,10 @@ export function FeedSourceCardLoaded({
useRemoveFeedMutation() useRemoveFeedMutation()
const {isPending: isPinPending, mutateAsync: pinFeed} = usePinFeedMutation() const {isPending: isPinPending, mutateAsync: pinFeed} = usePinFeedMutation()
const isSaved = Boolean(preferences?.feeds?.saved?.includes(feed?.uri || '')) const savedFeedConfig = preferences?.savedFeeds?.find(
f => f.value === feed?.uri,
)
const isSaved = Boolean(savedFeedConfig)
const onSave = React.useCallback(async () => { const onSave = React.useCallback(async () => {
if (!feed) return if (!feed) return
@@ -121,17 +118,17 @@ export function FeedSourceCardLoaded({
}, [_, feed, pinFeed, pinOnSave, saveFeed]) }, [_, feed, pinFeed, pinOnSave, saveFeed])
const onUnsave = React.useCallback(async () => { const onUnsave = React.useCallback(async () => {
if (!feed) return if (!savedFeedConfig) return
try { try {
await removeFeed({uri: feed.uri}) await removeFeed(savedFeedConfig)
// await item.unsave() // await item.unsave()
Toast.show(_(msg`Removed from my feeds`)) Toast.show(_(msg`Removed from my feeds`))
} catch (e) { } catch (e) {
Toast.show(_(msg`There was an issue contacting your server`)) Toast.show(_(msg`There was an issue contacting your server`))
logger.error('Failed to unsave feed', {message: e}) logger.error('Failed to unsave feed', {message: e})
} }
}, [_, feed, removeFeed]) }, [_, removeFeed, savedFeedConfig])
const onToggleSaved = React.useCallback(async () => { const onToggleSaved = React.useCallback(async () => {
// Only feeds can be un/saved, lists are handled elsewhere // Only feeds can be un/saved, lists are handled elsewhere
@@ -193,10 +190,6 @@ export function FeedSourceCardLoaded({
</View> </View>
) )
const primaryAlgo = preferences?.primaryAlgorithm
const isPrimaryAlgo =
primaryAlgo?.enabled && primaryAlgo?.uri && primaryAlgo.uri === feed.uri
return ( return (
<> <>
<Pressable <Pressable
@@ -235,55 +228,35 @@ export function FeedSourceCardLoaded({
</View> </View>
{showSaveBtn && feed.type === 'feed' && ( {showSaveBtn && feed.type === 'feed' && (
<> <View style={[s.justifyCenter]}>
{gate('reduced_onboarding_and_home_algo') && isPrimaryAlgo ? ( <Pressable
<Button testID={`feed-${feed.displayName}-toggleSave`}
variant="solid" disabled={isSavePending || isPinPending || isRemovePending}
color="secondary" accessibilityRole="button"
size="small" accessibilityLabel={
label={_( isSaved
msg`This feed is already set as your primary algorithm.`, ? _(msg`Remove from my feeds`)
)} : _(msg`Add to my feeds`)
onPress={() => { }
primaryAlgoDialogControl.open() accessibilityHint=""
}}> onPress={onToggleSaved}
<ButtonIcon icon={Check} position="left" /> hitSlop={15}
<ButtonText> style={styles.btn}>
<Trans>Primary Algorithm</Trans> {isSaved ? (
</ButtonText> <FontAwesomeIcon
</Button> icon={['far', 'trash-can']}
) : ( size={19}
<View style={[s.justifyCenter]}> color={pal.colors.icon}
<Pressable />
testID={`feed-${feed.displayName}-toggleSave`} ) : (
disabled={isSavePending || isPinPending || isRemovePending} <FontAwesomeIcon
accessibilityRole="button" icon="plus"
accessibilityLabel={ size={18}
isSaved color={pal.colors.link}
? _(msg`Remove from my feeds`) />
: _(msg`Add to my feeds`) )}
} </Pressable>
accessibilityHint="" </View>
onPress={onToggleSaved}
hitSlop={15}
style={styles.btn}>
{isSaved ? (
<FontAwesomeIcon
icon={['far', 'trash-can']}
size={19}
color={pal.colors.icon}
/>
) : (
<FontAwesomeIcon
icon="plus"
size={18}
color={pal.colors.link}
/>
)}
</Pressable>
</View>
)}
</>
)} )}
</View> </View>
@@ -315,8 +288,6 @@ export function FeedSourceCardLoaded({
confirmButtonCta={_(msg`Remove`)} confirmButtonCta={_(msg`Remove`)}
confirmButtonColor="negative" confirmButtonColor="negative"
/> />
<PrimaryAlgoNoticeDialog control={primaryAlgoDialogControl} />
</> </>
) )
} }