Changeset View
Changeset View
Standalone View
Standalone View
native/invite-links/view-invite-links-screen.react.js
// @flow | // @flow | ||||
import Clipboard from '@react-native-clipboard/clipboard'; | import Clipboard from '@react-native-clipboard/clipboard'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Text, View } from 'react-native'; | import { Text, View } from 'react-native'; | ||||
import { TouchableOpacity } from 'react-native-gesture-handler'; | import { TouchableOpacity } from 'react-native-gesture-handler'; | ||||
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 type { InviteLink } from 'lib/types/link-types.js'; | import type { InviteLink } from 'lib/types/link-types.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 { displayActionResultModal } from '../navigation/action-result-modal.js'; | import { displayActionResultModal } from '../navigation/action-result-modal.js'; | ||||
import type { RootNavigationProp } from '../navigation/root-navigator.react.js'; | import type { RootNavigationProp } from '../navigation/root-navigator.react.js'; | ||||
import type { NavigationRoute } from '../navigation/route-names.js'; | import { | ||||
ManagePublicLinkRouteName, | |||||
type NavigationRoute, | |||||
} from '../navigation/route-names.js'; | |||||
import { useSelector } from '../redux/redux-utils.js'; | import { useSelector } from '../redux/redux-utils.js'; | ||||
import { useStyles, useColors } from '../themes/colors.js'; | import { useStyles, useColors } from '../themes/colors.js'; | ||||
export type ViewInviteLinksScreenParams = { | export type ViewInviteLinksScreenParams = { | ||||
+community: ThreadInfo, | +community: ThreadInfo, | ||||
}; | }; | ||||
type Props = { | type Props = { | ||||
Show All 12 Lines | function ViewInviteLinksScreen(props: Props): React.Node { | ||||
const styles = useStyles(unboundStyles); | const styles = useStyles(unboundStyles); | ||||
const { modalForegroundLabel } = useColors(); | const { modalForegroundLabel } = useColors(); | ||||
const linkUrl = `https://comm.app/invite/${inviteLink?.name ?? ''}`; | const linkUrl = `https://comm.app/invite/${inviteLink?.name ?? ''}`; | ||||
const onPressCopy = React.useCallback(() => { | const onPressCopy = React.useCallback(() => { | ||||
Clipboard.setString(linkUrl); | Clipboard.setString(linkUrl); | ||||
setTimeout(confirmCopy); | setTimeout(confirmCopy); | ||||
}, [linkUrl]); | }, [linkUrl]); | ||||
const { navigate } = props.navigation; | |||||
const onEditButtonClick = React.useCallback(() => { | |||||
navigate<'ManagePublicLink'>({ | |||||
name: ManagePublicLinkRouteName, | |||||
params: { | |||||
community, | |||||
}, | |||||
}); | |||||
}, [community, navigate]); | |||||
const canManageLinks = threadHasPermission( | |||||
community, | |||||
threadPermissions.MANAGE_INVITE_LINKS, | |||||
); | |||||
let publicLinkSection = null; | let publicLinkSection = null; | ||||
if (inviteLink) { | if (inviteLink || canManageLinks) { | ||||
let description; | |||||
if (canManageLinks) { | |||||
description = ( | |||||
<> | |||||
<Text style={styles.details}> | |||||
Public links allow unlimited uses and never expire. | |||||
</Text> | |||||
<TouchableOpacity onPress={onEditButtonClick}> | |||||
<Text style={[styles.details, styles.editLinkButton]}> | |||||
Edit public link | |||||
</Text> | |||||
</TouchableOpacity> | |||||
</> | |||||
); | |||||
} else { | |||||
description = ( | |||||
<Text style={styles.details}> | |||||
Use this public link to invite your friends into the community! | |||||
</Text> | |||||
); | |||||
} | |||||
publicLinkSection = ( | publicLinkSection = ( | ||||
<> | <> | ||||
<Text style={styles.sectionTitle}>PUBLIC LINK</Text> | <Text style={styles.sectionTitle}>PUBLIC LINK</Text> | ||||
<View style={styles.section}> | <View style={styles.section}> | ||||
<TouchableOpacity style={styles.link} onPress={onPressCopy}> | <TouchableOpacity style={styles.link} onPress={onPressCopy}> | ||||
<Text style={styles.linkText}>{linkUrl}</Text> | <Text style={styles.linkText}>{linkUrl}</Text> | ||||
<View style={styles.button}> | <View style={styles.button}> | ||||
<SWMansionIcon | <SWMansionIcon | ||||
name="link" | name="link" | ||||
size={24} | size={24} | ||||
color={modalForegroundLabel} | color={modalForegroundLabel} | ||||
/> | /> | ||||
<Text style={styles.copy}>Copy</Text> | <Text style={styles.copy}>Copy</Text> | ||||
</View> | </View> | ||||
</TouchableOpacity> | </TouchableOpacity> | ||||
<Text style={styles.details}> | {description} | ||||
Use this public link to invite your friends into the community! | |||||
</Text> | |||||
</View> | </View> | ||||
</> | </> | ||||
); | ); | ||||
} | } | ||||
return <View style={styles.container}>{publicLinkSection}</View>; | return <View style={styles.container}>{publicLinkSection}</View>; | ||||
} | } | ||||
const unboundStyles = { | const unboundStyles = { | ||||
Show All 15 Lines | section: { | ||||
borderTopColor: 'modalSeparator', | borderTopColor: 'modalSeparator', | ||||
borderTopWidth: 1, | borderTopWidth: 1, | ||||
backgroundColor: 'modalForeground', | backgroundColor: 'modalForeground', | ||||
padding: 16, | padding: 16, | ||||
}, | }, | ||||
link: { | link: { | ||||
paddingHorizontal: 16, | paddingHorizontal: 16, | ||||
paddingVertical: 9, | paddingVertical: 9, | ||||
marginBottom: 16, | |||||
backgroundColor: 'inviteLinkButtonBackground', | backgroundColor: 'inviteLinkButtonBackground', | ||||
borderRadius: 20, | borderRadius: 20, | ||||
flexDirection: 'row', | flexDirection: 'row', | ||||
justifyContent: 'space-between', | justifyContent: 'space-between', | ||||
}, | }, | ||||
linkText: { | linkText: { | ||||
fontSize: 14, | fontSize: 14, | ||||
fontWeight: '400', | fontWeight: '400', | ||||
Show All 11 Lines | copy: { | ||||
color: 'modalForegroundLabel', | color: 'modalForegroundLabel', | ||||
paddingLeft: 8, | paddingLeft: 8, | ||||
}, | }, | ||||
details: { | details: { | ||||
fontSize: 12, | fontSize: 12, | ||||
fontWeight: '400', | fontWeight: '400', | ||||
lineHeight: 18, | lineHeight: 18, | ||||
color: 'modalForegroundLabel', | color: 'modalForegroundLabel', | ||||
paddingTop: 16, | }, | ||||
editLinkButton: { | |||||
color: 'purpleLink', | |||||
}, | }, | ||||
}; | }; | ||||
export default ViewInviteLinksScreen; | export default ViewInviteLinksScreen; |