Changeset View
Changeset View
Standalone View
Standalone View
native/invite-links/manage-public-link-screen.react.js
// @flow | // @flow | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Text, View } from 'react-native'; | import { Text, View } from 'react-native'; | ||||
import { | |||||
createOrUpdatePublicLink, | |||||
createOrUpdatePublicLinkActionTypes, | |||||
} from 'lib/actions/link-actions.js'; | |||||
import { primaryInviteLinksSelector } from 'lib/selectors/invite-links-selectors.js'; | |||||
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; | |||||
import type { ThreadInfo } from 'lib/types/thread-types.js'; | import type { ThreadInfo } from 'lib/types/thread-types.js'; | ||||
import { | |||||
useDispatchActionPromise, | |||||
useServerCall, | |||||
} from 'lib/utils/action-utils.js'; | |||||
import Button from '../components/button.react.js'; | import Button from '../components/button.react.js'; | ||||
import TextInput from '../components/text-input.react.js'; | import TextInput from '../components/text-input.react.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 type { NavigationRoute } from '../navigation/route-names.js'; | ||||
import { useSelector } from '../redux/redux-utils.js'; | |||||
import { useStyles } from '../themes/colors.js'; | import { useStyles } from '../themes/colors.js'; | ||||
export type ManagePublicLinkScreenParams = { | export type ManagePublicLinkScreenParams = { | ||||
+community: ThreadInfo, | +community: ThreadInfo, | ||||
}; | }; | ||||
type Props = { | type Props = { | ||||
+navigation: RootNavigationProp<'ManagePublicLink'>, | +navigation: RootNavigationProp<'ManagePublicLink'>, | ||||
+route: NavigationRoute<'ManagePublicLink'>, | +route: NavigationRoute<'ManagePublicLink'>, | ||||
}; | }; | ||||
// eslint-disable-next-line no-unused-vars | |||||
function ManagePublicLinkScreen(props: Props): React.Node { | function ManagePublicLinkScreen(props: Props): React.Node { | ||||
const { community } = props.route.params; | |||||
const inviteLink = useSelector(primaryInviteLinksSelector)[community.id]; | |||||
const [name, setName] = React.useState( | |||||
inviteLink?.name ?? Math.random().toString(36).slice(-9), | |||||
); | |||||
const dispatchActionPromise = useDispatchActionPromise(); | |||||
const callCreateOrUpdatePublicLink = useServerCall(createOrUpdatePublicLink); | |||||
const createInviteLink = React.useCallback(() => { | |||||
dispatchActionPromise( | |||||
createOrUpdatePublicLinkActionTypes, | |||||
callCreateOrUpdatePublicLink({ | |||||
name, | |||||
communityID: community.id, | |||||
}), | |||||
); | |||||
}, [callCreateOrUpdatePublicLink, community.id, dispatchActionPromise, name]); | |||||
const createOrUpdatePublicLinkStatus = useSelector( | |||||
createOrUpdatePublicLinkStatusSelector, | |||||
); | |||||
const styles = useStyles(unboundStyles); | const styles = useStyles(unboundStyles); | ||||
return ( | return ( | ||||
<View> | <View> | ||||
<View style={styles.section}> | <View style={styles.section}> | ||||
<Text style={styles.sectionText}> | <Text style={styles.sectionText}> | ||||
Let your community be more accessible with your own unique public | Let your community be more accessible with your own unique public | ||||
link. By enabling a public link, you are allowing anyone who has your | link. By enabling a public link, you are allowing anyone who has your | ||||
link to join your community.{'\n\n'} | link to join your community.{'\n\n'} | ||||
Editing your community’s public link allows other communities to claim | Editing your community’s public link allows other communities to claim | ||||
your previous URL. | your previous URL. | ||||
</Text> | </Text> | ||||
</View> | </View> | ||||
<Text style={styles.sectionTitle}>INVITE URL</Text> | <Text style={styles.sectionTitle}>INVITE URL</Text> | ||||
<View style={styles.section}> | <View style={styles.section}> | ||||
<View style={styles.inviteLink}> | <View style={styles.inviteLink}> | ||||
<Text style={styles.inviteLinkPrefix}>https://comm.app/invite/</Text> | <Text style={styles.inviteLinkPrefix}>https://comm.app/invite/</Text> | ||||
<TextInput style={styles.input} /> | <TextInput | ||||
style={styles.input} | |||||
value={name} | |||||
onChangeText={setName} | |||||
autoCorrect={false} | |||||
autoCapitalize="none" | |||||
keyboardType="ascii-capable" | |||||
editable={createOrUpdatePublicLinkStatus !== 'loading'} | |||||
/> | |||||
</View> | </View> | ||||
<Button | <Button | ||||
style={[styles.button, styles.buttonPrimary]} | style={[styles.button, styles.buttonPrimary]} | ||||
onPress={() => {}} | onPress={createInviteLink} | ||||
disabled={createOrUpdatePublicLinkStatus === 'loading'} | |||||
> | > | ||||
<Text style={styles.buttonText}>Save & enable public link</Text> | <Text style={styles.buttonText}>Save & enable public link</Text> | ||||
</Button> | </Button> | ||||
</View> | </View> | ||||
</View> | </View> | ||||
); | ); | ||||
} | } | ||||
const createOrUpdatePublicLinkStatusSelector = createLoadingStatusSelector( | |||||
createOrUpdatePublicLinkActionTypes, | |||||
); | |||||
const unboundStyles = { | const unboundStyles = { | ||||
sectionTitle: { | sectionTitle: { | ||||
fontSize: 14, | fontSize: 14, | ||||
fontWeight: '400', | fontWeight: '400', | ||||
lineHeight: 20, | lineHeight: 20, | ||||
color: 'modalBackgroundLabel', | color: 'modalBackgroundLabel', | ||||
paddingHorizontal: 16, | paddingHorizontal: 16, | ||||
paddingBottom: 4, | paddingBottom: 4, | ||||
▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines |