From e534ac62b3187bcbf4b4ab86e9bb9f1cc863c6e4 Mon Sep 17 00:00:00 2001 From: pompurin404 Date: Sat, 19 Oct 2024 12:13:20 +0800 Subject: [PATCH] support narrow sidebar style --- src/renderer/src/App.tsx | 124 ++++++++++++------ .../src/components/sider/conn-card.tsx | 33 ++++- .../src/components/sider/dns-card.tsx | 33 ++++- .../src/components/sider/log-card.tsx | 34 ++++- .../src/components/sider/mihomo-core-card.tsx | 34 ++++- .../src/components/sider/override-card.tsx | 31 ++++- .../src/components/sider/profile-card.tsx | 32 ++++- .../src/components/sider/proxy-card.tsx | 32 ++++- .../src/components/sider/resource-card.tsx | 33 ++++- .../src/components/sider/rule-card.tsx | 33 ++++- .../src/components/sider/sniff-card.tsx | 32 ++++- .../src/components/sider/substore-card.tsx | 35 ++++- .../components/sider/sysproxy-switcher.tsx | 32 ++++- .../src/components/sider/tun-switcher.tsx | 32 ++++- 14 files changed, 469 insertions(+), 81 deletions(-) diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 46fdbf5f..da11eaaf 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -72,6 +72,9 @@ const App: React.FC = () => { const setTitlebar = (): void => { if (!useWindowFrame) { const options = { height: 48 } as TitleBarOverlayOptions + if (platform === 'darwin' && siderWidthValue === 60) { + options.height = 20 + } try { if (platform !== 'darwin') { options.color = window.getComputedStyle(document.documentElement).backgroundColor @@ -142,19 +145,19 @@ const App: React.FC = () => { } const componentMap = { - sysproxy: , - tun: , - profile: , - proxy: , - mihomo: , - connection: , - dns: , - sniff: , - log: , - rule: , - resource: , - override: , - substore: + sysproxy: SysproxySwitcher, + tun: TunSwitcher, + profile: ProfileCard, + proxy: ProxyCard, + mihomo: MihomoCoreCard, + connection: ConnCard, + dns: DNSCard, + sniff: SniffCard, + log: LogCard, + rule: RuleCard, + resource: ResourceCard, + override: OverrideCard, + substore: SubStoreCard } return ( @@ -163,11 +166,14 @@ const App: React.FC = () => { if (resizing) { setResizing(false) patchAppConfig({ siderWidth: siderWidthValue }) + setTitlebar() } }} onMouseMove={(e) => { if (!resizing) return - if (e.clientX <= 250) { + if (e.clientX <= 150) { + setSiderWidthValue(60) + } else if (e.clientX <= 250) { setSiderWidthValue(250) } else if (e.clientX >= 400) { setSiderWidthValue(400) @@ -177,19 +183,24 @@ const App: React.FC = () => { }} className={`w-full h-[100vh] flex ${resizing ? 'cursor-ew-resize' : ''}`} > -
-
-
-
- -

ihomo Party

+ {siderWidthValue === 60 ? ( +
+
+ +
+
+
+ {order.map((key: string) => { + const Component = componentMap[key] + if (!Component) return null + return + })}
- +
+
-
- -
- -
- - {order.map((key: string) => { - return componentMap[key] - })} - + ) : ( +
+
+
+
+ +

ihomo Party

+
+ + +
- -
+
+ +
+ +
+ + {order.map((key: string) => { + const Component = componentMap[key] + if (!Component) return null + return + })} + +
+
+
+ )} +
{ setResizing(true) diff --git a/src/renderer/src/components/sider/conn-card.tsx b/src/renderer/src/components/sider/conn-card.tsx index dd137c60..923319bb 100644 --- a/src/renderer/src/components/sider/conn-card.tsx +++ b/src/renderer/src/components/sider/conn-card.tsx @@ -1,8 +1,8 @@ -import { Button, Card, CardBody, CardFooter } from '@nextui-org/react' +import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react' import { FaCircleArrowDown, FaCircleArrowUp } from 'react-icons/fa6' -import { useLocation } from 'react-router-dom' +import { useLocation, useNavigate } from 'react-router-dom' import { calcTraffic } from '@renderer/utils/calc' -import { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { IoLink } from 'react-icons/io5' @@ -16,11 +16,16 @@ let currentDownload: number | undefined = undefined let hasShowTraffic = false let drawing = false -const ConnCard: React.FC = () => { +interface Props { + iconOnly?: boolean +} +const ConnCard: React.FC = (props) => { const { theme = 'system', systemTheme = 'dark' } = useTheme() + const { iconOnly } = props const { appConfig } = useAppConfig() const { showTraffic = false, connectionCardStatus = 'col-span-2', customTheme } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/connections') const [upload, setUpload] = useState(0) @@ -87,6 +92,26 @@ const ConnCard: React.FC = () => { } }, [showTraffic]) + if (iconOnly) { + return ( +
+ + + +
+ ) + } + return (
{ +import React from 'react' + +interface Props { + iconOnly?: boolean +} +const DNSCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { dnsCardStatus = 'col-span-1', controlDns = true } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/dns') const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig() const { dns, tun } = controledMihomoConfig || {} @@ -31,6 +38,26 @@ const DNSCard: React.FC = () => { await patchMihomoConfig({ dns: { enable } }) } + if (iconOnly) { + return ( +
+ + + +
+ ) + } + return (
{ +import React from 'react' + +interface Props { + iconOnly?: boolean +} + +const LogCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { logCardStatus = 'col-span-1' } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/logs') const { attributes, @@ -20,6 +28,26 @@ const LogCard: React.FC = () => { id: 'log' }) const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null + + if (iconOnly) { + return ( +
+ + + +
+ ) + } return (
{ +interface Props { + iconOnly?: boolean +} + +const MihomoCoreCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { mihomoCoreCardStatus = 'col-span-2' } = appConfig || {} const { data: version, mutate } = useSWR('mihomoVersion', mihomoVersion) const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/mihomo') const { attributes, @@ -43,6 +49,26 @@ const MihomoCoreCard: React.FC = () => { } }, []) + if (iconOnly) { + return ( +
+ + + +
+ ) + } + return (
{ +interface Props { + iconOnly?: boolean +} + +const OverrideCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { overrideCardStatus = 'col-span-1' } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/override') const { attributes, @@ -22,6 +28,25 @@ const OverrideCard: React.FC = () => { id: 'override' }) const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null + if (iconOnly) { + return ( +
+ + + +
+ ) + } return (
{ +interface Props { + iconOnly?: boolean +} + +const ProfileCard: React.FC = (props) => { const { appConfig, patchAppConfig } = useAppConfig() + const { iconOnly } = props const { profileCardStatus = 'col-span-2', profileDisplayDate = 'expire' } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/profiles') const [updating, setUpdating] = useState(false) const [showRuntimeConfig, setShowRuntimeConfig] = useState(false) @@ -47,6 +53,26 @@ const ProfileCard: React.FC = () => { const usage = (extra?.upload ?? 0) + (extra?.download ?? 0) const total = extra?.total ?? 0 + if (iconOnly) { + return ( +
+ + + +
+ ) + } + return (
{ +interface Props { + iconOnly?: boolean +} + +const ProxyCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { proxyCardStatus = 'col-span-1' } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/proxies') const { groups = [] } = useGroups() const { @@ -24,6 +31,25 @@ const ProxyCard: React.FC = () => { }) const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null + if (iconOnly) { + return ( +
+ + + +
+ ) + } return (
{ + +interface Props { + iconOnly?: boolean +} + +const ResourceCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { resourceCardStatus = 'col-span-1' } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/resources') const { attributes, @@ -21,6 +28,26 @@ const ResourceCard: React.FC = () => { id: 'resource' }) const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null + + if (iconOnly) { + return ( +
+ + + +
+ ) + } return (
{ +interface Props { + iconOnly?: boolean +} + +const RuleCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { ruleCardStatus = 'col-span-1' } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/rules') const { rules } = useRules() const { @@ -23,6 +30,26 @@ const RuleCard: React.FC = () => { id: 'rule' }) const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null + + if (iconOnly) { + return ( +
+ + + +
+ ) + } return (
{ +interface Props { + iconOnly?: boolean +} +const SniffCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { sniffCardStatus = 'col-span-1', controlSniff = true } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/sniffer') const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig() const { sniffer } = controledMihomoConfig || {} @@ -32,6 +38,26 @@ const SniffCard: React.FC = () => { await patchMihomoConfig({ sniffer: { enable } }) } + if (iconOnly) { + return ( +
+ + + +
+ ) + } + return (
{ +import React from 'react' + +interface Props { + iconOnly?: boolean +} + +const SubStoreCard: React.FC = (props) => { const { appConfig } = useAppConfig() + const { iconOnly } = props const { substoreCardStatus = 'col-span-1', useSubStore = true } = appConfig || {} const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/substore') const { attributes, @@ -20,6 +28,27 @@ const SubStoreCard: React.FC = () => { id: 'substore' }) const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null + + if (iconOnly) { + return ( +
+ + + +
+ ) + } + return (
{ +interface Props { + iconOnly?: boolean +} + +const SysproxySwitcher: React.FC = (props) => { + const { iconOnly } = props const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/sysproxy') const { appConfig, patchAppConfig } = useAppConfig() const { sysProxy, sysproxyCardStatus = 'col-span-1' } = appConfig || {} @@ -36,6 +42,26 @@ const SysproxySwitcher: React.FC = () => { } } + if (iconOnly) { + return ( +
+ + + +
+ ) + } + return (
{ +interface Props { + iconOnly?: boolean +} + +const TunSwitcher: React.FC = (props) => { + const { iconOnly } = props const location = useLocation() + const navigate = useNavigate() const match = location.pathname.includes('/tun') || false const { appConfig } = useAppConfig() const { tunCardStatus = 'col-span-1' } = appConfig || {} @@ -39,6 +45,26 @@ const TunSwitcher: React.FC = () => { window.electron.ipcRenderer.send('updateTrayMenu') } + if (iconOnly) { + return ( +
+ + + +
+ ) + } + return (