forked from Archives/Athou_commafeed
save sidebar width in local storage (#1093)
This commit is contained in:
@@ -71,7 +71,6 @@ function Providers(props: { children: React.ReactNode }) {
|
|||||||
const ApiDocumentationPage = React.lazy(async () => await import("pages/app/ApiDocumentationPage"))
|
const ApiDocumentationPage = React.lazy(async () => await import("pages/app/ApiDocumentationPage"))
|
||||||
|
|
||||||
function AppRoutes() {
|
function AppRoutes() {
|
||||||
const sidebarWidth = useAppSelector(state => state.tree.sidebarWidth)
|
|
||||||
const sidebarVisible = useAppSelector(state => state.tree.sidebarVisible)
|
const sidebarVisible = useAppSelector(state => state.tree.sidebarVisible)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -82,10 +81,7 @@ function AppRoutes() {
|
|||||||
<Route path="register" element={<RegistrationPage />} />
|
<Route path="register" element={<RegistrationPage />} />
|
||||||
<Route path="passwordRecovery" element={<PasswordRecoveryPage />} />
|
<Route path="passwordRecovery" element={<PasswordRecoveryPage />} />
|
||||||
<Route path="api" element={<ApiDocumentationPage />} />
|
<Route path="api" element={<ApiDocumentationPage />} />
|
||||||
<Route
|
<Route path="app" element={<Layout header={<Header />} sidebar={<Tree />} sidebarVisible={sidebarVisible} />}>
|
||||||
path="app"
|
|
||||||
element={<Layout header={<Header />} sidebar={<Tree />} sidebarWidth={sidebarWidth} sidebarVisible={sidebarVisible} />}
|
|
||||||
>
|
|
||||||
<Route path="category">
|
<Route path="category">
|
||||||
<Route path=":id" element={<FeedEntriesPage sourceType="category" />} />
|
<Route path=":id" element={<FeedEntriesPage sourceType="category" />} />
|
||||||
<Route path=":id/details" element={<CategoryDetailsPage />} />
|
<Route path=":id/details" element={<CategoryDetailsPage />} />
|
||||||
|
|||||||
@@ -8,13 +8,11 @@ import { visitCategoryTree } from "app/utils"
|
|||||||
interface TreeState {
|
interface TreeState {
|
||||||
rootCategory?: Category
|
rootCategory?: Category
|
||||||
mobileMenuOpen: boolean
|
mobileMenuOpen: boolean
|
||||||
sidebarWidth: number
|
|
||||||
sidebarVisible: boolean
|
sidebarVisible: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: TreeState = {
|
const initialState: TreeState = {
|
||||||
mobileMenuOpen: false,
|
mobileMenuOpen: false,
|
||||||
sidebarWidth: 350,
|
|
||||||
sidebarVisible: true,
|
sidebarVisible: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,9 +23,6 @@ export const treeSlice = createSlice({
|
|||||||
setMobileMenuOpen: (state, action: PayloadAction<boolean>) => {
|
setMobileMenuOpen: (state, action: PayloadAction<boolean>) => {
|
||||||
state.mobileMenuOpen = action.payload
|
state.mobileMenuOpen = action.payload
|
||||||
},
|
},
|
||||||
setSidebarWidth: (state, action: PayloadAction<number>) => {
|
|
||||||
state.sidebarWidth = action.payload
|
|
||||||
},
|
|
||||||
toggleSidebar: state => {
|
toggleSidebar: state => {
|
||||||
state.sidebarVisible = !state.sidebarVisible
|
state.sidebarVisible = !state.sidebarVisible
|
||||||
},
|
},
|
||||||
@@ -58,4 +53,4 @@ export const treeSlice = createSlice({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const { setMobileMenuOpen, setSidebarWidth, toggleSidebar } = treeSlice.actions
|
export const { setMobileMenuOpen, toggleSidebar } = treeSlice.actions
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ActionIcon, AppShell, Box, Center, Group, ScrollArea, Title, useMantine
|
|||||||
import { Constants } from "app/constants"
|
import { Constants } from "app/constants"
|
||||||
import { redirectToAdd, redirectToRootCategory } from "app/redirect/thunks"
|
import { redirectToAdd, redirectToRootCategory } from "app/redirect/thunks"
|
||||||
import { useAppDispatch, useAppSelector } from "app/store"
|
import { useAppDispatch, useAppSelector } from "app/store"
|
||||||
import { setMobileMenuOpen, setSidebarWidth } from "app/tree/slice"
|
import { setMobileMenuOpen } from "app/tree/slice"
|
||||||
import { reloadTree } from "app/tree/thunks"
|
import { reloadTree } from "app/tree/thunks"
|
||||||
import { reloadProfile, reloadSettings, reloadTags } from "app/user/thunks"
|
import { reloadProfile, reloadSettings, reloadTags } from "app/user/thunks"
|
||||||
import { ActionButton } from "components/ActionButton"
|
import { ActionButton } from "components/ActionButton"
|
||||||
@@ -19,10 +19,10 @@ import { type ReactNode, Suspense, useEffect } from "react"
|
|||||||
import Draggable from "react-draggable"
|
import Draggable from "react-draggable"
|
||||||
import { TbMenu2, TbPlus, TbX } from "react-icons/tb"
|
import { TbMenu2, TbPlus, TbX } from "react-icons/tb"
|
||||||
import { Outlet } from "react-router-dom"
|
import { Outlet } from "react-router-dom"
|
||||||
|
import useLocalStorage from "use-local-storage"
|
||||||
|
|
||||||
interface LayoutProps {
|
interface LayoutProps {
|
||||||
sidebar: ReactNode
|
sidebar: ReactNode
|
||||||
sidebarWidth: number
|
|
||||||
sidebarVisible: boolean
|
sidebarVisible: boolean
|
||||||
header: ReactNode
|
header: ReactNode
|
||||||
}
|
}
|
||||||
@@ -45,6 +45,7 @@ export default function Layout(props: LayoutProps) {
|
|||||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||||
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||||
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
||||||
|
const [sidebarWidth, setSidebarWidth] = useLocalStorage("sidebar-width", 350)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
useWebSocket()
|
useWebSocket()
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ export default function Layout(props: LayoutProps) {
|
|||||||
<AppShell
|
<AppShell
|
||||||
header={{ height: Constants.layout.headerHeight }}
|
header={{ height: Constants.layout.headerHeight }}
|
||||||
navbar={{
|
navbar={{
|
||||||
width: props.sidebarWidth,
|
width: sidebarWidth,
|
||||||
breakpoint: Constants.layout.mobileBreakpoint,
|
breakpoint: Constants.layout.mobileBreakpoint,
|
||||||
collapsed: { mobile: !mobileMenuOpen, desktop: !props.sidebarVisible },
|
collapsed: { mobile: !mobileMenuOpen, desktop: !props.sidebarVisible },
|
||||||
}}
|
}}
|
||||||
@@ -117,7 +118,7 @@ export default function Layout(props: LayoutProps) {
|
|||||||
</OnMobile>
|
</OnMobile>
|
||||||
<OnDesktop>
|
<OnDesktop>
|
||||||
<Group p="md">
|
<Group p="md">
|
||||||
<Group justify="space-between" style={{ width: props.sidebarWidth - 16 }}>
|
<Group justify="space-between" style={{ width: sidebarWidth - 16 }}>
|
||||||
<Box>
|
<Box>
|
||||||
<LogoAndTitle />
|
<LogoAndTitle />
|
||||||
</Box>
|
</Box>
|
||||||
@@ -135,7 +136,7 @@ export default function Layout(props: LayoutProps) {
|
|||||||
<Draggable
|
<Draggable
|
||||||
axis="x"
|
axis="x"
|
||||||
defaultPosition={{
|
defaultPosition={{
|
||||||
x: props.sidebarWidth,
|
x: sidebarWidth,
|
||||||
y: Constants.layout.headerHeight,
|
y: Constants.layout.headerHeight,
|
||||||
}}
|
}}
|
||||||
bounds={{
|
bounds={{
|
||||||
@@ -143,9 +144,7 @@ export default function Layout(props: LayoutProps) {
|
|||||||
right: 1000,
|
right: 1000,
|
||||||
}}
|
}}
|
||||||
grid={[30, 30]}
|
grid={[30, 30]}
|
||||||
onDrag={(_e, data) => {
|
onDrag={(_e, data) => setSidebarWidth(data.x)}
|
||||||
dispatch(setSidebarWidth(data.x))
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
Reference in New Issue
Block a user