diff --git a/native/navigation/invite-link-modal.react.js b/native/navigation/invite-link-modal.react.js
index 7bb3decad..5d3c3866e 100644
--- a/native/navigation/invite-link-modal.react.js
+++ b/native/navigation/invite-link-modal.react.js
@@ -1,174 +1,222 @@
// @flow
+import invariant from 'invariant';
import * as React from 'react';
import { View, Text } from 'react-native';
+import {
+ joinThread,
+ joinThreadActionTypes,
+} from 'lib/actions/thread-actions.js';
import type { InviteLinkVerificationResponse } from 'lib/types/link-types.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from 'lib/utils/action-utils.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 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,
};
type Props = {
+navigation: RootNavigationProp<'InviteLinkModal'>,
+route: NavigationRoute<'InviteLinkModal'>,
};
function InviteLinkModal(props: Props): React.Node {
const styles = useStyles(unboundStyles);
- const { invitationDetails } = props.route.params;
+ const { invitationDetails, secret } = props.route.params;
React.useEffect(() => {
if (invitationDetails.status === 'already_joined') {
props.navigation.goBack();
}
}, [invitationDetails.status, props.navigation]);
const header = React.useMemo(() => {
if (invitationDetails.status === 'valid') {
return (
<>
You have been invited to join
{invitationDetails.community.name}
>
);
}
return (
<>
Invite invalid
This invite link may be expired, please try again with another invite
link
>
);
}, [
invitationDetails,
styles.communityName,
styles.invalidInviteExplanation,
styles.invalidInviteTitle,
styles.invitation,
]);
+ const callJoinThread = useServerCall(joinThread);
+ const navContext = React.useContext(NavContext);
+ const calendarQuery = useSelector(state =>
+ nonThreadCalendarQuery({
+ redux: state,
+ navContext,
+ }),
+ );
+ const communityID = invitationDetails.community?.id;
+ const createJoinCommunityAction = React.useCallback(async () => {
+ invariant(
+ communityID,
+ 'CommunityID should be present while calling this function',
+ );
+ const query = calendarQuery();
+ const result = await callJoinThread({
+ threadID: communityID,
+ calendarQuery: {
+ startDate: query.startDate,
+ endDate: query.endDate,
+ filters: [
+ ...query.filters,
+ { type: 'threads', threadIDs: [communityID] },
+ ],
+ },
+ inviteLinkSecret: secret,
+ });
+ props.navigation.goBack();
+ return result;
+ }, [calendarQuery, callJoinThread, communityID, props.navigation, secret]);
+ const dispatchActionPromise = useDispatchActionPromise();
+ const joinCommunity = React.useCallback(() => {
+ dispatchActionPromise(joinThreadActionTypes, createJoinCommunityAction());
+ }, [createJoinCommunityAction, dispatchActionPromise]);
+
const buttons = React.useMemo(() => {
if (invitationDetails.status === 'valid') {
return (
<>
>
);
}
return (
);
}, [
invitationDetails.status,
+ joinCommunity,
props.navigation.goBack,
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,
},
};
export default InviteLinkModal;