mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-28 07:14:40 +08:00
feat: add navigation collapse functionality to layout (#5815)
* feat(layout): add collapsible navbar toggle in UI settings * refactor(layout): adjust collapsed navbar styles * docs: Changelog.md --------- Co-authored-by: Slinetrac <realakayuki@gmail.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
- 允许代理页面允许高级过滤搜索
|
||||
- 备份设置页面新增导入备份按钮
|
||||
- 允许修改通知弹窗位置(「界面设置」->「通知位置」)
|
||||
- 支持收起导航栏(「界面设置」->「收起导航栏」)
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
@@ -70,6 +70,9 @@ pub struct IVerge {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub notice_position: Option<String>,
|
||||
|
||||
/// collapse navigation bar
|
||||
pub collapse_navbar: Option<bool>,
|
||||
|
||||
/// sysproxy tray icon
|
||||
pub sysproxy_tray_icon: Option<bool>,
|
||||
|
||||
@@ -396,6 +399,7 @@ impl IVerge {
|
||||
tray_icon: Some("monochrome".into()),
|
||||
menu_icon: Some("monochrome".into()),
|
||||
notice_position: Some("top-right".into()),
|
||||
collapse_navbar: Some(false),
|
||||
common_tray_icon: Some(false),
|
||||
sysproxy_tray_icon: Some(false),
|
||||
tun_tray_icon: Some(false),
|
||||
@@ -481,6 +485,7 @@ impl IVerge {
|
||||
patch!(menu_icon);
|
||||
patch!(menu_order);
|
||||
patch!(notice_position);
|
||||
patch!(collapse_navbar);
|
||||
patch!(common_tray_icon);
|
||||
patch!(sysproxy_tray_icon);
|
||||
patch!(tun_tray_icon);
|
||||
|
||||
@@ -158,3 +158,103 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout.layout--nav-collapsed {
|
||||
--layout-nav-collapsed-width: 72px;
|
||||
--layout-nav-item-size: 52px;
|
||||
--layout-nav-item-radius: 12px;
|
||||
--layout-nav-logo-size: 56px;
|
||||
|
||||
.layout-content {
|
||||
&__left {
|
||||
flex: 0 0 var(--layout-nav-collapsed-width) !important;
|
||||
width: var(--layout-nav-collapsed-width) !important;
|
||||
min-width: var(--layout-nav-collapsed-width) !important;
|
||||
max-width: var(--layout-nav-collapsed-width) !important;
|
||||
border-right: none !important;
|
||||
|
||||
.the-traffic {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
> .MuiBox-root {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.the-logo {
|
||||
flex: 0 0 var(--layout-nav-logo-size) !important;
|
||||
height: var(--layout-nav-logo-size) !important;
|
||||
margin: 8px 0 4px !important;
|
||||
padding: 0 !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.the-logo > div {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.the-logo > div > svg:last-child {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.the-logo .MuiSvgIcon-root {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.the-logo .the-newbtn {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.the-menu {
|
||||
width: var(--layout-nav-collapsed-width) !important;
|
||||
overflow-x: hidden;
|
||||
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.MuiListItem-root {
|
||||
max-width: 100% !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.MuiListItemButton-root {
|
||||
justify-content: center !important;
|
||||
width: var(--layout-nav-item-size) !important;
|
||||
height: var(--layout-nav-item-size) !important;
|
||||
min-height: var(--layout-nav-item-size) !important;
|
||||
max-width: var(--layout-nav-item-size) !important;
|
||||
flex: 0 0 var(--layout-nav-item-size) !important;
|
||||
flex-grow: 0 !important;
|
||||
flex-shrink: 0 !important;
|
||||
margin: 6px auto !important;
|
||||
padding: 0 !important;
|
||||
border-radius: var(--layout-nav-item-radius) !important;
|
||||
}
|
||||
|
||||
.MuiListItemIcon-root {
|
||||
min-width: auto !important;
|
||||
margin: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.MuiListItemText-root {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,14 @@ export const LayoutItem = (props: Props) => {
|
||||
const { to, children, icon, sortable } = props;
|
||||
const { verge } = useVerge();
|
||||
const { menu_icon } = verge ?? {};
|
||||
const navCollapsed = verge?.collapse_navbar ?? false;
|
||||
const resolved = useResolvedPath(to);
|
||||
const match = useMatch({ path: resolved.pathname, end: true });
|
||||
const navigate = useNavigate();
|
||||
|
||||
const effectiveMenuIcon =
|
||||
navCollapsed && menu_icon === "disable" ? "monochrome" : menu_icon;
|
||||
|
||||
const { setNodeRef, attributes, listeners, style, isDragging, disabled } =
|
||||
sortable ?? {};
|
||||
|
||||
@@ -84,9 +88,11 @@ export const LayoutItem = (props: Props) => {
|
||||
};
|
||||
},
|
||||
]}
|
||||
title={navCollapsed ? children : undefined}
|
||||
aria-label={navCollapsed ? children : undefined}
|
||||
onClick={() => navigate(to)}
|
||||
>
|
||||
{(menu_icon === "monochrome" || !menu_icon) && (
|
||||
{(effectiveMenuIcon === "monochrome" || !effectiveMenuIcon) && (
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
color: "text.primary",
|
||||
@@ -97,7 +103,7 @@ export const LayoutItem = (props: Props) => {
|
||||
{icon[0]}
|
||||
</ListItemIcon>
|
||||
)}
|
||||
{menu_icon === "colorful" && (
|
||||
{effectiveMenuIcon === "colorful" && (
|
||||
<ListItemIcon sx={{ cursor: draggable ? "grab" : "inherit" }}>
|
||||
{icon[1]}
|
||||
</ListItemIcon>
|
||||
@@ -105,7 +111,7 @@ export const LayoutItem = (props: Props) => {
|
||||
<ListItemText
|
||||
sx={{
|
||||
textAlign: "center",
|
||||
marginLeft: menu_icon === "disable" ? "" : "-35px",
|
||||
marginLeft: effectiveMenuIcon === "disable" ? "" : "-35px",
|
||||
}}
|
||||
primary={children}
|
||||
/>
|
||||
|
||||
@@ -338,6 +338,24 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
|
||||
</GuardState>
|
||||
</Item>
|
||||
|
||||
<Item>
|
||||
<ListItemText
|
||||
primary={t(
|
||||
"settings.components.verge.layout.fields.collapseNavBar",
|
||||
)}
|
||||
/>
|
||||
<GuardState
|
||||
value={verge?.collapse_navbar ?? false}
|
||||
valueProps="checked"
|
||||
onCatch={onError}
|
||||
onFormat={onSwitchFormat}
|
||||
onChange={(e) => onChangeData({ collapse_navbar: e })}
|
||||
onGuard={(e) => patchVerge({ collapse_navbar: e })}
|
||||
>
|
||||
<Switch edge="end" />
|
||||
</GuardState>
|
||||
</Item>
|
||||
|
||||
{OS === "macos" && (
|
||||
<Item>
|
||||
<ListItemText
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "أيقونة التنقل",
|
||||
"collapseNavBar": "طي شريط التنقل",
|
||||
"trayIcon": "أيقونة شريط المهام",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "أيقونة شريط مهام عامة",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "Navigationsleiste-Symbol",
|
||||
"collapseNavBar": "Navigationsleiste einklappen",
|
||||
"trayIcon": "Tray-Symbol",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "Standard-Tray-Symbol",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "Nav Icon",
|
||||
"collapseNavBar": "Collapse Navigation Bar",
|
||||
"trayIcon": "Tray Icon",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "Common Tray Icon",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "Icono de la barra de navegación",
|
||||
"collapseNavBar": "Colapsar barra de navegación",
|
||||
"trayIcon": "Icono de la bandeja",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "Icono de bandeja común",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "آیکون ناوبری",
|
||||
"collapseNavBar": "جمع کردن نوار ناوبری",
|
||||
"trayIcon": "آیکون سینی سیستم",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "آیکون مشترک سینی سیستم",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "Ikon Navigasi",
|
||||
"collapseNavBar": "Ciutkan bilah navigasi",
|
||||
"trayIcon": "Ikon Tray",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "Ikon Tray Umum",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "ナビゲーションバーアイコン",
|
||||
"collapseNavBar": "ナビゲーションバーを折りたたむ",
|
||||
"trayIcon": "トレイアイコン",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "通常のトレイアイコン",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "호버 점프 내비게이터",
|
||||
"hoverNavigatorDelay": "호버 점프 내비게이터 지연",
|
||||
"navIcon": "내비게이션 아이콘",
|
||||
"collapseNavBar": "내비게이션 바 접기",
|
||||
"trayIcon": "트레이 아이콘",
|
||||
"showProxyGroupsInline": "프록시 그룹 인라인 표시",
|
||||
"commonTrayIcon": "공용 트레이 아이콘",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "Иконки навигации",
|
||||
"collapseNavBar": "Свернуть панель навигации",
|
||||
"trayIcon": "Иконка в трее",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "Общий значок в трее",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "Gezinme Simgesi",
|
||||
"collapseNavBar": "Gezinme çubuğunu daralt",
|
||||
"trayIcon": "Tepsi Simgesi",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "Genel Tepsi Simgesi",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "Hover Jump Navigator",
|
||||
"hoverNavigatorDelay": "Hover Jump Navigator Delay",
|
||||
"navIcon": "Навигация иконкасы",
|
||||
"collapseNavBar": "Навигация панелен җыю",
|
||||
"trayIcon": "Трей иконкасы",
|
||||
"showProxyGroupsInline": "Show Proxy Groups Inline",
|
||||
"commonTrayIcon": "Гомуми трей иконкасы",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "悬浮跳转导航",
|
||||
"hoverNavigatorDelay": "悬浮跳转导航延迟",
|
||||
"navIcon": "导航栏图标",
|
||||
"collapseNavBar": "收起导航栏",
|
||||
"trayIcon": "托盘图标",
|
||||
"showProxyGroupsInline": "将代理组显示在托盘一级菜单",
|
||||
"commonTrayIcon": "常规托盘图标",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"hoverNavigator": "懸浮跳轉導航",
|
||||
"hoverNavigatorDelay": "懸浮跳轉導航延遲",
|
||||
"navIcon": "導覽列圖示",
|
||||
"collapseNavBar": "收起導覽列",
|
||||
"trayIcon": "系統匣圖示",
|
||||
"showProxyGroupsInline": "將代理組顯示在系統匣一級選單",
|
||||
"commonTrayIcon": "一般系統匣圖示",
|
||||
|
||||
@@ -117,6 +117,7 @@ const Layout = () => {
|
||||
const { theme } = useCustomTheme();
|
||||
const { verge, mutateVerge, patchVerge } = useVerge();
|
||||
const { language } = verge ?? {};
|
||||
const navCollapsed = verge?.collapse_navbar ?? false;
|
||||
const { switchLanguage } = useI18n();
|
||||
const navigate = useNavigate();
|
||||
const themeReady = useMemo(() => Boolean(theme), [theme]);
|
||||
@@ -281,7 +282,7 @@ const Layout = () => {
|
||||
<Paper
|
||||
square
|
||||
elevation={0}
|
||||
className={`${OS} layout`}
|
||||
className={`${OS} layout${navCollapsed ? " layout--nav-collapsed" : ""}`}
|
||||
style={{
|
||||
borderTopLeftRadius: "0px",
|
||||
borderTopRightRadius: "0px",
|
||||
|
||||
@@ -429,6 +429,7 @@ export const translationKeys = [
|
||||
"settings.components.verge.layout.fields.hoverNavigator",
|
||||
"settings.components.verge.layout.fields.hoverNavigatorDelay",
|
||||
"settings.components.verge.layout.fields.navIcon",
|
||||
"settings.components.verge.layout.fields.collapseNavBar",
|
||||
"settings.components.verge.layout.fields.trayIcon",
|
||||
"settings.components.verge.layout.fields.showProxyGroupsInline",
|
||||
"settings.components.verge.layout.fields.commonTrayIcon",
|
||||
|
||||
@@ -616,6 +616,7 @@ export interface TranslationResources {
|
||||
};
|
||||
layout: {
|
||||
fields: {
|
||||
collapseNavBar: string;
|
||||
commonTrayIcon: string;
|
||||
enableTrayIcon: string;
|
||||
enableTraySpeed: string;
|
||||
|
||||
1
src/types/global.d.ts
vendored
1
src/types/global.d.ts
vendored
@@ -815,6 +815,7 @@ interface IVergeConfig {
|
||||
menu_icon?: "monochrome" | "colorful" | "disable";
|
||||
menu_order?: string[];
|
||||
notice_position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
||||
collapse_navbar?: boolean;
|
||||
tray_icon?: "monochrome" | "colorful";
|
||||
common_tray_icon?: boolean;
|
||||
sysproxy_tray_icon?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user