Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permanent sidebar #46

Merged
merged 6 commits into from
Oct 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
Route,
Redirect,
} from 'react-router-dom';
import { Container } from '@mui/material';
import { Container, useMediaQuery } from '@mui/material';
import CssBaseline from '@mui/material/CssBaseline';
import {
createTheme, ThemeProvider, Theme, StyledEngineProvider,
Expand Down Expand Up @@ -76,6 +76,8 @@ export default function App() {
}),
[darkTheme],
);
// this can only be used after the theme object is created
const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));

return (
<Router>
Expand All @@ -88,7 +90,7 @@ export default function App() {
id="appMainContainer"
maxWidth={false}
disableGutters
style={{ paddingTop: '64px' }}
style={{ paddingTop: theme.spacing(8), paddingLeft: isMobileWidth ? '' : theme.spacing(8) }}
>
<Switch>
{/* General Routes */}
Expand Down
69 changes: 12 additions & 57 deletions src/components/TemporaryDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,7 @@ import Drawer from '@mui/material/Drawer';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import CollectionsBookmarkIcon from '@mui/icons-material/CollectionsBookmark';
import ExploreIcon from '@mui/icons-material/Explore';
import ExtensionIcon from '@mui/icons-material/Extension';
import GetAppIcon from '@mui/icons-material/GetApp';
import NewReleasesIcon from '@mui/icons-material/NewReleases';
import ListItemText from '@mui/material/ListItemText';
import SettingsIcon from '@mui/icons-material/Settings';
import { Link } from 'react-router-dom';

const useStyles = makeStyles({
Expand All @@ -30,9 +24,10 @@ interface IProps {
drawerOpen: boolean

setDrawerOpen: React.Dispatch<React.SetStateAction<boolean>>
navBarItems: Array<NavbarItem>
}

export default function TemporaryDrawer({ drawerOpen, setDrawerOpen }: IProps) {
export default function TemporaryDrawer({ drawerOpen, setDrawerOpen, navBarItems }: IProps) {
const classes = useStyles();

return (
Expand All @@ -49,56 +44,16 @@ export default function TemporaryDrawer({ drawerOpen, setDrawerOpen }: IProps) {
onKeyDown={() => setDrawerOpen(false)}
>
<List>
<Link to="/library" style={{ color: 'inherit', textDecoration: 'none' }}>
<ListItem button key="Library">
<ListItemIcon>
<CollectionsBookmarkIcon />
</ListItemIcon>
<ListItemText primary="Library" />
</ListItem>
</Link>

<Link to="/updates" style={{ color: 'inherit', textDecoration: 'none' }}>
<ListItem button key="Updates">
<ListItemIcon>
<NewReleasesIcon />
</ListItemIcon>
<ListItemText primary="Updates" />
</ListItem>
</Link>

<Link to="/manga/extensions" style={{ color: 'inherit', textDecoration: 'none' }}>
<ListItem button key="Extensions">
<ListItemIcon>
<ExtensionIcon />
</ListItemIcon>
<ListItemText primary="Extensions" />
</ListItem>
</Link>
<Link to="/manga/sources" style={{ color: 'inherit', textDecoration: 'none' }}>
<ListItem button key="Sources">
<ListItemIcon>
<ExploreIcon />
</ListItemIcon>
<ListItemText primary="Sources" />
</ListItem>
</Link>
<Link to="/manga/downloads" style={{ color: 'inherit', textDecoration: 'none' }}>
<ListItem button key="Manga Download Queue">
<ListItemIcon>
<GetAppIcon />
</ListItemIcon>
<ListItemText primary="Downloads" />
</ListItem>
</Link>
<Link to="/settings" style={{ color: 'inherit', textDecoration: 'none' }}>
<ListItem button key="settings">
<ListItemIcon>
<SettingsIcon />
</ListItemIcon>
<ListItemText primary="Settings" />
</ListItem>
</Link>
{navBarItems.map((({ path, title, IconComponent }: NavbarItem) => (
<Link to={path} style={{ color: 'inherit', textDecoration: 'none' }}>
<ListItem button key={title}>
<ListItemIcon>
<IconComponent />
</ListItemIcon>
<ListItemText primary={title} />
</ListItem>
</Link>
)))}
</List>
</div>
</Drawer>
Expand Down
77 changes: 63 additions & 14 deletions src/components/navbar/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,18 @@ import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import IconButton from '@mui/material/IconButton';
import MenuIcon from '@mui/icons-material/Menu';
import { useMediaQuery } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import CollectionsBookmarkIcon from '@mui/icons-material/CollectionsBookmark';
import NewReleasesIcon from '@mui/icons-material/NewReleases';
import ExtensionIcon from '@mui/icons-material/Extension';
import ExploreIcon from '@mui/icons-material/Explore';
import GetAppIcon from '@mui/icons-material/GetApp';
import SettingsIcon from '@mui/icons-material/Settings';
import TemporaryDrawer from 'components/TemporaryDrawer';
import NavBarContext from '../../context/NavbarContext';
import DarkTheme from '../../context/DarkTheme';
import TemporaryDrawer from '../TemporaryDrawer';
import PermanentSideBar from './PermanentSideBar';

const useStyles = makeStyles((theme) => ({
root: {
Expand All @@ -28,10 +37,41 @@ const useStyles = makeStyles((theme) => ({
},
}));

const navbarItems: Array<NavbarItem> = [
{
path: '/library',
title: 'Library',
IconComponent: CollectionsBookmarkIcon,
},
{
path: '/updates',
title: 'Updates',
IconComponent: NewReleasesIcon,
}, {
path: '/manga/extensions',
title: 'Extensions',
IconComponent: ExtensionIcon,
}, {
path: '/manga/sources',
title: 'Sources',
IconComponent: ExploreIcon,
}, {
path: '/manga/downloads',
title: 'Manga Download Queue',
IconComponent: GetAppIcon,
}, {
path: '/settings',
title: 'Settings',
IconComponent: SettingsIcon,
},
];

export default function NavBar() {
const classes = useStyles();
const [drawerOpen, setDrawerOpen] = useState(false);
const { title, action, override } = useContext(NavBarContext);
const theme = useTheme();
const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));

const { darkTheme } = useContext(DarkTheme);

Expand All @@ -43,24 +83,33 @@ export default function NavBar() {
<div className={classes.root}>
<AppBar position="fixed" color={darkTheme ? 'default' : 'primary'}>
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="menu"
disableRipple
onClick={() => setDrawerOpen(true)}
size="large"
>
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
{isMobileWidth && (
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="menu"
disableRipple
onClick={() => setDrawerOpen(true)}
size="large"
>
<MenuIcon />
</IconButton>
)}
<Typography variant={isMobileWidth ? 'h6' : 'h5'} className={classes.title}>
{title}
</Typography>
{action}
</Toolbar>
</AppBar>
<TemporaryDrawer drawerOpen={drawerOpen} setDrawerOpen={setDrawerOpen} />
{isMobileWidth ? (
<TemporaryDrawer
navBarItems={navbarItems}
drawerOpen={drawerOpen}
setDrawerOpen={setDrawerOpen}
/>
)
: <PermanentSideBar navBarItems={navbarItems} />}
</div>
)}
</>
Expand Down
60 changes: 60 additions & 0 deletions src/components/navbar/PermanentSideBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

import React from 'react';
import makeStyles from '@mui/styles/makeStyles';
import {
List, ListItem, ListItemIcon, Tooltip,
} from '@mui/material';
import { Link, useLocation } from 'react-router-dom';

const useStyles = makeStyles((theme) => ({
sideBar: {
height: '100vh',
width: theme.spacing(8),
backgroundColor: theme.palette.mode === 'light' ? theme.palette.grey[100] : theme.palette.grey[900],
position: 'fixed',
top: 0,
left: 0,
paddingTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
boxShadow: theme.shadows[5],
},
tooltip: {
fontSize: '1rem',
},
}));

interface IProps {
navBarItems: Array<NavbarItem>
}

export default function PermanentSideBar({ navBarItems }: IProps) {
const location = useLocation();
const classes = useStyles();
return (
<div className={classes.sideBar}>
<List>
{
// eslint-disable-next-line react/destructuring-assignment
navBarItems.map(({ path, title, IconComponent }: NavbarItem) => (
<Link to={path} style={{ color: 'inherit', textDecoration: 'none' }} key={path}>
<ListItem button key={title}>
<ListItemIcon>
<Tooltip placement="right" classes={{ tooltip: classes.tooltip }} title={title}>
<IconComponent color={location.pathname === path ? 'primary' : 'action'} fontSize="large" />
</Tooltip>
</ListItemIcon>
</ListItem>
</Link>
))
}
</List>
</div>
);
}
6 changes: 6 additions & 0 deletions src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,9 @@ interface SourcePreferences {
type: string
props: any
}

interface NavbarItem{
path: string,
title:string,
IconComponent: OverridableComponent<SvgIconTypeMap<{}, 'svg'>>,
}