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 @@ -35,8 +35,13 @@ return alertInfo.lastAlertTime > Date.now() - msInDay; } +function shouldSkipJoinCommunityAlert(alertInfo: AlertInfo): boolean { + return alertInfo.lastAlertTime > Date.now() - msInDay; +} + export { shouldSkipPushPermissionAlert, shouldSkipConnectFarcasterAlert, shouldSkipCreateSIWEBackupMessageAlert, + shouldSkipJoinCommunityAlert, }; diff --git a/native/components/join-community-alert-handler.react.js b/native/components/join-community-alert-handler.react.js new file mode 100644 --- /dev/null +++ b/native/components/join-community-alert-handler.react.js @@ -0,0 +1,74 @@ +// @flow + +import { useNavigation } from '@react-navigation/native'; +import * as React from 'react'; + +import { recordAlertActionType } from 'lib/actions/alert-actions.js'; +import { useIsLoggedInToIdentityAndAuthoritativeKeyserver } from 'lib/hooks/account-hooks.js'; +import { + alertTypes, + type RecordAlertActionPayload, +} from 'lib/types/alert-types.js'; +import type { CommunityInfos } from 'lib/types/community-types.js'; +import { shouldSkipJoinCommunityAlert } from 'lib/utils/push-alerts.js'; +import { useDispatch } from 'lib/utils/redux-utils.js'; +import sleep from 'lib/utils/sleep.js'; + +import { CommunityJoinerModalRouteName } from '../navigation/route-names.js'; +import { useSelector } from '../redux/redux-utils.js'; + +function JoinCommunityAlertHandler(): React.Node { + const { navigate } = useNavigation(); + + const isActive = useSelector(state => state.lifecycleState !== 'background'); + + const loggedIn = useIsLoggedInToIdentityAndAuthoritativeKeyserver(); + + const joinCommunityAlertInfo = useSelector( + state => state.alertStore.alertInfos[alertTypes.JOIN_COMMUNITY], + ); + + const communityInfos: CommunityInfos = useSelector( + state => state.communityStore.communityInfos, + ); + + const dispatch = useDispatch(); + + React.useEffect(() => { + if ( + !loggedIn || + !isActive || + shouldSkipJoinCommunityAlert(joinCommunityAlertInfo) || + Object.keys(communityInfos).length > 3 + ) { + return; + } + + void (async () => { + await sleep(1000); + + navigate(CommunityJoinerModalRouteName); + + const payload: RecordAlertActionPayload = { + alertType: alertTypes.JOIN_COMMUNITY, + time: Date.now(), + }; + + dispatch({ + type: recordAlertActionType, + payload, + }); + })(); + }, [ + communityInfos, + dispatch, + isActive, + joinCommunityAlertInfo, + loggedIn, + navigate, + ]); + + return null; +} + +export default JoinCommunityAlertHandler; diff --git a/native/root.react.js b/native/root.react.js --- a/native/root.react.js +++ b/native/root.react.js @@ -57,6 +57,7 @@ import ConnectFarcasterAlertHandler from './components/connect-farcaster-alert-handler.react.js'; import DMActivityHandler from './components/dm-activity-handler.react.js'; import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js'; +import JoinCommunityAlertHandler from './components/join-community-alert-handler.react.js'; import { NUXTipsContextProvider } from './components/nux-tips-context.react.js'; import PersistedStateGate from './components/persisted-state-gate.js'; import ReportHandler from './components/report-handler.react.js'; @@ -315,6 +316,7 @@ +