Invite Via Link: Show error when user is restricted to add new users (#4435)

This commit is contained in:
Alexander Zinchuk 2024-03-29 20:51:19 +01:00
parent 3eb675c8fa
commit e21249cf0f
3 changed files with 55 additions and 21 deletions

View File

@ -1444,10 +1444,11 @@ export async function addChatMembers(chat: ApiChat, users: ApiUser[]) {
shouldIgnoreUpdates: true,
shouldThrow: true,
});
if (updates) {
processUpdate(updates);
return handleUserPrivacyRestrictedUpdates(updates);
if (!updates) {
return undefined;
}
processUpdate(updates);
return handleUserPrivacyRestrictedUpdates(updates);
} catch (err) {
if ((err as Error).message === 'USER_PRIVACY_RESTRICTED') {
return users.map(({ id }) => id);

View File

@ -37,6 +37,7 @@ type OwnProps = {
isRoundCheckbox?: boolean;
lockedIds?: string[];
forceShowSelf?: boolean;
isViewOnly?: boolean;
onSelectedIdsChange?: (ids: string[]) => void;
onFilterChange?: (value: string) => void;
onDisabledClick?: (id: string) => void;
@ -63,6 +64,7 @@ const Picker: FC<OwnProps> = ({
isRoundCheckbox,
lockedIds,
forceShowSelf,
isViewOnly,
onSelectedIdsChange,
onFilterChange,
onDisabledClick,
@ -171,7 +173,7 @@ const Picker: FC<OwnProps> = ({
>
{viewportIds.map((id) => {
const renderCheckbox = () => {
return (
return isViewOnly ? undefined : (
<Checkbox
label=""
disabled={lockedIdsSet.has(id)}
@ -185,6 +187,7 @@ const Picker: FC<OwnProps> = ({
key={id}
className={buildClassName('chat-item-clickable picker-list-item', isRoundCheckbox && 'chat-item')}
disabled={lockedIdsSet.has(id)}
inactive={isViewOnly}
allowDisabledClick={Boolean(onDisabledClick)}
// eslint-disable-next-line react/jsx-no-bind
onClick={() => handleItemClick(id)}

View File

@ -7,6 +7,7 @@ import React, {
import { getActions, getGlobal } from '../../global';
import { getUserFullName } from '../../global/helpers';
import { selectChat } from '../../global/selectors';
import renderText from '../common/helpers/renderText';
import useLang from '../../hooks/useLang';
@ -50,39 +51,68 @@ const InviteViaLinkModal: FC<OwnProps> = ({
return userIds?.map((userId) => getUserFullName(usersById[userId])).join(', ');
}, [userIds]);
const canSendInviteLink = useMemo(() => {
if (!chatId) {
return false;
}
const chat = selectChat(getGlobal(), chatId);
return Boolean(chat?.isCreator || chat?.adminRights?.inviteUsers);
}, [chatId]);
const contentText = useMemo(() => {
const langKey = canSendInviteLink
? 'SendInviteLink.TextAvailableSingleUser'
: 'SendInviteLink.TextUnavailableSingleUser';
return renderText(lang(langKey, userNames), ['simple_markdown']);
}, [userNames, lang, canSendInviteLink]);
return (
<Modal
isOpen={Boolean(userIds && chatId)}
title={lang('SendInviteLink.InviteTitle')}
title={canSendInviteLink ? lang('SendInviteLink.InviteTitle') : lang('SendInviteLink.LinkUnavailableTitle')}
onClose={handleClose}
isSlim
>
<p className={styles.contentText}>
{renderText(lang('SendInviteLink.TextAvailableSingleUser', userNames), ['simple_markdown'])}
{contentText}
</p>
<Picker
className={styles.userPicker}
itemIds={userIds!}
selectedIds={selectedMemberIds}
onSelectedIdsChange={setSelectedMemberIds}
isViewOnly={!canSendInviteLink}
isRoundCheckbox
/>
<div className="dialog-buttons">
<Button
className="confirm-dialog-button"
isText
onClick={handleSendInviteLink}
disabled={!selectedMemberIds.length}
>
{lang('SendInviteLink.ActionInvite')}
</Button>
<Button
className="confirm-dialog-button"
isText
onClick={handleSkip}
>
{lang('SendInviteLink.ActionSkip')}
</Button>
{canSendInviteLink && (
<Button
className="confirm-dialog-button"
isText
onClick={handleSendInviteLink}
disabled={!selectedMemberIds.length}
>
{lang('SendInviteLink.ActionInvite')}
</Button>
)}
{canSendInviteLink && (
<Button
className="confirm-dialog-button"
isText
onClick={handleSkip}
>
{lang('SendInviteLink.ActionSkip')}
</Button>
)}
{!canSendInviteLink && (
<Button
className="confirm-dialog-button"
isText
onClick={handleClose}
>
{lang('SendInviteLink.ActionClose')}
</Button>
)}
</div>
</Modal>
);