diff --git a/native/invite-links/invite-links-button.react.js b/native/invite-links/invite-links-button.react.js
index 516fa2887..f7aa6b8d4 100644
--- a/native/invite-links/invite-links-button.react.js
+++ b/native/invite-links/invite-links-button.react.js
@@ -1,134 +1,134 @@
// @flow
import { useActionSheet } from '@expo/react-native-action-sheet';
import { useNavigation } from '@react-navigation/native';
import * as React from 'react';
import { TouchableOpacity, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
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 SWMansionIcon from '../components/swmansion-icon.react.js';
import {
InviteLinkNavigatorRouteName,
ManagePublicLinkRouteName,
ViewInviteLinksRouteName,
} from '../navigation/route-names.js';
import { useSelector } from '../redux/redux-utils.js';
import { useStyles } from '../themes/colors.js';
type Props = {
+community: ThreadInfo,
};
function InviteLinksButton(props: Props): React.Node {
const { community } = props;
const inviteLink = useSelector(primaryInviteLinksSelector)[community.id];
const { navigate } = useNavigation();
const navigateToInviteLinksView = React.useCallback(() => {
if (!inviteLink || !community) {
return;
}
navigate<'InviteLinkNavigator'>(InviteLinkNavigatorRouteName, {
screen: ViewInviteLinksRouteName,
params: {
community,
},
});
}, [community, inviteLink, navigate]);
const navigateToManagePublicLinkView = React.useCallback(() => {
navigate<'InviteLinkNavigator'>(InviteLinkNavigatorRouteName, {
screen: ManagePublicLinkRouteName,
params: {
community,
},
});
}, [community, navigate]);
const insets = useSafeAreaInsets();
const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme);
const styles = useStyles(unboundStyles);
const { showActionSheetWithOptions } = useActionSheet();
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',
+ label: 'Manage invite links',
action: navigateToManagePublicLinkView,
});
}
if (inviteLink) {
result.push({
- label: 'Invite Link',
+ label: 'Invite link',
action: navigateToInviteLinksView,
});
}
if (result.length > 0) {
return result;
}
return null;
}, [
community,
inviteLink,
navigateToInviteLinksView,
navigateToManagePublicLinkView,
]);
const openActionSheet = React.useCallback(() => {
if (!actions) {
return;
}
const options = [...actions.map(a => a.label), 'Cancel'];
showActionSheetWithOptions(
{
options,
cancelButtonIndex: options.length - 1,
containerStyle: {
paddingBottom: insets.bottom,
},
userInterfaceStyle: activeTheme ?? 'dark',
},
selectedIndex => {
if (selectedIndex !== undefined && selectedIndex < actions.length) {
actions[selectedIndex].action();
}
},
);
}, [actions, activeTheme, insets.bottom, showActionSheetWithOptions]);
let button = null;
if (actions) {
button = (
);
}
return {button};
}
const unboundStyles = {
button: {
color: 'drawerItemLabelLevel0',
},
container: {
width: 22,
},
};
export default InviteLinksButton;
diff --git a/native/invite-links/invite-links-navigator.react.js b/native/invite-links/invite-links-navigator.react.js
index c419626b2..052c884d4 100644
--- a/native/invite-links/invite-links-navigator.react.js
+++ b/native/invite-links/invite-links-navigator.react.js
@@ -1,97 +1,93 @@
// @flow
import {
createStackNavigator,
type StackNavigationHelpers,
type StackNavigationProp,
} from '@react-navigation/stack';
import * as React from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';
import ManagePublicLinkScreen from './manage-public-link-screen.react.js';
import ViewInviteLinksHeaderLeftButton from './view-invite-links-header-left-button.react.js';
-import ViewInviteLinksHeaderTitle from './view-invite-links-header-title.react.js';
import ViewInviteLinksScreen from './view-invite-links-screen.react.js';
import HeaderBackButton from '../navigation/header-back-button.react.js';
import { defaultStackScreenOptions } from '../navigation/options.js';
import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
import {
type InviteLinkParamList,
ViewInviteLinksRouteName,
type ScreenParamList,
ManagePublicLinkRouteName,
} from '../navigation/route-names.js';
import { useColors, useStyles } from '../themes/colors.js';
const safeAreaEdges = ['bottom'];
export type InviteLinksNavigationProps<
RouteName: $Keys = $Keys,
> = StackNavigationProp;
const InviteLinksStack = createStackNavigator<
ScreenParamList,
InviteLinkParamList,
StackNavigationHelpers,
>();
-const viewInviteLinksOptions = ({ route }) => ({
- // eslint-disable-next-line react/display-name
- headerTitle: props => (
-
- ),
+const viewInviteLinksOptions = {
+ headerTitle: 'Invite link',
headerLeft: ViewInviteLinksHeaderLeftButton,
headerBackImage: () => null,
headerBackTitleStyle: { marginLeft: 20 },
-});
+};
const managePublicLinkOptions = {
- headerTitle: 'Public Link',
+ headerTitle: 'Public link',
headerBackTitleVisible: false,
headerLeft: HeaderBackButton,
};
type Props = {
+navigation: RootNavigationProp<'InviteLinkNavigator'>,
...
};
// eslint-disable-next-line no-unused-vars
function InviteLinksNavigator(props: Props): React.Node {
const styles = useStyles(unboundStyles);
const colors = useColors();
const screenOptions = React.useMemo(
() => ({
...defaultStackScreenOptions,
headerStyle: {
backgroundColor: colors.modalBackground,
borderBottomWidth: 1,
},
}),
[colors.modalBackground],
);
return (
);
}
const unboundStyles = {
container: {
flex: 1,
backgroundColor: 'modalBackground',
},
};
export default InviteLinksNavigator;
diff --git a/native/invite-links/manage-public-link-screen.react.js b/native/invite-links/manage-public-link-screen.react.js
index 9e9f10573..627b1c8ae 100644
--- a/native/invite-links/manage-public-link-screen.react.js
+++ b/native/invite-links/manage-public-link-screen.react.js
@@ -1,206 +1,205 @@
// @flow
import * as React from 'react';
import { Text, View, Alert } from 'react-native';
import { inviteLinkUrl } from 'lib/facts/links.js';
import { useInviteLinksActions } from 'lib/hooks/invite-links.js';
import { primaryInviteLinksSelector } from 'lib/selectors/invite-links-selectors.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
import Button from '../components/button.react.js';
import TextInput from '../components/text-input.react.js';
import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
import type { NavigationRoute } from '../navigation/route-names.js';
import { useSelector } from '../redux/redux-utils.js';
import { useStyles } from '../themes/colors.js';
export type ManagePublicLinkScreenParams = {
+community: ThreadInfo,
};
type Props = {
+navigation: RootNavigationProp<'ManagePublicLink'>,
+route: NavigationRoute<'ManagePublicLink'>,
};
function ManagePublicLinkScreen(props: Props): React.Node {
const { community } = props.route.params;
const inviteLink = useSelector(primaryInviteLinksSelector)[community.id];
const {
error,
isLoading,
name,
setName,
createOrUpdateInviteLink,
disableInviteLink,
} = useInviteLinksActions(community.id, inviteLink);
const styles = useStyles(unboundStyles);
let errorComponent = null;
if (error) {
errorComponent = {error};
}
const onDisableButtonClick = React.useCallback(() => {
Alert.alert(
'Disable public link',
- 'Are you sure you want to disable your public link? Members who have your community’s public link but have not joined will not able to with the disabled link. \n' +
+ 'Are you sure you want to disable your public link?\n' +
'\n' +
- 'Other communities may also claim your previous public link url.',
+ 'Other communities will be able to claim the same URL.',
[
{
text: 'Confirm disable',
style: 'destructive',
onPress: disableInviteLink,
},
{
text: 'Cancel',
},
],
{
cancelable: true,
},
);
}, [disableInviteLink]);
let disablePublicLinkButton = null;
if (inviteLink) {
disablePublicLinkButton = (
);
}
return (
- 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 to join your community.{'\n\n'}
- Editing your community’s public link allows other communities to claim
- your previous URL.
+ Invite links make it easy for your friends to join your community.
+ Anybody who knows your community’s invite link will be able to join
+ it.{'\n\n'}Note that if you change your public link’s URL, other
+ communities will be able to claim the old URL.
INVITE URL{inviteLinkUrl('')}
{errorComponent}
{disablePublicLinkButton}
);
}
const unboundStyles = {
sectionTitle: {
fontSize: 14,
fontWeight: '400',
lineHeight: 20,
color: 'modalBackgroundLabel',
paddingHorizontal: 16,
paddingBottom: 4,
marginTop: 24,
},
section: {
borderBottomColor: 'modalSeparator',
borderBottomWidth: 1,
borderTopColor: 'modalSeparator',
borderTopWidth: 1,
backgroundColor: 'modalForeground',
padding: 16,
},
sectionText: {
fontSize: 14,
fontWeight: '400',
lineHeight: 22,
color: 'modalBackgroundLabel',
},
inviteLink: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 8,
},
inviteLinkPrefix: {
fontSize: 14,
fontWeight: '400',
lineHeight: 22,
color: 'disabledButtonText',
marginRight: 2,
},
input: {
color: 'panelForegroundLabel',
borderColor: 'panelSecondaryForegroundBorder',
borderWidth: 1,
borderRadius: 8,
paddingVertical: 13,
paddingHorizontal: 16,
flex: 1,
},
button: {
borderRadius: 8,
paddingVertical: 12,
paddingHorizontal: 24,
marginTop: 8,
},
buttonPrimary: {
backgroundColor: 'purpleButton',
},
destructiveButtonContainer: {
margin: 16,
},
destructiveButton: {
borderWidth: 1,
borderRadius: 8,
borderColor: 'vibrantRedButton',
},
destructiveButtonText: {
fontSize: 16,
fontWeight: '500',
lineHeight: 24,
color: 'vibrantRedButton',
textAlign: 'center',
},
buttonText: {
color: 'whiteText',
textAlign: 'center',
fontWeight: '500',
fontSize: 16,
lineHeight: 24,
},
error: {
fontSize: 12,
fontWeight: '400',
lineHeight: 18,
textAlign: 'center',
color: 'redText',
},
};
export default ManagePublicLinkScreen;
diff --git a/native/invite-links/view-invite-links-header-title.react.js b/native/invite-links/view-invite-links-header-title.react.js
deleted file mode 100644
index 112b292e8..000000000
--- a/native/invite-links/view-invite-links-header-title.react.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// @flow
-
-import type { HeaderTitleInputProps } from '@react-navigation/elements';
-import { HeaderTitle } from '@react-navigation/elements';
-import * as React from 'react';
-
-import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import { firstLine } from 'lib/utils/string-utils.js';
-
-type Props = {
- +community: ThreadInfo,
- ...HeaderTitleInputProps,
-};
-function ViewInviteLinksHeaderTitle(props: Props): React.Node {
- const { community, ...rest } = props;
- const { uiName } = useResolvedThreadInfo(community);
- const title = `Invite people to ${firstLine(uiName)}`;
- return {title};
-}
-
-const MemoizedViewInviteLinksHeaderTitle: React.ComponentType =
- React.memo(ViewInviteLinksHeaderTitle);
-
-export default MemoizedViewInviteLinksHeaderTitle;
diff --git a/native/invite-links/view-invite-links-screen.react.js b/native/invite-links/view-invite-links-screen.react.js
index 6a272f3d8..9b75b1dd8 100644
--- a/native/invite-links/view-invite-links-screen.react.js
+++ b/native/invite-links/view-invite-links-screen.react.js
@@ -1,167 +1,167 @@
// @flow
import Clipboard from '@react-native-clipboard/clipboard';
import * as React from 'react';
import { Text, View } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { inviteLinkUrl } from 'lib/facts/links.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 { threadPermissions } from 'lib/types/thread-permission-types.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
import SWMansionIcon from '../components/swmansion-icon.react.js';
import { displayActionResultModal } from '../navigation/action-result-modal.js';
import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
import {
ManagePublicLinkRouteName,
type NavigationRoute,
} from '../navigation/route-names.js';
import { useSelector } from '../redux/redux-utils.js';
import { useStyles, useColors } from '../themes/colors.js';
export type ViewInviteLinksScreenParams = {
+community: ThreadInfo,
};
type Props = {
+navigation: RootNavigationProp<'ViewInviteLinks'>,
+route: NavigationRoute<'ViewInviteLinks'>,
};
const confirmCopy = () => displayActionResultModal('copied!');
function ViewInviteLinksScreen(props: Props): React.Node {
const { community } = props.route.params;
const inviteLink: ?InviteLink = useSelector(primaryInviteLinksSelector)[
community.id
];
const styles = useStyles(unboundStyles);
const { modalForegroundLabel } = useColors();
const linkUrl = inviteLinkUrl(inviteLink?.name ?? '');
const onPressCopy = React.useCallback(() => {
Clipboard.setString(linkUrl);
setTimeout(confirmCopy);
}, [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;
if (inviteLink || canManageLinks) {
let description;
if (canManageLinks) {
description = (
<>
Public links allow unlimited uses and never expire.
Edit public link
>
);
} else {
description = (
- Use this public link to invite your friends into the community!
+ Share this invite link to help your friends join your community!
);
}
publicLinkSection = (
<>
PUBLIC LINK{linkUrl}Copy
{description}
>
);
}
return {publicLinkSection};
}
const unboundStyles = {
container: {
flex: 1,
paddingTop: 24,
},
sectionTitle: {
fontSize: 12,
fontWeight: '400',
lineHeight: 18,
color: 'modalBackgroundLabel',
paddingHorizontal: 16,
paddingBottom: 4,
},
section: {
borderBottomColor: 'modalSeparator',
borderBottomWidth: 1,
borderTopColor: 'modalSeparator',
borderTopWidth: 1,
backgroundColor: 'modalForeground',
padding: 16,
},
link: {
paddingHorizontal: 16,
paddingVertical: 9,
marginBottom: 16,
backgroundColor: 'inviteLinkButtonBackground',
borderRadius: 20,
flexDirection: 'row',
justifyContent: 'space-between',
},
linkText: {
fontSize: 14,
fontWeight: '400',
lineHeight: 22,
color: 'inviteLinkLinkColor',
},
button: {
flexDirection: 'row',
alignItems: 'center',
},
copy: {
fontSize: 12,
fontWeight: '400',
lineHeight: 18,
color: 'modalForegroundLabel',
paddingLeft: 8,
},
details: {
fontSize: 12,
fontWeight: '400',
lineHeight: 18,
color: 'modalForegroundLabel',
},
editLinkButton: {
color: 'purpleLink',
},
};
export default ViewInviteLinksScreen;
diff --git a/native/navigation/invite-link-modal.react.js b/native/navigation/invite-link-modal.react.js
index 716e80054..b805a26f4 100644
--- a/native/navigation/invite-link-modal.react.js
+++ b/native/navigation/invite-link-modal.react.js
@@ -1,254 +1,254 @@
// @flow
import invariant from 'invariant';
import * as React from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import {
joinThread,
joinThreadActionTypes,
} from 'lib/actions/thread-actions.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.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, 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
+ 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();
try {
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;
} catch (e) {
props.navigation.setParams({
invitationDetails: {
status: 'invalid',
},
secret,
});
throw e;
}
}, [calendarQuery, callJoinThread, communityID, props.navigation, secret]);
const dispatchActionPromise = useDispatchActionPromise();
const joinCommunity = React.useCallback(() => {
dispatchActionPromise(joinThreadActionTypes, createJoinCommunityAction());
}, [createJoinCommunityAction, dispatchActionPromise]);
const joinThreadLoadingStatus = useSelector(joinThreadLoadingStatusSelector);
const buttons = React.useMemo(() => {
if (invitationDetails.status === 'valid') {
const joinButtonContent =
joinThreadLoadingStatus === 'loading' ? (
) : (
- Accept Invite
+ Accept invite
);
return (
<>
>
);
}
return (
);
}, [
invitationDetails.status,
joinCommunity,
joinThreadLoadingStatus,
props.navigation.goBack,
styles.activityIndicatorStyle,
styles.button,
styles.buttonPrimary,
styles.buttonSecondary,
styles.buttonText,
styles.gap,
]);
return (
{header}{buttons}
);
}
const joinThreadLoadingStatusSelector = createLoadingStatusSelector(
joinThreadActionTypes,
);
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;
diff --git a/web/invite-links/accept-invite-modal.react.js b/web/invite-links/accept-invite-modal.react.js
index 148dc362f..3c807899d 100644
--- a/web/invite-links/accept-invite-modal.react.js
+++ b/web/invite-links/accept-invite-modal.react.js
@@ -1,133 +1,133 @@
// @flow
import invariant from 'invariant';
import * as React from 'react';
import {
joinThread,
joinThreadActionTypes,
} from 'lib/actions/thread-actions.js';
import ModalOverlay from 'lib/components/modal-overlay.react.js';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { type InviteLinkVerificationResponse } from 'lib/types/link-types.js';
import {
useDispatchActionPromise,
useServerCall,
} from 'lib/utils/action-utils.js';
import css from './accept-invite-modal.css';
import Button, { buttonThemes } from '../components/button.react.js';
import { useSelector } from '../redux/redux-utils.js';
import { nonThreadCalendarQuery } from '../selectors/nav-selectors.js';
type Props = {
+verificationResponse: InviteLinkVerificationResponse,
+inviteSecret: string,
};
function AcceptInviteModal(props: Props): React.Node {
const { verificationResponse, inviteSecret } = props;
const [isLinkValid, setIsLinkValid] = React.useState(
verificationResponse.status === 'valid',
);
const { popModal } = useModalContext();
React.useEffect(() => {
if (verificationResponse.status === 'already_joined') {
popModal();
}
}, [popModal, verificationResponse.status]);
const callJoinThread = useServerCall(joinThread);
const calendarQuery = useSelector(nonThreadCalendarQuery);
const communityID = verificationResponse.community?.id;
const createJoinCommunityAction = React.useCallback(async () => {
invariant(
communityID,
'CommunityID should be present while calling this function',
);
const query = calendarQuery();
try {
const result = await callJoinThread({
threadID: communityID,
calendarQuery: {
startDate: query.startDate,
endDate: query.endDate,
filters: [
...query.filters,
{ type: 'threads', threadIDs: [communityID] },
],
},
inviteLinkSecret: inviteSecret,
});
popModal();
return result;
} catch (e) {
setIsLinkValid(false);
throw e;
}
}, [calendarQuery, callJoinThread, communityID, inviteSecret, popModal]);
const dispatchActionPromise = useDispatchActionPromise();
const joinCommunity = React.useCallback(() => {
dispatchActionPromise(joinThreadActionTypes, createJoinCommunityAction());
}, [createJoinCommunityAction, dispatchActionPromise]);
const joinThreadLoadingStatus = useSelector(joinThreadLoadingStatusSelector);
let content;
if (verificationResponse.status === 'valid' && isLinkValid) {
const { community } = verificationResponse;
content = (
<>
You have been invited to join
{community.name}
>
);
} else {
content = (
<>
Invite invalid
- This invite link may be expired, please try again with another
- invite link
+ This invite link may be expired. Please try again with another
+ invite link.
>
);
}
return (
{content}
);
}
const joinThreadLoadingStatusSelector = createLoadingStatusSelector(
joinThreadActionTypes,
);
export default AcceptInviteModal;
diff --git a/web/invite-links/view-invite-link-modal.react.js b/web/invite-links/view-invite-link-modal.react.js
index de6b93540..4f59c1fb9 100644
--- a/web/invite-links/view-invite-link-modal.react.js
+++ b/web/invite-links/view-invite-link-modal.react.js
@@ -1,44 +1,33 @@
// @flow
import * as React from 'react';
import { useModalContext } from 'lib/components/modal-provider.react.js';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import type { InviteLink } from 'lib/types/link-types.js';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
import CopyInviteLinkButton from './copy-invite-link-button.react.js';
import css from './view-invite-link-modal.css';
import Modal from '../modals/modal.react.js';
-import { useSelector } from '../redux/redux-utils.js';
type Props = {
+inviteLink: InviteLink,
};
function ViewInviteLinkModal(props: Props): React.Node {
const { inviteLink } = props;
- const threadInfo = useSelector(
- state => threadInfoSelector(state)[inviteLink.communityID],
- );
- const resolvedThreadInfo = useResolvedThreadInfo(threadInfo);
const { popModal } = useModalContext();
return (
-
+
- Use this public link to invite your friends into the community!
+ Share this invite link to help your friends join your community!