import type { FC } from '../../../lib/teact/teact'; import React, { memo, useCallback, useMemo, useState, } from '../../../lib/teact/teact'; import { getActions, withGlobal } from '../../../global'; import { ManagementScreens } from '../../../types'; import type { ApiChat, ApiChatBannedRights, ApiChatMember } from '../../../api/types'; import stopEvent from '../../../util/stopEvent'; import buildClassName from '../../../util/buildClassName'; import { isChatPublic } from '../../../global/helpers'; import useLang from '../../../hooks/useLang'; import { selectChat } from '../../../global/selectors'; import useHistoryBack from '../../../hooks/useHistoryBack'; import useManagePermissions from '../hooks/useManagePermissions'; import ListItem from '../../ui/ListItem'; import Checkbox from '../../ui/Checkbox'; import FloatingActionButton from '../../ui/FloatingActionButton'; import Spinner from '../../ui/Spinner'; import PrivateChatInfo from '../../common/PrivateChatInfo'; type OwnProps = { chatId: string; onScreenSelect: (screen: ManagementScreens) => void; onChatMemberSelect: (memberId: string, isPromotedByCurrentUser?: boolean) => void; onClose: NoneToVoidFunction; isActive: boolean; }; type StateProps = { chat?: ApiChat; currentUserId?: string; hasLinkedChat?: boolean; }; const ITEM_HEIGHT = 24 + 32; const BEFORE_ITEMS_COUNT = 2; const ITEMS_COUNT = 9; function getLangKeyForBannedRightKey(key: keyof ApiChatBannedRights) { switch (key) { case 'sendMessages': return 'UserRestrictionsNoSend'; case 'sendMedia': return 'UserRestrictionsNoSendMedia'; case 'sendStickers': return 'UserRestrictionsNoSendStickers'; case 'embedLinks': return 'UserRestrictionsNoEmbedLinks'; case 'sendPolls': return 'UserRestrictionsNoSendPolls'; case 'changeInfo': return 'UserRestrictionsNoChangeInfo'; case 'inviteUsers': return 'UserRestrictionsInviteUsers'; case 'pinMessages': return 'UserRestrictionsPinMessages'; case 'manageTopics': return 'GroupPermission.NoManageTopics'; case 'sendPlain': return 'UserRestrictionsNoSendText'; case 'sendDocs': return 'UserRestrictionsNoSendDocs'; case 'sendRoundvideos': return 'UserRestrictionsNoSendRound'; case 'sendVoices': return 'UserRestrictionsNoSendVoice'; case 'sendAudios': return 'UserRestrictionsNoSendMusic'; case 'sendVideos': return 'UserRestrictionsNoSendVideos'; case 'sendPhotos': return 'UserRestrictionsNoSendPhotos'; default: return undefined; } } const ManageGroupPermissions: FC = ({ onScreenSelect, onChatMemberSelect, chat, currentUserId, hasLinkedChat, onClose, isActive, }) => { const { updateChatDefaultBannedRights, showNotification } = getActions(); const { permissions, havePermissionChanged, isLoading, handlePermissionChange, setIsLoading, } = useManagePermissions(chat?.defaultBannedRights); const lang = useLang(); const { isForum } = chat || {}; const isPublic = useMemo(() => chat && isChatPublic(chat), [chat]); const shouldDisablePermissionForPublicGroup = hasLinkedChat || isPublic; useHistoryBack({ isActive, onBack: onClose, }); const handleRemovedUsersClick = useCallback(() => { onScreenSelect(ManagementScreens.GroupRemovedUsers); }, [onScreenSelect]); const handleAddExceptionClick = useCallback(() => { onScreenSelect(ManagementScreens.GroupUserPermissionsCreate); }, [onScreenSelect]); const handleExceptionMemberClick = useCallback((member: ApiChatMember) => { onChatMemberSelect(member.userId, member.promotedByUserId === currentUserId); onScreenSelect(ManagementScreens.GroupUserPermissions); }, [currentUserId, onChatMemberSelect, onScreenSelect]); const [isMediaDropdownOpen, setIsMediaDropdownOpen] = useState(false); const handleOpenMediaDropdown = useCallback((e: React.MouseEvent) => { stopEvent(e); setIsMediaDropdownOpen(!isMediaDropdownOpen); }, [isMediaDropdownOpen]); const handleDisabledClick = useCallback(() => { showNotification({ message: lang('lng_rights_permission_unavailable') }); }, [lang, showNotification]); const handleSavePermissions = useCallback(() => { if (!chat) { return; } setIsLoading(true); updateChatDefaultBannedRights({ chatId: chat.id, bannedRights: permissions }); }, [chat, permissions, setIsLoading, updateChatDefaultBannedRights]); const removedUsersCount = useMemo(() => { if (!chat || !chat.fullInfo || !chat.fullInfo.kickedMembers) { return 0; } return chat.fullInfo.kickedMembers.length; }, [chat]); const exceptionMembers = useMemo(() => { if (!chat || !chat.fullInfo || !chat.fullInfo.members) { return []; } return chat.fullInfo.members.filter(({ bannedRights }) => Boolean(bannedRights)); }, [chat]); const getMemberExceptions = useCallback((member: ApiChatMember) => { const { bannedRights } = member; if (!bannedRights || !chat) { return undefined; } const { defaultBannedRights } = chat; return Object.keys(bannedRights).reduce((result, k) => { const key = k as keyof ApiChatBannedRights; if ( !bannedRights[key] || (defaultBannedRights?.[key]) || key === 'sendInline' || key === 'viewMessages' || key === 'sendGames' ) { return result; } const langKey = getLangKeyForBannedRightKey(key); if (!langKey) { return result; } const translatedString = lang(langKey); return `${result}${!result.length ? translatedString : `, ${translatedString}`}`; }, ''); }, [chat, lang]); return (

{lang('ChannelPermissionsHeader')}

{isForum && (
)}
{lang('ChannelBlockedUsers')} {removedUsersCount}

{lang('PrivacyExceptions')}

{lang('ChannelAddException')} {exceptionMembers.map((member) => ( handleExceptionMemberClick(member)} > ))}
{isLoading ? ( ) : ( )}
); }; export default memo(withGlobal( (global, { chatId }): StateProps => { const chat = selectChat(global, chatId); const hasLinkedChat = Boolean(chat?.fullInfo?.linkedChatId); return { chat, currentUserId: global.currentUserId, hasLinkedChat }; }, )(ManageGroupPermissions));