import React, { FC, memo, useCallback, useEffect, useRef, useState, } from '../../lib/teact/teact'; import { withGlobal } from '../../lib/teact/teactn'; import { GlobalActions } from '../../global/types'; import { ManagementScreens, ProfileState } from '../../types'; import { IS_MOBILE_SCREEN } from '../../util/environment'; import { debounce } from '../../util/schedulers'; import { pick } from '../../util/iteratees'; import buildClassName from '../../util/buildClassName'; import { selectChat, selectCurrentGifSearch, selectCurrentStickerSearch, selectCurrentTextSearch, selectIsChatWithSelf, } from '../../modules/selectors'; import { isChatAdmin, isChatChannel, isChatPrivate } from '../../modules/helpers'; import useCurrentOrPrev from '../../hooks/useCurrentOrPrev'; import useFlag from '../../hooks/useFlag'; import useLang from '../../hooks/useLang'; import CalendarModal from '../common/CalendarModal.async'; import SearchInput from '../ui/SearchInput'; import Button from '../ui/Button'; import Transition from '../ui/Transition'; import './RightHeader.scss'; type OwnProps = { chatId?: number; isColumnOpen?: boolean; isProfile?: boolean; isSearch?: boolean; isManagement?: boolean; isStickerSearch?: boolean; isGifSearch?: boolean; isPollResults?: boolean; profileState?: ProfileState; managementScreen?: ManagementScreens; onClose: () => void; }; type StateProps = { canManage?: boolean; isChannel?: boolean; messageSearchQuery?: string; stickerSearchQuery?: string; gifSearchQuery?: string; }; type DispatchProps = Pick; const COLUMN_CLOSE_DELAY_MS = 300; const runDebouncedForSearch = debounce((cb) => cb(), 200, false); enum HeaderContent { Profile, MemberList, SharedMedia, Search, Management, ManageInitial, ManageChannelSubscribers, ManageChatAdministrators, ManageChatPrivacyType, ManageDiscussion, ManageGroupPermissions, ManageGroupRemovedUsers, ManageGroupUserPermissionsCreate, ManageGroupUserPermissions, ManageGroupRecentActions, ManageGroupAdminRights, ManageGroupMembers, StickerSearch, GifSearch, PollResults, } const RightHeader: FC = ({ isColumnOpen, isProfile, isSearch, isManagement, isStickerSearch, isGifSearch, isPollResults, profileState, managementScreen, canManage, isChannel, onClose, messageSearchQuery, stickerSearchQuery, gifSearchQuery, setLocalTextSearchQuery, setStickerSearchQuery, setGifSearchQuery, searchTextMessagesLocal, toggleManagement, searchMessagesByDate, }) => { // eslint-disable-next-line no-null/no-null const backButtonRef = useRef(null); const [isCalendarOpen, openCalendar, closeCalendar] = useFlag(); const handleMessageSearchQueryChange = useCallback((query: string) => { setLocalTextSearchQuery({ query }); if (query.length) { runDebouncedForSearch(searchTextMessagesLocal); } }, [searchTextMessagesLocal, setLocalTextSearchQuery]); const handleJumpToDate = useCallback((date: Date) => { searchMessagesByDate({ timestamp: date.valueOf() / 1000 }); closeCalendar(); }, [closeCalendar, searchMessagesByDate]); const handleStickerSearchQueryChange = useCallback((query: string) => { setStickerSearchQuery({ query }); }, [setStickerSearchQuery]); const handleGifSearchQueryChange = useCallback((query: string) => { setGifSearchQuery({ query }); }, [setGifSearchQuery]); const [shouldSkipTransition, setShouldSkipTransition] = useState(!isColumnOpen); useEffect(() => { setTimeout(() => { setShouldSkipTransition(!isColumnOpen); }, COLUMN_CLOSE_DELAY_MS); }, [isColumnOpen]); const lang = useLang(); const contentKey = isProfile ? ( profileState === ProfileState.Profile ? ( HeaderContent.Profile ) : profileState === ProfileState.SharedMedia ? ( HeaderContent.SharedMedia ) : profileState === ProfileState.MemberList ? ( HeaderContent.MemberList ) : -1 // Never reached ) : isSearch ? ( HeaderContent.Search ) : isPollResults ? ( HeaderContent.PollResults ) : isStickerSearch ? ( HeaderContent.StickerSearch ) : isGifSearch ? ( HeaderContent.GifSearch ) : isManagement ? ( managementScreen === ManagementScreens.Initial ? ( HeaderContent.ManageInitial ) : managementScreen === ManagementScreens.ChatPrivacyType ? ( HeaderContent.ManageChatPrivacyType ) : managementScreen === ManagementScreens.Discussion ? ( HeaderContent.ManageDiscussion ) : managementScreen === ManagementScreens.ChannelSubscribers ? ( HeaderContent.ManageChannelSubscribers ) : managementScreen === ManagementScreens.GroupPermissions ? ( HeaderContent.ManageGroupPermissions ) : managementScreen === ManagementScreens.ChatAdministrators ? ( HeaderContent.ManageChatAdministrators ) : managementScreen === ManagementScreens.GroupRemovedUsers ? ( HeaderContent.ManageGroupRemovedUsers ) : managementScreen === ManagementScreens.GroupUserPermissionsCreate ? ( HeaderContent.ManageGroupUserPermissionsCreate ) : managementScreen === ManagementScreens.GroupUserPermissions ? ( HeaderContent.ManageGroupUserPermissions ) : managementScreen === ManagementScreens.GroupRecentActions ? ( HeaderContent.ManageGroupRecentActions ) : managementScreen === ManagementScreens.ChatAdminRights ? ( HeaderContent.ManageGroupAdminRights ) : managementScreen === ManagementScreens.GroupMembers ? ( HeaderContent.ManageGroupMembers ) : undefined // Never reached ) : undefined; // When column is closed const renderingContentKey = useCurrentOrPrev(contentKey, true) ?? -1; function renderHeaderContent() { if (renderingContentKey === -1) { return undefined; } switch (renderingContentKey) { case HeaderContent.PollResults: return

{lang('PollResults')}

; case HeaderContent.Search: return ( <> ); case HeaderContent.ManageInitial: return

{lang('Edit')}

; case HeaderContent.ManageChatPrivacyType: return

{lang(isChannel ? 'ChannelTypeHeader' : 'GroupTypeHeader')}

; case HeaderContent.ManageDiscussion: return

{lang('Discussion')}

; case HeaderContent.ManageChatAdministrators: return

{lang('ChannelAdministrators')}

; case HeaderContent.ManageGroupRecentActions: return

{lang('Group.Info.AdminLog')}

; case HeaderContent.ManageGroupAdminRights: return

{lang('EditAdminRights')}

; case HeaderContent.ManageGroupPermissions: return

{lang('ChannelPermissions')}

; case HeaderContent.ManageGroupRemovedUsers: return

{lang('ChannelBlockedUsers')}

; case HeaderContent.ManageGroupUserPermissionsCreate: return

{lang('ChannelAddException')}

; case HeaderContent.ManageGroupUserPermissions: return

{lang('UserRestrictions')}

; case HeaderContent.StickerSearch: return ( ); case HeaderContent.GifSearch: return ( ); case HeaderContent.SharedMedia: return

{lang('SharedMedia')}

; case HeaderContent.ManageChannelSubscribers: return

{lang('ChannelSubscribers')}

; case HeaderContent.MemberList: case HeaderContent.ManageGroupMembers: return

{lang('GroupMembers')}

; default: return ( <>

Profile

{canManage && ( )}
); } } const isBackButton = ( IS_MOBILE_SCREEN || contentKey === HeaderContent.SharedMedia || contentKey === HeaderContent.MemberList || isManagement ); const buttonClassName = buildClassName( 'animated-close-icon', shouldSkipTransition && 'no-transition', ); // Add class in the next AF to synchronize with animation with Transition components useEffect(() => { backButtonRef.current!.classList.toggle('state-back', isBackButton); }, [isBackButton]); return (
{renderHeaderContent} {!IS_MOBILE_SCREEN && ( )}
); }; export default memo(withGlobal( (global, { chatId, isProfile, isManagement }): StateProps => { const { query: messageSearchQuery } = selectCurrentTextSearch(global) || {}; const { query: stickerSearchQuery } = selectCurrentStickerSearch(global) || {}; const { query: gifSearchQuery } = selectCurrentGifSearch(global) || {}; const chat = chatId ? selectChat(global, chatId) : undefined; const isChannel = chat && isChatChannel(chat); const canManage = Boolean( !isManagement && isProfile && chat && !selectIsChatWithSelf(global, chat.id) // chat.isCreator is for Basic Groups && (isChatPrivate(chat.id) || ((isChatAdmin(chat) || chat.isCreator) && !chat.isNotJoined)), ); return { canManage, isChannel, messageSearchQuery, stickerSearchQuery, gifSearchQuery, }; }, (setGlobal, actions): DispatchProps => pick(actions, [ 'setLocalTextSearchQuery', 'setStickerSearchQuery', 'setGifSearchQuery', 'searchTextMessagesLocal', 'toggleManagement', 'searchMessagesByDate', ]), )(RightHeader));