diff --git a/native/invite-links/invite-links-button.react.js b/native/invite-links/invite-links-button.react.js new file mode 100644 --- /dev/null +++ b/native/invite-links/invite-links-button.react.js @@ -0,0 +1,88 @@ +// @flow + +import { useActionSheet } from '@expo/react-native-action-sheet'; +import { useNavigation } from '@react-navigation/native'; +import * as React from 'react'; +import { TouchableOpacity } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; + +import { primaryInviteLinksSelector } from 'lib/selectors/invite-links-selectors.js'; +import type { ThreadInfo } from 'lib/types/thread-types.js'; + +import SWMansionIcon from '../components/swmansion-icon.react.js'; +import { + InviteLinkNavigatorRouteName, + ViewInviteLinksRouteName, +} from '../navigation/route-names.js'; +import { useSelector } from '../redux/redux-utils.js'; +import { useStyles } from '../themes/colors.js'; + +type Props = { + +community: ThreadInfo, +}; + +function InviteLinksButton(props: Props): React.Node { + const { community } = props; + const inviteLink = useSelector(primaryInviteLinksSelector)[community.id]; + + const { navigate } = useNavigation(); + const navigateToInviteLinksView = React.useCallback(() => { + if (!inviteLink || !community) { + return; + } + navigate<'InviteLinkNavigator'>(InviteLinkNavigatorRouteName, { + screen: ViewInviteLinksRouteName, + params: { + community, + }, + }); + }, [community, inviteLink, navigate]); + + const insets = useSafeAreaInsets(); + const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme); + const styles = useStyles(unboundStyles); + + const { showActionSheetWithOptions } = useActionSheet(); + const options = React.useMemo(() => ['Invite Link', 'Cancel'], []); + + const openActionSheet = React.useCallback(() => { + showActionSheetWithOptions( + { + options, + cancelButtonIndex: 1, + containerStyle: { + paddingBottom: insets.bottom, + }, + userInterfaceStyle: activeTheme ?? 'dark', + }, + selectedIndex => { + if (selectedIndex === 0) { + navigateToInviteLinksView(); + } + }, + ); + }, [ + activeTheme, + insets.bottom, + navigateToInviteLinksView, + options, + showActionSheetWithOptions, + ]); + + if (!inviteLink) { + return null; + } + return ( + + + + ); +} + +const unboundStyles = { + button: { + color: 'drawerItemLabelLevel0', + }, +}; + +export default InviteLinksButton; 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,23 @@ // @flow +import { useDrawerStatus } from '@react-navigation/drawer'; 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 { + useDispatchActionPromise, + useServerCall, +} from 'lib/utils/action-utils.js'; import { createRecursiveDrawerItemsData, appendSuffix, @@ -34,6 +43,21 @@ ); const styles = useStyles(unboundStyles); + const callFetchPrimaryLinks = useServerCall(fetchPrimaryInviteLinks); + const dispatchActionPromise = useDispatchActionPromise(); + const drawerStatus = useDrawerStatus(); + React.useEffect(() => { + (async () => { + if (drawerStatus !== 'open') { + return; + } + await dispatchActionPromise( + fetchPrimaryInviteLinkActionTypes, + callFetchPrimaryLinks(), + ); + })(); + }, [callFetchPrimaryLinks, dispatchActionPromise, drawerStatus]); + const [openCommunity, setOpenCommunity] = React.useState( communitiesSuffixed.length === 1 ? communitiesSuffixed[0].id : null, ); 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 @@ -11,6 +11,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 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'; @@ -107,6 +108,7 @@ {avatar} {uiName} + {children}