diff --git a/native/navigation/invite-link-modal.react.js b/native/navigation/invite-link-modal.react.js index 98e7685c0..b7d579e0e 100644 --- a/native/navigation/invite-link-modal.react.js +++ b/native/navigation/invite-link-modal.react.js @@ -1,219 +1,243 @@ // @flow import * as React from 'react'; import { View, Text, ActivityIndicator } from 'react-native'; import { inviteLinkTexts, useAcceptInviteLink, } from 'lib/hooks/invite-links.js'; import type { LinkStatus } from 'lib/hooks/invite-links.js'; +import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; import type { KeyserverOverride } from 'lib/shared/invite-links'; import type { InviteLinkVerificationResponse } from 'lib/types/link-types.js'; import { nonThreadCalendarQuery } from './nav-selectors.js'; import { NavContext } from './navigation-context.js'; import type { RootNavigationProp } from './root-navigator.react.js'; import type { NavigationRoute } from './route-names.js'; +import { useNavigateToThread } from '../chat/message-list-types.js'; import Button from '../components/button.react.js'; import Modal from '../components/modal.react.js'; import { useSelector } from '../redux/redux-utils.js'; import { useStyles } from '../themes/colors.js'; export type InviteLinkModalParams = { +invitationDetails: InviteLinkVerificationResponse, +secret: string, +keyserverOverride?: ?KeyserverOverride, }; type Props = { +navigation: RootNavigationProp<'InviteLinkModal'>, +route: NavigationRoute<'InviteLinkModal'>, }; function InviteLinkModal(props: Props): React.Node { const styles = useStyles(unboundStyles); const { invitationDetails, secret, keyserverOverride } = props.route.params; const [linkStatus, setLinkStatus] = React.useState( invitationDetails.status === 'expired' ? 'invalid' : invitationDetails.status, ); const navContext = React.useContext(NavContext); const calendarQuery = useSelector(state => nonThreadCalendarQuery({ redux: state, navContext, }), ); const { joinCommunity, joinThreadLoadingStatus } = useAcceptInviteLink({ verificationResponse: invitationDetails, inviteSecret: secret, keyserverOverride, calendarQuery, onFinish: props.navigation.goBack, setLinkStatus, }); const header = React.useMemo(() => { if (invitationDetails.status === 'valid' && linkStatus === 'valid') { return ( <> You have been invited to join {invitationDetails.community.name} ); } return ( <> {inviteLinkTexts[linkStatus].header} {inviteLinkTexts[linkStatus].message} ); }, [ invitationDetails, styles.communityName, styles.invalidInviteExplanation, styles.invalidInviteTitle, styles.invitation, linkStatus, ]); + const threadInfos = useSelector(threadInfoSelector); + const navigateToThread = useNavigateToThread(); + const closeModal = React.useCallback(() => { + const communityID = invitationDetails.community?.id; + if ( + linkStatus === 'already_joined' && + communityID && + threadInfos[communityID] + ) { + navigateToThread({ threadInfo: threadInfos[communityID] }); + } else { + props.navigation.goBack(); + } + }, [ + invitationDetails.community?.id, + linkStatus, + navigateToThread, + props.navigation, + threadInfos, + ]); + const buttons = React.useMemo(() => { if (linkStatus === 'valid') { const joinButtonContent = joinThreadLoadingStatus === 'loading' ? ( ) : ( Accept invite ); return ( <> ); } return ( ); }, [ - linkStatus, + closeModal, joinCommunity, joinThreadLoadingStatus, + linkStatus, props.navigation.goBack, styles.activityIndicatorStyle, styles.button, styles.buttonPrimary, styles.buttonSecondary, styles.buttonText, styles.gap, ]); return ( {header} {buttons} ); } const unboundStyles = { modal: { backgroundColor: 'modalForeground', paddingVertical: 24, paddingHorizontal: 16, flex: 0, }, invitation: { color: 'whiteText', textAlign: 'center', fontSize: 14, fontWeight: '400', lineHeight: 22, marginBottom: 24, }, communityName: { color: 'whiteText', textAlign: 'center', fontSize: 18, fontWeight: '500', lineHeight: 24, }, invalidInviteTitle: { color: 'whiteText', textAlign: 'center', fontSize: 22, fontWeight: '500', lineHeight: 28, marginBottom: 24, }, invalidInviteExplanation: { color: 'whiteText', textAlign: 'center', fontSize: 14, fontWeight: '400', lineHeight: 22, }, separator: { height: 1, backgroundColor: 'modalSeparator', marginVertical: 24, }, gap: { marginBottom: 16, }, button: { borderRadius: 8, paddingVertical: 12, paddingHorizontal: 24, }, buttonPrimary: { backgroundColor: 'purpleButton', }, buttonSecondary: { borderColor: 'secondaryButtonBorder', borderWidth: 1, }, buttonText: { color: 'whiteText', textAlign: 'center', fontSize: 16, fontWeight: '500', lineHeight: 24, }, activityIndicatorStyle: { paddingVertical: 2, }, }; export default InviteLinkModal;