TelegramPWA/src/components/middle/HeaderMenuContainer.tsx
2021-11-05 22:03:02 +03:00

278 lines
7.3 KiB
TypeScript

import React, {
FC, memo, useCallback, useEffect, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiChat } from '../../api/types';
import { IAnchorPosition } from '../../types';
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
import { disableScrolling, enableScrolling } from '../../util/scrollLock';
import {
selectChat, selectNotifySettings, selectNotifyExceptions, selectUser,
} from '../../modules/selectors';
import { pick } from '../../util/iteratees';
import {
isUserId, getCanDeleteChat, selectIsChatMuted, getCanAddContact,
} from '../../modules/helpers';
import useShowTransition from '../../hooks/useShowTransition';
import useLang from '../../hooks/useLang';
import Portal from '../ui/Portal';
import Menu from '../ui/Menu';
import MenuItem from '../ui/MenuItem';
import DeleteChatModal from '../common/DeleteChatModal';
import './HeaderMenuContainer.scss';
type DispatchProps = Pick<GlobalActions, (
'updateChatMutedState' | 'enterMessageSelectMode' | 'sendBotCommand' | 'restartBot' | 'openLinkedChat' | 'addContact'
)>;
export type OwnProps = {
chatId: string;
threadId: number;
isOpen: boolean;
anchor: IAnchorPosition;
isChannel?: boolean;
canStartBot?: boolean;
canRestartBot?: boolean;
canSubscribe?: boolean;
canSearch?: boolean;
canMute?: boolean;
canLeave?: boolean;
onSubscribeChannel: () => void;
onSearchClick: () => void;
onClose: () => void;
onCloseAnimationEnd: () => void;
};
type StateProps = {
chat?: ApiChat;
isPrivate?: boolean;
isMuted?: boolean;
canAddContact?: boolean;
canDeleteChat?: boolean;
hasLinkedChat?: boolean;
};
const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
chatId,
isOpen,
anchor,
isChannel,
canStartBot,
canRestartBot,
canSubscribe,
canSearch,
canMute,
canLeave,
chat,
isPrivate,
isMuted,
canDeleteChat,
hasLinkedChat,
canAddContact,
onSubscribeChannel,
onSearchClick,
onClose,
onCloseAnimationEnd,
updateChatMutedState,
enterMessageSelectMode,
sendBotCommand,
restartBot,
openLinkedChat,
addContact,
}) => {
const [isMenuOpen, setIsMenuOpen] = useState(true);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const { x, y } = anchor;
useShowTransition(isOpen, onCloseAnimationEnd, undefined, false);
const handleDelete = useCallback(() => {
setIsMenuOpen(false);
setIsDeleteModalOpen(true);
}, []);
const closeMenu = useCallback(() => {
setIsMenuOpen(false);
onClose();
}, [onClose]);
const closeDeleteModal = useCallback(() => {
setIsDeleteModalOpen(false);
onClose();
}, [onClose]);
const handleStartBot = useCallback(() => {
sendBotCommand({ command: '/start' });
}, [sendBotCommand]);
const handleRestartBot = useCallback(() => {
restartBot({ chatId });
}, [chatId, restartBot]);
const handleToggleMuteClick = useCallback(() => {
updateChatMutedState({ chatId, isMuted: !isMuted });
closeMenu();
}, [chatId, closeMenu, isMuted, updateChatMutedState]);
const handleLinkedChatClick = useCallback(() => {
openLinkedChat({ id: chatId });
closeMenu();
}, [chatId, closeMenu, openLinkedChat]);
const handleAddContactClick = useCallback(() => {
addContact({ userId: chatId });
closeMenu();
}, [addContact, chatId, closeMenu]);
const handleSubscribe = useCallback(() => {
onSubscribeChannel();
closeMenu();
}, [closeMenu, onSubscribeChannel]);
const handleSearch = useCallback(() => {
onSearchClick();
closeMenu();
}, [closeMenu, onSearchClick]);
const handleSelectMessages = useCallback(() => {
enterMessageSelectMode();
closeMenu();
}, [closeMenu, enterMessageSelectMode]);
useEffect(() => {
disableScrolling();
return enableScrolling;
}, []);
const lang = useLang();
return (
<Portal>
<div className="HeaderMenuContainer">
<Menu
isOpen={isMenuOpen}
positionX="right"
style={`left: ${x}px;top: ${y}px;`}
onClose={closeMenu}
>
{IS_SINGLE_COLUMN_LAYOUT && canStartBot && (
<MenuItem
icon="bots"
onClick={handleStartBot}
>
{lang('BotStart')}
</MenuItem>
)}
{IS_SINGLE_COLUMN_LAYOUT && canRestartBot && (
<MenuItem
icon="bots"
onClick={handleRestartBot}
>
{lang('BotRestart')}
</MenuItem>
)}
{IS_SINGLE_COLUMN_LAYOUT && canSubscribe && (
<MenuItem
icon={isChannel ? 'channel' : 'group'}
onClick={handleSubscribe}
>
{lang(isChannel ? 'Subscribe' : 'Join Group')}
</MenuItem>
)}
{canAddContact && (
<MenuItem
icon="add-user"
onClick={handleAddContactClick}
>
{lang('AddContact')}
</MenuItem>
)}
{IS_SINGLE_COLUMN_LAYOUT && canSearch && (
<MenuItem
icon="search"
onClick={handleSearch}
>
{lang('Search')}
</MenuItem>
)}
{canMute && (
<MenuItem
icon={isMuted ? 'unmute' : 'mute'}
onClick={handleToggleMuteClick}
>
{lang(isMuted ? 'ChatsUnmute' : 'ChatsMute')}
</MenuItem>
)}
{hasLinkedChat && (
<MenuItem
icon={isChannel ? 'comments' : 'channel'}
onClick={handleLinkedChatClick}
>
{lang(isChannel ? 'ViewDiscussion' : 'lng_profile_view_channel')}
</MenuItem>
)}
<MenuItem
icon="select"
onClick={handleSelectMessages}
>
{lang('ReportSelectMessages')}
</MenuItem>
{canLeave && (
<MenuItem
destructive
icon="delete"
onClick={handleDelete}
>
{lang(isPrivate
? 'DeleteChatUser'
: (canDeleteChat ? 'GroupInfo.DeleteAndExit' : (isChannel ? 'LeaveChannel' : 'Group.LeaveGroup')))}
</MenuItem>
)}
</Menu>
{chat && (
<DeleteChatModal
isOpen={isDeleteModalOpen}
onClose={closeDeleteModal}
chat={chat}
/>
)}
</div>
</Portal>
);
};
export default memo(withGlobal<OwnProps>(
(global, { chatId }): StateProps => {
const chat = selectChat(global, chatId);
if (!chat || chat.isRestricted) {
return {};
}
const isPrivate = isUserId(chat.id);
const user = isPrivate ? selectUser(global, chatId) : undefined;
const canAddContact = user && getCanAddContact(user);
return {
chat,
isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),
isPrivate,
canAddContact,
canDeleteChat: getCanDeleteChat(chat),
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'updateChatMutedState',
'enterMessageSelectMode',
'sendBotCommand',
'restartBot',
'openLinkedChat',
'addContact',
]),
)(HeaderMenuContainer));