diff --git a/lib/components/sync-community-store-handler.react.js b/lib/components/sync-community-store-handler.react.js new file mode 100644 --- /dev/null +++ b/lib/components/sync-community-store-handler.react.js @@ -0,0 +1,58 @@ +// @flow + +import _debounce from 'lodash/debounce.js'; +import * as React from 'react'; + +import { + useFetchCommunityInfos, + fetchCommunityInfosActionTypes, +} from '../actions/community-actions.js'; +import { isLoggedIn } from '../selectors/user-selectors.js'; +import { thinThreadTypes } from '../types/thread-types-enum.js'; +import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; +import { useSelector } from '../utils/redux-utils.js'; + +const FETCH_COMMUNITY_INFOS_DEBOUNCE_DURATION = 5000; + +function SyncCommunityStoreHandler(): React.Node { + const loggedIn = useSelector(isLoggedIn); + const threadInfos = useSelector(state => state.threadStore.threadInfos); + const communityInfos = useSelector( + state => state.communityStore.communityInfos, + ); + const callFetchCommunityInfos = useFetchCommunityInfos(); + const dispatchActionPromise = useDispatchActionPromise(); + + const debouncedFetchCommunityInfos = React.useMemo( + () => + _debounce(() => { + void dispatchActionPromise( + fetchCommunityInfosActionTypes, + callFetchCommunityInfos(), + ); + }, FETCH_COMMUNITY_INFOS_DEBOUNCE_DURATION), + [callFetchCommunityInfos, dispatchActionPromise], + ); + + React.useEffect(() => { + if (!loggedIn) { + return; + } + + const communityRootThreads = Object.values(threadInfos).filter( + thread => thread.type === thinThreadTypes.COMMUNITY_ROOT, + ); + + const missingCommunityInfos = communityRootThreads.some( + thread => !(thread.id in communityInfos), + ); + + if (missingCommunityInfos) { + debouncedFetchCommunityInfos(); + } + }, [communityInfos, debouncedFetchCommunityInfos, loggedIn, threadInfos]); + + return null; +} + +export default SyncCommunityStoreHandler; diff --git a/native/root.react.js b/native/root.react.js --- a/native/root.react.js +++ b/native/root.react.js @@ -34,6 +34,7 @@ import PrekeysHandler from 'lib/components/prekeys-handler.react.js'; import { QRAuthProvider } from 'lib/components/qr-auth-provider.react.js'; import { StaffContextProvider } from 'lib/components/staff-provider.react.js'; +import SyncCommunityStoreHandler from 'lib/components/sync-community-store-handler.react.js'; import { UserIdentityCacheProvider } from 'lib/components/user-identity-cache.react.js'; import { DBOpsHandler } from 'lib/handlers/db-ops-handler.react.js'; import { HoldersHandler } from 'lib/handlers/holders-handler.react.js'; @@ -390,6 +391,7 @@ + {navigation} diff --git a/web/app.react.js b/web/app.react.js --- a/web/app.react.js +++ b/web/app.react.js @@ -24,6 +24,7 @@ import PlatformDetailsSynchronizer from 'lib/components/platform-details-synchronizer.react.js'; import { QRAuthProvider } from 'lib/components/qr-auth-provider.react.js'; import { StaffContextProvider } from 'lib/components/staff-provider.react.js'; +import SyncCommunityStoreHandler from 'lib/components/sync-community-store-handler.react.js'; import { DBOpsHandler } from 'lib/handlers/db-ops-handler.react.js'; import { HoldersHandler } from 'lib/handlers/holders-handler.react.js'; import { TunnelbrokerDeviceTokenHandler } from 'lib/handlers/tunnelbroker-device-token-handler.react.js'; @@ -258,6 +259,7 @@ + {content}