From 79b3da1da65631bca9b4a85a31d82a06133e41ec Mon Sep 17 00:00:00 2001 From: pompurin404 Date: Fri, 6 Sep 2024 17:44:26 +0800 Subject: [PATCH] support custom sidebar --- changelog.md | 6 + src/main/utils/init.ts | 10 +- src/main/utils/template.ts | 11 +- src/renderer/src/App.tsx | 16 +- .../src/components/settings/sider-config.tsx | 78 ++++++++ .../src/components/sider/conn-card.tsx | 122 +++++++----- .../src/components/sider/dns-card.tsx | 5 +- .../src/components/sider/log-card.tsx | 7 +- .../src/components/sider/mihomo-core-card.tsx | 126 +++++++----- .../src/components/sider/override-card.tsx | 7 +- .../src/components/sider/profile-card.tsx | 186 +++++++++++------- .../src/components/sider/proxy-card.tsx | 5 +- .../src/components/sider/resource-card.tsx | 7 +- .../src/components/sider/rule-card.tsx | 7 +- .../src/components/sider/sniff-card.tsx | 7 +- .../src/components/sider/substore-card.tsx | 7 +- .../components/sider/sysproxy-switcher.tsx | 4 +- .../src/components/sider/tun-switcher.tsx | 3 +- src/renderer/src/pages/connections.tsx | 8 +- src/renderer/src/pages/settings.tsx | 2 + src/shared/types.d.ts | 14 ++ 21 files changed, 433 insertions(+), 205 deletions(-) create mode 100644 src/renderer/src/components/settings/sider-config.tsx diff --git a/changelog.md b/changelog.md index 980429c..66b7bd7 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,12 @@ - 1.2.x YAML覆写语法有所变动,请更新后参考文档进行修改 +### New Features + +- 支持自定义侧边栏卡片大小 +- 支持隐藏侧边栏卡片 + ### Bug Fixes - 修复Ubuntu下每次开启Tun都需要密码的问题 +- 修复Sub-Store无法读取剪切板的问题 diff --git a/src/main/utils/init.ts b/src/main/utils/init.ts index 379649e..cb4c25c 100644 --- a/src/main/utils/init.ts +++ b/src/main/utils/init.ts @@ -126,14 +126,14 @@ async function migration(): Promise { 'tun', 'profile', 'proxy', - 'mihomo', - 'connection', - 'dns', - 'sniff', - 'log', 'rule', 'resource', 'override', + 'connection', + 'mihomo', + 'dns', + 'sniff', + 'log', 'substore' ], useSubStore = true diff --git a/src/main/utils/template.ts b/src/main/utils/template.ts index cc8c3a7..bb0ce5c 100644 --- a/src/main/utils/template.ts +++ b/src/main/utils/template.ts @@ -18,19 +18,18 @@ export const defaultConfig: IAppConfig = { controlSniff: true, nameserverPolicy: {}, siderOrder: [ - 'mode', 'sysproxy', 'tun', 'profile', 'proxy', - 'mihomo', - 'connection', - 'dns', - 'sniff', - 'log', 'rule', 'resource', 'override', + 'connection', + 'mihomo', + 'dns', + 'sniff', + 'log', 'substore' ], sysProxy: { enable: false, mode: 'manual' } diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index fac976e..f46afd5 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -37,23 +37,20 @@ const App: React.FC = () => { const { appConfig, patchAppConfig } = useAppConfig() const { appTheme = 'system', - controlDns = true, - controlSniff = true, - useSubStore = true, useWindowFrame = false, siderOrder = [ 'sysproxy', 'tun', 'profile', 'proxy', - 'mihomo', - 'connection', - 'dns', - 'sniff', - 'log', 'rule', 'resource', 'override', + 'connection', + 'mihomo', + 'dns', + 'sniff', + 'log', 'substore' ] } = appConfig || {} @@ -169,9 +166,6 @@ const App: React.FC = () => { })} > {order.map((key: string) => { - if (key === 'dns' && controlDns === false) return null - if (key === 'sniff' && controlSniff === false) return null - if (key === 'substore' && useSubStore === false) return null return componentMap[key] })} diff --git a/src/renderer/src/components/settings/sider-config.tsx b/src/renderer/src/components/settings/sider-config.tsx new file mode 100644 index 0000000..c5336fb --- /dev/null +++ b/src/renderer/src/components/settings/sider-config.tsx @@ -0,0 +1,78 @@ +import React from 'react' +import SettingCard from '../base/base-setting-card' +import SettingItem from '../base/base-setting-item' +import { RadioGroup, Radio } from '@nextui-org/react' +import { useAppConfig } from '@renderer/hooks/use-app-config' +const titleMap = { + sysproxyCardStatus: '系统代理', + tunCardStatus: '虚拟网卡', + profileCardStatus: '订阅管理', + proxyCardStatus: '代理组', + ruleCardStatus: '规则', + resourceCardStatus: '外部资源', + overrideCardStatus: '覆写', + connectionCardStatus: '连接', + mihomoCoreCardStatus: '内核', + dnsCardStatus: 'DNS', + sniffCardStatus: '域名嗅探', + logCardStatus: '日志', + substoreCardStatus: 'Sub-Store' +} +const SiderConfig: React.FC = () => { + const { appConfig, patchAppConfig } = useAppConfig() + const { + sysproxyCardStatus = 'col-span-1', + tunCardStatus = 'col-span-1', + profileCardStatus = 'col-span-2', + proxyCardStatus = 'col-span-1', + ruleCardStatus = 'col-span-1', + resourceCardStatus = 'col-span-1', + overrideCardStatus = 'col-span-1', + connectionCardStatus = 'col-span-2', + mihomoCoreCardStatus = 'col-span-2', + dnsCardStatus = 'col-span-1', + sniffCardStatus = 'col-span-1', + logCardStatus = 'col-span-1', + substoreCardStatus = 'col-span-1' + } = appConfig || {} + + const cardStatus = { + sysproxyCardStatus, + tunCardStatus, + profileCardStatus, + proxyCardStatus, + ruleCardStatus, + resourceCardStatus, + overrideCardStatus, + connectionCardStatus, + mihomoCoreCardStatus, + dnsCardStatus, + sniffCardStatus, + logCardStatus, + substoreCardStatus + } + + return ( + + {Object.keys(cardStatus).map((key, index, array) => { + return ( + + { + patchAppConfig({ [key]: v as CardStatus }) + }} + > + + + 隐藏 + + + ) + })} + + ) +} + +export default SiderConfig diff --git a/src/renderer/src/components/sider/conn-card.tsx b/src/renderer/src/components/sider/conn-card.tsx index a7478c8..3619461 100644 --- a/src/renderer/src/components/sider/conn-card.tsx +++ b/src/renderer/src/components/sider/conn-card.tsx @@ -20,7 +20,7 @@ let drawing = false const ConnCard: React.FC = () => { const { theme = 'system', systemTheme = 'dark' } = useTheme() const { appConfig } = useAppConfig() - const { showTraffic } = appConfig || {} + const { showTraffic, connectionCardStatus = 'col-span-2' } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/connections') @@ -172,52 +172,86 @@ const ConnCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-2" + className={connectionCardStatus} > - navigate('/connections')} - > - -
- -
-
-
{calcTraffic(upload)}/s
- + {connectionCardStatus === 'col-span-2' ? ( + <> + navigate('/connections')} + > + +
+ +
+
+
{calcTraffic(upload)}/s
+ +
+
+
{calcTraffic(download)}/s
+ +
+
-
-
{calcTraffic(download)}/s
- -
-
+ + +

+ 连接 +

+
+ +
+
- - -

连接

-
- -
- -
+ + ) : ( + navigate('/logs')} + > + +
+ +
+
+ +

+ 连接 +

+
+
+ )}
) } diff --git a/src/renderer/src/components/sider/dns-card.tsx b/src/renderer/src/components/sider/dns-card.tsx index 238e727..2779da1 100644 --- a/src/renderer/src/components/sider/dns-card.tsx +++ b/src/renderer/src/components/sider/dns-card.tsx @@ -6,7 +6,10 @@ import { useLocation, useNavigate } from 'react-router-dom' import { patchMihomoConfig } from '@renderer/utils/ipc' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' +import { useAppConfig } from '@renderer/hooks/use-app-config' const DNSCard: React.FC = () => { + const { appConfig } = useAppConfig() + const { dnsCardStatus = 'col-span-1', controlDns = true } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/dns') @@ -37,7 +40,7 @@ const DNSCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1" + className={`${dnsCardStatus} ${!controlDns ? 'hidden' : ''}`} > { + const { appConfig } = useAppConfig() + const { logCardStatus = 'col-span-1' } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/logs') @@ -26,11 +29,11 @@ const LogCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1" + className={logCardStatus} > navigate('/logs')} > diff --git a/src/renderer/src/components/sider/mihomo-core-card.tsx b/src/renderer/src/components/sider/mihomo-core-card.tsx index e13a060..810f081 100644 --- a/src/renderer/src/components/sider/mihomo-core-card.tsx +++ b/src/renderer/src/components/sider/mihomo-core-card.tsx @@ -8,8 +8,12 @@ import { CSS } from '@dnd-kit/utilities' import { useLocation, useNavigate } from 'react-router-dom' import PubSub from 'pubsub-js' import useSWR from 'swr' +import { useAppConfig } from '@renderer/hooks/use-app-config' +import { LuCpu } from 'react-icons/lu' const MihomoCoreCard: React.FC = () => { + const { appConfig } = useAppConfig() + const { mihomoCoreCardStatus = 'col-span-2' } = appConfig || {} const { data: version, mutate } = useSWR('mihomoVersion', mihomoVersion) const navigate = useNavigate() const location = useLocation() @@ -48,55 +52,87 @@ const MihomoCoreCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-2" + className={mihomoCoreCardStatus} > - navigate('/mihomo')} - className={`${match ? 'bg-primary' : ''}`} - > - -
-

navigate('/mihomo')} + className={`${match ? 'bg-primary' : ''}`} + > + +
- {version?.version ?? '-'} -

+

+ {version?.version ?? '-'} +

- +
+
+ +
- - -
- - -
-

内核设置

-

{calcTraffic(mem)}

-
-
-
+

内核设置

+

{calcTraffic(mem)}

+
+ +
+ ) : ( + navigate('/mihomo')} + > + +
+ +
+
+ +

+ 内核设置 +

+
+
+ )} ) } diff --git a/src/renderer/src/components/sider/override-card.tsx b/src/renderer/src/components/sider/override-card.tsx index d092d5c..085cab2 100644 --- a/src/renderer/src/components/sider/override-card.tsx +++ b/src/renderer/src/components/sider/override-card.tsx @@ -4,8 +4,11 @@ import { MdFormatOverline } from 'react-icons/md' import { useLocation, useNavigate } from 'react-router-dom' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' +import { useAppConfig } from '@renderer/hooks/use-app-config' const OverrideCard: React.FC = () => { + const { appConfig } = useAppConfig() + const { overrideCardStatus = 'col-span-1' } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/override') @@ -28,11 +31,11 @@ const OverrideCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1" + className={overrideCardStatus} > navigate('/override')} > diff --git a/src/renderer/src/components/sider/profile-card.tsx b/src/renderer/src/components/sider/profile-card.tsx index cf281f6..26142f9 100644 --- a/src/renderer/src/components/sider/profile-card.tsx +++ b/src/renderer/src/components/sider/profile-card.tsx @@ -11,11 +11,15 @@ import 'dayjs/locale/zh-cn' import dayjs from 'dayjs' import { useState } from 'react' import ConfigViewer from './config-viewer' +import { useAppConfig } from '@renderer/hooks/use-app-config' +import { TiFolder } from 'react-icons/ti' dayjs.extend(relativeTime) dayjs.locale('zh-cn') const ProfileCard: React.FC = () => { + const { appConfig } = useAppConfig() + const { profileCardStatus = 'col-span-2' } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/profiles') @@ -52,98 +56,128 @@ const ProfileCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-2" + className={profileCardStatus} > {showRuntimeConfig && setShowRuntimeConfig(false)} />} - navigate('/profiles')} - > - -
-

navigate('/profiles')} + > + +
- {info?.name} -

-
- - {info.type === 'remote' && ( + {info?.name} + +
- )} + {info.type === 'remote' && ( + + )} +
-
- {info.type === 'remote' && extra && ( -
- {`${calcTraffic(usage)}/${calcTraffic(total)}`} - - {extra.expire ? dayjs.unix(extra.expire).format('YYYY-MM-DD') : '长期有效'} - -
- )} - {info.type === 'local' && ( -
- - 本地 - + {`${calcTraffic(usage)}/${calcTraffic(total)}`} + + {extra.expire ? dayjs.unix(extra.expire).format('YYYY-MM-DD') : '长期有效'} + +
+ )} + {info.type === 'local' && ( +
+ + 本地 + +
+ )} +
+ + {extra && ( + + )} + +
+ ) : ( + navigate('/profiles')} + > + +
+
- )} -
- - {extra && ( - - )} - -
+ + +

+ 订阅管理 +

+
+
+ )} ) } diff --git a/src/renderer/src/components/sider/proxy-card.tsx b/src/renderer/src/components/sider/proxy-card.tsx index b92bfca..86f67a7 100644 --- a/src/renderer/src/components/sider/proxy-card.tsx +++ b/src/renderer/src/components/sider/proxy-card.tsx @@ -4,8 +4,11 @@ import { CSS } from '@dnd-kit/utilities' import { LuGroup } from 'react-icons/lu' import { useLocation, useNavigate } from 'react-router-dom' import { useGroups } from '@renderer/hooks/use-groups' +import { useAppConfig } from '@renderer/hooks/use-app-config' const ProxyCard: React.FC = () => { + const { appConfig } = useAppConfig() + const { proxyCardStatus = 'col-span-1' } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/proxies') @@ -30,7 +33,7 @@ const ProxyCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-2" + className={proxyCardStatus} > { + const { appConfig } = useAppConfig() + const { resourceCardStatus = 'col-span-1' } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/resources') @@ -27,11 +30,11 @@ const ResourceCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1" + className={resourceCardStatus} > navigate('/resources')} > diff --git a/src/renderer/src/components/sider/rule-card.tsx b/src/renderer/src/components/sider/rule-card.tsx index b875cdd..e596f76 100644 --- a/src/renderer/src/components/sider/rule-card.tsx +++ b/src/renderer/src/components/sider/rule-card.tsx @@ -4,8 +4,11 @@ import { useLocation, useNavigate } from 'react-router-dom' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { useRules } from '@renderer/hooks/use-rules' +import { useAppConfig } from '@renderer/hooks/use-app-config' const RuleCard: React.FC = () => { + const { appConfig } = useAppConfig() + const { ruleCardStatus = 'col-span-1' } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/rules') @@ -29,11 +32,11 @@ const RuleCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1" + className={ruleCardStatus} > navigate('/rules')} > diff --git a/src/renderer/src/components/sider/sniff-card.tsx b/src/renderer/src/components/sider/sniff-card.tsx index 4a00d2f..74af64a 100644 --- a/src/renderer/src/components/sider/sniff-card.tsx +++ b/src/renderer/src/components/sider/sniff-card.tsx @@ -6,8 +6,11 @@ import { patchMihomoConfig } from '@renderer/utils/ipc' import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' +import { useAppConfig } from '@renderer/hooks/use-app-config' const SniffCard: React.FC = () => { + const { appConfig } = useAppConfig() + const { sniffCardStatus = 'col-span-1', controlSniff = true } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/sniffer') @@ -38,11 +41,11 @@ const SniffCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1" + className={`${sniffCardStatus} ${!controlSniff ? 'hidden' : ''}`} > navigate('/sniffer')} > diff --git a/src/renderer/src/components/sider/substore-card.tsx b/src/renderer/src/components/sider/substore-card.tsx index 1c0f9a8..fbfa65d 100644 --- a/src/renderer/src/components/sider/substore-card.tsx +++ b/src/renderer/src/components/sider/substore-card.tsx @@ -3,7 +3,10 @@ import { useLocation, useNavigate } from 'react-router-dom' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import SubStoreIcon from '../base/substore-icon' +import { useAppConfig } from '@renderer/hooks/use-app-config' const SubStoreCard: React.FC = () => { + const { appConfig } = useAppConfig() + const { substoreCardStatus = 'col-span-1', useSubStore = true } = appConfig || {} const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/substore') @@ -26,11 +29,11 @@ const SubStoreCard: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1" + className={`${substoreCardStatus} ${!useSubStore ? 'hidden' : ''}`} > navigate('/substore')} > diff --git a/src/renderer/src/components/sider/sysproxy-switcher.tsx b/src/renderer/src/components/sider/sysproxy-switcher.tsx index 8395fc2..87463be 100644 --- a/src/renderer/src/components/sider/sysproxy-switcher.tsx +++ b/src/renderer/src/components/sider/sysproxy-switcher.tsx @@ -13,7 +13,7 @@ const SysproxySwitcher: React.FC = () => { const location = useLocation() const match = location.pathname.includes('/sysproxy') const { appConfig, patchAppConfig } = useAppConfig() - const { sysProxy } = appConfig || {} + const { sysProxy, sysproxyCardStatus = 'col-span-1' } = appConfig || {} const { enable } = sysProxy || {} const { attributes, @@ -44,7 +44,7 @@ const SysproxySwitcher: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1 " + className={sysproxyCardStatus} > { const match = location.pathname.includes('/tun') || false const [openPasswordModal, setOpenPasswordModal] = useState(false) const { appConfig, patchAppConfig } = useAppConfig() + const { tunCardStatus = 'col-span-1' } = appConfig || {} const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig() const { tun } = controledMihomoConfig || {} const { enable } = tun || {} @@ -62,7 +63,7 @@ const TunSwitcher: React.FC = () => { transition, zIndex: isDragging ? 'calc(infinity)' : undefined }} - className="col-span-1" + className={tunCardStatus} > {openPasswordModal && ( { ↓ {calcTraffic(connectionsInfo?.downloadTotal ?? 0)}{' '} - +