From d04177aea8535f069d08b47f7c70505293a82bed Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 5 May 2023 15:53:10 +0400 Subject: [PATCH] Left Column: Fix resizer in archive component (#3152) --- src/components/left/LeftColumn.tsx | 42 ++++++++------------------ src/components/main/Main.scss | 1 + src/components/main/Main.tsx | 6 ++-- src/components/middle/MiddleColumn.tsx | 33 +++++++++++++++----- src/components/ui/Transition.tsx | 15 ++------- src/hooks/useResize.ts | 27 +++++++++++------ src/styles/index.scss | 2 +- 7 files changed, 62 insertions(+), 64 deletions(-) diff --git a/src/components/left/LeftColumn.tsx b/src/components/left/LeftColumn.tsx index 259ae98e2..64a6fded0 100644 --- a/src/components/left/LeftColumn.tsx +++ b/src/components/left/LeftColumn.tsx @@ -1,9 +1,9 @@ +import type { RefObject } from 'react'; import React, { - memo, useCallback, useEffect, useRef, useState, + memo, useCallback, useEffect, useState, } from '../../lib/teact/teact'; import { getActions, withGlobal } from '../../global'; -import type { FC } from '../../lib/teact/teact'; import type { GlobalState } from '../../global/types'; import { LeftColumnContent, SettingsScreens } from '../../types'; import type { ReducerAction } from '../../hooks/useReducer'; @@ -13,7 +13,6 @@ import { IS_MAC_OS, IS_PWA, LAYERS_ANIMATION_NAME } from '../../util/windowEnvir import captureEscKeyListener from '../../util/captureEscKeyListener'; import { selectCurrentChat, selectIsForumPanelOpen, selectTabState } from '../../global/selectors'; import useFoldersReducer from '../../hooks/reducers/useFoldersReducer'; -import { useResize } from '../../hooks/useResize'; import { useHotkeys } from '../../hooks/useHotkeys'; import useSyncEffect from '../../hooks/useSyncEffect'; @@ -25,12 +24,15 @@ import ArchivedChats from './ArchivedChats.async'; import './LeftColumn.scss'; +interface OwnProps { + ref: RefObject; +} + type StateProps = { searchQuery?: string; searchDate?: number; isFirstChatFolderActive: boolean; shouldSkipHistoryAnimations?: boolean; - leftColumnWidth?: number; currentUserId?: string; hasPasscode?: boolean; nextSettingsScreen?: SettingsScreens; @@ -57,12 +59,12 @@ enum ContentType { const RENDER_COUNT = Object.keys(ContentType).length / 2; const RESET_TRANSITION_DELAY_MS = 250; -const LeftColumn: FC = ({ +function LeftColumn({ + ref, searchQuery, searchDate, isFirstChatFolderActive, shouldSkipHistoryAnimations, - leftColumnWidth, currentUserId, hasPasscode, nextSettingsScreen, @@ -73,7 +75,7 @@ const LeftColumn: FC = ({ forumPanelChatId, isClosingSearch, archiveSettings, -}) => { +}: OwnProps & StateProps) { const { setGlobalSearchQuery, setGlobalSearchClosing, @@ -82,14 +84,10 @@ const LeftColumn: FC = ({ setGlobalSearchDate, loadPasswordInfo, clearTwoFaError, - setLeftColumnWidth, - resetLeftColumnWidth, openChat, requestNextSettingsScreen, } = getActions(); - // eslint-disable-next-line no-null/no-null - const resizeRef = useRef(null); const [content, setContent] = useState(LeftColumnContent.ChatList); const [settingsScreen, setSettingsScreen] = useState(SettingsScreens.Main); const [contactsFilter, setContactsFilter] = useState(''); @@ -410,12 +408,6 @@ const LeftColumn: FC = ({ } }, [foldersDispatch, nextFoldersAction, nextSettingsScreen, requestNextSettingsScreen]); - const { - initResize, resetResize, handleMouseUp, - } = useResize(resizeRef, (n) => setLeftColumnWidth({ - leftColumnWidth: n, - }), resetLeftColumnWidth, leftColumnWidth, '--left-column-width'); - const handleSettingsScreenSelect = useCallback((screen: SettingsScreens) => { setContent(LeftColumnContent.Settings); setSettingsScreen(screen); @@ -493,7 +485,7 @@ const LeftColumn: FC = ({ return ( = ({ shouldWrap wrapExceptionKey={ContentType.Main} id="LeftColumn" - afterChildren={( -
- )} > {renderContent} ); -}; +} -export default memo(withGlobal( +export default memo(withGlobal( (global): StateProps => { const tabState = selectTabState(global); const { @@ -530,7 +514,6 @@ export default memo(withGlobal( nextFoldersAction, } = tabState; const { - leftColumnWidth, currentUserId, passcode: { hasPasscode, @@ -549,7 +532,6 @@ export default memo(withGlobal( searchDate: date, isFirstChatFolderActive: activeChatFolder === 0, shouldSkipHistoryAnimations, - leftColumnWidth, currentUserId, hasPasscode, nextSettingsScreen, diff --git a/src/components/main/Main.scss b/src/components/main/Main.scss index 851ecf57c..4de9e1734 100644 --- a/src/components/main/Main.scss +++ b/src/components/main/Main.scss @@ -35,6 +35,7 @@ min-width: var(--left-column-min-width); max-width: var(--left-column-max-width); height: 100%; + overflow: hidden; position: relative; background-color: var(--color-background); diff --git a/src/components/main/Main.tsx b/src/components/main/Main.tsx index 1688e846f..fab4e5bd5 100644 --- a/src/components/main/Main.tsx +++ b/src/components/main/Main.tsx @@ -257,6 +257,8 @@ const Main: FC = ({ // eslint-disable-next-line no-null/no-null const containerRef = useRef(null); + // eslint-disable-next-line no-null/no-null + const leftColumnRef = useRef(null); const { isDesktop } = useAppLayout(); useEffect(() => { @@ -488,8 +490,8 @@ const Main: FC = ({ return (
- - + + diff --git a/src/components/middle/MiddleColumn.tsx b/src/components/middle/MiddleColumn.tsx index 2c061bfdb..681310c61 100644 --- a/src/components/middle/MiddleColumn.tsx +++ b/src/components/middle/MiddleColumn.tsx @@ -1,4 +1,4 @@ -import type { FC } from '../../lib/teact/teact'; +import type { RefObject } from 'react'; import React, { useEffect, useState, memo, useMemo, useCallback, } from '../../lib/teact/teact'; @@ -67,6 +67,7 @@ import useForceUpdate from '../../hooks/useForceUpdate'; import useSyncEffect from '../../hooks/useSyncEffect'; import useAppLayout from '../../hooks/useAppLayout'; import usePinnedMessage from './hooks/usePinnedMessage'; +import { useResize } from '../../hooks/useResize'; import Transition from '../ui/Transition'; import MiddleHeader from './MiddleHeader'; @@ -88,6 +89,7 @@ import './MiddleColumn.scss'; import styles from './MiddleColumn.module.scss'; interface OwnProps { + leftColumnRef: RefObject; isMobile?: boolean; } @@ -99,7 +101,6 @@ type StateProps = { replyingToId?: number; isPrivate?: boolean; isPinnedMessageList?: boolean; - isScheduledMessageList?: boolean; canPost?: boolean; currentUserBannedRights?: ApiChatBannedRights; defaultBannedRights?: ApiChatBannedRights; @@ -114,6 +115,7 @@ type StateProps = { isLeftColumnShown?: boolean; isRightColumnShown?: boolean; isBackgroundBlurred?: boolean; + leftColumnWidth?: number; hasCurrentTextSearch?: boolean; isSelectModeActive?: boolean; isSeenByModalOpen: boolean; @@ -142,7 +144,8 @@ function isImage(item: DataTransferItem) { const LAYER_ANIMATION_DURATION_MS = 450 + ANIMATION_END_DELAY; -const MiddleColumn: FC = ({ +function MiddleColumn({ + leftColumnRef, chatId, threadId, messageListType, @@ -165,6 +168,7 @@ const MiddleColumn: FC = ({ isLeftColumnShown, isRightColumnShown, isBackgroundBlurred, + leftColumnWidth, hasCurrentTextSearch, isSelectModeActive, isSeenByModalOpen, @@ -185,7 +189,7 @@ const MiddleColumn: FC = ({ shouldLoadFullChat, lastSyncTime, pinnedIds, -}) => { +}: OwnProps & StateProps) { const { openChat, openPreviousChat, @@ -199,6 +203,8 @@ const MiddleColumn: FC = ({ restartBot, showNotification, loadFullChat, + setLeftColumnWidth, + resetLeftColumnWidth, } = getActions(); const { width: windowWidth } = useWindowSize(); @@ -319,6 +325,12 @@ const MiddleColumn: FC = ({ } }, [shouldLoadFullChat, chatId, isReady, loadFullChat]); + const { + initResize, resetResize, handleMouseUp, + } = useResize(leftColumnRef, (n) => setLeftColumnWidth({ + leftColumnWidth: n, + }), resetLeftColumnWidth, leftColumnWidth, '--left-column-width'); + const handleDragEnter = useCallback((e: React.DragEvent) => { const { items } = e.dataTransfer || {}; const shouldDrawQuick = items && items.length > 0 && Array.from(items) @@ -452,6 +464,12 @@ const MiddleColumn: FC = ({ `} onClick={(isTablet && isLeftColumnShown) ? handleTabletFocus : undefined} > +
= ({
); -}; +} export default memo(withGlobal( (global, { isMobile }): StateProps => { @@ -637,7 +655,7 @@ export default memo(withGlobal( messageLanguageModal, } = selectTabState(global); const currentMessageList = selectCurrentMessageList(global); - const { chats: { listIds }, lastSyncTime } = global; + const { chats: { listIds }, leftColumnWidth, lastSyncTime } = global; const state: StateProps = { theme, @@ -656,6 +674,7 @@ export default memo(withGlobal( withInterfaceAnimations: selectCanAnimateInterface(global), currentTransitionKey: Math.max(0, messageLists.length - 1), activeEmojiInteractions, + leftColumnWidth, lastSyncTime, }; @@ -675,7 +694,6 @@ export default memo(withGlobal( const canPost = chat && getCanPostInChat(chat, threadId, isComments); const isBotNotStarted = selectIsChatBotNotStarted(global, chatId); const isPinnedMessageList = messageListType === 'pinned'; - const isScheduledMessageList = messageListType === 'scheduled'; const isMainThread = messageListType === 'thread' && threadId === MAIN_THREAD_ID; const isChannel = Boolean(chat && isChatChannel(chat)); const canSubscribe = Boolean( @@ -711,7 +729,6 @@ export default memo(withGlobal( && !(shouldJoinToSend && chat?.isNotJoined) && !shouldBlockSendInForum, isPinnedMessageList, - isScheduledMessageList, currentUserBannedRights: chat?.currentUserBannedRights, defaultBannedRights: chat?.defaultBannedRights, hasPinned: ( diff --git a/src/components/ui/Transition.tsx b/src/components/ui/Transition.tsx index 9a1da7875..de67ac676 100644 --- a/src/components/ui/Transition.tsx +++ b/src/components/ui/Transition.tsx @@ -40,7 +40,6 @@ export type TransitionProps = { onStart?: NoneToVoidFunction; onStop?: NoneToVoidFunction; children: React.ReactNode | ChildrenFn; - afterChildren?: React.ReactNode; }; const FALLBACK_ANIMATION_END = 1000; @@ -50,7 +49,6 @@ const CLASSES = { from: 'Transition_slide-from', to: 'Transition_slide-to', inactive: 'Transition_slide-inactive', - afterSlides: 'Transition_afterSlides', }; const DISABLEABLE_ANIMATIONS = new Set([ 'slide', 'slideRtl', 'slideFade', 'zoomFade', 'slideLayers', 'pushSlide', 'reveal', @@ -75,7 +73,6 @@ function Transition({ onStart, onStop, children, - afterChildren, }: TransitionProps) { const currentKeyRef = useRef(); // No need for a container to update on change @@ -128,14 +125,12 @@ function Transition({ const prevActiveIndex = renderCount ? prevActiveKey : keys.indexOf(prevActiveKey); const activeIndex = renderCount ? activeKey : keys.indexOf(activeKey); - const childNodes = Array.from(container.childNodes) - .filter((el) => !(el instanceof HTMLElement && el.classList.contains(CLASSES.afterSlides))); + const childNodes = Array.from(container.childNodes); if (!childNodes.length) { return; } - const childElements = (Array.from(container.children) as HTMLElement[]) - .filter((el) => !el.classList.contains(CLASSES.afterSlides)); + const childElements = Array.from(container.children) as HTMLElement[]; childElements.forEach((el) => { addExtraClass(el, CLASSES.slide); @@ -319,12 +314,6 @@ function Transition({ : rendered; }); - if (afterChildren) { - contents.push(( -
{afterChildren}
- )); - } - return (
(0); const setElementStyle = useCallback((width?: number) => { - if (!elementRef.current) { - return; - } + requestMutation(() => { + if (!elementRef.current) { + return; + } - const widthPx = width ? `${width}px` : ''; - elementRef.current.style.width = widthPx; - if (cssPropertyName) { - elementRef.current.style.setProperty(cssPropertyName, widthPx); - } + const widthPx = width ? `${width}px` : ''; + elementRef.current.style.width = widthPx; + if (cssPropertyName) { + elementRef.current.style.setProperty(cssPropertyName, widthPx); + } + }); }, [cssPropertyName, elementRef]); useLayoutEffect(() => { @@ -36,13 +39,17 @@ export function useResize( }, [cssPropertyName, elementRef, initialWidth, setElementStyle]); function handleMouseUp() { - document.body.classList.remove('cursor-ew-resize'); + requestMutation(() => { + document.body.classList.remove('cursor-ew-resize'); + }); } function initResize(e: React.MouseEvent) { e.preventDefault(); - document.body.classList.add('cursor-ew-resize'); + requestMutation(() => { + document.body.classList.add('cursor-ew-resize'); + }); setInitialMouseX(e.clientX); setInitialElementWidth(elementRef.current!.offsetWidth); diff --git a/src/styles/index.scss b/src/styles/index.scss index b3cd46457..0a36f219c 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -115,7 +115,7 @@ body.cursor-ew-resize { display: none; position: absolute; top: 0; - right: -0.25rem; + left: 0; bottom: 0; width: 0.25rem; z-index: var(--z-resize-handle);