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,87 @@ +// @flow + +import { useNavigation } from '@react-navigation/native'; +import * as React from 'react'; + +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 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 { DirectoryPromptBottomSheetRouteName } from '../navigation/route-names.js'; +import { useSelector } from '../redux/redux-utils.js'; +import { useOnFirstLaunchEffect } from '../utils/hooks.js'; + +function DisplayCommunityDirectoryPromptHandler(): React.Node { + const loggedIn = useIsLoggedInToIdentityAndAuthoritativeKeyserver(); + const lifecycleState = useSelector(state => state.lifecycleState); + const isActive = lifecycleState !== 'background'; + const fid = useCurrentUserFID(); + const communityInfos: CommunityInfos = useSelector( + state => state.communityStore.communityInfos, + ); + + const prevLifecycleStateRef = React.useRef(); + const [foregroundCount, setForegroundCount] = React.useState(0); + + React.useEffect(() => { + if ( + prevLifecycleStateRef.current === 'background' && + lifecycleState === 'active' + ) { + setForegroundCount(prev => prev + 1); + } + prevLifecycleStateRef.current = lifecycleState; + }, [lifecycleState]); + + const prevCanQueryRef = React.useRef(); + const canQuery = isActive && loggedIn; + + if (canQuery === prevCanQueryRef.current) { + return null; + } + prevCanQueryRef.current = canQuery; + + if ( + !loggedIn || + !isActive || + fid !== null || + Object.keys(communityInfos).length > 3 || + foregroundCount < 1 + ) { + return null; + } + + return ; +} + +function DisplayCommunityDirectoryPromptHandlerInner(): React.Node { + const { navigate } = useNavigation(); + const dispatchActionPromise = useDispatchActionPromise(); + const fetchPromise = useLegacyAshoatKeyserverCall( + fetchAllCommunityInfosWithNames, + ); + + const effect = React.useCallback(async () => { + void dispatchActionPromise( + fetchAllCommunityInfosWithNamesActionTypes, + fetchPromise(), + ); + const response = await fetchPromise(); + const fetchedCommunities = response.allCommunityInfosWithNames; + + navigate<'DirectoryPromptBottomSheet'>({ + name: DirectoryPromptBottomSheetRouteName, + params: { communities: fetchedCommunities }, + }); + }, [dispatchActionPromise, fetchPromise, navigate]); + + useOnFirstLaunchEffect('JOIN_COMMUNITY_ALERT', effect); +} + +export default DisplayCommunityDirectoryPromptHandler; diff --git a/native/root.react.js b/native/root.react.js --- a/native/root.react.js +++ b/native/root.react.js @@ -59,6 +59,7 @@ import { AutoJoinCommunityHandler } from './components/auto-join-community-handler.react.js'; import BackgroundIdentityLoginHandler from './components/background-identity-login-handler.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'; @@ -325,6 +326,7 @@ +