From d8d002cc4adaa9d70d0153277fc25ac4c3d904f1 Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 24 Dec 2021 13:02:49 +0000 Subject: [PATCH] feat(header): add chevron / unified sidebar collapse --- src/components/navigation/LeftSidebar.tsx | 5 +- src/components/ui/Header.tsx | 72 +++++++++++++++++++++-- src/mobx/stores/Layout.ts | 2 +- src/pages/channels/ChannelHeader.tsx | 45 ++++---------- src/pages/developer/Developer.tsx | 7 +-- src/pages/friends/Friends.tsx | 7 +-- src/pages/home/Home.tsx | 32 +--------- 7 files changed, 91 insertions(+), 79 deletions(-) diff --git a/src/components/navigation/LeftSidebar.tsx b/src/components/navigation/LeftSidebar.tsx index 309cb360..2e61cc15 100644 --- a/src/components/navigation/LeftSidebar.tsx +++ b/src/components/navigation/LeftSidebar.tsx @@ -1,3 +1,4 @@ +import { observer } from "mobx-react-lite"; import { Route, Switch } from "react-router"; import { useApplicationState } from "../../mobx/State"; @@ -8,7 +9,7 @@ import HomeSidebar from "./left/HomeSidebar"; import ServerListSidebar from "./left/ServerListSidebar"; import ServerSidebar from "./left/ServerSidebar"; -export default function LeftSidebar() { +export default observer(() => { const layout = useApplicationState().layout; const isOpen = layout.getSectionState(SIDEBAR_CHANNELS, true); @@ -35,4 +36,4 @@ export default function LeftSidebar() { ); -} +}); diff --git a/src/components/ui/Header.tsx b/src/components/ui/Header.tsx index 1b9a7da1..18ee8d03 100644 --- a/src/components/ui/Header.tsx +++ b/src/components/ui/Header.tsx @@ -1,15 +1,25 @@ -import { Menu } from "@styled-icons/boxicons-regular"; +import { + ChevronLeft, + ChevronRight, + Menu, +} from "@styled-icons/boxicons-regular"; +import { observer } from "mobx-react-lite"; import styled, { css } from "styled-components"; import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice"; +import { useApplicationState } from "../../mobx/State"; +import { SIDEBAR_CHANNELS } from "../../mobx/stores/Layout"; + +import { Children } from "../../types/Preact"; + interface Props { borders?: boolean; background?: boolean; placement: "primary" | "secondary"; } -export default styled.div` +const Header = styled.div` gap: 10px; height: 48px; flex: 0 auto; @@ -33,10 +43,6 @@ export default styled.div` color: var(--secondary-foreground); } - /*@media only screen and (max-width: 768px) { - padding: 0 12px; - }*/ - ${() => isTouchscreenDevice && css` @@ -66,6 +72,60 @@ export default styled.div` `} `; +export default Header; + +const IconContainer = styled.div` + display: flex; + align-items: center; + cursor: pointer; + color: var(--secondary-foreground); + margin-right: 5px; + + > svg { + margin-right: -5px; + } + + ${!isTouchscreenDevice && + css` + &:hover { + color: var(--foreground); + } + `} +`; + +interface PageHeaderProps { + noBurger?: boolean; + children: Children; + icon: Children; +} + +export const PageHeader = observer( + ({ children, icon, noBurger }: PageHeaderProps) => { + const layout = useApplicationState().layout; + + return ( +
+ {!noBurger && } + + layout.toggleSectionState(SIDEBAR_CHANNELS, true) + }> + {!isTouchscreenDevice && + layout.getSectionState(SIDEBAR_CHANNELS, true) && ( + + )} + {icon} + {!isTouchscreenDevice && + !layout.getSectionState(SIDEBAR_CHANNELS, true) && ( + + )} + + {children} +
+ ); + }, +); + export function HamburgerAction() { if (!isTouchscreenDevice) return null; diff --git a/src/mobx/stores/Layout.ts b/src/mobx/stores/Layout.ts index 80d03109..324626ad 100644 --- a/src/mobx/stores/Layout.ts +++ b/src/mobx/stores/Layout.ts @@ -177,6 +177,6 @@ export default class Layout implements Store, Persistent { * @param def Default state value */ @action toggleSectionState(id: string, def?: boolean) { - this.setSectionState(id, !this.getSectionState(id, def)); + this.setSectionState(id, !this.getSectionState(id, def), def); } } diff --git a/src/pages/channels/ChannelHeader.tsx b/src/pages/channels/ChannelHeader.tsx index 30c857a7..70b8f34d 100644 --- a/src/pages/channels/ChannelHeader.tsx +++ b/src/pages/channels/ChannelHeader.tsx @@ -1,4 +1,9 @@ -import { At, Hash } from "@styled-icons/boxicons-regular"; +import { + At, + ChevronLeft, + ChevronRight, + Hash, +} from "@styled-icons/boxicons-regular"; import { Notepad, Group } from "@styled-icons/boxicons-solid"; import { observer } from "mobx-react-lite"; import { Channel } from "revolt.js/dist/maps/Channels"; @@ -8,14 +13,17 @@ import styled, { css } from "styled-components"; import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice"; import { useApplicationState } from "../../mobx/State"; -import { SIDEBAR_MEMBERS } from "../../mobx/stores/Layout"; +import { SIDEBAR_CHANNELS, SIDEBAR_MEMBERS } from "../../mobx/stores/Layout"; import { useIntermediate } from "../../context/intermediate/Intermediate"; import { getChannelName } from "../../context/revoltjs/util"; import { useStatusColour } from "../../components/common/user/UserIcon"; import UserStatus from "../../components/common/user/UserStatus"; -import Header, { HamburgerAction } from "../../components/ui/Header"; +import Header, { + HamburgerAction, + PageHeader, +} from "../../components/ui/Header"; import Markdown from "../../components/markdown/Markdown"; import HeaderActions from "./actions/HeaderActions"; @@ -68,25 +76,6 @@ const Info = styled.div` } `; -const IconConainer = styled.div` - display: flex; - align-items: center; - cursor: pointer; - color: var(--secondary-foreground); - margin-right: 5px; - - > svg { - margin-right: -5px; - } - - ${!isTouchscreenDevice && - css` - &:hover { - color: var(--foreground); - } - `} -`; - export default observer(({ channel }: ChannelHeaderProps) => { const { openScreen } = useIntermediate(); const layout = useApplicationState().layout; @@ -110,15 +99,7 @@ export default observer(({ channel }: ChannelHeaderProps) => { } return ( -
- - - layout.toggleSectionState(SIDEBAR_MEMBERS, true) - }> - {/*isTouchscreenDevice && FIXME: requires mobx merge */} - {icon} - + {name} {isTouchscreenDevice && @@ -162,6 +143,6 @@ export default observer(({ channel }: ChannelHeaderProps) => { )} -
+ ); }); diff --git a/src/pages/developer/Developer.tsx b/src/pages/developer/Developer.tsx index 782662a4..ddf50ea9 100644 --- a/src/pages/developer/Developer.tsx +++ b/src/pages/developer/Developer.tsx @@ -7,7 +7,7 @@ import { TextReact } from "../../lib/i18n"; import { AppContext } from "../../context/revoltjs/RevoltClient"; -import Header from "../../components/ui/Header"; +import Header, { PageHeader } from "../../components/ui/Header"; export default function Developer() { // const voice = useContext(VoiceContext); @@ -27,10 +27,7 @@ export default function Developer() { return (
-
- - Developer Tab -
+ }>Developer Tab
diff --git a/src/pages/friends/Friends.tsx b/src/pages/friends/Friends.tsx index bc348ef0..1a0bea04 100644 --- a/src/pages/friends/Friends.tsx +++ b/src/pages/friends/Friends.tsx @@ -16,7 +16,7 @@ import { useClient } from "../../context/revoltjs/RevoltClient"; import CollapsibleSection from "../../components/common/CollapsibleSection"; import Tooltip from "../../components/common/Tooltip"; import UserIcon from "../../components/common/user/UserIcon"; -import Header from "../../components/ui/Header"; +import Header, { PageHeader } from "../../components/ui/Header"; import IconButton from "../../components/ui/IconButton"; import { Children } from "../../types/Preact"; @@ -72,8 +72,7 @@ export default observer(() => { const isEmpty = lists.reduce((p: number, n) => p + n.length, 0) === 0; return ( <> -
- {!isTouchscreenDevice && } + } noBurger>
@@ -115,7 +114,7 @@ export default observer(() => { */}
- +
{ const client = useContext(AppContext); const state = useApplicationState(); - const toggleChannelSidebar = () => { - if (isTouchscreenDevice) { - return; - } - - state.layout.toggleSectionState(SIDEBAR_CHANNELS, true); - }; - const toggleSeasonalTheme = () => state.settings.set( "appearance:seasonal", @@ -107,12 +84,9 @@ export default observer(() => {
)}
-
- - - + }> -
+