From f43b7af3cd3b67c220bc40259c644c0be455ff0a Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Thu, 11 Jul 2024 17:22:52 +0200 Subject: [PATCH] Refactor base app layout --- src/App.tsx | 67 ++++++--- src/components/context/NavbarContext.tsx | 21 +++ src/components/navbar/DefaultNavBar.tsx | 136 ++++++++++------- .../navbar/NavBarContextProvider.tsx | 31 +++- .../navbar/navigation/DesktopSideBar.tsx | 140 +++++++++++++----- .../navbar/navigation/MobileBottomBar.tsx | 112 ++++++-------- .../MultiSelectListPreference.tsx | 1 - src/components/tabs/TabsMenu.tsx | 64 +++++--- src/components/tabs/TabsWrapper.tsx | 26 ++-- .../virtuoso/StyledGroupItemWrapper.tsx | 7 +- .../virtuoso/StyledGroupedVirtuoso.tsx | 32 ++-- src/screens/Browse.tsx | 14 +- src/screens/Extensions.tsx | 30 +--- src/screens/Migration.tsx | 7 +- src/screens/SearchAll.tsx | 4 +- src/screens/Updates.tsx | 2 +- src/screens/settings/Categories.tsx | 6 +- src/screens/settings/LibraryDuplicates.tsx | 9 +- src/util/useResizeObserver.tsx | 22 +++ 19 files changed, 443 insertions(+), 288 deletions(-) create mode 100644 src/util/useResizeObserver.tsx diff --git a/src/App.tsx b/src/App.tsx index c00a69a6..b48628ae 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,12 +6,13 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import Container from '@mui/material/Container'; import CssBaseline from '@mui/material/CssBaseline'; import React, { useLayoutEffect } from 'react'; import { Navigate, Route, Routes, useLocation } from 'react-router-dom'; import { loadErrorMessages, loadDevMessages } from '@apollo/client/dev'; import { loadable } from 'react-lazily/loadable'; +import Box from '@mui/material/Box'; +import Toolbar from '@mui/material/Toolbar'; import { AppContext } from '@/components/context/AppContext'; import '@/i18n'; import { DefaultNavBar } from '@/components/navbar/DefaultNavBar'; @@ -20,6 +21,7 @@ import { WebUIUpdateChecker } from '@/components/util/WebUIUpdateChecker.tsx'; import { ServerUpdateChecker } from '@/components/util/ServerUpdateChecker.tsx'; import { lazyLoadFallback } from '@/util/LazyLoad.tsx'; import { ErrorBoundary } from '@/util/ErrorBoundary.tsx'; +import { useNavBarContext } from '@/components/context/NavbarContext.tsx'; const { Browse } = loadable(() => import('@/screens/Browse'), lazyLoadFallback); const { DownloadQueue } = loadable(() => import('@/screens/DownloadQueue'), lazyLoadFallback); @@ -76,26 +78,23 @@ const BackgroundSubscriptions = () => { return null; }; -export const App: React.FC = () => ( - - - - - - - - { + const { navBarWidth, bottomBarHeight } = useNavBarContext(); + + return ( + + + {/* General Routes */} @@ -142,12 +141,32 @@ export const App: React.FC = () => ( } /> - - - - } /> - - - + + ); +}; + +const ReaderApp = () => ( + + + } /> + + + +); + +export const App: React.FC = () => ( + + + + + + + + + + + + + ); diff --git a/src/components/context/NavbarContext.tsx b/src/components/context/NavbarContext.tsx index 6d83cf09..a2817179 100644 --- a/src/components/context/NavbarContext.tsx +++ b/src/components/context/NavbarContext.tsx @@ -16,6 +16,9 @@ type ContextType = { title: string | React.ReactNode; setTitle: (title: ContextType['title'], browserTitle?: string) => void; + appBarHeight: number; + setAppBarHeight: React.Dispatch>; + // AppBar action buttons action: any; setAction: React.Dispatch>; @@ -23,16 +26,34 @@ type ContextType = { // Allow default navbar to be overrided override: INavbarOverride; setOverride: React.Dispatch>; + + // NavBar + isCollapsed: boolean; + setIsCollapsed: React.Dispatch>; + + navBarWidth: number; + setNavBarWidth: React.Dispatch>; + + bottomBarHeight: number; + setBottomBarHeight: React.Dispatch>; }; export const NavBarContext = React.createContext({ history: [], title: 'Suwayomi', setTitle: (): void => {}, + appBarHeight: 0, + setAppBarHeight: (): void => {}, action:
, setAction: (): void => {}, override: { status: false, value:
}, setOverride: (): void => {}, + isCollapsed: false, + setIsCollapsed: (): void => {}, + navBarWidth: 0, + setNavBarWidth: (): void => {}, + bottomBarHeight: 0, + setBottomBarHeight: (): void => {}, }); export const useNavBarContext = () => useContext(NavBarContext); diff --git a/src/components/navbar/DefaultNavBar.tsx b/src/components/navbar/DefaultNavBar.tsx index c3a9d269..68b4bad3 100644 --- a/src/components/navbar/DefaultNavBar.tsx +++ b/src/components/navbar/DefaultNavBar.tsx @@ -6,12 +6,11 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import React, { useContext } from 'react'; +import { useCallback, useContext, useMemo, useRef } from 'react'; import AppBar from '@mui/material/AppBar'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; -import Box from '@mui/material/Box'; import CollectionsBookmarkIcon from '@mui/icons-material/CollectionsBookmark'; import CollectionsOutlinedBookmarkIcon from '@mui/icons-material/CollectionsBookmarkOutlined'; import NewReleasesIcon from '@mui/icons-material/NewReleases'; @@ -23,15 +22,17 @@ import GetAppOutlinedIcon from '@mui/icons-material/GetAppOutlined'; import SettingsIcon from '@mui/icons-material/Settings'; import ArrowBack from '@mui/icons-material/ArrowBack'; import { useLocation } from 'react-router-dom'; -import { createPortal } from 'react-dom'; import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import MenuIcon from '@mui/icons-material/Menu'; +import Stack from '@mui/material/Stack'; import { NavbarItem } from '@/typings'; import { NavBarContext } from '@/components/context/NavbarContext'; -import { DesktopSideBar } from '@/components/navbar/navigation/DesktopSideBar'; -import { MobileBottomBar } from '@/components/navbar/navigation/MobileBottomBar'; import { useBackButton } from '@/util/useBackButton.ts'; import { getOptionForDirection } from '@/theme.ts'; import { MediaQuery } from '@/lib/ui/MediaQuery.tsx'; +import { DesktopSideBar } from '@/components/navbar/navigation/DesktopSideBar.tsx'; +import { useResizeObserver } from '@/util/useResizeObserver.tsx'; +import { MobileBottomBar } from '@/components/navbar/navigation/MobileBottomBar.tsx'; const navbarItems: Array = [ { @@ -72,7 +73,8 @@ const navbarItems: Array = [ ]; export function DefaultNavBar() { - const { title, action, override } = useContext(NavBarContext); + const { title, action, override, isCollapsed, setIsCollapsed, setAppBarHeight, navBarWidth } = + useContext(NavBarContext); const { pathname } = useLocation(); const handleBack = useBackButton(); @@ -80,59 +82,91 @@ export function DefaultNavBar() { const isMobileWidth = MediaQuery.useIsMobileWidth(); const isMainRoute = navbarItems.some(({ path }) => path === pathname); + const actualNavBarWidth = isMobileWidth || isCollapsed ? 0 : navBarWidth; + + const appBarRef = useRef(null); + useResizeObserver( + appBarRef, + useCallback(() => setAppBarHeight(appBarRef.current?.clientHeight ?? 0), [appBarRef]), + ); + + const activeNavBar: NavbarItem['show'] = isMobileWidth ? 'mobile' : 'desktop'; + const visibleNavBarItems = useMemo( + () => navbarItems.filter(({ show }) => ['both', activeNavBar].includes(show)), + [isMobileWidth], + ); + const NavBarComponent = useMemo(() => (isMobileWidth ? MobileBottomBar : DesktopSideBar), [isMobileWidth]); + + const navBar = useMemo( + () => , + [NavBarComponent, visibleNavBarItems], + ); + // Allow default navbar to be overrided if (override.status) return override.value; - let navbar: JSX.Element | null = null; - if (isMobileWidth) { - if (isMainRoute) { - navbar = it.show !== 'desktop')} />; - } - } else { - navbar = it.show !== 'mobile')} />; - } - return ( - - - - {!isMainRoute && ( - + theme.zIndex.drawer + 1, + }} + color="default" + > + + {!isMobileWidth && ( + - {getOptionForDirection(, )} - + setIsCollapsed(false)}> + + + )} - - {title} - - {action} -