diff --git a/native/navigation/community-drawer-content.react.js b/native/navigation/community-drawer-content.react.js index a59f05dde..360b5ef2e 100644 --- a/native/navigation/community-drawer-content.react.js +++ b/native/navigation/community-drawer-content.react.js @@ -1,234 +1,249 @@ // @flow import { useDrawerStatus } from '@react-navigation/drawer'; import { useNavigation } from '@react-navigation/native'; import * as React from 'react'; import { FlatList, Platform, View, Text, TouchableOpacity } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useSelector } from 'react-redux'; +import { + fetchCommunityInfosActionTypes, + useFetchCommunityInfos, +} from 'lib/actions/community-actions.js'; import { fetchPrimaryInviteLinkActionTypes, useFetchPrimaryInviteLinks, } from 'lib/actions/link-actions.js'; import { childThreadInfos, communityThreadSelector, } from 'lib/selectors/thread-selectors.js'; import { threadTypeIsCommunityRoot } from 'lib/types/thread-types-enum.js'; import { createRecursiveDrawerItemsData, useAppendCommunitySuffix, } from 'lib/utils/drawer-utils.react.js'; import { useResolvedThreadInfos } from 'lib/utils/entity-helpers.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import CommunityDrawerItem from './community-drawer-item.react.js'; import { CommunityCreationRouteName } from './route-names.js'; import { useNavigateToThread } from '../chat/message-list-types.js'; import SWMansionIcon from '../components/swmansion-icon.react.js'; import { useStyles } from '../themes/colors.js'; import { flattenDrawerItemsData, filterOutThreadAndDescendantIDs, type CommunityDrawerItemDataFlattened, } from '../utils/drawer-utils.react.js'; const maxDepth = 2; const safeAreaEdges: $ReadOnlyArray = Platform.select({ ios: ['top'], default: ['top', 'bottom'], }); function CommunityDrawerContent(): React.Node { const communities = useSelector(communityThreadSelector); const resolvedCommunities = useResolvedThreadInfos(communities); const communitiesSuffixed = useAppendCommunitySuffix(resolvedCommunities); const styles = useStyles(unboundStyles); const callFetchPrimaryLinks = useFetchPrimaryInviteLinks(); + const fetchCommunityInfos = useFetchCommunityInfos(); + const dispatchActionPromise = useDispatchActionPromise(); const drawerStatus = useDrawerStatus(); React.useEffect(() => { if (drawerStatus !== 'open') { return; } void dispatchActionPromise( fetchPrimaryInviteLinkActionTypes, callFetchPrimaryLinks(), ); - }, [callFetchPrimaryLinks, dispatchActionPromise, drawerStatus]); + void dispatchActionPromise( + fetchCommunityInfosActionTypes, + fetchCommunityInfos(), + ); + }, [ + callFetchPrimaryLinks, + dispatchActionPromise, + drawerStatus, + fetchCommunityInfos, + ]); const [expanded, setExpanded] = React.useState>(() => { if (communitiesSuffixed.length === 1) { return new Set([communitiesSuffixed[0].id]); } return new Set(); }); const setOpenCommunityOrClose = React.useCallback( (id: string) => expanded.has(id) ? setExpanded(new Set()) : setExpanded(new Set([id])), [expanded], ); const labelStylesObj = useStyles(labelUnboundStyles); const labelStyles = React.useMemo( () => [ labelStylesObj.level0Label, labelStylesObj.level1Label, labelStylesObj.level2Label, ], [labelStylesObj], ); const childThreadInfosMap = useSelector(childThreadInfos); const drawerItemsData = React.useMemo( () => createRecursiveDrawerItemsData( childThreadInfosMap, communitiesSuffixed, labelStyles, maxDepth, ), [childThreadInfosMap, communitiesSuffixed, labelStyles], ); const toggleExpanded = React.useCallback( (id: string) => setExpanded(expandedState => { if (expanded.has(id)) { return new Set( filterOutThreadAndDescendantIDs( [...expandedState.values()], drawerItemsData, id, ), ); } return new Set([...expanded.values(), id]); }), [drawerItemsData, expanded], ); const navigateToThread = useNavigateToThread(); const renderItem = React.useCallback( ({ item, }: { +item: CommunityDrawerItemDataFlattened, ... }): React.Node => { const isCommunity = threadTypeIsCommunityRoot(item.threadInfo.type); return ( ); }, [expanded, navigateToThread, setOpenCommunityOrClose, toggleExpanded], ); const { navigate } = useNavigation(); const onPressCommunityCreation = React.useCallback(() => { navigate(CommunityCreationRouteName); }, [navigate]); const communityCreationButton = ( Create community ); const flattenedDrawerItemsData = React.useMemo( () => flattenDrawerItemsData(drawerItemsData, [...expanded.values()]), [drawerItemsData, expanded], ); return ( {communityCreationButton} ); } const unboundStyles = { drawerContent: { flex: 1, paddingRight: 8, paddingTop: 8, paddingBottom: 8, }, communityCreationContainer: { flexDirection: 'row', padding: 24, alignItems: 'center', borderTopWidth: 1, borderColor: 'panelSeparator', }, communityCreationText: { color: 'panelForegroundLabel', fontSize: 16, lineHeight: 24, fontWeight: '500', }, communityCreationIconContainer: { height: 28, width: 28, justifyContent: 'center', alignItems: 'center', borderRadius: 16, marginRight: 12, backgroundColor: 'panelSecondaryForeground', }, communityCreationIcon: { color: 'panelForegroundLabel', }, }; const labelUnboundStyles = { level0Label: { color: 'drawerItemLabelLevel0', fontSize: 16, lineHeight: 24, fontWeight: '500', }, level1Label: { color: 'drawerItemLabelLevel1', fontSize: 14, lineHeight: 22, fontWeight: '500', }, level2Label: { color: 'drawerItemLabelLevel2', fontSize: 14, lineHeight: 22, fontWeight: '400', }, }; const MemoizedCommunityDrawerContent: React.ComponentType<{}> = React.memo( CommunityDrawerContent, ); export default MemoizedCommunityDrawerContent;