Page MenuHomePhabricator

D7731.diff
No OneTemporary

D7731.diff

diff --git a/lib/utils/drawer-utils.react.js b/lib/utils/drawer-utils.react.js
--- a/lib/utils/drawer-utils.react.js
+++ b/lib/utils/drawer-utils.react.js
@@ -1,6 +1,7 @@
// @flow
import { threadIsChannel } from '../shared/thread-utils.js';
+import type { InviteLink } from '../types/link-types.js';
import {
type ThreadInfo,
type ResolvedThreadInfo,
@@ -12,6 +13,7 @@
+itemChildren?: $ReadOnlyArray<CommunityDrawerItemData<T>>,
+hasSubchannelsButton: boolean,
+labelStyle: T,
+ +inviteLink: ?InviteLink,
};
function createRecursiveDrawerItemsData<LabelStyleType>(
@@ -19,12 +21,14 @@
communities: $ReadOnlyArray<ResolvedThreadInfo>,
labelStyles: $ReadOnlyArray<LabelStyleType>,
maxDepth: number,
+ inviteLinks: ?{ +[threadID: string]: InviteLink },
): $ReadOnlyArray<CommunityDrawerItemData<LabelStyleType>> {
const result = communities.map(community => ({
threadInfo: community,
itemChildren: [],
labelStyle: labelStyles[0],
hasSubchannelsButton: false,
+ inviteLink: inviteLinks?.[community.id],
}));
let queue = result.map(item => [item, 0]);
@@ -42,6 +46,7 @@
hasSubchannelsButton:
lvl + 1 === maxDepth &&
threadHasSubchannels(childItem, childThreadInfosMap),
+ inviteLink: inviteLinks?.[item.threadInfo.id],
}));
queue = queue.concat(
item.itemChildren.map(childItem => [childItem, lvl + 1]),
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
@@ -1,14 +1,26 @@
// @flow
+import { useDrawerStatus } from '@react-navigation/drawer';
+import { useNavigation } from '@react-navigation/native';
import * as React from 'react';
import { FlatList, Platform } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useSelector } from 'react-redux';
+import {
+ fetchPrimaryInviteLinkActionTypes,
+ fetchPrimaryInviteLinks,
+} from 'lib/actions/link-actions.js';
import {
childThreadInfos,
communityThreadSelector,
} from 'lib/selectors/thread-selectors.js';
+import type { InviteLink } from 'lib/types/link-types';
+import type { ThreadInfo } from 'lib/types/thread-types';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from 'lib/utils/action-utils.js';
import {
createRecursiveDrawerItemsData,
appendSuffix,
@@ -16,6 +28,7 @@
import { useResolvedThreadInfos } from 'lib/utils/entity-helpers.js';
import CommunityDrawerItemCommunity from './community-drawer-item-community.react.js';
+import { ViewInviteLinksModalRouteName } from './route-names.js';
import { useNavigateToThread } from '../chat/message-list-types.js';
import { useStyles } from '../themes/colors.js';
@@ -34,6 +47,30 @@
);
const styles = useStyles(unboundStyles);
+ const [inviteLinks, setInviteLinks] = React.useState(null);
+ const callFetchPrimaryLinks = useServerCall(fetchPrimaryInviteLinks);
+ const dispatchActionPromise = useDispatchActionPromise();
+ const drawerStatus = useDrawerStatus();
+ React.useEffect(() => {
+ (async () => {
+ if (drawerStatus !== 'open') {
+ return;
+ }
+ const createFetchPrimaryLinksPromise = async () => {
+ const response = await callFetchPrimaryLinks();
+ const links = {};
+ for (const link of response.links) {
+ links[link.communityID] = link;
+ }
+ setInviteLinks(links);
+ };
+ await dispatchActionPromise(
+ fetchPrimaryInviteLinkActionTypes,
+ createFetchPrimaryLinksPromise(),
+ );
+ })();
+ }, [callFetchPrimaryLinks, dispatchActionPromise, drawerStatus]);
+
const [openCommunity, setOpenCommunity] = React.useState(
communitiesSuffixed.length === 1 ? communitiesSuffixed[0].id : null,
);
@@ -45,6 +82,20 @@
setOpenCommunity(open => (open === index ? null : index));
}, []);
+ const { navigate } = useNavigation();
+ const navigateToInviteLinksView = React.useCallback(
+ (community: ThreadInfo, inviteLink: InviteLink) => {
+ navigate<'ViewInviteLinksModal'>({
+ name: ViewInviteLinksModalRouteName,
+ params: {
+ community,
+ inviteLink,
+ },
+ });
+ },
+ [navigate],
+ );
+
const renderItem = React.useCallback(
({ item }) => (
<CommunityDrawerItemCommunity
@@ -53,9 +104,15 @@
toggleExpanded={setOpenCommunityOrClose}
expanded={item.threadInfo.id === openCommunity}
navigateToThread={navigateToThread}
+ navigateToInviteLinksView={navigateToInviteLinksView}
/>
),
- [navigateToThread, openCommunity, setOpenCommunityOrClose],
+ [
+ navigateToInviteLinksView,
+ navigateToThread,
+ openCommunity,
+ setOpenCommunityOrClose,
+ ],
);
const labelStylesObj = useStyles(labelUnboundStyles);
@@ -75,8 +132,9 @@
communitiesSuffixed,
labelStyles,
maxDepth,
+ inviteLinks,
),
- [childThreadInfosMap, communitiesSuffixed, labelStyles],
+ [childThreadInfosMap, communitiesSuffixed, inviteLinks, labelStyles],
);
return (
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,8 +1,12 @@
// @flow
+import { useActionSheet } from '@expo/react-native-action-sheet';
import * as React from 'react';
import { View, FlatList, TouchableOpacity } from 'react-native';
+import { useSafeAreaInsets } from 'react-native-safe-area-context';
+import type { InviteLink } from 'lib/types/link-types';
+import type { ThreadInfo } from 'lib/types/thread-types';
import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react.js';
import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
@@ -11,6 +15,7 @@
import ThreadAvatar from '../avatars/thread-avatar.react.js';
import type { MessageListParams } from '../chat/message-list-types.js';
import { SingleLine } from '../components/single-line.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
import { useStyles } from '../themes/colors.js';
import type { TextStyle } from '../types/styles.js';
import { useShouldRenderAvatars } from '../utils/avatar-utils.js';
@@ -20,14 +25,25 @@
+toggleExpanded: (threadID: string) => void,
+expanded: boolean,
+navigateToThread: (params: MessageListParams) => void,
+ +navigateToInviteLinksView: (
+ community: ThreadInfo,
+ inviteLink: InviteLink,
+ ) => void,
};
function CommunityDrawerItem(props: DrawerItemProps): React.Node {
const {
- itemData: { threadInfo, itemChildren, labelStyle, hasSubchannelsButton },
+ itemData: {
+ threadInfo,
+ itemChildren,
+ labelStyle,
+ hasSubchannelsButton,
+ inviteLink,
+ },
navigateToThread,
expanded,
toggleExpanded,
+ navigateToInviteLinksView,
} = props;
const styles = useStyles(unboundStyles);
@@ -38,9 +54,10 @@
key={item.threadInfo.id}
itemData={item}
navigateToThread={navigateToThread}
+ navigateToInviteLinksView={navigateToInviteLinksView}
/>
),
- [navigateToThread],
+ [navigateToInviteLinksView, navigateToThread],
);
const children = React.useMemo(() => {
@@ -95,6 +112,49 @@
);
}, [shouldRenderAvatars, styles.avatarContainer, threadInfo]);
+ const insets = useSafeAreaInsets();
+ const { showActionSheetWithOptions } = useActionSheet();
+ const inviteLinksButton = React.useMemo(() => {
+ if (!inviteLink) {
+ return null;
+ }
+ const options = ['Invite Link', 'Cancel'];
+ const containerStyle = {
+ paddingBottom: insets.bottom,
+ };
+ return (
+ <TouchableOpacity
+ onPress={() =>
+ showActionSheetWithOptions(
+ {
+ options,
+ cancelButtonIndex: 1,
+ containerStyle,
+ },
+ selectedIndex => {
+ if (selectedIndex === 0) {
+ navigateToInviteLinksView(threadInfo, inviteLink);
+ }
+ },
+ )
+ }
+ >
+ <SWMansionIcon
+ name="menu-vertical"
+ size={22}
+ style={styles.inviteLinksButton}
+ />
+ </TouchableOpacity>
+ );
+ }, [
+ insets.bottom,
+ inviteLink,
+ navigateToInviteLinksView,
+ showActionSheetWithOptions,
+ styles.inviteLinksButton,
+ threadInfo,
+ ]);
+
return (
<View>
<View style={styles.threadEntry}>
@@ -107,6 +167,7 @@
{avatar}
<SingleLine style={labelStyle}>{uiName}</SingleLine>
</TouchableOpacity>
+ {inviteLinksButton}
</View>
{children}
</View>
@@ -120,6 +181,9 @@
chatView: {
marginLeft: 16,
},
+ inviteLinksButton: {
+ color: 'drawerItemLabelLevel0',
+ },
threadEntry: {
flexDirection: 'row',
marginVertical: 6,
@@ -138,6 +202,7 @@
export type CommunityDrawerItemChatProps = {
+itemData: CommunityDrawerItemData<TextStyle>,
+navigateToThread: (params: MessageListParams) => void,
+ +navigateToInviteLinksView: () => void,
};
function CommunityDrawerItemChat(

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 25, 9:29 AM (37 m, 46 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2702337
Default Alt Text
D7731.diff (9 KB)

Event Timeline