diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js --- a/lib/shared/search-utils.js +++ b/lib/shared/search-utils.js @@ -49,7 +49,6 @@ import { values } from '../utils/objects.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useSelector } from '../utils/redux-utils.js'; -import { supportsFarcasterDCs } from '../utils/services-utils.js'; const notFriendNotice = 'not friend'; @@ -113,6 +112,7 @@ inputParentThreadInfo, inputCommunityThreadInfo, threadType, + isFarcasterDCsIntegrationEnabled, }: { +text: string, +userInfos: { +[id: string]: AccountUserInfo }, @@ -122,6 +122,7 @@ +inputParentThreadInfo?: ?ThreadInfo, +inputCommunityThreadInfo?: ?ThreadInfo, +threadType?: ?ThreadType, + +isFarcasterDCsIntegrationEnabled?: boolean, }): UserListItem[] { const memoizedUserInfos = React.useMemo(() => values(userInfos), [userInfos]); const searchIndex: SearchIndex = useUserSearchIndex(memoizedUserInfos); @@ -286,7 +287,7 @@ let notice, alert; const username = result.username; const isFarcasterUser = - supportsFarcasterDCs && !!extractFIDFromUserID(result.id); + isFarcasterDCsIntegrationEnabled && !!extractFIDFromUserID(result.id); if ( relationshipStatus && relationshipBlockedInEitherDirection(relationshipStatus) @@ -345,6 +346,7 @@ parentThreadInfo, threadType, viewerID, + isFarcasterDCsIntegrationEnabled, ]); return sortedMembers; diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js --- a/lib/shared/thread-utils.js +++ b/lib/shared/thread-utils.js @@ -116,7 +116,7 @@ import { entries, values } from '../utils/objects.js'; import { useSelector } from '../utils/redux-utils.js'; import { userSurfacedPermissionsFromRolePermissions } from '../utils/role-utils.js'; -import { supportsFarcasterDCs } from '../utils/services-utils.js'; +import { useIsFarcasterDCsIntegrationEnabled } from '../utils/services-utils.js'; import { firstLine } from '../utils/string-utils.js'; import { pendingThreadIDRegex, @@ -1132,6 +1132,8 @@ function useExistingThreadInfoFinder( baseThreadInfo: ?ThreadInfo, ): ExistingThreadInfoFinder { + const isFarcasterDCsIntegrationEnabled = + useIsFarcasterDCsIntegrationEnabled(); const threadInfos = useSelector(threadInfoSelector); const loggedInUserInfo = useLoggedInUserInfo(); @@ -1188,7 +1190,10 @@ } let protocol: ThreadProtocol = keyserverThreadProtocol; - if (params.allUsersSupportFarcasterThreads && supportsFarcasterDCs) { + if ( + params.allUsersSupportFarcasterThreads && + isFarcasterDCsIntegrationEnabled + ) { protocol = farcasterThreadProtocol; } else if (params.allUsersSupportThickThreads) { protocol = dmThreadProtocol; @@ -1203,7 +1208,13 @@ ], }); }, - [baseThreadInfo, threadInfos, loggedInUserInfo, pendingToRealizedThreadIDs], + [ + baseThreadInfo, + threadInfos, + loggedInUserInfo, + pendingToRealizedThreadIDs, + isFarcasterDCsIntegrationEnabled, + ], ); } diff --git a/lib/shared/threads/protocols/thread-protocols.js b/lib/shared/threads/protocols/thread-protocols.js --- a/lib/shared/threads/protocols/thread-protocols.js +++ b/lib/shared/threads/protocols/thread-protocols.js @@ -5,14 +5,14 @@ import { keyserverThreadProtocol } from './keyserver-thread-protocol.js'; import type { RawThreadInfo } from '../../../types/minimally-encoded-thread-permissions-types.js'; import { type LegacyRawThreadInfo } from '../../../types/thread-types.js'; -import { supportsFarcasterDCs } from '../../../utils/services-utils.js'; import { type ThreadProtocol } from '../thread-spec.js'; import { threadSpecs } from '../thread-specs.js'; -const protocols = (): $ReadOnlyArray> => - supportsFarcasterDCs - ? [farcasterThreadProtocol, dmThreadProtocol, keyserverThreadProtocol] - : [dmThreadProtocol, keyserverThreadProtocol]; +const protocols = (): $ReadOnlyArray> => [ + farcasterThreadProtocol, + dmThreadProtocol, + keyserverThreadProtocol, +]; function getProtocolByThreadID(threadID: string): ?ThreadProtocol { return protocols().find(p => p.threadIDMatchesProtocol(threadID)); diff --git a/lib/utils/services-utils.js b/lib/utils/services-utils.js --- a/lib/utils/services-utils.js +++ b/lib/utils/services-utils.js @@ -2,8 +2,10 @@ import base64 from 'base-64'; +import { getConfig } from './config.js'; import { getMessageForException } from './errors.js'; import type { AuthMetadata } from '../shared/identity-client-context.js'; +import { useIsCurrentUserStaff } from '../shared/staff-utils.js'; // If this is true, then the app is able to support multiple keyservers. This // requires the use of Tunnelbroker and the backup service to persist and sync @@ -14,7 +16,13 @@ // an authoritative keyserver for things like DMs. const relyingOnAuthoritativeKeyserver = true; -const supportsFarcasterDCs = false; +function useIsFarcasterDCsIntegrationEnabled(): boolean { + const isCurrentUserStaff = useIsCurrentUserStaff(); + if (getConfig().isStaffRelease) { + return true; + } + return isCurrentUserStaff; +} // If this returns true, then we're using the login 2.0, which means that a user // can either restore an account (primary login) or log in using the QR code @@ -74,5 +82,5 @@ errorMessageIsInvalidCSAT, fullBackupSupportEnabled, useFullBackupSupportEnabled, - supportsFarcasterDCs, + useIsFarcasterDCsIntegrationEnabled, }; diff --git a/native/account/registration/connect-farcaster.react.js b/native/account/registration/connect-farcaster.react.js --- a/native/account/registration/connect-farcaster.react.js +++ b/native/account/registration/connect-farcaster.react.js @@ -7,7 +7,7 @@ import { IdentityClientContext } from 'lib/shared/identity-client-context.js'; import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.js'; import type { BaseFCAvatarInfo } from 'lib/utils/farcaster-helpers.js'; -import { supportsFarcasterDCs } from 'lib/utils/services-utils.js'; +import { useIsFarcasterDCsIntegrationEnabled } from 'lib/utils/services-utils.js'; import type { AuthNavigationProp } from './auth-navigator.react.js'; import { siweNonceExpired } from './ethereum-utils.js'; @@ -49,6 +49,9 @@ const { navigate } = navigation; const userSelections = route.params?.userSelections; + const isFarcasterDCsIntegrationEnabled = + useIsFarcasterDCsIntegrationEnabled(); + const registrationContext = React.useContext(RegistrationContext); invariant(registrationContext, 'registrationContext should be set'); const { @@ -66,7 +69,7 @@ (fid?: ?string, farcasterAvatarURL: ?string) => { setWebViewState('closed'); - if (fid && supportsFarcasterDCs) { + if (fid && isFarcasterDCsIntegrationEnabled) { navigate<'ConnectFarcasterDCs'>({ name: 'ConnectFarcasterDCs', params: { @@ -130,6 +133,7 @@ ethereumAccount, userSelections, setCachedSelections, + isFarcasterDCsIntegrationEnabled, ], ); diff --git a/native/chat/message-list-container.react.js b/native/chat/message-list-container.react.js --- a/native/chat/message-list-container.react.js +++ b/native/chat/message-list-container.react.js @@ -28,7 +28,7 @@ import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import type { AccountUserInfo, UserListItem } from 'lib/types/user-types.js'; import { pinnedMessageCountText } from 'lib/utils/message-pinning-utils.js'; -import { supportsFarcasterDCs } from 'lib/utils/services-utils.js'; +import { useIsFarcasterDCsIntegrationEnabled } from 'lib/utils/services-utils.js'; import { type MessagesMeasurer, useHeightMeasurer } from './chat-context.js'; import { ChatInputBar } from './chat-input-bar.react.js'; @@ -272,6 +272,7 @@ >([]); const otherUserInfos = useSelector(userInfoSelectorForPotentialMembers); + const supportsFarcasterDCs = useIsFarcasterDCsIntegrationEnabled(); const serverSearchResults = useSearchUsers(usernameInputText, { searchFarcaster: supportsFarcasterDCs, diff --git a/native/chat/message-list-thread-search.react.js b/native/chat/message-list-thread-search.react.js --- a/native/chat/message-list-thread-search.react.js +++ b/native/chat/message-list-thread-search.react.js @@ -7,7 +7,7 @@ import { extractFIDFromUserID } from 'lib/shared/id-utils.js'; import { notFriendNotice } from 'lib/shared/search-utils.js'; import type { AccountUserInfo, UserListItem } from 'lib/types/user-types.js'; -import { supportsFarcasterDCs } from 'lib/utils/services-utils.js'; +import { useIsFarcasterDCsIntegrationEnabled } from 'lib/utils/services-utils.js'; import { createTagInput } from '../components/tag-input.react.js'; import UserList from '../components/user-list.react.js'; @@ -41,6 +41,7 @@ userSearchResults, }) { const styles = useStyles(unboundStyles); + const supportsFarcasterDCs = useIsFarcasterDCsIntegrationEnabled(); const [userListItems, nonFriends] = React.useMemo(() => { const nonFriendsSet = new Set(); @@ -89,6 +90,7 @@ resolveToUser, updateUsernameInput, viewerID, + supportsFarcasterDCs, ], ); 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 @@ -16,7 +16,7 @@ } 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 { useIsFarcasterDCsIntegrationEnabled } from 'lib/utils/services-utils.js'; import sleep from 'lib/utils/sleep.js'; import { ConnectFarcasterBottomSheetRouteName } from '../navigation/route-names.js'; @@ -31,6 +31,8 @@ const fid = useCurrentUserFID(); const currentUserSupportsDCs = useCurrentUserSupportsDCs(); + const isFarcasterDCsIntegrationEnabled = + useIsFarcasterDCsIntegrationEnabled(); const setLocalFID = useSetLocalFID(); @@ -50,7 +52,7 @@ shouldSkipConnectFarcasterAlert(connectFarcasterAlertInfo, fid) || connectFarcasterAlertInfo.coldStartCount < 2 || (!shouldShowForInitialConnection && !shouldShowForDCs) || - !supportsFarcasterDCs + !isFarcasterDCsIntegrationEnabled ) { return; } @@ -82,6 +84,7 @@ currentUserSupportsDCs, dispatch, fid, + isFarcasterDCsIntegrationEnabled, isActive, loggedIn, navigate, 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 @@ -10,7 +10,7 @@ useCurrentUserFID, useCurrentUserSupportsDCs, } from 'lib/utils/farcaster-utils.js'; -import { supportsFarcasterDCs } from 'lib/utils/services-utils.js'; +import { useIsFarcasterDCsIntegrationEnabled } from 'lib/utils/services-utils.js'; import FarcasterPrompt from './farcaster-prompt.react.js'; import FarcasterWebView, { @@ -46,6 +46,7 @@ const fid = useCurrentUserFID(); const currentUserSupportsDCs = useCurrentUserSupportsDCs(); + const supportsFarcasterDCs = useIsFarcasterDCsIntegrationEnabled(); const tryLinkFID = useTryLinkFID(); @@ -62,7 +63,7 @@ setIsLoadingLinkFID(false); } }, - [tryLinkFID], + [tryLinkFID, supportsFarcasterDCs], ); const bottomSheetContext = React.useContext(BottomSheetContext); @@ -87,7 +88,14 @@ setShowConnectDCs(true); } } - }, [fid, goBack, isAppForegrounded, currentUserSupportsDCs, showConnectDCs]); + }, [ + fid, + goBack, + isAppForegrounded, + currentUserSupportsDCs, + showConnectDCs, + supportsFarcasterDCs, + ]); const onPressConnect = React.useCallback(() => { setIsLoadingLinkFID(true); 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 @@ -9,7 +9,7 @@ useCurrentUserSupportsDCs, useUnlinkFID, } from 'lib/utils/farcaster-utils.js'; -import { supportsFarcasterDCs } from 'lib/utils/services-utils.js'; +import { useIsFarcasterDCsIntegrationEnabled } from 'lib/utils/services-utils.js'; import ConnectFarcasterDCs from './connect-farcaster-dcs.react.js'; import type { ProfileNavigationProp } from './profile.react.js'; @@ -32,6 +32,7 @@ function FarcasterAccountSettings(props: Props): React.Node { const fid = useCurrentUserFID(); const currentUserSupportsDCs = useCurrentUserSupportsDCs(); + const supportsFarcasterDCs = useIsFarcasterDCsIntegrationEnabled(); const styles = useStyles(unboundStyles); @@ -156,6 +157,7 @@ disconnectButtonVariant, fid, currentUserSupportsDCs, + supportsFarcasterDCs, onPressConnectFarcaster, onPressDisconnect, onPressConnectDCs, @@ -169,7 +171,7 @@ return 'disconnect_or_connect_DC'; } return 'disconnect'; - }, [fid, currentUserSupportsDCs]); + }, [fid, currentUserSupportsDCs, supportsFarcasterDCs]); return React.useMemo(() => { if (showConnectDCs) { diff --git a/native/profile/profile-screen.react.js b/native/profile/profile-screen.react.js --- a/native/profile/profile-screen.react.js +++ b/native/profile/profile-screen.react.js @@ -31,7 +31,7 @@ type DispatchActionPromise, } from 'lib/utils/redux-promise-utils.js'; import { - supportsFarcasterDCs, + useIsFarcasterDCsIntegrationEnabled, useIsRestoreFlowEnabled, } from 'lib/utils/services-utils.js'; @@ -187,6 +187,7 @@ +currentUserFID: ?string, +usingRestoreFlow: boolean, +farcasterConversationsSync: (limit: number) => Promise, + +supportsFarcasterDCs: boolean, }; class ProfileScreen extends React.PureComponent { @@ -285,7 +286,7 @@ ); } let farcaster; - if (staffCanSee && supportsFarcasterDCs) { + if (staffCanSee && this.props.supportsFarcasterDCs) { farcaster = ( <> ); }, diff --git a/web/chat/chat-thread-composer.react.js b/web/chat/chat-thread-composer.react.js --- a/web/chat/chat-thread-composer.react.js +++ b/web/chat/chat-thread-composer.react.js @@ -28,7 +28,7 @@ import { threadTypes } from 'lib/types/thread-types-enum.js'; import type { AccountUserInfo, UserListItem } from 'lib/types/user-types.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; -import { supportsFarcasterDCs } from 'lib/utils/services-utils.js'; +import { useIsFarcasterDCsIntegrationEnabled } from 'lib/utils/services-utils.js'; import css from './chat-thread-composer.css'; import UserAvatar from '../avatars/user-avatar.react.js'; @@ -69,8 +69,11 @@ [userInfoInputArray, viewerID], ); + const isFarcasterDCsIntegrationEnabled = + useIsFarcasterDCsIntegrationEnabled(); + const searchResults = useSearchUsers(usernameInputText, { - searchFarcaster: supportsFarcasterDCs, + searchFarcaster: isFarcasterDCsIntegrationEnabled, }); const auxUserInfos = useSelector(state => state.auxUserStore.auxUserInfos); @@ -81,6 +84,7 @@ auxUserInfos, excludeUserIDs, includeServerSearchUsers: searchResults, + isFarcasterDCsIntegrationEnabled, }); const userListItemsWithENSNames = useResolvableNames(userListItems); @@ -106,7 +110,7 @@ const { alert, notice, disabled, ...user } = userListItem; setUsernameInputText(''); const isFarcasterUser = - supportsFarcasterDCs && !!extractFIDFromUserID(user.id); + isFarcasterDCsIntegrationEnabled && !!extractFIDFromUserID(user.id); if ( ((!isFarcasterUser && notice === notFriendNotice) || user.id === viewerID) && @@ -164,6 +168,7 @@ existingThreadInfoFinderForCreatingThread, dispatch, pushModal, + isFarcasterDCsIntegrationEnabled, ], ); diff --git a/web/settings/account-settings.react.js b/web/settings/account-settings.react.js --- a/web/settings/account-settings.react.js +++ b/web/settings/account-settings.react.js @@ -29,7 +29,7 @@ } from 'lib/utils/crypto-utils.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import { - supportsFarcasterDCs, + useIsFarcasterDCsIntegrationEnabled, useIsRestoreFlowEnabled, } from 'lib/utils/services-utils.js'; @@ -64,6 +64,7 @@ const dispatchActionPromise = useDispatchActionPromise(); const checkIfPrimaryDevice = useCheckIfPrimaryDevice(); const usingRestoreFlow = useIsRestoreFlowEnabled(); + const supportsFarcasterDCs = useIsFarcasterDCsIntegrationEnabled(); const logOutUser = React.useCallback(async () => { // if web is primary device, we're on legacy flow const isPrimaryDevice = await checkIfPrimaryDevice();