Page MenuHomePhabricator

D11863.id40140.diff
No OneTemporary

D11863.id40140.diff

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
@@ -1,7 +1,12 @@
// @flow
+import invariant from 'invariant';
+import * as React from 'react';
+
+import { setSyncedMetadataEntryActionType } from '../actions/synced-metadata-actions.js';
+import { IdentityClientContext } from '../shared/identity-client-context.js';
import { syncedMetadataNames } from '../types/synced-metadata-types.js';
-import { useSelector } from '../utils/redux-utils.js';
+import { useSelector, useDispatch } from '../utils/redux-utils.js';
function useCurrentUserFID(): ?string {
return useSelector(
@@ -12,4 +17,29 @@
);
}
-export { useCurrentUserFID };
+function useLinkFID(): (fid: string) => Promise<void> {
+ const identityClientContext = React.useContext(IdentityClientContext);
+ invariant(identityClientContext, 'identityClientContext should be set');
+
+ const { identityClient } = identityClientContext;
+ const { linkFarcasterAccount } = identityClient;
+
+ const dispatch = useDispatch();
+
+ return React.useCallback(
+ async (fid: string) => {
+ await linkFarcasterAccount(fid);
+
+ dispatch({
+ type: setSyncedMetadataEntryActionType,
+ payload: {
+ name: syncedMetadataNames.CURRENT_USER_FID,
+ data: fid,
+ },
+ });
+ },
+ [dispatch, linkFarcasterAccount],
+ );
+}
+
+export { useCurrentUserFID, useLinkFID };
diff --git a/native/components/connect-farcaster-bottom-sheet.react.js b/native/components/connect-farcaster-bottom-sheet.react.js
--- a/native/components/connect-farcaster-bottom-sheet.react.js
+++ b/native/components/connect-farcaster-bottom-sheet.react.js
@@ -5,11 +5,8 @@
import { View, StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { setSyncedMetadataEntryActionType } from 'lib/actions/synced-metadata-actions.js';
import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.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 FarcasterPrompt from './farcaster-prompt.react.js';
import FarcasterWebView, {
@@ -20,6 +17,7 @@
import BottomSheet from '../bottom-sheet/bottom-sheet.react.js';
import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
import type { NavigationRoute } from '../navigation/route-names.js';
+import { useTryLinkFID } from '../utils/farcaster-utils.js';
const bottomSheetPaddingTop = 32;
const farcasterPromptHeight = 350;
@@ -34,25 +32,30 @@
function ConnectFarcasterBottomSheet(props: Props): React.Node {
const { navigation } = props;
- const dispatch = useDispatch();
+ const { goBack } = navigation;
+
+ const [webViewState, setWebViewState] =
+ React.useState<FarcasterWebViewState>('closed');
+
+ const [isLoadingLinkFID, setIsLoadingLinkFID] = React.useState(false);
const fid = useCurrentUserFID();
+ const tryLinkFID = useTryLinkFID();
+
const onSuccess = React.useCallback(
- (newFID: string) => {
- dispatch({
- type: setSyncedMetadataEntryActionType,
- payload: {
- name: syncedMetadataNames.CURRENT_USER_FID,
- data: newFID,
- },
- });
+ async (newFID: string) => {
+ setWebViewState('closed');
+
+ try {
+ await tryLinkFID(newFID);
+ } finally {
+ setIsLoadingLinkFID(false);
+ }
},
- [dispatch],
+ [tryLinkFID],
);
- const { goBack } = navigation;
-
const bottomSheetRef = React.useRef(null);
const bottomSheetContext = React.useContext(BottomSheetContext);
@@ -71,9 +74,6 @@
);
}, [insets.bottom, setContentHeight]);
- const [webViewState, setWebViewState] =
- React.useState<FarcasterWebViewState>('closed');
-
const isAppForegrounded = useIsAppForegrounded();
React.useEffect(() => {
@@ -83,11 +83,11 @@
}, [fid, isAppForegrounded]);
const onPressConnect = React.useCallback(() => {
+ setIsLoadingLinkFID(true);
setWebViewState('opening');
}, []);
- const connectButtonVariant =
- webViewState === 'opening' ? 'loading' : 'enabled';
+ const connectButtonVariant = isLoadingLinkFID ? 'loading' : 'enabled';
const connectFarcasterBottomSheet = React.useMemo(
() => (
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
@@ -3,10 +3,7 @@
import * as React from 'react';
import { View } from 'react-native';
-import {
- setSyncedMetadataEntryActionType,
- clearSyncedMetadataEntryActionType,
-} from 'lib/actions/synced-metadata-actions.js';
+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';
@@ -18,6 +15,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 { useTryLinkFID } from '../utils/farcaster-utils.js';
type Props = {
+navigation: ProfileNavigationProp<'FarcasterAccountSettings'>,
@@ -44,26 +42,29 @@
const [webViewState, setWebViewState] =
React.useState<FarcasterWebViewState>('closed');
+ const [isLoadingLinkFID, setIsLoadingLinkFID] = React.useState(false);
+
+ const tryLinkFID = useTryLinkFID();
+
const onSuccess = React.useCallback(
- (newFID: string) => {
+ async (newFID: string) => {
setWebViewState('closed');
- dispatch({
- type: setSyncedMetadataEntryActionType,
- payload: {
- name: syncedMetadataNames.CURRENT_USER_FID,
- data: newFID,
- },
- });
+
+ try {
+ await tryLinkFID(newFID);
+ } finally {
+ setIsLoadingLinkFID(false);
+ }
},
- [dispatch],
+ [tryLinkFID],
);
const onPressConnectFarcaster = React.useCallback(() => {
+ setIsLoadingLinkFID(true);
setWebViewState('opening');
}, []);
- const connectButtonVariant =
- webViewState === 'opening' ? 'loading' : 'enabled';
+ const connectButtonVariant = isLoadingLinkFID ? 'loading' : 'enabled';
const button = React.useMemo(() => {
if (fid) {
diff --git a/native/utils/farcaster-utils.js b/native/utils/farcaster-utils.js
new file mode 100644
--- /dev/null
+++ b/native/utils/farcaster-utils.js
@@ -0,0 +1,42 @@
+// @flow
+
+import * as React from 'react';
+import { Alert } from 'react-native';
+
+import { getMessageForException } from 'lib/utils/errors.js';
+import { useLinkFID } from 'lib/utils/farcaster-utils.js';
+
+import {
+ getFarcasterAccountAlreadyLinkedAlertDetails,
+ UnknownErrorAlertDetails,
+} from './alert-messages.js';
+
+function useTryLinkFID(): (newFid: string) => Promise<void> {
+ const linkFID = useLinkFID();
+
+ return React.useCallback(
+ async (newFID: string) => {
+ try {
+ await linkFID(newFID);
+ } catch (e) {
+ if (
+ getMessageForException(e) ===
+ 'farcaster ID already associated with different user'
+ ) {
+ const { title, message } =
+ getFarcasterAccountAlreadyLinkedAlertDetails();
+
+ Alert.alert(title, message);
+ } else {
+ Alert.alert(
+ UnknownErrorAlertDetails.title,
+ UnknownErrorAlertDetails.message,
+ );
+ }
+ }
+ },
+ [linkFID],
+ );
+}
+
+export { useTryLinkFID };

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 2, 6:14 PM (21 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2608511
Default Alt Text
D11863.id40140.diff (7 KB)

Event Timeline