Management: Add button for group members (#4551)

This commit is contained in:
Alexander Zinchuk 2024-05-14 04:23:42 +02:00
parent 6e056cb2ef
commit 84af0ce28a
2 changed files with 41 additions and 13 deletions

View File

@ -701,7 +701,8 @@ export default memo(withGlobal<OwnProps>(
const areMembersHidden = hasMembersTab && chat const areMembersHidden = hasMembersTab && chat
&& (chat.isForbidden || (chatFullInfo && !chatFullInfo.canViewMembers)); && (chat.isForbidden || (chatFullInfo && !chatFullInfo.canViewMembers));
const canAddMembers = hasMembersTab && chat const canAddMembers = hasMembersTab && chat
&& (getHasAdminRight(chat, 'inviteUsers') || !isUserRightBanned(chat, 'inviteUsers') || chat.isCreator); && (getHasAdminRight(chat, 'inviteUsers') || (!isChannel && !isUserRightBanned(chat, 'inviteUsers'))
|| chat.isCreator);
const canDeleteMembers = hasMembersTab && chat && (getHasAdminRight(chat, 'banUsers') || chat.isCreator); const canDeleteMembers = hasMembersTab && chat && (getHasAdminRight(chat, 'banUsers') || chat.isCreator);
const activeDownloads = selectActiveDownloads(global, chatId); const activeDownloads = selectActiveDownloads(global, chatId);
const { similarChannelIds } = selectSimilarChannelIds(global, chatId) || {}; const { similarChannelIds } = selectSimilarChannelIds(global, chatId) || {};

View File

@ -1,15 +1,15 @@
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import React, { import React, {
memo, useCallback, useMemo, useRef, useState, memo, useMemo, useRef, useState,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../global'; import { getActions, getGlobal, withGlobal } from '../../../global';
import type { ApiChatMember, ApiUserStatus } from '../../../api/types'; import type { ApiChatMember, ApiUserStatus } from '../../../api/types';
import { ManagementScreens } from '../../../types'; import { ManagementScreens, NewChatMembersProgress } from '../../../types';
import { import {
filterUsersByName, getHasAdminRight, isChatBasicGroup, filterUsersByName, getHasAdminRight, isChatBasicGroup,
isChatChannel, isUserBot, sortUserIds, isChatChannel, isUserBot, isUserRightBanned, sortUserIds,
} from '../../../global/helpers'; } from '../../../global/helpers';
import { selectChat, selectChatFullInfo, selectTabState } from '../../../global/selectors'; import { selectChat, selectChatFullInfo, selectTabState } from '../../../global/selectors';
import { unique } from '../../../util/iteratees'; import { unique } from '../../../util/iteratees';
@ -20,9 +20,12 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll'; import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation'; import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import Icon from '../../common/Icon';
import NothingFound from '../../common/NothingFound'; import NothingFound from '../../common/NothingFound';
import PrivateChatInfo from '../../common/PrivateChatInfo'; import PrivateChatInfo from '../../common/PrivateChatInfo';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InfiniteScroll from '../../ui/InfiniteScroll'; import InfiniteScroll from '../../ui/InfiniteScroll';
import InputText from '../../ui/InputText'; import InputText from '../../ui/InputText';
import ListItem, { type MenuItemContextAction } from '../../ui/ListItem'; import ListItem, { type MenuItemContextAction } from '../../ui/ListItem';
@ -42,6 +45,7 @@ type OwnProps = {
type StateProps = { type StateProps = {
userStatusesById: Record<string, ApiUserStatus>; userStatusesById: Record<string, ApiUserStatus>;
members?: ApiChatMember[]; members?: ApiChatMember[];
canAddMembers?: boolean;
adminMembersById?: Record<string, ApiChatMember>; adminMembersById?: Record<string, ApiChatMember>;
isChannel?: boolean; isChannel?: boolean;
localContactIds?: string[]; localContactIds?: string[];
@ -59,6 +63,7 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
chatId, chatId,
noAdmins, noAdmins,
members, members,
canAddMembers,
adminMembersById, adminMembersById,
userStatusesById, userStatusesById,
isChannel, isChannel,
@ -77,7 +82,8 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
onChatMemberSelect, onChatMemberSelect,
}) => { }) => {
const { const {
openChat, setUserSearchQuery, closeManagement, toggleParticipantsHidden, openChat, setUserSearchQuery, closeManagement,
toggleParticipantsHidden, setNewChatMembersDialogState, toggleManagement,
} = getActions(); } = getActions();
const lang = useLang(); const lang = useLang();
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
@ -137,7 +143,7 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
const [viewportIds, getMore] = useInfiniteScroll(undefined, displayedIds, Boolean(searchQuery)); const [viewportIds, getMore] = useInfiniteScroll(undefined, displayedIds, Boolean(searchQuery));
const handleMemberClick = useCallback((id: string) => { const handleMemberClick = useLastCallback((id: string) => {
if (noAdmins) { if (noAdmins) {
onChatMemberSelect!(id, true); onChatMemberSelect!(id, true);
onScreenSelect!(ManagementScreens.ChatNewAdminRights); onScreenSelect!(ManagementScreens.ChatNewAdminRights);
@ -145,24 +151,30 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
closeManagement(); closeManagement();
openChat({ id }); openChat({ id });
} }
}, [closeManagement, noAdmins, onChatMemberSelect, onScreenSelect, openChat]); });
const handleFilterChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => { const handleFilterChange = useLastCallback((e: React.ChangeEvent<HTMLInputElement>) => {
setUserSearchQuery({ query: e.target.value }); setUserSearchQuery({ query: e.target.value });
}, [setUserSearchQuery]); });
const handleKeyDown = useKeyboardListNavigation(containerRef, isActive, (index) => { const handleKeyDown = useKeyboardListNavigation(containerRef, isActive, (index) => {
if (viewportIds && viewportIds.length > 0) { if (viewportIds && viewportIds.length > 0) {
handleMemberClick(viewportIds[index === -1 ? 0 : index]); handleMemberClick(viewportIds[index === -1 ? 0 : index]);
} }
}, '.ListItem-button', true); }, '.ListItem-button', true);
const handleDeleteMembersModalClose = useCallback(() => { const handleDeleteMembersModalClose = useLastCallback(() => {
setDeletingUserId(undefined); setDeletingUserId(undefined);
}, []); });
const handleToggleParticipantsHidden = useCallback(() => { const handleToggleParticipantsHidden = useLastCallback(() => {
toggleParticipantsHidden({ chatId, isEnabled: !areParticipantsHidden }); toggleParticipantsHidden({ chatId, isEnabled: !areParticipantsHidden });
}, [areParticipantsHidden, chatId, toggleParticipantsHidden]); });
const handleNewMemberDialogOpen = useLastCallback(() => {
toggleManagement();
setNewChatMembersDialogState({ newChatMembersProgress: NewChatMembersProgress.InProgress });
});
useHistoryBack({ useHistoryBack({
isActive, isActive,
@ -240,6 +252,15 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
)} )}
</div> </div>
</div> </div>
{canAddMembers && (
<FloatingActionButton
isShown
onClick={handleNewMemberDialogOpen}
ariaLabel={lang('lng_channel_add_users')}
>
<Icon name="add-user-filled" />
</FloatingActionButton>
)}
{canDeleteMembers && ( {canDeleteMembers && (
<DeleteMemberModal <DeleteMemberModal
isOpen={Boolean(deletingUserId)} isOpen={Boolean(deletingUserId)}
@ -265,6 +286,11 @@ export default memo(withGlobal<OwnProps>(
const canHideParticipants = canDeleteMembers && !isChatBasicGroup(chat) && chat.membersCount !== undefined const canHideParticipants = canDeleteMembers && !isChatBasicGroup(chat) && chat.membersCount !== undefined
&& hiddenMembersMinCount !== undefined && chat.membersCount >= hiddenMembersMinCount; && hiddenMembersMinCount !== undefined && chat.membersCount >= hiddenMembersMinCount;
const canAddMembers = chat && ((getHasAdminRight(chat, 'inviteUsers')
|| (!isChannel && !isUserRightBanned(chat, 'inviteUsers')))
|| chat.isCreator
);
const { const {
query: searchQuery, query: searchQuery,
fetchingStatus, fetchingStatus,
@ -275,6 +301,7 @@ export default memo(withGlobal<OwnProps>(
return { return {
areParticipantsHidden: Boolean(chat && areParticipantsHidden), areParticipantsHidden: Boolean(chat && areParticipantsHidden),
members, members,
canAddMembers,
adminMembersById, adminMembersById,
userStatusesById, userStatusesById,
isChannel, isChannel,