Changeset View
Changeset View
Standalone View
Standalone View
native/navigation/community-drawer-content.react.js
Show All 9 Lines | |||||
import { | import { | ||||
fetchPrimaryInviteLinkActionTypes, | fetchPrimaryInviteLinkActionTypes, | ||||
fetchPrimaryInviteLinks, | fetchPrimaryInviteLinks, | ||||
} from 'lib/actions/link-actions.js'; | } from 'lib/actions/link-actions.js'; | ||||
import { | import { | ||||
childThreadInfos, | childThreadInfos, | ||||
communityThreadSelector, | communityThreadSelector, | ||||
} from 'lib/selectors/thread-selectors.js'; | } from 'lib/selectors/thread-selectors.js'; | ||||
import { threadTypeIsCommunityRoot } from 'lib/types/thread-types-enum.js'; | |||||
import { | import { | ||||
useDispatchActionPromise, | useDispatchActionPromise, | ||||
useServerCall, | useServerCall, | ||||
} from 'lib/utils/action-utils.js'; | } from 'lib/utils/action-utils.js'; | ||||
import { | import { | ||||
createRecursiveDrawerItemsData, | createRecursiveDrawerItemsData, | ||||
appendSuffix, | appendSuffix, | ||||
} from 'lib/utils/drawer-utils.react.js'; | } from 'lib/utils/drawer-utils.react.js'; | ||||
import { useResolvedThreadInfos } from 'lib/utils/entity-helpers.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 { CommunityCreationRouteName } from './route-names.js'; | ||||
import { useNavigateToThread } from '../chat/message-list-types.js'; | import { useNavigateToThread } from '../chat/message-list-types.js'; | ||||
import SWMansionIcon from '../components/swmansion-icon.react.js'; | import SWMansionIcon from '../components/swmansion-icon.react.js'; | ||||
import { useStyles } from '../themes/colors.js'; | import { useStyles } from '../themes/colors.js'; | ||||
import { | |||||
flattenDrawerItemsData, | |||||
filterOutThreadAndDescendantIDs, | |||||
} from '../utils/drawer-utils.react.js'; | |||||
const maxDepth = 2; | const maxDepth = 2; | ||||
const safeAreaEdges = Platform.select({ | const safeAreaEdges = Platform.select({ | ||||
ios: ['top'], | ios: ['top'], | ||||
default: ['top', 'bottom'], | default: ['top', 'bottom'], | ||||
}); | }); | ||||
function CommunityDrawerContent(): React.Node { | function CommunityDrawerContent(): React.Node { | ||||
Show All 15 Lines | (async () => { | ||||
} | } | ||||
await dispatchActionPromise( | await dispatchActionPromise( | ||||
fetchPrimaryInviteLinkActionTypes, | fetchPrimaryInviteLinkActionTypes, | ||||
callFetchPrimaryLinks(), | callFetchPrimaryLinks(), | ||||
); | ); | ||||
})(); | })(); | ||||
}, [callFetchPrimaryLinks, dispatchActionPromise, drawerStatus]); | }, [callFetchPrimaryLinks, dispatchActionPromise, drawerStatus]); | ||||
const [openCommunity, setOpenCommunity] = React.useState( | const [expanded, setExpanded] = React.useState(() => { | ||||
communitiesSuffixed.length === 1 ? communitiesSuffixed[0].id : null, | if (communitiesSuffixed.length === 1) { | ||||
); | return new Set([communitiesSuffixed[0].id]); | ||||
} | |||||
const navigateToThread = useNavigateToThread(); | return new Set(); | ||||
const childThreadInfosMap = useSelector(childThreadInfos); | }); | ||||
const setOpenCommunityOrClose = React.useCallback((index: string) => { | |||||
setOpenCommunity(open => (open === index ? null : index)); | |||||
}, []); | |||||
const renderItem = React.useCallback( | const setOpenCommunityOrClose = React.useCallback( | ||||
({ item }) => ( | (id: string) => | ||||
<CommunityDrawerItemCommunity | expanded.has(id) ? setExpanded(new Set()) : setExpanded(new Set([id])), | ||||
key={item.threadInfo.id} | [expanded], | ||||
itemData={item} | |||||
toggleExpanded={setOpenCommunityOrClose} | |||||
expanded={item.threadInfo.id === openCommunity} | |||||
navigateToThread={navigateToThread} | |||||
/> | |||||
), | |||||
[navigateToThread, openCommunity, setOpenCommunityOrClose], | |||||
); | ); | ||||
const labelStylesObj = useStyles(labelUnboundStyles); | const labelStylesObj = useStyles(labelUnboundStyles); | ||||
const labelStyles = React.useMemo( | const labelStyles = React.useMemo( | ||||
() => [ | () => [ | ||||
labelStylesObj.level0Label, | labelStylesObj.level0Label, | ||||
labelStylesObj.level1Label, | labelStylesObj.level1Label, | ||||
labelStylesObj.level2Label, | labelStylesObj.level2Label, | ||||
], | ], | ||||
[labelStylesObj], | [labelStylesObj], | ||||
); | ); | ||||
const childThreadInfosMap = useSelector(childThreadInfos); | |||||
const drawerItemsData = React.useMemo( | const drawerItemsData = React.useMemo( | ||||
() => | () => | ||||
createRecursiveDrawerItemsData( | createRecursiveDrawerItemsData( | ||||
childThreadInfosMap, | childThreadInfosMap, | ||||
communitiesSuffixed, | communitiesSuffixed, | ||||
labelStyles, | labelStyles, | ||||
maxDepth, | maxDepth, | ||||
), | ), | ||||
[childThreadInfosMap, communitiesSuffixed, labelStyles], | [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 ( | |||||
<CommunityDrawerItem | |||||
key={item.threadInfo.id} | |||||
itemData={item} | |||||
navigateToThread={navigateToThread} | |||||
isExpanded={expanded.has(item.threadInfo.id)} | |||||
toggleExpanded={ | |||||
isCommunity ? setOpenCommunityOrClose : toggleExpanded | |||||
} | |||||
/> | |||||
); | |||||
}, | |||||
[expanded, navigateToThread, setOpenCommunityOrClose, toggleExpanded], | |||||
); | |||||
const { navigate } = useNavigation(); | const { navigate } = useNavigation(); | ||||
const onPressCommunityCreation = React.useCallback(() => { | const onPressCommunityCreation = React.useCallback(() => { | ||||
navigate(CommunityCreationRouteName); | navigate(CommunityCreationRouteName); | ||||
}, [navigate]); | }, [navigate]); | ||||
const communityCreationButton = ( | const communityCreationButton = ( | ||||
<TouchableOpacity onPress={onPressCommunityCreation} activeOpacity={0.4}> | <TouchableOpacity onPress={onPressCommunityCreation} activeOpacity={0.4}> | ||||
<View style={styles.communityCreationContainer}> | <View style={styles.communityCreationContainer}> | ||||
<View style={styles.communityCreationIconContainer}> | <View style={styles.communityCreationIconContainer}> | ||||
<SWMansionIcon | <SWMansionIcon | ||||
name="plus" | name="plus" | ||||
size={22} | size={22} | ||||
style={styles.communityCreationIcon} | style={styles.communityCreationIcon} | ||||
/> | /> | ||||
</View> | </View> | ||||
<Text style={styles.communityCreationText}>Create community</Text> | <Text style={styles.communityCreationText}>Create community</Text> | ||||
</View> | </View> | ||||
</TouchableOpacity> | </TouchableOpacity> | ||||
); | ); | ||||
const flattenedDrawerItemsData = React.useMemo( | |||||
() => flattenDrawerItemsData(drawerItemsData, [...expanded.values()]), | |||||
[drawerItemsData, expanded], | |||||
); | |||||
return ( | return ( | ||||
<SafeAreaView style={styles.drawerContent} edges={safeAreaEdges}> | <SafeAreaView style={styles.drawerContent} edges={safeAreaEdges}> | ||||
<FlatList data={drawerItemsData} renderItem={renderItem} /> | <FlatList | ||||
data={flattenedDrawerItemsData} | |||||
renderItem={renderItem} | |||||
initialNumToRender={30} | |||||
/> | |||||
{communityCreationButton} | {communityCreationButton} | ||||
</SafeAreaView> | </SafeAreaView> | ||||
); | ); | ||||
} | } | ||||
const unboundStyles = { | const unboundStyles = { | ||||
drawerContent: { | drawerContent: { | ||||
flex: 1, | flex: 1, | ||||
▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines |