diff --git a/lib/types/alert-types.js b/lib/types/alert-types.js --- a/lib/types/alert-types.js +++ b/lib/types/alert-types.js @@ -4,6 +4,7 @@ NOTIF_PERMISSION: 'notif-permission', CONNECT_FARCASTER: 'connect-farcaster', SIWE_BACKUP_MESSAGE: 'siwe-backup-message', + DISPLAY_DIRECTORY_PROMPT: 'display-directory-prompt', }); type AlertType = $Values<typeof alertTypes>; @@ -36,6 +37,7 @@ [alertTypes.NOTIF_PERMISSION]: defaultAlertInfo, [alertTypes.CONNECT_FARCASTER]: defaultAlertInfo, [alertTypes.SIWE_BACKUP_MESSAGE]: defaultAlertInfo, + [alertTypes.DISPLAY_DIRECTORY_PROMPT]: defaultAlertInfo, }); const securityUpdateLogoutText: string = diff --git a/native/components/display-community-directory-prompt.react.js b/native/components/display-community-directory-prompt.react.js new file mode 100644 --- /dev/null +++ b/native/components/display-community-directory-prompt.react.js @@ -0,0 +1,104 @@ +// @flow + +import { useNavigation } from '@react-navigation/native'; +import * as React from 'react'; + +import { recordAlertActionType } from 'lib/actions/alert-actions.js'; +import { + fetchAllCommunityInfosWithNamesActionTypes, + fetchAllCommunityInfosWithNames, +} from 'lib/actions/community-actions.js'; +import { useIsLoggedInToIdentityAndAuthoritativeKeyserver } from 'lib/hooks/account-hooks.js'; +import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; +import { viewerIsMember } from 'lib/shared/thread-utils.js'; +import { + alertTypes, + type RecordAlertActionPayload, +} from 'lib/types/alert-types.js'; +import type { CommunityInfos } from 'lib/types/community-types.js'; +import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js'; +import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; +import { useDispatch } from 'lib/utils/redux-utils.js'; + +import { useCurrentLeafRouteName } from '../navigation/nav-selectors.js'; +import { + DirectoryPromptBottomSheetRouteName, + HomeChatThreadListRouteName, +} from '../navigation/route-names.js'; +import { useSelector } from '../redux/redux-utils.js'; +import { showCommunityDirectory } from '../utils/directory-utils.js'; + +function DisplayCommunityDirectoryPromptHandler(): React.Node { + const loggedIn = useIsLoggedInToIdentityAndAuthoritativeKeyserver(); + const isActive = useSelector(state => state.lifecycleState !== 'background'); + const fid = useCurrentUserFID(); + const communityInfos: CommunityInfos = useSelector( + state => state.communityStore.communityInfos, + ); + const coldStartCount = useSelector(state => state.alertStore.coldStartCount); + const displayDirectoryPromptAlertInfo = useSelector( + state => state.alertStore.alertInfos[alertTypes.DISPLAY_DIRECTORY_PROMPT], + ); + const currentRoute = useCurrentLeafRouteName(); + + if ( + !showCommunityDirectory || + !loggedIn || + !isActive || + fid !== null || + Object.keys(communityInfos).length > 4 || + coldStartCount < 2 || + displayDirectoryPromptAlertInfo.totalAlerts > 0 || + currentRoute !== HomeChatThreadListRouteName + ) { + return null; + } + + return <DisplayCommunityDirectoryPromptHandlerInner />; +} + +function DisplayCommunityDirectoryPromptHandlerInner(): React.Node { + const { navigate } = useNavigation(); + const dispatch = useDispatch(); + const dispatchActionPromise = useDispatchActionPromise(); + const hasShownDirectoryPrompt = React.useRef(false); + const fetchPromise = useLegacyAshoatKeyserverCall( + fetchAllCommunityInfosWithNames, + )(); + + React.useEffect(() => { + if (hasShownDirectoryPrompt.current) { + return; + } + hasShownDirectoryPrompt.current = true; + + void dispatchActionPromise( + fetchAllCommunityInfosWithNamesActionTypes, + fetchPromise, + ); + + void (async () => { + const response = await fetchPromise; + const fetchedCommunities = response.allCommunityInfosWithNames.filter( + community => !viewerIsMember(community.threadInfo), + ); + + navigate<'DirectoryPromptBottomSheet'>({ + name: DirectoryPromptBottomSheetRouteName, + params: { communities: fetchedCommunities }, + }); + + const payload: RecordAlertActionPayload = { + alertType: alertTypes.DISPLAY_DIRECTORY_PROMPT, + time: Date.now(), + }; + + dispatch({ + type: recordAlertActionType, + payload, + }); + })(); + }, [dispatch, dispatchActionPromise, fetchPromise, navigate]); +} + +export default DisplayCommunityDirectoryPromptHandler; diff --git a/native/navigation/community-drawer-content.react.js b/native/navigation/community-drawer-content.react.js --- a/native/navigation/community-drawer-content.react.js +++ b/native/navigation/community-drawer-content.react.js @@ -30,7 +30,6 @@ import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import CommunityDrawerItem from './community-drawer-item.react.js'; -import { showCommunityDirectory } from './root-navigator.react.js'; import { CommunityCreationRouteName, CommunityJoinerModalRouteName, @@ -40,6 +39,7 @@ import { useSelector } from '../redux/redux-utils.js'; import { useStyles } from '../themes/colors.js'; import Alert from '../utils/alert.js'; +import { showCommunityDirectory } from '../utils/directory-utils.js'; import { flattenDrawerItemsData, filterOutThreadAndDescendantIDs, diff --git a/native/navigation/root-navigator.react.js b/native/navigation/root-navigator.react.js --- a/native/navigation/root-navigator.react.js +++ b/native/navigation/root-navigator.react.js @@ -84,8 +84,6 @@ import RolesNavigator from '../roles/roles-navigator.react.js'; import UserProfileBottomSheetNavigator from '../user-profile/user-profile-bottom-sheet-navigator.react.js'; -export const showCommunityDirectory = __DEV__; - enableScreens(); export type RootNavigationHelpers<ParamList: ParamListBase = ParamListBase> = { diff --git a/native/root.react.js b/native/root.react.js --- a/native/root.react.js +++ b/native/root.react.js @@ -61,6 +61,7 @@ import BackgroundIdentityLoginHandler from './components/background-identity-login-handler.react.js'; import ColdStartTracker from './components/cold-start-tracker.react.js'; import ConnectFarcasterAlertHandler from './components/connect-farcaster-alert-handler.react.js'; +import DisplayCommunityDirectoryPromptHandler from './components/display-community-directory-prompt.react.js'; import DMActivityHandler from './components/dm-activity-handler.react.js'; import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js'; import { NUXTipsContextProvider } from './components/nux-tips-context.react.js'; @@ -328,6 +329,7 @@ </ChatContextProvider> <NavigationHandler /> <PersistedStateGate> + <DisplayCommunityDirectoryPromptHandler /> <FarcasterDataHandler> <ConnectFarcasterAlertHandler /> </FarcasterDataHandler> diff --git a/native/utils/directory-utils.js b/native/utils/directory-utils.js new file mode 100644 --- /dev/null +++ b/native/utils/directory-utils.js @@ -0,0 +1,3 @@ +// @flow + +export const showCommunityDirectory = false;