diff --git a/native/components/auto-join-community-handler.react.js b/lib/components/base-auto-join-community-handler.react.js
copy from native/components/auto-join-community-handler.react.js
copy to lib/components/base-auto-join-community-handler.react.js
--- a/native/components/auto-join-community-handler.react.js
+++ b/lib/components/base-auto-join-community-handler.react.js
@@ -4,35 +4,32 @@
import _pickBy from 'lodash/fp/pickBy.js';
import * as React from 'react';
-import { NeynarClientContext } from 'lib/components/neynar-client-provider.react.js';
-import blobService from 'lib/facts/blob-service.js';
-import { useIsLoggedInToIdentityAndAuthoritativeKeyserver } from 'lib/hooks/account-hooks.js';
-import { extractKeyserverIDFromID } from 'lib/keyserver-conn/keyserver-call-utils.js';
+import { NeynarClientContext } from '../components/neynar-client-provider.react.js';
+import blobService from '../facts/blob-service.js';
+import { useIsLoggedInToIdentityAndAuthoritativeKeyserver } from '../hooks/account-hooks.js';
+import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js';
import {
farcasterChannelTagBlobHash,
useJoinCommunity,
-} from 'lib/shared/community-utils.js';
-import type { AuthMetadata } from 'lib/shared/identity-client-context.js';
-import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
-import type { KeyserverOverride } from 'lib/shared/invite-links.js';
+} from '../shared/community-utils.js';
+import type { AuthMetadata } from '../shared/identity-client-context.js';
+import { IdentityClientContext } from '../shared/identity-client-context.js';
+import type { KeyserverOverride } from '../shared/invite-links.js';
import type {
OngoingJoinCommunityData,
JoinCommunityStep,
-} from 'lib/types/community-types.js';
-import type { CalendarQuery } from 'lib/types/entry-types.js';
-import type { SetState } from 'lib/types/hook-types.js';
-import { defaultThreadSubscription } from 'lib/types/subscription-types.js';
-import { getBlobFetchableURL } from 'lib/utils/blob-service.js';
-import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js';
-import { promiseAll } from 'lib/utils/promises.js';
+} from '../types/community-types.js';
+import type { CalendarQuery } from '../types/entry-types.js';
+import type { SetState } from '../types/hook-types.js';
+import { defaultThreadSubscription } from '../types/subscription-types.js';
+import { getBlobFetchableURL } from '../utils/blob-service.js';
+import { useCurrentUserFID } from '../utils/farcaster-utils.js';
+import { promiseAll } from '../utils/promises.js';
+import { useSelector } from '../utils/redux-utils.js';
import {
usingCommServicesAccessToken,
createDefaultHTTPRequestHeaders,
-} from 'lib/utils/services-utils.js';
-
-import { nonThreadCalendarQuery } from '../navigation/nav-selectors.js';
-import { NavContext } from '../navigation/navigation-context.js';
-import { useSelector } from '../redux/redux-utils.js';
+} from '../utils/services-utils.js';
type CommunityToAutoJoin = {
+communityID: string,
@@ -44,7 +41,13 @@
+[communityID: string]: CommunityToAutoJoin,
};
-function AutoJoinCommunityHandler(): React.Node {
+type Props = {
+ +calendarQuery: () => CalendarQuery,
+};
+
+function BaseAutoJoinCommunityHandler(props: Props): React.Node {
+ const { calendarQuery } = props;
+
const isActive = useSelector(state => state.lifecycleState !== 'background');
const loggedIn = useIsLoggedInToIdentityAndAuthoritativeKeyserver();
@@ -53,19 +56,10 @@
const neynarClient = React.useContext(NeynarClientContext)?.client;
- const navContext = React.useContext(NavContext);
-
const identityClientContext = React.useContext(IdentityClientContext);
invariant(identityClientContext, 'IdentityClientContext should be set');
const { getAuthMetadata } = identityClientContext;
- const calendarQuery = useSelector(state =>
- nonThreadCalendarQuery({
- redux: state,
- navContext,
- }),
- );
-
const threadInfos = useSelector(state => state.threadStore.threadInfos);
const keyserverInfos = useSelector(
@@ -213,6 +207,7 @@
+communitiesToAutoJoin: CommunitiesToAutoJoin,
+setCommunitiesToAutoJoin: SetState,
};
+
function JoinHandler(props: JoinHandlerProps) {
const {
communityID,
@@ -295,4 +290,4 @@
return null;
}
-export { AutoJoinCommunityHandler };
+export { BaseAutoJoinCommunityHandler };
diff --git a/native/components/auto-join-community-handler.react.js b/native/components/auto-join-community-handler.react.js
--- a/native/components/auto-join-community-handler.react.js
+++ b/native/components/auto-join-community-handler.react.js
@@ -1,64 +1,16 @@
// @flow
-import invariant from 'invariant';
-import _pickBy from 'lodash/fp/pickBy.js';
import * as React from 'react';
-import { NeynarClientContext } from 'lib/components/neynar-client-provider.react.js';
-import blobService from 'lib/facts/blob-service.js';
-import { useIsLoggedInToIdentityAndAuthoritativeKeyserver } from 'lib/hooks/account-hooks.js';
-import { extractKeyserverIDFromID } from 'lib/keyserver-conn/keyserver-call-utils.js';
-import {
- farcasterChannelTagBlobHash,
- useJoinCommunity,
-} from 'lib/shared/community-utils.js';
-import type { AuthMetadata } from 'lib/shared/identity-client-context.js';
-import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
-import type { KeyserverOverride } from 'lib/shared/invite-links.js';
-import type {
- OngoingJoinCommunityData,
- JoinCommunityStep,
-} from 'lib/types/community-types.js';
-import type { CalendarQuery } from 'lib/types/entry-types.js';
-import type { SetState } from 'lib/types/hook-types.js';
-import { defaultThreadSubscription } from 'lib/types/subscription-types.js';
-import { getBlobFetchableURL } from 'lib/utils/blob-service.js';
-import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js';
-import { promiseAll } from 'lib/utils/promises.js';
-import {
- usingCommServicesAccessToken,
- createDefaultHTTPRequestHeaders,
-} from 'lib/utils/services-utils.js';
+import { BaseAutoJoinCommunityHandler } from 'lib/components/base-auto-join-community-handler.react.js';
import { nonThreadCalendarQuery } from '../navigation/nav-selectors.js';
import { NavContext } from '../navigation/navigation-context.js';
import { useSelector } from '../redux/redux-utils.js';
-type CommunityToAutoJoin = {
- +communityID: string,
- +keyserverOverride: ?KeyserverOverride,
- +joinStatus: 'inactive' | 'joining' | 'joined',
-};
-
-type CommunitiesToAutoJoin = {
- +[communityID: string]: CommunityToAutoJoin,
-};
-
function AutoJoinCommunityHandler(): React.Node {
- const isActive = useSelector(state => state.lifecycleState !== 'background');
-
- const loggedIn = useIsLoggedInToIdentityAndAuthoritativeKeyserver();
-
- const fid = useCurrentUserFID();
-
- const neynarClient = React.useContext(NeynarClientContext)?.client;
-
const navContext = React.useContext(NavContext);
- const identityClientContext = React.useContext(IdentityClientContext);
- invariant(identityClientContext, 'IdentityClientContext should be set');
- const { getAuthMetadata } = identityClientContext;
-
const calendarQuery = useSelector(state =>
nonThreadCalendarQuery({
redux: state,
@@ -66,233 +18,7 @@
}),
);
- const threadInfos = useSelector(state => state.threadStore.threadInfos);
-
- const keyserverInfos = useSelector(
- state => state.keyserverStore.keyserverInfos,
- );
-
- const [communitiesToAutoJoin, setCommunitiesToAutoJoin] =
- React.useState();
-
- const prevCanQueryRef = React.useRef();
- const canQuery = loggedIn;
-
- React.useEffect(() => {
- if (canQuery === prevCanQueryRef.current) {
- return;
- }
-
- prevCanQueryRef.current = canQuery;
- if (!loggedIn || !isActive || !fid || !neynarClient || !threadInfos) {
- return;
- }
-
- void (async () => {
- const authMetadataPromise: Promise = (async () => {
- if (!usingCommServicesAccessToken) {
- return undefined;
- }
- return await getAuthMetadata();
- })();
-
- const followedFarcasterChannelsPromise =
- neynarClient.fetchFollowedFarcasterChannels(fid);
-
- const [authMetadata, followedFarcasterChannels] = await Promise.all([
- authMetadataPromise,
- followedFarcasterChannelsPromise,
- ]);
-
- const headers = authMetadata
- ? createDefaultHTTPRequestHeaders(authMetadata)
- : {};
-
- const followedFarcasterChannelIDs = followedFarcasterChannels.map(
- channel => channel.id,
- );
-
- const promises: { [string]: Promise } = {};
-
- for (const channelID of followedFarcasterChannelIDs) {
- promises[channelID] = (async () => {
- const blobHash = farcasterChannelTagBlobHash(channelID);
- const blobURL = getBlobFetchableURL(blobHash);
-
- const blobResult = await fetch(blobURL, {
- method: blobService.httpEndpoints.GET_BLOB.method,
- headers,
- });
-
- if (blobResult.status !== 200) {
- return null;
- }
-
- const { commCommunityID, keyserverURL } = await blobResult.json();
- const keyserverID = extractKeyserverIDFromID(commCommunityID);
-
- // The user is already in the community
- if (threadInfos[commCommunityID]) {
- return null;
- }
-
- const keyserverOverride = !keyserverInfos[keyserverID]
- ? {
- keyserverID,
- keyserverURL: keyserverURL.replace(/\/$/, ''),
- }
- : null;
-
- return {
- communityID: commCommunityID,
- keyserverOverride,
- joinStatus: 'inactive',
- };
- })();
- }
-
- const communitiesObj = await promiseAll(promises);
-
- const filteredCommunitiesObj = _pickBy(Boolean)(communitiesObj);
-
- const communitesToJoin: { ...CommunitiesToAutoJoin } = {};
-
- for (const key in filteredCommunitiesObj) {
- const communityID = filteredCommunitiesObj[key].communityID;
- communitesToJoin[communityID] = filteredCommunitiesObj[key];
- }
-
- setCommunitiesToAutoJoin(communitesToJoin);
- })();
- }, [
- threadInfos,
- fid,
- isActive,
- loggedIn,
- neynarClient,
- getAuthMetadata,
- keyserverInfos,
- canQuery,
- ]);
-
- const joinHandlers = React.useMemo(() => {
- if (!communitiesToAutoJoin) {
- return null;
- }
-
- return Object.keys(communitiesToAutoJoin).map(id => {
- const communityToAutoJoin = communitiesToAutoJoin[id];
-
- const { communityID, keyserverOverride, joinStatus } =
- communityToAutoJoin;
-
- if (joinStatus === 'joined') {
- return null;
- }
-
- return (
-
- );
- });
- }, [calendarQuery, communitiesToAutoJoin]);
-
- return joinHandlers;
-}
-
-type JoinHandlerProps = {
- +communityID: string,
- +keyserverOverride: ?KeyserverOverride,
- +calendarQuery: () => CalendarQuery,
- +communitiesToAutoJoin: CommunitiesToAutoJoin,
- +setCommunitiesToAutoJoin: SetState,
-};
-function JoinHandler(props: JoinHandlerProps) {
- const {
- communityID,
- keyserverOverride,
- calendarQuery,
- communitiesToAutoJoin,
- setCommunitiesToAutoJoin,
- } = props;
-
- const [ongoingJoinData, setOngoingJoinData] =
- React.useState(null);
-
- const [step, setStep] = React.useState('inactive');
-
- const joinCommunity = useJoinCommunity({
- communityID,
- keyserverOverride,
- calendarQuery,
- ongoingJoinData,
- setOngoingJoinData,
- step,
- setStep,
- defaultSubscription: defaultThreadSubscription,
- });
-
- React.useEffect(() => {
- const joinStatus = communitiesToAutoJoin[communityID]?.joinStatus;
- if (joinStatus !== 'inactive') {
- return;
- }
-
- void joinCommunity();
- }, [
- communitiesToAutoJoin,
- communityID,
- joinCommunity,
- setCommunitiesToAutoJoin,
- ]);
-
- React.useEffect(() => {
- if (step !== 'add_keyserver') {
- return;
- }
-
- setCommunitiesToAutoJoin(prev => {
- if (!prev) {
- return null;
- }
-
- return {
- ...prev,
- [communityID]: {
- ...prev[communityID],
- joinStatus: 'joining',
- },
- };
- });
- }, [communityID, setCommunitiesToAutoJoin, step]);
-
- React.useEffect(() => {
- if (step !== 'finished') {
- return;
- }
-
- setCommunitiesToAutoJoin(prev => {
- if (!prev) {
- return null;
- }
-
- return {
- ...prev,
- [communityID]: {
- ...prev[communityID],
- joinStatus: 'joined',
- },
- };
- });
- }, [communityID, step, setCommunitiesToAutoJoin]);
-
- return null;
+ return ;
}
export { AutoJoinCommunityHandler };