Changeset View
Changeset View
Standalone View
Standalone View
native/invite-links/invite-links-button.react.js
// @flow | // @flow | ||||
import { useActionSheet } from '@expo/react-native-action-sheet'; | import { useActionSheet } from '@expo/react-native-action-sheet'; | ||||
import { useNavigation } from '@react-navigation/native'; | import { useNavigation } from '@react-navigation/native'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { TouchableOpacity } from 'react-native'; | import { TouchableOpacity } from 'react-native'; | ||||
import { useSafeAreaInsets } from 'react-native-safe-area-context'; | import { useSafeAreaInsets } from 'react-native-safe-area-context'; | ||||
import { primaryInviteLinksSelector } from 'lib/selectors/invite-links-selectors.js'; | import { primaryInviteLinksSelector } from 'lib/selectors/invite-links-selectors.js'; | ||||
import { threadHasPermission } from 'lib/shared/thread-utils.js'; | |||||
import { threadPermissions } from 'lib/types/thread-permission-types.js'; | |||||
import type { ThreadInfo } from 'lib/types/thread-types.js'; | import type { ThreadInfo } from 'lib/types/thread-types.js'; | ||||
import SWMansionIcon from '../components/swmansion-icon.react.js'; | import SWMansionIcon from '../components/swmansion-icon.react.js'; | ||||
import { | import { | ||||
InviteLinkNavigatorRouteName, | InviteLinkNavigatorRouteName, | ||||
ManagePublicLinkRouteName, | |||||
ViewInviteLinksRouteName, | ViewInviteLinksRouteName, | ||||
} from '../navigation/route-names.js'; | } from '../navigation/route-names.js'; | ||||
import { useSelector } from '../redux/redux-utils.js'; | import { useSelector } from '../redux/redux-utils.js'; | ||||
import { useStyles } from '../themes/colors.js'; | import { useStyles } from '../themes/colors.js'; | ||||
type Props = { | type Props = { | ||||
+community: ThreadInfo, | +community: ThreadInfo, | ||||
}; | }; | ||||
Show All 9 Lines | const navigateToInviteLinksView = React.useCallback(() => { | ||||
} | } | ||||
navigate<'InviteLinkNavigator'>(InviteLinkNavigatorRouteName, { | navigate<'InviteLinkNavigator'>(InviteLinkNavigatorRouteName, { | ||||
screen: ViewInviteLinksRouteName, | screen: ViewInviteLinksRouteName, | ||||
params: { | params: { | ||||
community, | community, | ||||
}, | }, | ||||
}); | }); | ||||
}, [community, inviteLink, navigate]); | }, [community, inviteLink, navigate]); | ||||
const navigateToManagePublicLinkView = React.useCallback(() => { | |||||
navigate<'InviteLinkNavigator'>(InviteLinkNavigatorRouteName, { | |||||
screen: ManagePublicLinkRouteName, | |||||
params: { | |||||
community, | |||||
}, | |||||
}); | |||||
}, [community, navigate]); | |||||
const insets = useSafeAreaInsets(); | const insets = useSafeAreaInsets(); | ||||
const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme); | const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme); | ||||
const styles = useStyles(unboundStyles); | const styles = useStyles(unboundStyles); | ||||
const { showActionSheetWithOptions } = useActionSheet(); | const { showActionSheetWithOptions } = useActionSheet(); | ||||
const options = React.useMemo(() => ['Invite Link', 'Cancel'], []); | const actions = React.useMemo(() => { | ||||
if (!community) { | |||||
return null; | |||||
} | |||||
const result = []; | |||||
const canManageLinks = threadHasPermission( | |||||
community, | |||||
threadPermissions.MANAGE_INVITE_LINKS, | |||||
); | |||||
if (canManageLinks) { | |||||
result.push({ | |||||
label: 'Manage Invite Links', | |||||
action: navigateToManagePublicLinkView, | |||||
}); | |||||
} | |||||
if (inviteLink) { | |||||
result.push({ | |||||
label: 'Invite Link', | |||||
action: navigateToInviteLinksView, | |||||
}); | |||||
} | |||||
if (result.length > 0) { | |||||
return result; | |||||
} | |||||
return null; | |||||
}, [ | |||||
community, | |||||
inviteLink, | |||||
navigateToInviteLinksView, | |||||
navigateToManagePublicLinkView, | |||||
]); | |||||
const openActionSheet = React.useCallback(() => { | const openActionSheet = React.useCallback(() => { | ||||
if (!actions) { | |||||
return; | |||||
} | |||||
const options = [...actions.map(a => a.label), 'Cancel']; | |||||
showActionSheetWithOptions( | showActionSheetWithOptions( | ||||
{ | { | ||||
options, | options, | ||||
cancelButtonIndex: 1, | cancelButtonIndex: options.length - 1, | ||||
containerStyle: { | containerStyle: { | ||||
paddingBottom: insets.bottom, | paddingBottom: insets.bottom, | ||||
}, | }, | ||||
userInterfaceStyle: activeTheme ?? 'dark', | userInterfaceStyle: activeTheme ?? 'dark', | ||||
}, | }, | ||||
selectedIndex => { | selectedIndex => { | ||||
if (selectedIndex === 0) { | if (selectedIndex !== undefined && selectedIndex < actions.length) { | ||||
navigateToInviteLinksView(); | actions[selectedIndex].action(); | ||||
} | } | ||||
}, | }, | ||||
); | ); | ||||
}, [ | }, [actions, activeTheme, insets.bottom, showActionSheetWithOptions]); | ||||
activeTheme, | |||||
insets.bottom, | |||||
navigateToInviteLinksView, | |||||
options, | |||||
showActionSheetWithOptions, | |||||
]); | |||||
if (!inviteLink) { | if (!actions) { | ||||
return null; | return null; | ||||
} | } | ||||
return ( | return ( | ||||
<TouchableOpacity onPress={openActionSheet}> | <TouchableOpacity onPress={openActionSheet}> | ||||
<SWMansionIcon name="menu-vertical" size={22} style={styles.button} /> | <SWMansionIcon name="menu-vertical" size={22} style={styles.button} /> | ||||
</TouchableOpacity> | </TouchableOpacity> | ||||
); | ); | ||||
} | } | ||||
const unboundStyles = { | const unboundStyles = { | ||||
button: { | button: { | ||||
color: 'drawerItemLabelLevel0', | color: 'drawerItemLabelLevel0', | ||||
}, | }, | ||||
}; | }; | ||||
export default InviteLinksButton; | export default InviteLinksButton; |