diff --git a/lib/utils/farcaster-utils.js b/lib/utils/farcaster-utils.js --- a/lib/utils/farcaster-utils.js +++ b/lib/utils/farcaster-utils.js @@ -3,7 +3,10 @@ import invariant from 'invariant'; import * as React from 'react'; -import { setSyncedMetadataEntryActionType } from '../actions/synced-metadata-actions.js'; +import { + setSyncedMetadataEntryActionType, + clearSyncedMetadataEntryActionType, +} from '../actions/synced-metadata-actions.js'; import { IdentityClientContext } from '../shared/identity-client-context.js'; import { syncedMetadataNames } from '../types/synced-metadata-types.js'; import { useSelector, useDispatch } from '../utils/redux-utils.js'; @@ -42,4 +45,25 @@ ); } -export { useCurrentUserFID, useLinkFID }; +function useUnlinkFID(): () => Promise { + const identityClientContext = React.useContext(IdentityClientContext); + invariant(identityClientContext, 'identityClientContext should be set'); + + const { identityClient } = identityClientContext; + const { unlinkFarcasterAccount } = identityClient; + + const dispatch = useDispatch(); + + return React.useCallback(async () => { + await unlinkFarcasterAccount(); + + dispatch({ + type: clearSyncedMetadataEntryActionType, + payload: { + name: syncedMetadataNames.CURRENT_USER_FID, + }, + }); + }, [dispatch, unlinkFarcasterAccount]); +} + +export { useCurrentUserFID, useLinkFID, useUnlinkFID }; diff --git a/native/profile/farcaster-account-settings.react.js b/native/profile/farcaster-account-settings.react.js --- a/native/profile/farcaster-account-settings.react.js +++ b/native/profile/farcaster-account-settings.react.js @@ -1,12 +1,9 @@ // @flow import * as React from 'react'; -import { View } from 'react-native'; +import { View, Alert } from 'react-native'; -import { clearSyncedMetadataEntryActionType } from 'lib/actions/synced-metadata-actions.js'; -import { syncedMetadataNames } from 'lib/types/synced-metadata-types.js'; -import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js'; -import { useDispatch } from 'lib/utils/redux-utils.js'; +import { useCurrentUserFID, useUnlinkFID } from 'lib/utils/farcaster-utils.js'; import type { ProfileNavigationProp } from './profile.react.js'; import RegistrationButton from '../account/registration/registration-button.react.js'; @@ -15,6 +12,7 @@ import type { FarcasterWebViewState } from '../components/farcaster-web-view.react.js'; import type { NavigationRoute } from '../navigation/route-names.js'; import { useStyles } from '../themes/colors.js'; +import { UnknownErrorAlertDetails } from '../utils/alert-messages.js'; import { useTryLinkFID } from '../utils/farcaster-utils.js'; type Props = { @@ -24,20 +22,27 @@ // eslint-disable-next-line no-unused-vars function FarcasterAccountSettings(props: Props): React.Node { - const dispatch = useDispatch(); - const fid = useCurrentUserFID(); const styles = useStyles(unboundStyles); - const onPressDisconnect = React.useCallback(() => { - dispatch({ - type: clearSyncedMetadataEntryActionType, - payload: { - name: syncedMetadataNames.CURRENT_USER_FID, - }, - }); - }, [dispatch]); + const [isLoadingUnlinkFID, setIsLoadingUnlinkFID] = React.useState(false); + + const unlinkFID = useUnlinkFID(); + + const onPressDisconnect = React.useCallback(async () => { + setIsLoadingUnlinkFID(true); + try { + await unlinkFID(); + } catch { + Alert.alert( + UnknownErrorAlertDetails.title, + UnknownErrorAlertDetails.message, + ); + } finally { + setIsLoadingUnlinkFID(false); + } + }, [unlinkFID]); const [webViewState, setWebViewState] = React.useState('closed'); @@ -64,6 +69,8 @@ setWebViewState('opening'); }, []); + const disconnectButtonVariant = isLoadingUnlinkFID ? 'loading' : 'outline'; + const connectButtonVariant = isLoadingLinkFID ? 'loading' : 'enabled'; const button = React.useMemo(() => { @@ -72,7 +79,7 @@ ); } @@ -84,7 +91,13 @@ variant={connectButtonVariant} /> ); - }, [connectButtonVariant, fid, onPressConnectFarcaster, onPressDisconnect]); + }, [ + connectButtonVariant, + disconnectButtonVariant, + fid, + onPressConnectFarcaster, + onPressDisconnect, + ]); const farcasterPromptTextType = fid ? 'disconnect' : 'optional'; const farcasterAccountSettings = React.useMemo(