diff --git a/web/modals/threads/members/members-modal.react.js b/web/modals/threads/members/members-modal.react.js
--- a/web/modals/threads/members/members-modal.react.js
+++ b/web/modals/threads/members/members-modal.react.js
@@ -3,6 +3,7 @@
import * as React from 'react';
import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { primaryInviteLinksSelector } from 'lib/selectors/invite-links-selectors.js';
import { useUserSearchIndex } from 'lib/selectors/nav-selectors.js';
import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import {
@@ -11,6 +12,7 @@
} from 'lib/shared/thread-utils.js';
import type { RelativeMemberInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { threadTypeIsCommunityRoot } from 'lib/types/thread-types-enum.js';
import { useRolesFromCommunityThreadInfo } from 'lib/utils/role-utils.js';
import { AddMembersModal } from './add-members-modal.react.js';
@@ -18,6 +20,8 @@
import css from './members-modal.css';
import Button from '../../../components/button.react.js';
import Tabs, { type TabData } from '../../../components/tabs.react.js';
+import ManageInviteLinksModal from '../../../invite-links/manage-invite-links-modal.react.js';
+import ViewInviteLinkModal from '../../../invite-links/view-invite-link-modal.react.js';
import { useSelector } from '../../../redux/redux-utils.js';
import SearchModal from '../../search-modal.react.js';
@@ -117,14 +121,41 @@
const threadInfo = useSelector(state => threadInfoSelector(state)[threadID]);
- const onClickAddMembers = React.useCallback(() => {
- pushModal();
- }, [popModal, pushModal, threadID]);
+ const inviteLink = useSelector(primaryInviteLinksSelector)[threadID];
+ const canManageLinks = useThreadHasPermission(
+ threadInfo,
+ threadPermissions.MANAGE_INVITE_LINKS,
+ );
+
+ const isCommunityRoot = threadTypeIsCommunityRoot(threadInfo.type);
- const canAddMembers = useThreadHasPermission(
+ const onClickAddMembers = React.useCallback(() => {
+ if (!isCommunityRoot) {
+ pushModal();
+ } else if (inviteLink) {
+ pushModal();
+ } else if (canManageLinks) {
+ pushModal();
+ }
+ }, [
+ canManageLinks,
+ inviteLink,
+ isCommunityRoot,
+ popModal,
+ pushModal,
+ threadID,
+ ]);
+
+ const canAddMembersViaInviteLink =
+ isCommunityRoot && (inviteLink || canManageLinks);
+
+ const hasAddMembersPermission = useThreadHasPermission(
threadInfo,
threadPermissions.ADD_MEMBERS,
);
+ const canAddMembersManually = hasAddMembersPermission && !isCommunityRoot;
+
+ const canAddMembers = canAddMembersManually || canAddMembersViaInviteLink;
const addMembersButton = React.useMemo(() => {
if (!canAddMembers) {