From 69725f8f375d0c35936d3e16172f165a23e84733 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 22 Apr 2024 17:39:19 -0500 Subject: [PATCH] Migrate SavedFeeds screen --- src/view/screens/SavedFeeds.tsx | 157 ++++++++++++++++---------------- 1 file changed, 77 insertions(+), 80 deletions(-) diff --git a/src/view/screens/SavedFeeds.tsx b/src/view/screens/SavedFeeds.tsx index ba41f2fdc0..0335497cde 100644 --- a/src/view/screens/SavedFeeds.tsx +++ b/src/view/screens/SavedFeeds.tsx @@ -1,5 +1,6 @@ import React from 'react' import {ActivityIndicator, Pressable, StyleSheet, View} from 'react-native' +import {AppBskyActorDefs} from '@atproto/api' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -7,13 +8,11 @@ import {useFocusEffect} from '@react-navigation/native' import {NativeStackScreenProps} from '@react-navigation/native-stack' import {track} from '#/lib/analytics/analytics' -import {useGate} from '#/lib/statsig/statsig' import {logger} from '#/logger' import { - usePinFeedMutation, usePreferencesQuery, useSetSaveFeedsMutation, - useUnpinFeedMutation, + useUpdateSavedFeedMutation, } from '#/state/queries/preferences' import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {useSetMinimalShellMode} from '#/state/shell' @@ -65,10 +64,9 @@ export function SavedFeeds({}: Props) { const currentFeeds = optimisticSavedFeedsResponse && !setSavedFeedsError ? optimisticSavedFeedsResponse - : preferences?.feeds || {saved: [], pinned: []} - const unpinned = currentFeeds.saved.filter(f => { - return !currentFeeds.pinned?.includes(f) - }) + : preferences?.savedFeeds || [] + const pinnedFeeds = currentFeeds.filter(f => f.pinned) + const unpinnedFeeds = currentFeeds.filter(f => !f.pinned) useFocusEffect( React.useCallback(() => { @@ -93,7 +91,7 @@ export function SavedFeeds({}: Props) { {preferences?.feeds ? ( - !currentFeeds.pinned.length ? ( + !pinnedFeeds.length ? ( ) : ( - currentFeeds.pinned.map(uri => ( + pinnedFeeds.map(f => ( {preferences?.feeds ? ( - !unpinned.length ? ( + !unpinnedFeeds.length ? ( ) : ( - unpinned.map(uri => ( + unpinnedFeeds.map(f => ( ['mutateAsync'] resetSaveFeedsMutationState: ReturnType< typeof useSetSaveFeedsMutation @@ -197,17 +194,9 @@ function ListItem({ const pal = usePalette('default') const {_} = useLingui() const playHaptic = useHaptics() - const {isPending: isPinPending, mutateAsync: pinFeed} = usePinFeedMutation() - const {isPending: isUnpinPending, mutateAsync: unpinFeed} = - useUnpinFeedMutation() - const isPending = isPinPending || isUnpinPending - const gate = useGate() - const primaryAlgo = preferences.primaryAlgorithm - const isPrimaryAlgoExperimentEnabled = gate( - 'reduced_onboarding_and_home_algo', - ) - const isPrimaryAlgo = primaryAlgo?.enabled && primaryAlgo?.uri === feedUri - const showPinButton = !(isPrimaryAlgoExperimentEnabled && isPrimaryAlgo) + const {isPending: isUpdatePending, mutateAsync: updateFeed} = + useUpdateSavedFeedMutation() + const feedUri = feed.value const onTogglePinned = React.useCallback(async () => { playHaptic() @@ -215,67 +204,74 @@ function ListItem({ try { resetSaveFeedsMutationState() - if (isPinned) { - await unpinFeed({uri: feedUri}) + if (feed.pinned) { + await updateFeed({ + ...feed, + pinned: false, + }) } else { - await pinFeed({uri: feedUri}) + await updateFeed({ + ...feed, + pinned: true, + }) } } catch (e) { Toast.show(_(msg`There was an issue contacting the server`)) logger.error('Failed to toggle pinned feed', {message: e}) } - }, [ - playHaptic, - resetSaveFeedsMutationState, - isPinned, - unpinFeed, - feedUri, - pinFeed, - _, - ]) + }, [_, playHaptic, feed, updateFeed, resetSaveFeedsMutationState]) const onPressUp = React.useCallback(async () => { if (!isPinned) return - // create new array, do not mutate - const pinned = [...currentFeeds.pinned] - const index = pinned.indexOf(feedUri) + const nextFeeds = currentFeeds.slice() + const ids = currentFeeds.map(f => f.id) + const index = ids.indexOf(feed.id) + const nextIndex = index - 1 if (index === -1 || index === 0) return - ;[pinned[index], pinned[index - 1]] = [pinned[index - 1], pinned[index]] + ;[nextFeeds[index], nextFeeds[nextIndex]] = [ + nextFeeds[nextIndex], + nextFeeds[index], + ] try { - await setSavedFeeds({saved: currentFeeds.saved, pinned}) + await setSavedFeeds(nextFeeds) track('CustomFeed:Reorder', { - uri: feedUri, - index: pinned.indexOf(feedUri), + uri: feed.value, + index: nextIndex, }) } catch (e) { Toast.show(_(msg`There was an issue contacting the server`)) logger.error('Failed to set pinned feed order', {message: e}) } - }, [feedUri, isPinned, setSavedFeeds, currentFeeds, _]) + }, [feed, isPinned, setSavedFeeds, currentFeeds, _]) const onPressDown = React.useCallback(async () => { if (!isPinned) return - const pinned = [...currentFeeds.pinned] - const index = pinned.indexOf(feedUri) + const nextFeeds = currentFeeds.slice() + const ids = currentFeeds.map(f => f.id) + const index = ids.indexOf(feed.id) + const nextIndex = index + 1 - if (index === -1 || index >= pinned.length - 1) return - ;[pinned[index], pinned[index + 1]] = [pinned[index + 1], pinned[index]] + if (index === -1 || index >= nextFeeds.length - 1) return + ;[nextFeeds[index], nextFeeds[nextIndex]] = [ + nextFeeds[nextIndex], + nextFeeds[index], + ] try { - await setSavedFeeds({saved: currentFeeds.saved, pinned}) + await setSavedFeeds(nextFeeds) track('CustomFeed:Reorder', { - uri: feedUri, - index: pinned.indexOf(feedUri), + uri: feed.value, + index: nextIndex, }) } catch (e) { Toast.show(_(msg`There was an issue contacting the server`)) logger.error('Failed to set pinned feed order', {message: e}) } - }, [feedUri, isPinned, setSavedFeeds, currentFeeds, _]) + }, [feed, isPinned, setSavedFeeds, currentFeeds, _]) return ( ({ - opacity: state.hovered || state.focused || isPending ? 0.5 : 1, + opacity: + state.hovered || state.focused || isUpdatePending ? 0.5 : 1, })}> ({ - opacity: state.hovered || state.focused || isPending ? 0.5 : 1, + opacity: + state.hovered || state.focused || isUpdatePending ? 0.5 : 1, })}> @@ -316,24 +314,23 @@ function ListItem({ showSaveBtn showMinimalPlaceholder /> - {showPinButton && ( - - ({ - opacity: state.hovered || state.focused || isPending ? 0.5 : 1, - })}> - - - - )} + + ({ + opacity: + state.hovered || state.focused || isUpdatePending ? 0.5 : 1, + })}> + + + ) }