From 982ba8c3a71dd589a13b28eaf15066fafb6d7ee4 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Sat, 15 Apr 2023 13:50:23 +0200 Subject: [PATCH] [Perf] Get rid of redundant wrappers: #root, #UiLoader and #LeftColumn --- src/components/App.module.scss | 40 ++++ src/{ => components}/App.tsx | 67 ++++--- src/components/common/UiLoader.module.scss | 41 ---- src/components/common/UiLoader.tsx | 25 +-- src/components/left/LeftColumn.tsx | 175 +++++++++--------- src/components/main/Dialogs.scss | 8 - src/components/main/Dialogs.tsx | 8 +- src/components/main/Main.scss | 11 +- .../middle/composer/SymbolMenu.scss | 2 +- src/index.html | 3 +- src/index.tsx | 2 +- src/styles/_variables.scss | 1 + src/styles/print.scss | 1 - 13 files changed, 186 insertions(+), 198 deletions(-) create mode 100644 src/components/App.module.scss rename src/{ => components}/App.tsx (75%) delete mode 100644 src/components/main/Dialogs.scss diff --git a/src/components/App.module.scss b/src/components/App.module.scss new file mode 100644 index 000000000..01bc67249 --- /dev/null +++ b/src/components/App.module.scss @@ -0,0 +1,40 @@ +.bg { + height: 100%; + + background-color: var(--theme-background-color); + background-position: center; + background-repeat: no-repeat; + background-size: 100% 100%; + + @media (max-width: 600px) { + height: calc(var(--vh, 1vh) * 100); + } + + :global(html.theme-light) & { + background-image: url('../assets/chat-bg-br.png'); + } + + &::before { + content: ""; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + background-image: url('../assets/chat-bg-pattern-light.png'); + background-position: top right; + background-size: 510px auto; + background-repeat: repeat; + mix-blend-mode: overlay; + + :global(html.theme-dark) & { + background-image: url('../assets/chat-bg-pattern-dark.png'); + mix-blend-mode: unset; + } + + @media (max-width: 600px) { + bottom: auto; + height: calc(var(--vh, 1vh) * 100); + } + } +} diff --git a/src/App.tsx b/src/components/App.tsx similarity index 75% rename from src/App.tsx rename to src/components/App.tsx index ed7f2051c..5b8c66bb7 100644 --- a/src/App.tsx +++ b/src/components/App.tsx @@ -1,37 +1,43 @@ -import type { FC } from './lib/teact/teact'; -import React, { useEffect } from './lib/teact/teact'; -import { getActions, withGlobal } from './global'; +import type { FC } from '../lib/teact/teact'; +import React, { useEffect, useLayoutEffect } from '../lib/teact/teact'; +import { getActions, withGlobal } from '../global'; -import type { GlobalState } from './global/types'; -import type { UiLoaderPage } from './components/common/UiLoader'; +import type { GlobalState } from '../global/types'; +import type { UiLoaderPage } from './common/UiLoader'; +import type { ThemeKey } from '../types'; -import { IS_INSTALL_PROMPT_SUPPORTED, IS_MULTITAB_SUPPORTED, PLATFORM_ENV } from './util/windowEnvironment'; -import { INACTIVE_MARKER, PAGE_TITLE } from './config'; -import { selectTabState } from './global/selectors'; -import { updateSizes } from './util/windowSize'; -import { addActiveTabChangeListener } from './util/activeTabMonitor'; -import { hasStoredSession } from './util/sessions'; -import { setupBeforeInstallPrompt } from './util/installPrompt'; -import buildClassName from './util/buildClassName'; -import { parseInitialLocationHash } from './util/routing'; -import useFlag from './hooks/useFlag'; -import usePrevious from './hooks/usePrevious'; -import useAppLayout from './hooks/useAppLayout'; +import { IS_INSTALL_PROMPT_SUPPORTED, IS_MULTITAB_SUPPORTED, PLATFORM_ENV } from '../util/windowEnvironment'; +import { + DARK_THEME_BG_COLOR, INACTIVE_MARKER, LIGHT_THEME_BG_COLOR, PAGE_TITLE, +} from '../config'; +import { selectTabState, selectTheme } from '../global/selectors'; +import { updateSizes } from '../util/windowSize'; +import { addActiveTabChangeListener } from '../util/activeTabMonitor'; +import { hasStoredSession } from '../util/sessions'; +import buildClassName from '../util/buildClassName'; +import { parseInitialLocationHash } from '../util/routing'; +import useFlag from '../hooks/useFlag'; +import usePrevious from '../hooks/usePrevious'; +import useAppLayout from '../hooks/useAppLayout'; -import Auth from './components/auth/Auth'; -import Main from './components/main/Main.async'; -import LockScreen from './components/main/LockScreen.async'; -import AppInactive from './components/main/AppInactive'; -import Transition from './components/ui/Transition'; -import UiLoader from './components/common/UiLoader'; +import Auth from './auth/Auth'; +import Main from './main/Main.async'; +import LockScreen from './main/LockScreen.async'; +import AppInactive from './main/AppInactive'; +import Transition from './ui/Transition'; +import UiLoader from './common/UiLoader'; // import Test from './components/test/TestNoRedundancy'; +import styles from './App.module.scss'; +import { setupBeforeInstallPrompt } from '../util/installPrompt'; + type StateProps = { authState: GlobalState['authState']; isScreenLocked?: boolean; hasPasscode?: boolean; isInactiveAuth?: boolean; hasWebAuthTokenFailed?: boolean; + theme: ThemeKey; }; enum AppScreens { @@ -47,8 +53,9 @@ const App: FC = ({ authState, isScreenLocked, hasPasscode, - hasWebAuthTokenFailed, isInactiveAuth, + hasWebAuthTokenFailed, + theme, }) => { const { disconnect } = getActions(); @@ -185,6 +192,17 @@ const App: FC = ({ } } + useLayoutEffect(() => { + document.body.classList.add(styles.bg); + }, []); + + useLayoutEffect(() => { + document.body.style.setProperty( + '--theme-background-color', + theme === 'dark' ? DARK_THEME_BG_COLOR : LIGHT_THEME_BG_COLOR, + ); + }, [theme]); + return ( & { isRightColumnShown?: boolean; leftColumnWidth?: number; - theme: ThemeKey; }; const MAX_PRELOAD_DELAY = 700; @@ -111,7 +105,6 @@ const UiLoader: FC = ({ isRightColumnShown, shouldSkipHistoryAnimations, leftColumnWidth, - theme, }) => { const { setIsUiReady } = getActions(); @@ -154,11 +147,7 @@ const UiLoader: FC = ({ }); return ( -
+ <> {children} {shouldRenderMask && !shouldSkipHistoryAnimations && Boolean(page) && (
@@ -168,23 +157,22 @@ const UiLoader: FC = ({ className={styles.left} style={leftColumnWidth ? `width: ${leftColumnWidth}px` : undefined} /> -
+
{isRightColumnShown &&
}
) : (page === 'inactive' || page === 'lock') ? ( -
+
) : (
)}
)} -
+ ); }; export default withGlobal( (global, { isMobile }): StateProps => { - const theme = selectTheme(global); const tabState = selectTabState(global); return { @@ -192,7 +180,6 @@ export default withGlobal( uiReadyState: tabState.uiReadyState, isRightColumnShown: selectIsRightColumnShown(global, isMobile), leftColumnWidth: global.leftColumnWidth, - theme, }; }, )(UiLoader); diff --git a/src/components/left/LeftColumn.tsx b/src/components/left/LeftColumn.tsx index 2b61907ff..81104f538 100644 --- a/src/components/left/LeftColumn.tsx +++ b/src/components/left/LeftColumn.tsx @@ -406,95 +406,98 @@ const LeftColumn: FC = ({ setSettingsScreen(screen); }, []); + function renderContent(isActive: boolean) { + switch (contentType) { + case ContentType.Archived: + return ( + + ); + case ContentType.Settings: + return ( + + ); + case ContentType.NewChannel: + return ( + + ); + case ContentType.NewGroup: + return ( + + ); + default: + return ( + + ); + } + } + return ( -
- - {(isActive) => { - switch (contentType) { - case ContentType.Archived: - return ( - - ); - case ContentType.Settings: - return ( - - ); - case ContentType.NewChannel: - return ( - - ); - case ContentType.NewGroup: - return ( - - ); - default: - return ( - - ); - } - }} - -
-
+ {(isActive) => ( + <> + {renderContent(isActive)} +
+ + )} + ); }; diff --git a/src/components/main/Dialogs.scss b/src/components/main/Dialogs.scss deleted file mode 100644 index 03e4cb7f2..000000000 --- a/src/components/main/Dialogs.scss +++ /dev/null @@ -1,8 +0,0 @@ -#Dialogs { - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - z-index: var(--z-modal); -} diff --git a/src/components/main/Dialogs.tsx b/src/components/main/Dialogs.tsx index d4cebb536..37a5b8fa9 100644 --- a/src/components/main/Dialogs.tsx +++ b/src/components/main/Dialogs.tsx @@ -18,8 +18,6 @@ import Modal from '../ui/Modal'; import Button from '../ui/Button'; import Avatar from '../common/Avatar'; -import './Dialogs.scss'; - type StateProps = { dialogs: (ApiError | ApiInviteInfo | ApiContact)[]; animationLevel: AnimationLevel; @@ -179,11 +177,7 @@ const Dialogs: FC = ({ dialogs, animationLevel }) => { return renderError(dialog); }; - return ( -
- {Boolean(dialogs.length) && renderDialog(dialogs[dialogs.length - 1])} -
- ); + return Boolean(dialogs.length) && renderDialog(dialogs[dialogs.length - 1]); }; function getErrorHeader(error: ApiError) { diff --git a/src/components/main/Main.scss b/src/components/main/Main.scss index 92e218a1e..8330255de 100644 --- a/src/components/main/Main.scss +++ b/src/components/main/Main.scss @@ -28,22 +28,17 @@ } #LeftColumn { - width: 33vw; - --left-column-min-width: 16rem; --left-column-max-width: 26.5rem; + width: 33vw; min-width: var(--left-column-min-width); max-width: var(--left-column-max-width); - height: 100%; position: relative; - background-color: var(--color-background); + overflow: hidden; - & > div { - height: 100%; - overflow: hidden; - } + background-color: var(--color-background); @media (max-width: 600px) { height: calc(var(--vh, 1vh) * 100); diff --git a/src/components/middle/composer/SymbolMenu.scss b/src/components/middle/composer/SymbolMenu.scss index 10434b357..d56a44ca8 100644 --- a/src/components/middle/composer/SymbolMenu.scss +++ b/src/components/middle/composer/SymbolMenu.scss @@ -18,7 +18,7 @@ right: 0; bottom: 0; background: var(--color-background); - z-index: 1; + z-index: var(--z-symbol-menu-mobile); transition: transform var(--layer-transition); padding-right: env(safe-area-inset-right); diff --git a/src/index.html b/src/index.html index cb8280635..f0049dbbb 100644 --- a/src/index.html +++ b/src/index.html @@ -43,13 +43,12 @@ - + -
diff --git a/src/index.tsx b/src/index.tsx index 93ba8d383..d2ba7816f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -17,7 +17,7 @@ import { requestGlobal, subscribeToMultitabBroadcastChannel } from './util/multi import { onBeforeUnload } from './util/schedulers'; import { selectTabState } from './global/selectors'; -import App from './App'; +import App from './components/App'; import './styles/index.scss'; diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss index c5aeac64f..120125aae 100644 --- a/src/styles/_variables.scss +++ b/src/styles/_variables.scss @@ -242,6 +242,7 @@ $color-message-reaction-own-hover: #b5e0a4; --z-register-add-avatar: 5; --z-forum-panel: 5; --z-media-viewer-head: 3; + --z-symbol-menu-mobile: 2; --z-resize-handle: 2; --z-below: -1; diff --git a/src/styles/print.scss b/src/styles/print.scss index 67938c228..7fb70c708 100644 --- a/src/styles/print.scss +++ b/src/styles/print.scss @@ -26,7 +26,6 @@ html, body, #root, - #UiLoader, #Main, #MiddleColumn, .MessageList,