web: add support for hiding items from side bar

This commit is contained in:
Abdullah Atta
2023-12-20 12:08:16 +05:00
parent 2f77390a8e
commit 305a522a65
3 changed files with 78 additions and 11 deletions

View File

@@ -68,6 +68,7 @@ import {
import { isUserPremium } from "../../hooks/use-is-user-premium"; import { isUserPremium } from "../../hooks/use-is-user-premium";
import { showToast } from "../../utils/toast"; import { showToast } from "../../utils/toast";
import { usePersistentState } from "../../hooks/use-persistent-state"; import { usePersistentState } from "../../hooks/use-persistent-state";
import { MenuItem } from "@notesnook/ui";
type Route = { type Route = {
id: string; id: string;
@@ -144,6 +145,14 @@ function NavigationMenu(props: NavigationMenuProps) {
const setFollowSystemTheme = useThemeStore( const setFollowSystemTheme = useThemeStore(
(store) => store.setFollowSystemTheme (store) => store.setFollowSystemTheme
); );
const [hiddenRoutes, setHiddenRoutes] = usePersistentState(
"sidebarHiddenItems:routes",
db.settings.getSideBarHiddenItems("routes")
);
const [hiddenColors, setHiddenColors] = usePersistentState(
"sidebarHiddenItems:colors",
db.settings.getSideBarHiddenItems("colors")
);
const _navigate = useCallback( const _navigate = useCallback(
(path: string) => { (path: string) => {
@@ -163,6 +172,28 @@ function NavigationMenu(props: NavigationMenuProps) {
} else navigationHistory.delete(previousLocation); } else navigationHistory.delete(previousLocation);
}, [location, previousLocation, state]); }, [location, previousLocation, state]);
const getSidebarItems = useCallback(async () => {
return [
...toMenuItems(
orderItems(routes, db.settings.getSideBarOrder("routes")),
hiddenRoutes,
(ids) =>
db.settings
.setSideBarHiddenItems("routes", ids)
.then(() => setHiddenRoutes(ids))
),
{ type: "separator", key: "sep" },
...toMenuItems(
orderItems(colors, db.settings.getSideBarOrder("colors")),
hiddenColors,
(ids) =>
db.settings
.setSideBarHiddenItems("colors", ids)
.then(() => setHiddenColors(ids))
)
] as MenuItem[];
}, [colors, hiddenColors, hiddenRoutes]);
return ( return (
<ScopedThemeProvider <ScopedThemeProvider
scope="navigationMenu" scope="navigationMenu"
@@ -206,11 +237,11 @@ function NavigationMenu(props: NavigationMenuProps) {
> >
<Flex sx={{ flexDirection: "column" }}> <Flex sx={{ flexDirection: "column" }}>
<ReorderableList <ReorderableList
items={routes} items={routes.filter((r) => !hiddenRoutes.includes(r.id))}
orderKey={`sidebarOrder:builtin`} orderKey={`sidebarOrder:routes`}
order={() => db.settings.getSideBarOrder("builtin")} order={() => db.settings.getSideBarOrder("routes")}
onOrderChanged={(order) => onOrderChanged={(order) =>
db.settings.setSideBarOrder("builtin", order) db.settings.setSideBarOrder("routes", order)
} }
renderOverlay={({ item }) => ( renderOverlay={({ item }) => (
<NavigationItem <NavigationItem
@@ -244,12 +275,19 @@ function NavigationMenu(props: NavigationMenuProps) {
return toggleNavigationContainer(); return toggleNavigationContainer();
_navigate(item.path); _navigate(item.path);
}} }}
menuItems={[
{
type: "lazy-loader",
key: "sidebar-items-loader",
items: getSidebarItems
}
]}
/> />
)} )}
/> />
<ReorderableList <ReorderableList
items={colors} items={colors.filter((c) => !hiddenColors.includes(c.id))}
orderKey={`sidebarOrder:colors`} orderKey={`sidebarOrder:colors`}
order={() => db.settings.getSideBarOrder("colors")} order={() => db.settings.getSideBarOrder("colors")}
onOrderChanged={(order) => onOrderChanged={(order) =>
@@ -285,6 +323,15 @@ function NavigationMenu(props: NavigationMenuProps) {
onClick: async () => { onClick: async () => {
await showRenameColorDialog(color.id); await showRenameColorDialog(color.id);
} }
},
{
type: "separator",
key: "sep"
},
{
type: "lazy-loader",
key: "sidebar-items-loader",
items: getSidebarItems
} }
]} ]}
/> />
@@ -530,3 +577,23 @@ function orderItems<T extends { id: string }>(items: T[], order: string[]) {
sorted.push(...items.filter((i) => !order.includes(i.id))); sorted.push(...items.filter((i) => !order.includes(i.id)));
return sorted; return sorted;
} }
function toMenuItems<T extends { id: string; title: string }>(
items: T[],
hiddenIds: string[],
onHiddenIdsUpdated: (ids: string[]) => void
): MenuItem[] {
return items.map((item) => ({
type: "button",
key: item.id,
title: item.title,
isChecked: !hiddenIds.includes(item.id),
onClick: async () => {
const copy = hiddenIds.slice();
const index = copy.indexOf(item.id);
if (index > -1) copy.splice(index, 1);
else copy.push(item.id);
onHiddenIdsUpdated(copy);
}
}));
}

View File

@@ -66,11 +66,11 @@ const defaultSettings: SettingItemMap = {
"toolbarConfig:desktop": undefined, "toolbarConfig:desktop": undefined,
"toolbarConfig:mobile": undefined, "toolbarConfig:mobile": undefined,
"sideBarOrder:builtin": [], "sideBarOrder:routes": [],
"sideBarOrder:colors": [], "sideBarOrder:colors": [],
"sideBarOrder:shortcuts": [], "sideBarOrder:shortcuts": [],
"sideBarHiddenItems:builtin": [], "sideBarHiddenItems:routes": [],
"sideBarHiddenItems:colors": [] "sideBarHiddenItems:colors": []
}; };
@@ -191,7 +191,7 @@ export class Settings implements ICollection {
return this.get(`sideBarHiddenItems:${section}`); return this.get(`sideBarHiddenItems:${section}`);
} }
setSideBarHiddenItems(section: SideBarHideableSection, order: string[]) { setSideBarHiddenItems(section: SideBarHideableSection, ids: string[]) {
return this.set(`sideBarHiddenItems:${section}`, order); return this.set(`sideBarHiddenItems:${section}`, ids);
} }
} }

View File

@@ -424,8 +424,8 @@ export interface LegacySettingsItem extends BaseItem<"settings"> {
} }
export type ToolbarConfigPlatforms = "desktop" | "mobile"; export type ToolbarConfigPlatforms = "desktop" | "mobile";
export type SideBarSection = "builtin" | "colors" | "shortcuts"; export type SideBarSection = "routes" | "colors" | "shortcuts";
export type SideBarHideableSection = "builtin" | "colors"; export type SideBarHideableSection = "routes" | "colors";
export type SettingItemMap = { export type SettingItemMap = {
trashCleanupInterval: TrashCleanupInterval; trashCleanupInterval: TrashCleanupInterval;
titleFormat: string; titleFormat: string;