252 lines
7.8 KiB
TypeScript
252 lines
7.8 KiB
TypeScript
import type { FC } from '../../../lib/teact/teact';
|
|
import React, {
|
|
memo, useEffect, useRef, useState,
|
|
} from '../../../lib/teact/teact';
|
|
import { getActions } from '../../../global';
|
|
|
|
import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
|
|
import type { SettingsScreens } from '../../../types';
|
|
import { LeftColumnContent } from '../../../types';
|
|
|
|
import { PRODUCTION_URL } from '../../../config';
|
|
import buildClassName from '../../../util/buildClassName';
|
|
import { IS_ELECTRON, IS_TOUCH_ENV } from '../../../util/windowEnvironment';
|
|
|
|
import useForumPanelRender from '../../../hooks/useForumPanelRender';
|
|
import useLastCallback from '../../../hooks/useLastCallback';
|
|
import useOldLang from '../../../hooks/useOldLang';
|
|
import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDeprecated';
|
|
|
|
import Button from '../../ui/Button';
|
|
import Transition from '../../ui/Transition';
|
|
import NewChatButton from '../NewChatButton';
|
|
import LeftSearch from '../search/LeftSearch.async';
|
|
import ChatFolders from './ChatFolders';
|
|
import ContactList from './ContactList.async';
|
|
import ForumPanel from './ForumPanel';
|
|
import LeftMainHeader from './LeftMainHeader';
|
|
|
|
import './LeftMain.scss';
|
|
|
|
type OwnProps = {
|
|
content: LeftColumnContent;
|
|
searchQuery?: string;
|
|
searchDate?: number;
|
|
contactsFilter: string;
|
|
shouldSkipTransition?: boolean;
|
|
foldersDispatch: FolderEditDispatch;
|
|
isAppUpdateAvailable?: boolean;
|
|
isElectronUpdateAvailable?: boolean;
|
|
isForumPanelOpen?: boolean;
|
|
isClosingSearch?: boolean;
|
|
onSearchQuery: (query: string) => void;
|
|
onContentChange: (content: LeftColumnContent) => void;
|
|
onSettingsScreenSelect: (screen: SettingsScreens) => void;
|
|
onTopicSearch: NoneToVoidFunction;
|
|
onReset: () => void;
|
|
};
|
|
|
|
const TRANSITION_RENDER_COUNT = Object.keys(LeftColumnContent).length / 2;
|
|
const BUTTON_CLOSE_DELAY_MS = 250;
|
|
|
|
let closeTimeout: number | undefined;
|
|
|
|
const LeftMain: FC<OwnProps> = ({
|
|
content,
|
|
searchQuery,
|
|
searchDate,
|
|
isClosingSearch,
|
|
contactsFilter,
|
|
shouldSkipTransition,
|
|
foldersDispatch,
|
|
isAppUpdateAvailable,
|
|
isElectronUpdateAvailable,
|
|
isForumPanelOpen,
|
|
onSearchQuery,
|
|
onContentChange,
|
|
onSettingsScreenSelect,
|
|
onReset,
|
|
onTopicSearch,
|
|
}) => {
|
|
const { closeForumPanel } = getActions();
|
|
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
|
|
const [isElectronAutoUpdateEnabled, setIsElectronAutoUpdateEnabled] = useState(false);
|
|
|
|
useEffect(() => {
|
|
window.electron?.getIsAutoUpdateEnabled().then(setIsElectronAutoUpdateEnabled);
|
|
}, []);
|
|
|
|
const {
|
|
shouldRenderForumPanel, handleForumPanelAnimationEnd,
|
|
handleForumPanelAnimationStart, isAnimationStarted,
|
|
} = useForumPanelRender(isForumPanelOpen);
|
|
const isForumPanelRendered = isForumPanelOpen && content === LeftColumnContent.ChatList;
|
|
const isForumPanelVisible = isForumPanelRendered && isAnimationStarted;
|
|
|
|
const {
|
|
shouldRender: shouldRenderUpdateButton,
|
|
transitionClassNames: updateButtonClassNames,
|
|
} = useShowTransitionDeprecated(isAppUpdateAvailable || isElectronUpdateAvailable);
|
|
|
|
const isMouseInside = useRef(false);
|
|
|
|
const handleMouseEnter = useLastCallback(() => {
|
|
if (content !== LeftColumnContent.ChatList) {
|
|
return;
|
|
}
|
|
isMouseInside.current = true;
|
|
setIsNewChatButtonShown(true);
|
|
});
|
|
|
|
const handleMouseLeave = useLastCallback(() => {
|
|
isMouseInside.current = false;
|
|
|
|
if (closeTimeout) {
|
|
clearTimeout(closeTimeout);
|
|
closeTimeout = undefined;
|
|
}
|
|
|
|
closeTimeout = window.setTimeout(() => {
|
|
if (!isMouseInside.current) {
|
|
setIsNewChatButtonShown(false);
|
|
}
|
|
}, BUTTON_CLOSE_DELAY_MS);
|
|
});
|
|
|
|
const handleSelectSettings = useLastCallback(() => {
|
|
onContentChange(LeftColumnContent.Settings);
|
|
});
|
|
|
|
const handleSelectContacts = useLastCallback(() => {
|
|
onContentChange(LeftColumnContent.Contacts);
|
|
});
|
|
|
|
const handleSelectArchived = useLastCallback(() => {
|
|
onContentChange(LeftColumnContent.Archived);
|
|
closeForumPanel();
|
|
});
|
|
|
|
const handleUpdateClick = useLastCallback(() => {
|
|
if (IS_ELECTRON && !isElectronAutoUpdateEnabled) {
|
|
window.open(`${PRODUCTION_URL}/get`, '_blank', 'noopener');
|
|
} else if (isElectronUpdateAvailable) {
|
|
window.electron?.installUpdate();
|
|
} else {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
|
|
const handleSelectNewChannel = useLastCallback(() => {
|
|
onContentChange(LeftColumnContent.NewChannelStep1);
|
|
});
|
|
|
|
const handleSelectNewGroup = useLastCallback(() => {
|
|
onContentChange(LeftColumnContent.NewGroupStep1);
|
|
});
|
|
|
|
useEffect(() => {
|
|
let autoCloseTimeout: number | undefined;
|
|
if (content !== LeftColumnContent.ChatList) {
|
|
autoCloseTimeout = window.setTimeout(() => {
|
|
setIsNewChatButtonShown(false);
|
|
}, BUTTON_CLOSE_DELAY_MS);
|
|
} else if (isMouseInside.current || IS_TOUCH_ENV) {
|
|
setIsNewChatButtonShown(true);
|
|
}
|
|
|
|
return () => {
|
|
if (autoCloseTimeout) {
|
|
clearTimeout(autoCloseTimeout);
|
|
autoCloseTimeout = undefined;
|
|
}
|
|
};
|
|
}, [content]);
|
|
|
|
const lang = useOldLang();
|
|
|
|
return (
|
|
<div
|
|
id="LeftColumn-main"
|
|
onMouseEnter={!IS_TOUCH_ENV ? handleMouseEnter : undefined}
|
|
onMouseLeave={!IS_TOUCH_ENV ? handleMouseLeave : undefined}
|
|
>
|
|
<LeftMainHeader
|
|
shouldHideSearch={isForumPanelVisible}
|
|
content={content}
|
|
contactsFilter={contactsFilter}
|
|
onSearchQuery={onSearchQuery}
|
|
onSelectSettings={handleSelectSettings}
|
|
onSelectContacts={handleSelectContacts}
|
|
onSelectArchived={handleSelectArchived}
|
|
onReset={onReset}
|
|
shouldSkipTransition={shouldSkipTransition}
|
|
isClosingSearch={isClosingSearch}
|
|
/>
|
|
<Transition
|
|
name={shouldSkipTransition ? 'none' : 'zoomFade'}
|
|
renderCount={TRANSITION_RENDER_COUNT}
|
|
activeKey={content}
|
|
shouldCleanup
|
|
cleanupExceptionKey={LeftColumnContent.ChatList}
|
|
shouldWrap
|
|
wrapExceptionKey={LeftColumnContent.ChatList}
|
|
>
|
|
{(isActive) => {
|
|
switch (content) {
|
|
case LeftColumnContent.ChatList:
|
|
return (
|
|
<ChatFolders
|
|
shouldHideFolderTabs={isForumPanelVisible}
|
|
onSettingsScreenSelect={onSettingsScreenSelect}
|
|
onLeftColumnContentChange={onContentChange}
|
|
foldersDispatch={foldersDispatch}
|
|
isForumPanelOpen={isForumPanelVisible}
|
|
/>
|
|
);
|
|
case LeftColumnContent.GlobalSearch:
|
|
return (
|
|
<LeftSearch
|
|
searchQuery={searchQuery}
|
|
searchDate={searchDate}
|
|
isActive={isActive}
|
|
onReset={onReset}
|
|
/>
|
|
);
|
|
case LeftColumnContent.Contacts:
|
|
return <ContactList filter={contactsFilter} isActive={isActive} onReset={onReset} />;
|
|
default:
|
|
return undefined;
|
|
}
|
|
}}
|
|
</Transition>
|
|
{shouldRenderUpdateButton && (
|
|
<Button
|
|
fluid
|
|
badge
|
|
className={buildClassName('btn-update', updateButtonClassNames)}
|
|
onClick={handleUpdateClick}
|
|
>
|
|
{lang('lng_update_telegram')}
|
|
</Button>
|
|
)}
|
|
{shouldRenderForumPanel && (
|
|
<ForumPanel
|
|
isOpen={isForumPanelOpen}
|
|
isHidden={!isForumPanelRendered}
|
|
onTopicSearch={onTopicSearch}
|
|
onOpenAnimationStart={handleForumPanelAnimationStart}
|
|
onCloseAnimationEnd={handleForumPanelAnimationEnd}
|
|
/>
|
|
)}
|
|
<NewChatButton
|
|
isShown={isNewChatButtonShown}
|
|
onNewPrivateChat={handleSelectContacts}
|
|
onNewChannel={handleSelectNewChannel}
|
|
onNewGroup={handleSelectNewGroup}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default memo(LeftMain);
|