diff --git a/native/navigation/community-drawer-content.react.js b/native/navigation/community-drawer-content.react.js
--- a/native/navigation/community-drawer-content.react.js
+++ b/native/navigation/community-drawer-content.react.js
@@ -15,6 +15,7 @@
childThreadInfos,
communityThreadSelector,
} from 'lib/selectors/thread-selectors.js';
+import { threadTypeIsCommunityRoot } from 'lib/types/thread-types-enum.js';
import {
useDispatchActionPromise,
useServerCall,
@@ -25,11 +26,15 @@
} from 'lib/utils/drawer-utils.react.js';
import { useResolvedThreadInfos } from 'lib/utils/entity-helpers.js';
-import CommunityDrawerItemCommunity from './community-drawer-item-community.react.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,
+} from '../utils/drawer-utils.react.js';
const maxDepth = 2;
const safeAreaEdges = Platform.select({
@@ -61,28 +66,17 @@
})();
}, [callFetchPrimaryLinks, dispatchActionPromise, drawerStatus]);
- const [openCommunity, setOpenCommunity] = React.useState(
- communitiesSuffixed.length === 1 ? communitiesSuffixed[0].id : null,
- );
-
- const navigateToThread = useNavigateToThread();
- const childThreadInfosMap = useSelector(childThreadInfos);
-
- const setOpenCommunityOrClose = React.useCallback((index: string) => {
- setOpenCommunity(open => (open === index ? null : index));
- }, []);
-
- const renderItem = React.useCallback(
- ({ item }) => (
-
- ),
- [navigateToThread, openCommunity, setOpenCommunityOrClose],
+ 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);
@@ -94,6 +88,7 @@
],
[labelStylesObj],
);
+ const childThreadInfosMap = useSelector(childThreadInfos);
const drawerItemsData = React.useMemo(
() =>
@@ -106,6 +101,43 @@
[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 }) => {
+ const isCommunity = threadTypeIsCommunityRoot(item.threadInfo.type);
+ return (
+
+ );
+ },
+ [expanded, navigateToThread, setOpenCommunityOrClose, toggleExpanded],
+ );
+
const { navigate } = useNavigation();
const onPressCommunityCreation = React.useCallback(() => {
navigate(CommunityCreationRouteName);
@@ -126,9 +158,18 @@
);
+ const flattenedDrawerItemsData = React.useMemo(
+ () => flattenDrawerItemsData(drawerItemsData, [...expanded.values()]),
+ [drawerItemsData, expanded],
+ );
+
return (
-
+
{communityCreationButton}
);
diff --git a/native/navigation/community-drawer-item-community.react.js b/native/navigation/community-drawer-item-community.react.js
deleted file mode 100644
--- a/native/navigation/community-drawer-item-community.react.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// @flow
-
-import * as React from 'react';
-import { View } from 'react-native';
-
-import CommunityDrawerItem from './community-drawer-item.react.js';
-import type { DrawerItemProps } from './community-drawer-item.react.js';
-import { useStyles } from '../themes/colors.js';
-
-function CommunityDrawerItemCommunity(props: DrawerItemProps): React.Node {
- const styles = useStyles(unboundStyles);
-
- const style = React.useMemo(
- () =>
- props.expanded
- ? [styles.communityExpanded, styles.communityBase]
- : styles.communityBase,
- [props.expanded, styles.communityBase, styles.communityExpanded],
- );
-
- return (
-
-
-
- );
-}
-
-const unboundStyles = {
- communityBase: {
- paddingVertical: 2,
- paddingRight: 24,
- paddingLeft: 8,
- overflow: 'hidden',
- },
- communityExpanded: {
- backgroundColor: 'drawerOpenCommunityBackground',
- borderTopRightRadius: 8,
- borderBottomRightRadius: 8,
- },
-};
-
-const MemoizedCommunityDrawerItemCommunity: React.ComponentType =
- React.memo(CommunityDrawerItemCommunity);
-export default MemoizedCommunityDrawerItemCommunity;
diff --git a/native/navigation/community-drawer-item.react.js b/native/navigation/community-drawer-item.react.js
--- a/native/navigation/community-drawer-item.react.js
+++ b/native/navigation/community-drawer-item.react.js
@@ -1,9 +1,8 @@
// @flow
import * as React from 'react';
-import { View, FlatList, TouchableOpacity } from 'react-native';
+import { View, TouchableOpacity } from 'react-native';
-import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react.js';
import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
import { ExpandButton, ExpandButtonDisabled } from './expand-buttons.react.js';
@@ -13,68 +12,53 @@
import { SingleLine } from '../components/single-line.react.js';
import InviteLinksButton from '../invite-links/invite-links-button.react.js';
import { useStyles } from '../themes/colors.js';
-import type { TextStyle } from '../types/styles.js';
import { useShouldRenderAvatars } from '../utils/avatar-utils.js';
+import type { CommunityDrawerItemDataFlattened } from '../utils/drawer-utils.react.js';
export type DrawerItemProps = {
- +itemData: CommunityDrawerItemData,
+ +itemData: CommunityDrawerItemDataFlattened,
+toggleExpanded: (threadID: string) => void,
- +expanded: boolean,
+ +isExpanded: boolean,
+navigateToThread: (params: MessageListParams) => void,
};
function CommunityDrawerItem(props: DrawerItemProps): React.Node {
const {
- itemData: { threadInfo, itemChildren, labelStyle, hasSubchannelsButton },
+ itemData: {
+ threadInfo,
+ labelStyle,
+ hasSubchannelsButton,
+ hasChildren,
+ itemStyle,
+ },
navigateToThread,
- expanded,
+ isExpanded,
toggleExpanded,
} = props;
const styles = useStyles(unboundStyles);
- const renderItem = React.useCallback(
- ({ item }) => (
-
- ),
- [navigateToThread],
- );
-
- const children = React.useMemo(() => {
- if (!expanded) {
- return null;
- }
- if (hasSubchannelsButton) {
+ const subchannelsButton = React.useMemo(() => {
+ if (isExpanded && hasSubchannelsButton) {
return (
);
}
- return ;
- }, [
- expanded,
- itemChildren,
- renderItem,
- hasSubchannelsButton,
- styles.subchannelsButton,
- threadInfo,
- ]);
+ return null;
+ }, [isExpanded, hasSubchannelsButton, styles.subchannelsButton, threadInfo]);
const onExpandToggled = React.useCallback(() => {
toggleExpanded(threadInfo.id);
}, [toggleExpanded, threadInfo.id]);
const itemExpandButton = React.useMemo(() => {
- if (!itemChildren?.length && !hasSubchannelsButton) {
+ if (!hasChildren && !hasSubchannelsButton) {
return ;
}
- return ;
- }, [itemChildren?.length, hasSubchannelsButton, onExpandToggled, expanded]);
+ return ;
+ }, [hasChildren, hasSubchannelsButton, onExpandToggled, isExpanded]);
const onPress = React.useCallback(() => {
navigateToThread({ threadInfo });
@@ -96,8 +80,19 @@
);
}, [shouldRenderAvatars, styles.avatarContainer, threadInfo]);
+ const containerStyle = React.useMemo(
+ () => [
+ styles.container,
+ {
+ paddingLeft: itemStyle.indentation,
+ },
+ styles[itemStyle.background],
+ ],
+ [itemStyle.indentation, itemStyle.background, styles],
+ );
+
return (
-
+
{itemExpandButton}
- {children}
+ {subchannelsButton}
);
}
const unboundStyles = {
+ container: {
+ paddingRight: 24,
+ },
+ none: {
+ paddingVertical: 2,
+ },
+ beginning: {
+ backgroundColor: 'drawerOpenCommunityBackground',
+ borderTopRightRadius: 8,
+ paddingTop: 2,
+ },
+ middle: {
+ backgroundColor: 'drawerOpenCommunityBackground',
+ paddingRight: 24,
+ },
+ end: {
+ backgroundColor: 'drawerOpenCommunityBackground',
+ borderBottomRightRadius: 8,
+ paddingBottom: 2,
+ },
avatarContainer: {
marginRight: 8,
},
- chatView: {
- marginLeft: 16,
- },
threadEntry: {
flexDirection: 'row',
marginVertical: 6,
@@ -137,34 +149,6 @@
},
};
-export type CommunityDrawerItemChatProps = {
- +itemData: CommunityDrawerItemData,
- +navigateToThread: (params: MessageListParams) => void,
-};
-
-function CommunityDrawerItemChat(
- props: CommunityDrawerItemChatProps,
-): React.Node {
- const [expanded, setExpanded] = React.useState(false);
- const styles = useStyles(unboundStyles);
-
- const toggleExpanded = React.useCallback(() => {
- setExpanded(isExpanded => !isExpanded);
- }, []);
-
- return (
-
-
-
- );
-}
-const MemoizedCommunityDrawerItemChat: React.ComponentType =
- React.memo(CommunityDrawerItemChat);
-
const MemoizedCommunityDrawerItem: React.ComponentType =
React.memo(CommunityDrawerItem);