Page MenuHomePhorge

D15148.1765126462.diff
No OneTemporary

Size
19 KB
Referenced Files
None
Subscribers
None

D15148.1765126462.diff

diff --git a/lib/components/farcaster-data-handler.react.js b/lib/components/farcaster-data-handler.react.js
--- a/lib/components/farcaster-data-handler.react.js
+++ b/lib/components/farcaster-data-handler.react.js
@@ -198,8 +198,8 @@
await neynarClient.checkIfCurrentUserFIDIsValid(fid);
if (!isCurrentUserFIDValid) {
await unlinkFID();
+ return;
}
- return;
}
if (identityFID) {
diff --git a/lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js b/lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js
--- a/lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js
+++ b/lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js
@@ -70,13 +70,13 @@
export type FarcasterConnectionUpdated = {
+type: 'FARCASTER_CONNECTION_UPDATED',
+farcasterID: ?string,
- +hasDCsToken: ?boolean,
+ +hasDCsToken: boolean,
};
export const farcasterConnectionUpdatedValidator: TInterface<FarcasterConnectionUpdated> =
tShape<FarcasterConnectionUpdated>({
type: tString(userActionsP2PMessageTypes.FARCASTER_CONNECTION_UPDATED),
farcasterID: t.maybe(t.String),
- hasDCsToken: t.maybe(t.Boolean),
+ hasDCsToken: t.Boolean,
});
export type UserActionP2PMessage =
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
@@ -21,7 +21,6 @@
const DISABLE_CONNECT_FARCASTER_ALERT = false;
const NO_FID_METADATA = 'NONE';
-const NO_DCS_SUPPORT_METADATA = 'NONE';
function useCurrentUserFID(): ?string {
// There is a distinction between null & undefined for the fid value.
@@ -42,11 +41,7 @@
return currentUserFID;
}
-function useCurrentUserSupportsDCs(): ?boolean {
- // There is a distinction between null & undefined for the fid DCs value.
- // If the fid DCs is null this means that the user has decided NOT to set
- // a Farcaster DCs association. If the fid DCs is undefined this means that
- // the user has not yet been prompted to set a Farcaster DCs association.
+function useCurrentUserSupportsDCs(): boolean {
const currentUserFIDDCs = useSelector(
state =>
state.syncedMetadataStore.syncedMetadata[
@@ -54,10 +49,6 @@
] ?? undefined,
);
- if (currentUserFIDDCs === NO_DCS_SUPPORT_METADATA) {
- return null;
- }
-
return currentUserFIDDCs === 'true';
}
@@ -96,16 +87,13 @@
);
}
-function useSetLocalCurrentUserSupportsDCs(): (connected: ?boolean) => void {
+function useSetLocalCurrentUserSupportsDCs(): (connected: boolean) => void {
const dispatch = useDispatch();
const { invalidateCacheForUser } = useUserIdentityCache();
const currentUserID = useSelector(state => state.currentUserInfo?.id);
return React.useCallback(
(connected: ?boolean) => {
- // If we're unsetting the DCs support, we should set it to
- // NO_DCS_SUPPORT_METADATA to avoid prompting the user for it again
- const connectionStatus =
- connected === null ? NO_DCS_SUPPORT_METADATA : String(connected);
+ const connectionStatus = String(connected);
dispatch({
type: setSyncedMetadataEntryActionType,
payload: {
@@ -152,7 +140,7 @@
async (fid: string) => {
await linkFarcasterAccount(fid);
setLocalFID(fid);
- await broadcastConnectionStatus(fid, null);
+ await broadcastConnectionStatus(fid, false);
},
[linkFarcasterAccount, setLocalFID, broadcastConnectionStatus],
);
@@ -199,9 +187,9 @@
return React.useCallback(async () => {
await unlinkFarcasterAccount();
- setLocalFID(null);
- setLocalDCsSupport(null);
- await broadcastConnectionStatus(null, null);
+ setLocalFID(undefined);
+ setLocalDCsSupport(false);
+ await broadcastConnectionStatus(null, false);
clearFarcasterThreads();
}, [
unlinkFarcasterAccount,
@@ -243,7 +231,7 @@
const currentUserID = useSelector(state => state.currentUserInfo?.id);
const userDevices = useSelector(getOwnPeerDevices);
return React.useCallback(
- async (farcasterID: ?string, hasDCsToken: ?boolean) => {
+ async (farcasterID: ?string, hasDCsToken: boolean) => {
if (!currentUserID) {
return;
}
@@ -304,7 +292,6 @@
export {
DISABLE_CONNECT_FARCASTER_ALERT,
NO_FID_METADATA,
- NO_DCS_SUPPORT_METADATA,
useCurrentUserFID,
useCurrentUserSupportsDCs,
useFarcasterDCsLoaded,
diff --git a/lib/utils/push-alerts.js b/lib/utils/push-alerts.js
--- a/lib/utils/push-alerts.js
+++ b/lib/utils/push-alerts.js
@@ -1,8 +1,8 @@
// @flow
+import { isDev } from './dev-utils.js';
+import { DISABLE_CONNECT_FARCASTER_ALERT } from './farcaster-utils.js';
import type { AlertInfo } from '../types/alert-types.js';
-import { isDev } from '../utils/dev-utils.js';
-import { DISABLE_CONNECT_FARCASTER_ALERT } from '../utils/farcaster-utils.js';
const msInDay = 24 * 60 * 60 * 1000;
@@ -26,7 +26,7 @@
return (
isDev ||
DISABLE_CONNECT_FARCASTER_ALERT ||
- fid !== undefined ||
+ fid === null ||
alertInfo.totalAlerts > 0
);
}
diff --git a/native/bottom-sheet/bottom-sheet.react.js b/native/bottom-sheet/bottom-sheet.react.js
--- a/native/bottom-sheet/bottom-sheet.react.js
+++ b/native/bottom-sheet/bottom-sheet.react.js
@@ -52,6 +52,8 @@
backdropComponent={BottomSheetBackdrop}
onChange={onChange}
enablePanDownToClose={true}
+ keyboardBehavior="interactive"
+ keyboardBlurBehavior="restore"
>
{children}
</GorhomBottomSheet>
diff --git a/native/components/connect-farcaster-alert-handler.react.js b/native/components/connect-farcaster-alert-handler.react.js
--- a/native/components/connect-farcaster-alert-handler.react.js
+++ b/native/components/connect-farcaster-alert-handler.react.js
@@ -11,10 +11,12 @@
} from 'lib/types/alert-types.js';
import {
useCurrentUserFID,
+ useCurrentUserSupportsDCs,
useSetLocalFID,
} from 'lib/utils/farcaster-utils.js';
import { shouldSkipConnectFarcasterAlert } from 'lib/utils/push-alerts.js';
import { useDispatch } from 'lib/utils/redux-utils.js';
+import { supportsFarcasterDCs } from 'lib/utils/services-utils.js';
import sleep from 'lib/utils/sleep.js';
import { ConnectFarcasterBottomSheetRouteName } from '../navigation/route-names.js';
@@ -28,6 +30,7 @@
const loggedIn = useIsLoggedInToIdentityAndAuthoritativeKeyserver();
const fid = useCurrentUserFID();
+ const currentUserSupportsDCs = useCurrentUserSupportsDCs();
const setLocalFID = useSetLocalFID();
@@ -38,11 +41,16 @@
const dispatch = useDispatch();
React.useEffect(() => {
+ const shouldShowForDCs = fid && !currentUserSupportsDCs;
+ const shouldShowForInitialConnection = !fid;
+
if (
!loggedIn ||
!isActive ||
shouldSkipConnectFarcasterAlert(connectFarcasterAlertInfo, fid) ||
- connectFarcasterAlertInfo.coldStartCount < 2
+ connectFarcasterAlertInfo.coldStartCount < 2 ||
+ (!shouldShowForInitialConnection && !shouldShowForDCs) ||
+ !supportsFarcasterDCs
) {
return;
}
@@ -54,7 +62,9 @@
// again. We set it here, rather than in the bottom sheet itself, to avoid
// the scenario where the user connects their Farcaster account but we
// accidentally overwrite the FID on close and set it to null.
- setLocalFID(null);
+ if (!fid) {
+ setLocalFID(null);
+ }
navigate(ConnectFarcasterBottomSheetRouteName);
const payload: RecordAlertActionPayload = {
@@ -69,6 +79,7 @@
})();
}, [
connectFarcasterAlertInfo,
+ currentUserSupportsDCs,
dispatch,
fid,
isActive,
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
@@ -6,7 +6,11 @@
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.js';
-import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js';
+import {
+ useCurrentUserFID,
+ useCurrentUserSupportsDCs,
+} from 'lib/utils/farcaster-utils.js';
+import { supportsFarcasterDCs } from 'lib/utils/services-utils.js';
import FarcasterPrompt from './farcaster-prompt.react.js';
import FarcasterWebView, {
@@ -17,6 +21,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 ConnectFarcasterDCs from '../profile/connect-farcaster-dcs.react.js';
import { useTryLinkFID } from '../utils/farcaster-utils.js';
const farcasterPromptHeight = 350;
@@ -37,8 +42,10 @@
React.useState<FarcasterWebViewState>('closed');
const [isLoadingLinkFID, setIsLoadingLinkFID] = React.useState(false);
+ const [showConnectDCs, setShowConnectDCs] = React.useState(false);
const fid = useCurrentUserFID();
+ const currentUserSupportsDCs = useCurrentUserSupportsDCs();
const tryLinkFID = useTryLinkFID();
@@ -48,6 +55,9 @@
try {
await tryLinkFID(newFID);
+ if (supportsFarcasterDCs) {
+ setShowConnectDCs(true);
+ }
} finally {
setIsLoadingLinkFID(false);
}
@@ -71,19 +81,45 @@
React.useEffect(() => {
if (fid && isAppForegrounded) {
- goBack();
+ if (currentUserSupportsDCs || !supportsFarcasterDCs) {
+ goBack();
+ } else if (supportsFarcasterDCs && !showConnectDCs) {
+ setShowConnectDCs(true);
+ }
}
- }, [fid, goBack, isAppForegrounded]);
+ }, [fid, goBack, isAppForegrounded, currentUserSupportsDCs, showConnectDCs]);
const onPressConnect = React.useCallback(() => {
setIsLoadingLinkFID(true);
setWebViewState('opening');
}, []);
+ const onConnectDCsSuccess = React.useCallback(() => {
+ setShowConnectDCs(false);
+ goBack();
+ }, [goBack]);
+
+ const onConnectDCsCancel = React.useCallback(() => {
+ setShowConnectDCs(false);
+ goBack();
+ }, [goBack]);
+
const connectButtonVariant = isLoadingLinkFID ? 'loading' : 'enabled';
- const connectFarcasterBottomSheet = React.useMemo(
- () => (
+ const connectFarcasterBottomSheet = React.useMemo(() => {
+ if (showConnectDCs) {
+ return (
+ <BottomSheet onClosed={goBack}>
+ <ConnectFarcasterDCs
+ onSuccess={onConnectDCsSuccess}
+ onCancel={onConnectDCsCancel}
+ useBottomSheetTextInput={true}
+ />
+ </BottomSheet>
+ );
+ }
+
+ return (
<BottomSheet onClosed={goBack}>
<View style={styles.container}>
<View style={styles.promptContainer}>
@@ -97,9 +133,17 @@
</View>
<FarcasterWebView onSuccess={onSuccess} webViewState={webViewState} />
</BottomSheet>
- ),
- [goBack, onPressConnect, connectButtonVariant, onSuccess, webViewState],
- );
+ );
+ }, [
+ showConnectDCs,
+ goBack,
+ onConnectDCsSuccess,
+ onConnectDCsCancel,
+ onPressConnect,
+ connectButtonVariant,
+ onSuccess,
+ webViewState,
+ ]);
return connectFarcasterBottomSheet;
}
diff --git a/native/profile/connect-farcaster-dcs.react.js b/native/profile/connect-farcaster-dcs.react.js
--- a/native/profile/connect-farcaster-dcs.react.js
+++ b/native/profile/connect-farcaster-dcs.react.js
@@ -1,5 +1,6 @@
// @flow
+import { BottomSheetTextInput } from '@gorhom/bottom-sheet';
import * as React from 'react';
import { ScrollView, View } from 'react-native';
@@ -13,19 +14,25 @@
import PrimaryButton from '../components/primary-button.react.js';
import { FarcasterAuthContextProvider } from '../farcaster-auth/farcaster-auth-context-provider.react.js';
import { useGetAuthToken } from '../farcaster-auth/farcaster-auth-utils.js';
-import { useStyles } from '../themes/colors.js';
+import {
+ useStyles,
+ useColors,
+ useKeyboardAppearance,
+} from '../themes/colors.js';
import Alert from '../utils/alert.js';
type Props = {
+onSuccess: () => void,
+onCancel: () => void,
+ +useBottomSheetTextInput?: boolean,
};
function InnerConnectFarcasterDCs(props: Props): React.Node {
- const { onSuccess, onCancel } = props;
+ const { onSuccess, onCancel, useBottomSheetTextInput = false } = props;
const [mnemonic, setMnemonic] = React.useState<?string>(null);
const [signingInProgress, setSigningInProgress] = React.useState(false);
+ const [focused, setFocused] = React.useState(false);
const scrollViewRef =
React.useRef<?React.ElementRef<typeof ScrollView>>(null);
@@ -58,6 +65,7 @@
}, []);
const onInputFocus = React.useCallback(() => {
+ setFocused(true);
// Scroll to make the input fully visible when focused
setTimeout(() => {
if (scrollViewRef.current) {
@@ -66,6 +74,10 @@
}, 100);
}, []);
+ const onInputBlur = React.useCallback(() => {
+ setFocused(false);
+ }, []);
+
let buttonVariant = 'enabled';
if (!mnemonic) {
buttonVariant = 'disabled';
@@ -74,9 +86,71 @@
}
const styles = useStyles(unboundStyles);
+ const colors = useColors();
+ const keyboardAppearance = useKeyboardAppearance();
+
+ const textInputStyle = React.useMemo(
+ () =>
+ focused
+ ? [styles.textInput, styles.focusedTextInput]
+ : [styles.textInput],
+ [focused, styles.textInput, styles.focusedTextInput],
+ );
+
+ const textInput = React.useMemo(() => {
+ if (useBottomSheetTextInput) {
+ return (
+ <BottomSheetTextInput
+ autoCapitalize="none"
+ autoComplete="off"
+ autoCorrect={false}
+ editable={!signingInProgress}
+ keyboardType="default"
+ onChangeText={onChangeMnemonicText}
+ onFocus={onInputFocus}
+ onBlur={onInputBlur}
+ onSubmitEditing={onConnect}
+ placeholder="Wallet mnemonic"
+ placeholderTextColor={colors.panelSecondaryForegroundBorder}
+ returnKeyType="go"
+ secureTextEntry={true}
+ value={mnemonic}
+ style={textInputStyle}
+ keyboardAppearance={keyboardAppearance}
+ />
+ );
+ }
+ return (
+ <RegistrationTextInput
+ autoCapitalize="none"
+ autoComplete="off"
+ autoCorrect={false}
+ editable={!signingInProgress}
+ keyboardType="default"
+ onChangeText={onChangeMnemonicText}
+ onFocus={onInputFocus}
+ onSubmitEditing={onConnect}
+ placeholder="Wallet mnemonic"
+ returnKeyType="go"
+ secureTextEntry={true}
+ value={mnemonic}
+ />
+ );
+ }, [
+ colors.panelSecondaryForegroundBorder,
+ keyboardAppearance,
+ mnemonic,
+ onChangeMnemonicText,
+ onConnect,
+ onInputBlur,
+ onInputFocus,
+ signingInProgress,
+ textInputStyle,
+ useBottomSheetTextInput,
+ ]);
return (
- <View style={styles.container}>
+ <>
<ScrollView
ref={scrollViewRef}
style={styles.scrollView}
@@ -85,22 +159,7 @@
>
<View style={styles.contentContainer}>
<FarcasterPrompt textType="connect_DC" />
- <View style={styles.inputContainer}>
- <RegistrationTextInput
- autoCapitalize="none"
- autoComplete="off"
- autoCorrect={false}
- editable={!signingInProgress}
- keyboardType="default"
- onChangeText={onChangeMnemonicText}
- onFocus={onInputFocus}
- onSubmitEditing={onConnect}
- placeholder="Wallet mnemonic"
- returnKeyType="go"
- secureTextEntry={true}
- value={mnemonic}
- />
- </View>
+ <View style={styles.inputContainer}>{textInput}</View>
</View>
</ScrollView>
<View style={styles.buttonContainer}>
@@ -111,16 +170,11 @@
/>
<PrimaryButton onPress={onCancel} label="Cancel" variant="outline" />
</View>
- </View>
+ </>
);
}
const unboundStyles = {
- container: {
- flex: 1,
- backgroundColor: 'panelBackground',
- paddingBottom: 16,
- },
scrollView: {
flex: 1,
},
@@ -138,6 +192,16 @@
marginVertical: 8,
marginHorizontal: 16,
},
+ textInput: {
+ color: 'panelForegroundLabel',
+ borderColor: 'panelSecondaryForegroundBorder',
+ borderWidth: 1,
+ borderRadius: 4,
+ padding: 12,
+ },
+ focusedTextInput: {
+ borderColor: 'panelForegroundLabel',
+ },
};
function ConnectFarcasterDCs(props: Props): React.Node {
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
@@ -174,10 +174,12 @@
return React.useMemo(() => {
if (showConnectDCs) {
return (
- <ConnectFarcasterDCs
- onSuccess={onConnectDCsSuccess}
- onCancel={onConnectDCsCancel}
- />
+ <View style={styles.farcasterContainer}>
+ <ConnectFarcasterDCs
+ onSuccess={onConnectDCsSuccess}
+ onCancel={onConnectDCsCancel}
+ />
+ </View>
);
}
@@ -203,6 +205,7 @@
showConnectDCs,
styles.buttonContainer,
styles.connectContainer,
+ styles.farcasterContainer,
styles.promptContainer,
styles.scrollViewContentContainer,
webViewState,
@@ -210,6 +213,11 @@
}
const unboundStyles = {
+ farcasterContainer: {
+ flex: 1,
+ backgroundColor: 'panelBackground',
+ paddingBottom: 16,
+ },
connectContainer: {
flex: 1,
backgroundColor: 'panelBackground',
diff --git a/native/redux/persist-constants.js b/native/redux/persist-constants.js
--- a/native/redux/persist-constants.js
+++ b/native/redux/persist-constants.js
@@ -5,6 +5,6 @@
// NOTE: renaming this constant requires updating
// `native/native_rust_library/build.rs` to correctly
// scrap Redux state version from this file.
-const storeVersion = 95;
+const storeVersion = 96;
export { rootKey, storeVersion };
diff --git a/native/redux/persist.js b/native/redux/persist.js
--- a/native/redux/persist.js
+++ b/native/redux/persist.js
@@ -1707,6 +1707,30 @@
},
};
}: MigrationFunction<NavInfo, AppState>),
+ [96]: (async (state: AppState) => {
+ const updatedAlertStore = {
+ ...state.alertStore,
+ alertInfos: {
+ ...state.alertStore.alertInfos,
+ [alertTypes.CONNECT_FARCASTER]: defaultAlertInfo,
+ },
+ };
+
+ const syncedMetadataStoreOperations: $ReadOnlyArray<ClientDBSyncedMetadataStoreOperation> =
+ [
+ createReplaceSyncedMetadataOperation(
+ syncedMetadataNames.ALERT_STORE,
+ JSON.stringify(updatedAlertStore),
+ ),
+ ];
+
+ return {
+ state,
+ ops: {
+ syncedMetadataStoreOperations,
+ },
+ };
+ }: MigrationFunction<NavInfo, AppState>),
});
const persistConfig = {
diff --git a/web/redux/persist-constants.js b/web/redux/persist-constants.js
--- a/web/redux/persist-constants.js
+++ b/web/redux/persist-constants.js
@@ -3,6 +3,6 @@
const rootKey = 'root';
const rootKeyPrefix = 'persist:';
const completeRootKey = `${rootKeyPrefix}${rootKey}`;
-const storeVersion = 95;
+const storeVersion = 96;
export { rootKey, rootKeyPrefix, completeRootKey, storeVersion };
diff --git a/web/redux/persist.js b/web/redux/persist.js
--- a/web/redux/persist.js
+++ b/web/redux/persist.js
@@ -916,6 +916,10 @@
},
};
}: MigrationFunction<WebNavInfo, AppState>),
+ [96]: (async (state: AppState) => ({
+ state,
+ ops: {},
+ }): MigrationFunction<WebNavInfo, AppState>),
};
const persistConfig: PersistConfig = {

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 7, 4:54 PM (17 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5845111
Default Alt Text
D15148.1765126462.diff (19 KB)

Event Timeline