diff --git a/lib/shared/community-utils.js b/lib/shared/community-utils.js --- a/lib/shared/community-utils.js +++ b/lib/shared/community-utils.js @@ -3,6 +3,8 @@ import * as React from 'react'; import { + createOrUpdateFarcasterChannelTagActionTypes, + useCreateOrUpdateFarcasterChannelTag, deleteFarcasterChannelTagActionTypes, useDeleteFarcasterChannelTag, } from '../actions/community-actions.js'; @@ -15,6 +17,56 @@ return `farcaster_channel_tag_${farcasterChannelID}`; } +const createOrUpdateFarcasterChannelTagStatusSelector = + createLoadingStatusSelector(createOrUpdateFarcasterChannelTagActionTypes); +function useCreateFarcasterChannelTag( + commCommunityID: string, + setError: SetState, +): { + +createTag: (farcasterChannelID: string) => mixed, + +isLoading: boolean, +} { + const dispatchActionPromise = useDispatchActionPromise(); + + const createOrUpdateFarcasterChannelTag = + useCreateOrUpdateFarcasterChannelTag(); + + const createCreateOrUpdateActionPromise = React.useCallback( + async (farcasterChannelID: string) => { + try { + return await createOrUpdateFarcasterChannelTag({ + commCommunityID, + farcasterChannelID, + }); + } catch (e) { + setError(e.message); + throw e; + } + }, + [commCommunityID, createOrUpdateFarcasterChannelTag, setError], + ); + + const createTag = React.useCallback( + (farcasterChannelID: string) => { + void dispatchActionPromise( + createOrUpdateFarcasterChannelTagActionTypes, + createCreateOrUpdateActionPromise(farcasterChannelID), + ); + }, + [createCreateOrUpdateActionPromise, dispatchActionPromise], + ); + + const createOrUpdateFarcasterChannelTagStatus = useSelector( + createOrUpdateFarcasterChannelTagStatusSelector, + ); + const isLoading = createOrUpdateFarcasterChannelTagStatus === 'loading'; + + return { + createTag, + isLoading, + }; +} + const deleteFarcasterChannelTagStatusSelector = createLoadingStatusSelector( deleteFarcasterChannelTagActionTypes, ); @@ -65,4 +117,8 @@ }; } -export { farcasterChannelTagBlobHash, useRemoveFarcasterChannelTag }; +export { + farcasterChannelTagBlobHash, + useCreateFarcasterChannelTag, + useRemoveFarcasterChannelTag, +}; diff --git a/native/community-settings/tag-farcaster-channel/tag-channel-button.react.js b/native/community-settings/tag-farcaster-channel/tag-channel-button.react.js --- a/native/community-settings/tag-farcaster-channel/tag-channel-button.react.js +++ b/native/community-settings/tag-farcaster-channel/tag-channel-button.react.js @@ -7,25 +7,17 @@ import { Text, View, Platform, ActivityIndicator } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { - createOrUpdateFarcasterChannelTagActionTypes, - useCreateOrUpdateFarcasterChannelTag, -} from 'lib/actions/community-actions.js'; import { NeynarClientContext } from 'lib/components/neynar-client-provider.react.js'; -import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; +import { useCreateFarcasterChannelTag } from 'lib/shared/community-utils.js'; import type { NeynarChannel } from 'lib/types/farcaster-types.js'; import type { SetState } from 'lib/types/hook-types.js'; import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js'; -import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import Button from '../../components/button.react.js'; import { TagFarcasterChannelByNameRouteName } from '../../navigation/route-names.js'; import { useSelector } from '../../redux/redux-utils.js'; import { useStyles, useColors } from '../../themes/colors.js'; -const createOrUpdateFarcasterChannelTagStatusSelector = - createLoadingStatusSelector(createOrUpdateFarcasterChannelTagActionTypes); - type Props = { +communityID: string, +setError: SetState, @@ -67,24 +59,9 @@ const insets = useSafeAreaInsets(); - const dispatchActionPromise = useDispatchActionPromise(); - - const createOrUpdateFarcasterChannelTag = - useCreateOrUpdateFarcasterChannelTag(); - - const createCreateOrUpdateActionPromise = React.useCallback( - async (channelID: string) => { - try { - return await createOrUpdateFarcasterChannelTag({ - commCommunityID: communityID, - farcasterChannelID: channelID, - }); - } catch (e) { - setError(e.message); - throw e; - } - }, - [communityID, createOrUpdateFarcasterChannelTag, setError], + const { createTag, isLoading } = useCreateFarcasterChannelTag( + communityID, + setError, ); const onOptionSelected = React.useCallback( @@ -111,19 +88,9 @@ const channel = channelOptions[selectedIndex]; - void dispatchActionPromise( - createOrUpdateFarcasterChannelTagActionTypes, - createCreateOrUpdateActionPromise(channel.id), - ); + createTag(channel.id); }, - [ - channelOptions, - communityID, - createCreateOrUpdateActionPromise, - dispatchActionPromise, - navigate, - setError, - ], + [channelOptions, communityID, createTag, navigate, setError], ); const onPressTag = React.useCallback(() => { @@ -158,32 +125,18 @@ showActionSheetWithOptions, ]); - const createOrUpdateFarcasterChannelTagStatus = useSelector( - createOrUpdateFarcasterChannelTagStatusSelector, - ); - const isLoadingCreateOrUpdateFarcasterChannelTag = - createOrUpdateFarcasterChannelTagStatus === 'loading'; - const buttonContent = React.useMemo(() => { - if (isLoadingCreateOrUpdateFarcasterChannelTag) { + if (isLoading) { return ( ); } return Tag channel; - }, [ - colors.panelForegroundLabel, - isLoadingCreateOrUpdateFarcasterChannelTag, - styles.buttonText, - ]); + }, [colors.panelForegroundLabel, isLoading, styles.buttonText]); return ( - );