From 73d609c1bfce99830a416010ce3f0b661043f329 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Tue, 22 Oct 2024 21:39:21 +0100 Subject: [PATCH] Adjust Feed wizard, delete unused code --- src/screens/Feeds/Wizard/State.tsx | 43 +-- src/screens/Feeds/Wizard/StepDetails.tsx | 12 +- src/screens/Feeds/Wizard/StepFeeds.tsx | 126 -------- src/screens/Feeds/Wizard/StepProfiles.tsx | 110 ------- src/screens/Feeds/Wizard/index.tsx | 331 ++-------------------- 5 files changed, 27 insertions(+), 595 deletions(-) delete mode 100644 src/screens/Feeds/Wizard/StepFeeds.tsx delete mode 100644 src/screens/Feeds/Wizard/StepProfiles.tsx diff --git a/src/screens/Feeds/Wizard/State.tsx b/src/screens/Feeds/Wizard/State.tsx index f65933fbb0..8e25229b3f 100644 --- a/src/screens/Feeds/Wizard/State.tsx +++ b/src/screens/Feeds/Wizard/State.tsx @@ -5,13 +5,10 @@ import { AppBskyGraphStarterpack, } from '@atproto/api' import {GeneratorView} from '@atproto/api/dist/client/types/app/bsky/feed/defs' -import {msg} from '@lingui/macro' -import {STARTER_PACK_MAX_SIZE} from '#/lib/constants' import {useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' -const steps = ['Details', 'Profiles', 'Feeds'] as const +const steps = ['Details'] as const type Step = (typeof steps)[number] type Action = @@ -20,10 +17,6 @@ type Action = | {type: 'SetCanNext'; canNext: boolean} | {type: 'SetName'; name: string} | {type: 'SetDescription'; description: string} - | {type: 'AddProfile'; profile: AppBskyActorDefs.ProfileViewBasic} - | {type: 'RemoveProfile'; profileDid: string} - | {type: 'AddFeed'; feed: GeneratorView} - | {type: 'RemoveFeed'; feedUri: string} | {type: 'SetProcessing'; processing: boolean} | {type: 'SetError'; error: string} @@ -52,7 +45,7 @@ function reducer(state: State, action: Action): State { // -- Navigation const currentIndex = steps.indexOf(state.currentStep) - if (action.type === 'Next' && state.currentStep !== 'Feeds') { + if (action.type === 'Next') { updatedState = { ...state, currentStep: steps[currentIndex + 1], @@ -73,38 +66,6 @@ function reducer(state: State, action: Action): State { case 'SetDescription': updatedState = {...state, description: action.description} break - case 'AddProfile': - if (state.profiles.length > STARTER_PACK_MAX_SIZE) { - Toast.show( - msg`You may only add up to ${STARTER_PACK_MAX_SIZE} profiles` - .message ?? '', - 'info', - ) - } else { - updatedState = {...state, profiles: [...state.profiles, action.profile]} - } - break - case 'RemoveProfile': - updatedState = { - ...state, - profiles: state.profiles.filter( - profile => profile.did !== action.profileDid, - ), - } - break - case 'AddFeed': - if (state.feeds.length >= 3) { - Toast.show(msg`You may only add up to 3 feeds`.message ?? '', 'info') - } else { - updatedState = {...state, feeds: [...state.feeds, action.feed]} - } - break - case 'RemoveFeed': - updatedState = { - ...state, - feeds: state.feeds.filter(f => f.uri !== action.feedUri), - } - break case 'SetProcessing': updatedState = {...state, processing: action.processing} break diff --git a/src/screens/Feeds/Wizard/StepDetails.tsx b/src/screens/Feeds/Wizard/StepDetails.tsx index 4ee2cada97..11a3db9fda 100644 --- a/src/screens/Feeds/Wizard/StepDetails.tsx +++ b/src/screens/Feeds/Wizard/StepDetails.tsx @@ -29,24 +29,22 @@ export function StepDetails() { - Invites, but personal + Your own feed - - Invite your friends to follow your favorite feeds and people - + Curate your and other people's posts into a feed - What do you want to call your starter pack? + What do you want to call your feed? dispatch({type: 'SetName', name: text})} @@ -67,7 +65,7 @@ export function StepDetails() { label={_( msg`${ currentProfile?.displayName || currentProfile?.handle - }'s favorite feeds and people - join me!`, + }'s favorite posts`, )} value={state.description} onChangeText={text => diff --git a/src/screens/Feeds/Wizard/StepFeeds.tsx b/src/screens/Feeds/Wizard/StepFeeds.tsx deleted file mode 100644 index 0cf6ab2312..0000000000 --- a/src/screens/Feeds/Wizard/StepFeeds.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React, {useState} from 'react' -import {ListRenderItemInfo, View} from 'react-native' -import {KeyboardAwareScrollView} from 'react-native-keyboard-controller' -import {AppBskyFeedDefs, ModerationOpts} from '@atproto/api' -import {Trans} from '@lingui/macro' - -import {DISCOVER_FEED_URI} from '#/lib/constants' -import {useA11y} from '#/state/a11y' -import { - useGetPopularFeedsQuery, - usePopularFeedsSearch, - useSavedFeeds, -} from '#/state/queries/feed' -import {List} from '#/view/com/util/List' -import {useWizardState} from '#/screens/StarterPack/Wizard/State' -import {atoms as a, useTheme} from '#/alf' -import {SearchInput} from '#/components/forms/SearchInput' -import {useThrottledValue} from '#/components/hooks/useThrottledValue' -import {Loader} from '#/components/Loader' -import {ScreenTransition} from '#/components/StarterPack/Wizard/ScreenTransition' -import {WizardFeedCard} from '#/components/StarterPack/Wizard/WizardListCard' -import {Text} from '#/components/Typography' - -function keyExtractor(item: AppBskyFeedDefs.GeneratorView) { - return item.uri -} - -export function StepFeeds({moderationOpts}: {moderationOpts: ModerationOpts}) { - const t = useTheme() - const [state, dispatch] = useWizardState() - const [query, setQuery] = useState('') - const throttledQuery = useThrottledValue(query, 500) - const {screenReaderEnabled} = useA11y() - - const {data: savedFeedsAndLists, isFetchedAfterMount: isFetchedSavedFeeds} = - useSavedFeeds() - const savedFeeds = savedFeedsAndLists?.feeds - .filter(f => f.type === 'feed' && f.view.uri !== DISCOVER_FEED_URI) - .map(f => f.view) as AppBskyFeedDefs.GeneratorView[] - - const { - data: popularFeedsPages, - fetchNextPage, - isLoading: isLoadingPopularFeeds, - } = useGetPopularFeedsQuery({ - limit: 30, - }) - const popularFeeds = popularFeedsPages?.pages.flatMap(p => p.feeds) ?? [] - - // If we have saved feeds already loaded, display them immediately - // Then, when popular feeds have loaded we can concat them to the saved feeds - const suggestedFeeds = - savedFeeds || isFetchedSavedFeeds - ? popularFeeds - ? savedFeeds.concat( - popularFeeds.filter(f => !savedFeeds.some(sf => sf.uri === f.uri)), - ) - : savedFeeds - : undefined - - const {data: searchedFeeds, isFetching: isFetchingSearchedFeeds} = - usePopularFeedsSearch({query: throttledQuery}) - - const isLoading = - !isFetchedSavedFeeds || isLoadingPopularFeeds || isFetchingSearchedFeeds - - const renderItem = ({ - item, - }: ListRenderItemInfo) => { - return ( - - ) - } - - return ( - - - - setQuery(t)} - onClearText={() => setQuery('')} - /> - - - fetchNextPage() : undefined - } - onEndReachedThreshold={2} - renderScrollComponent={props => } - keyboardShouldPersistTaps="handled" - disableFullWindowScroll={true} - sideBorders={false} - style={{flex: 1}} - ListEmptyComponent={ - - {isLoading ? ( - - ) : ( - - No feeds found. Try searching for something else. - - )} - - } - /> - - ) -} diff --git a/src/screens/Feeds/Wizard/StepProfiles.tsx b/src/screens/Feeds/Wizard/StepProfiles.tsx deleted file mode 100644 index 054a6a63e2..0000000000 --- a/src/screens/Feeds/Wizard/StepProfiles.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import React, {useState} from 'react' -import {ListRenderItemInfo, View} from 'react-native' -import {KeyboardAwareScrollView} from 'react-native-keyboard-controller' -import {AppBskyActorDefs, ModerationOpts} from '@atproto/api' -import {Trans} from '@lingui/macro' - -import {isNative} from '#/platform/detection' -import {useA11y} from '#/state/a11y' -import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete' -import {useActorSearchPaginated} from '#/state/queries/actor-search' -import {List} from '#/view/com/util/List' -import {useWizardState} from '#/screens/StarterPack/Wizard/State' -import {atoms as a, useTheme} from '#/alf' -import {SearchInput} from '#/components/forms/SearchInput' -import {Loader} from '#/components/Loader' -import {ScreenTransition} from '#/components/StarterPack/Wizard/ScreenTransition' -import {WizardProfileCard} from '#/components/StarterPack/Wizard/WizardListCard' -import {Text} from '#/components/Typography' - -function keyExtractor(item: AppBskyActorDefs.ProfileViewBasic) { - return item?.did ?? '' -} - -export function StepProfiles({ - moderationOpts, -}: { - moderationOpts: ModerationOpts -}) { - const t = useTheme() - const [state, dispatch] = useWizardState() - const [query, setQuery] = useState('') - const {screenReaderEnabled} = useA11y() - - const { - data: topPages, - fetchNextPage, - isLoading: isLoadingTopPages, - } = useActorSearchPaginated({ - query: encodeURIComponent('*'), - }) - const topFollowers = topPages?.pages - .flatMap(p => p.actors) - .filter(p => !p.associated?.labeler) - - const {data: resultsUnfiltered, isFetching: isFetchingResults} = - useActorAutocompleteQuery(query, true, 12) - const results = resultsUnfiltered?.filter(p => !p.associated?.labeler) - - const isLoading = isLoadingTopPages || isFetchingResults - - const renderItem = ({ - item, - }: ListRenderItemInfo) => { - return ( - - ) - } - - return ( - - - - setQuery('')} - /> - - - } - keyboardShouldPersistTaps="handled" - disableFullWindowScroll={true} - sideBorders={false} - style={[a.flex_1]} - onEndReached={ - !query && !screenReaderEnabled ? () => fetchNextPage() : undefined - } - onEndReachedThreshold={isNative ? 2 : 0.25} - ListEmptyComponent={ - - {isLoading ? ( - - ) : ( - - Nobody was found. Try searching for someone else. - - )} - - } - /> - - ) -} diff --git a/src/screens/Feeds/Wizard/index.tsx b/src/screens/Feeds/Wizard/index.tsx index d7948cec0d..ad37f8855f 100644 --- a/src/screens/Feeds/Wizard/index.tsx +++ b/src/screens/Feeds/Wizard/index.tsx @@ -1,37 +1,27 @@ import React from 'react' -import {Keyboard, TouchableOpacity, View} from 'react-native' +import {TouchableOpacity, View} from 'react-native' import { KeyboardAwareScrollView, useKeyboardController, } from 'react-native-keyboard-controller' -import {useSafeAreaInsets} from 'react-native-safe-area-context' import {Image} from 'expo-image' -import { - AppBskyActorDefs, - AppBskyGraphDefs, - AtUri, - ModerationOpts, -} from '@atproto/api' -import {GeneratorView} from '@atproto/api/dist/client/types/app/bsky/feed/defs' +import {AppBskyGraphDefs, AtUri} from '@atproto/api' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {msg, Plural, Trans} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useFocusEffect, useNavigation} from '@react-navigation/native' import {NativeStackScreenProps} from '@react-navigation/native-stack' -import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from '#/lib/constants' +import {HITSLOP_10} from '#/lib/constants' import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name' import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types' import {logEvent} from '#/lib/statsig/statsig' -import {sanitizeDisplayName} from '#/lib/strings/display-names' -import {sanitizeHandle} from '#/lib/strings/handles' -import {enforceLen} from '#/lib/strings/helpers' import { getStarterPackOgCard, parseStarterPackUri, } from '#/lib/strings/starter-pack' import {logger} from '#/logger' -import {isAndroid, isNative, isWeb} from '#/platform/detection' +import {isAndroid, isWeb} from '#/platform/detection' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useAllListMembersQuery} from '#/state/queries/list-members' import {useProfileQuery} from '#/state/queries/profile' @@ -43,21 +33,15 @@ import { import {useSession} from '#/state/session' import {useSetMinimalShellMode} from '#/state/shell' import * as Toast from '#/view/com/util/Toast' -import {UserAvatar} from '#/view/com/util/UserAvatar' import {CenteredView} from '#/view/com/util/Views' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' -import {useDialogControl} from '#/components/Dialog' import * as Layout from '#/components/Layout' import {ListMaybePlaceholder} from '#/components/Lists' -import {Loader} from '#/components/Loader' -import {WizardEditListDialog} from '#/components/StarterPack/Wizard/WizardEditListDialog' import {Text} from '#/components/Typography' import {useWizardState, WizardStep} from './State' import {Provider} from './State' import {StepDetails} from './StepDetails' -import {StepFeeds} from './StepFeeds' -import {StepProfiles} from './StepProfiles' export function Wizard({ route, @@ -123,8 +107,6 @@ export function Wizard({ @@ -134,13 +116,9 @@ export function Wizard({ function WizardInner({ currentStarterPack, currentListItems, - profile, - moderationOpts, }: { currentStarterPack?: AppBskyGraphDefs.StarterPackView currentListItems?: AppBskyGraphDefs.ListItemView[] - profile: AppBskyActorDefs.ProfileViewBasic - moderationOpts: ModerationOpts }) { const navigation = useNavigation() const {_} = useLingui() @@ -183,16 +161,8 @@ function WizardInner({ {header: string; nextBtn: string; subtitle?: string} > = { Details: { - header: _(msg`Starter Pack`), - nextBtn: _(msg`Next`), - }, - Profiles: { - header: _(msg`Choose People`), - nextBtn: _(msg`Next`), - }, - Feeds: { - header: _(msg`Choose Feeds`), - nextBtn: state.feeds.length === 0 ? _(msg`Skip`) : _(msg`Finish`), + header: _(msg`Create a Feed`), + nextBtn: _(msg`Finish`), }, } const currUiStrings = wizardUiStrings[state.currentStep] @@ -263,22 +233,6 @@ function WizardInner({ } } - const onNext = () => { - if (state.currentStep === 'Feeds') { - submit() - return - } - - const keyboardVisible = Keyboard.isVisible() - Keyboard.dismiss() - setTimeout( - () => { - dispatch({type: 'Next'}) - }, - keyboardVisible ? 16 : 0, - ) - } - return ( - - {state.currentStep === 'Details' ? ( - - ) : state.currentStep === 'Profiles' ? ( - - ) : state.currentStep === 'Feeds' ? ( - - ) : null} + + {state.currentStep === 'Details' ? : null} - - {state.currentStep !== 'Details' && ( -