adjust the sidebar

This commit is contained in:
pompurin404 2024-08-01 09:30:14 +08:00
parent 574bdb05be
commit 3dd436d837
No known key found for this signature in database
16 changed files with 143 additions and 58 deletions

View File

@ -1,5 +1,5 @@
import { ipcMain } from 'electron'
import { mihomoVersion } from './mihomo-api'
import { mihomoConfig, mihomoVersion, patchMihomoConfig } from './mihomo-api'
import { checkAutoRun, disableAutoRun, enableAutoRun } from './autoRun'
import {
getAppConfig,
@ -12,17 +12,15 @@ import { restartCore } from './manager'
export function registerIpcMainHandlers(): void {
ipcMain.handle('mihomoVersion', mihomoVersion)
ipcMain.handle('mihomoConfig', mihomoConfig)
ipcMain.handle('patchMihomoConfig', async (_e, patch) => await patchMihomoConfig(patch))
ipcMain.handle('checkAutoRun', checkAutoRun)
ipcMain.handle('enableAutoRun', enableAutoRun)
ipcMain.handle('disableAutoRun', disableAutoRun)
ipcMain.handle('getAppConfig', (_e, force) => getAppConfig(force))
ipcMain.handle('setAppConfig', (_e, config) => {
setAppConfig(config)
})
ipcMain.handle('setAppConfig', (_e, config) => setAppConfig(config))
ipcMain.handle('getControledMihomoConfig', (_e, force) => getControledMihomoConfig(force))
ipcMain.handle('setControledMihomoConfig', (_e, config) => {
setControledMihomoConfig(config)
})
ipcMain.handle('setControledMihomoConfig', (_e, config) => setControledMihomoConfig(config))
ipcMain.handle('getProfileConfig', (_e, force) => getProfileConfig(force))
ipcMain.handle('restartCore', () => restartCore())
}

View File

@ -26,3 +26,14 @@ export async function mihomoVersion(): Promise<IMihomoVersion> {
const instance = await getAxios()
return instance.get('/version') as Promise<IMihomoVersion>
}
export const mihomoConfig = async (): Promise<IMihomoConfig> => {
const instance = await getAxios()
return instance.get('/configs') as Promise<IMihomoConfig>
}
/// Update current configs
export const patchMihomoConfig = async (patch: Partial<IMihomoConfig>): Promise<void> => {
const instance = await getAxios()
return instance.patch('/configs', patch)
}

View File

@ -42,46 +42,49 @@ const App: React.FC = () => {
return (
<div className="w-full h-[100vh] flex">
<div className="side w-[250px] h-full">
<div className="flex justify-between h-[32px] m-2">
<h3 className="select-none text-lg font-bold leading-[32px]"></h3>
<Button
size="sm"
isIconOnly
color={location.pathname.includes('/settings') ? 'primary' : 'default'}
variant={location.pathname.includes('/settings') ? 'solid' : 'light'}
onPress={() => {
navigate('/settings')
}}
startContent={<IoSettings className="text-[20px]" />}
/>
<div className="side w-[250px] h-full overflow-y-auto no-scrollbar">
<div className="sticky top-0 z-40 backdrop-blur h-[48px]">
<div className="flex justify-between p-2">
<h3 className="select-none text-lg font-bold leading-[32px]">Mihomo Party</h3>
<Button
size="sm"
isIconOnly
color={location.pathname.includes('/settings') ? 'primary' : 'default'}
variant={location.pathname.includes('/settings') ? 'solid' : 'light'}
onPress={() => {
navigate('/settings')
}}
startContent={<IoSettings className="text-[20px]" />}
/>
</div>
<Divider />
</div>
<div className="mx-2">
<div className="m-2">
<OutboundModeSwitcher />
</div>
<h3 className="select-none text-lg font-bold m-2"></h3>
<div className="flex justify-between mx-2">
{/* <h3 className="select-none text-lg font-bold m-2">代理模式</h3> */}
<div className="flex justify-between mx-2 mb-2">
<SysproxySwitcher />
<TunSwitcher />
</div>
<h3 className="select-none text-lg font-bold m-2"></h3>
<div className="w-full h-[calc(100%-260px)] overflow-y-auto no-scrollbar">
<div className="mx-2">
<MihomoCoreCard />
<ProfileCard />
<ProxyCard />
</div>
<div className="flex justify-between mx-2">
<ConnCard />
<LogCard />
</div>
<div className="flex justify-between mx-2">
<RuleCard />
<OverrideCard />
</div>
{/* <h3 className="select-none text-lg font-bold m-2">配置</h3> */}
{/* <div className="w-full h-[calc(100%-260px)]"> */}
<div className="mx-2">
<ProfileCard />
<ProxyCard />
<MihomoCoreCard />
</div>
<div className="flex justify-between mx-2">
<ConnCard />
<LogCard />
</div>
<div className="flex justify-between mx-2">
<RuleCard />
<OverrideCard />
</div>
{/* </div> */}
</div>
<Divider orientation="vertical" />
<div className="main w-[calc(100%-251px)] h-full overflow-y-auto">{page}</div>

View File

@ -2,6 +2,10 @@
@tailwind components;
@tailwind utilities;
.no-scrollbar::-webkit-scrollbar {
display: none;
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;

View File

@ -11,22 +11,27 @@ import {
import { useAppConfig } from '@renderer/hooks/use-config'
import { mihomoVersion, restartCore } from '@renderer/utils/ipc'
import { IoMdRefresh } from 'react-icons/io'
import { useLocation, useNavigate } from 'react-router-dom'
import useSWR from 'swr'
const CoreMap = {
mihomo: 'Mihomo',
'mihomo-alpha': 'Mihomo Alpha'
mihomo: '稳定版',
'mihomo-alpha': '预览版'
}
const MihomoCoreCard: React.FC = () => {
const { data: version, mutate } = useSWR('mihomoVersion', mihomoVersion)
const { appConfig, patchAppConfig } = useAppConfig()
const { core } = appConfig || {}
const navigate = useNavigate()
const location = useLocation()
return (
<Card
fullWidth
className={`mb-2 ${location.pathname.includes('/profiles') ? 'bg-primary' : ''}`}
isPressable
onPress={() => navigate('/mihomo')}
className={`mb-2 ${location.pathname.includes('/mihomo') ? 'bg-primary' : ''}`}
>
<CardBody>
<div className="flex justify-between h-[32px]">
@ -49,7 +54,7 @@ const MihomoCoreCard: React.FC = () => {
<CardFooter className="pt-1">
<Dropdown>
<DropdownTrigger>
<Button variant="faded" fullWidth>
<Button fullWidth size="sm" variant="solid">
{core ? CoreMap[core] : ''}
</Button>
</DropdownTrigger>
@ -60,8 +65,8 @@ const MihomoCoreCard: React.FC = () => {
await mutate()
}}
>
<DropdownItem key="mihomo">Mihomo </DropdownItem>
<DropdownItem key="mihomo-alpha">Mihomo Alpha</DropdownItem>
<DropdownItem key="mihomo">{CoreMap['mihomo']}</DropdownItem>
<DropdownItem key="mihomo-alpha">{CoreMap['mihomo-alpha']}</DropdownItem>
</DropdownMenu>
</Dropdown>
</CardFooter>

View File

@ -1,17 +1,23 @@
import { Tabs, Tab } from '@nextui-org/react'
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
import { patchMihomoConfig } from '@renderer/utils/ipc'
import { Key } from 'react'
const OutboundModeSwitcher: React.FC = () => {
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
const { mode } = controledMihomoConfig || {}
const onChangeMode = async (mode: OutboundMode): Promise<void> => {
await patchControledMihomoConfig({ mode })
await patchMihomoConfig({ mode })
}
return (
<Tabs
fullWidth
color="primary"
selectedKey={mode}
onSelectionChange={(key: Key) => patchControledMihomoConfig({ mode: key as OutboundMode })}
onSelectionChange={(key: Key) => onChangeMode(key as OutboundMode)}
>
<Tab
className={`select-none ${mode === 'rule' ? 'font-bold' : ''}`}

View File

@ -1,13 +1,26 @@
import { Button, Card, CardBody, CardFooter, Switch } from '@nextui-org/react'
import { IoSettings } from 'react-icons/io5'
import { AiOutlineGlobal } from 'react-icons/ai'
import { useLocation, useNavigate } from 'react-router-dom'
const SysproxySwitcher: React.FC = () => {
const navigate = useNavigate()
const location = useLocation()
return (
<Card className="w-[50%] mr-1">
<Card
className={`w-[50%] mr-1 ${location.pathname.includes('/sysproxy') ? 'bg-primary' : ''}`}
isPressable
onPress={() => navigate('/sysproxy')}
>
<CardBody className="pb-1 pt-0 px-0">
<div className="flex justify-between">
<Button isIconOnly className="bg-transparent" variant="flat" color="default">
<IoSettings color="default" className="text-lg" />
<Button
isIconOnly
className="bg-transparent pointer-events-none"
variant="flat"
color="default"
>
<AiOutlineGlobal color="default" className="text-[24px]" />
</Button>
<Switch size="sm" />
</div>

View File

@ -1,13 +1,21 @@
import { Button, Card, CardBody, CardFooter, Switch } from '@nextui-org/react'
import { IoSettings } from 'react-icons/io5'
import { TbDeviceIpadHorizontalBolt } from 'react-icons/tb'
import { useLocation, useNavigate } from 'react-router-dom'
const TunSwitcher: React.FC = () => {
const navigate = useNavigate()
const location = useLocation()
return (
<Card className="w-[50%] ml-1">
<Card
className={`w-[50%] ml-1 ${location.pathname.includes('/tun') ? 'bg-primary' : ''}`}
isPressable
onPress={() => navigate('/tun')}
>
<CardBody className="pb-1 pt-0 px-0">
<div className="flex justify-between">
<Button isIconOnly className="bg-transparent" variant="flat" color="default">
<IoSettings color="default" className="text-lg" />
<TbDeviceIpadHorizontalBolt color="default" className="text-[24px] font-bold" />
</Button>
<Switch size="sm" />
</div>

View File

@ -12,7 +12,7 @@ export const useAppConfig = (): RetuenType => {
const patchAppConfig = async (value: Partial<IAppConfig>): Promise<void> => {
await setAppConfig(value)
await mutateAppConfig()
mutateAppConfig()
}
return {

View File

@ -4,7 +4,7 @@ import { getControledMihomoConfig, setControledMihomoConfig } from '@renderer/ut
interface RetuenType {
controledMihomoConfig: Partial<IMihomoConfig> | undefined
mutateControledMihomoConfig: () => void
patchControledMihomoConfig: (value: Partial<IMihomoConfig>) => void
patchControledMihomoConfig: (value: Partial<IMihomoConfig>) => Promise<void>
}
export const useControledMihomoConfig = (): RetuenType => {
@ -15,7 +15,7 @@ export const useControledMihomoConfig = (): RetuenType => {
const patchControledMihomoConfig = async (value: Partial<IMihomoConfig>): Promise<void> => {
await setControledMihomoConfig(value)
await mutateControledMihomoConfig()
mutateControledMihomoConfig()
}
return {

View File

@ -0,0 +1,5 @@
const Mihomo: React.FC = () => {
return <div>Mihomo</div>
}
export default Mihomo

View File

@ -43,7 +43,7 @@ const Settings: React.FC = () => {
} else {
disableAutoRun()
}
mutate(v)
mutate()
}}
/>
</SettingItem>
@ -53,7 +53,6 @@ const Settings: React.FC = () => {
isSelected={silentStart}
onValueChange={(v) => {
patchAppConfig({ silentStart: v })
mutate()
}}
/>
</SettingItem>

View File

@ -0,0 +1,5 @@
const Sysproxy: React.FC = () => {
return <div>Sysproxy</div>
}
export default Sysproxy

View File

@ -0,0 +1,5 @@
const Tun: React.FC = () => {
return <div>Tun</div>
}
export default Tun

View File

@ -6,8 +6,23 @@ import Settings from '@renderer/pages/settings'
import Profiles from '@renderer/pages/profiles'
import Logs from '@renderer/pages/logs'
import Connections from '@renderer/pages/connections'
import Mihomo from '@renderer/pages/mihomo'
import Sysproxy from '@renderer/pages/syspeoxy'
import Tun from '@renderer/pages/tun'
const routes = [
{
path: '/mihomo',
element: <Mihomo />
},
{
path: '/sysproxy',
element: <Sysproxy />
},
{
path: '/tun',
element: <Tun />
},
{
path: '/proxies',
element: <Proxies />

View File

@ -2,6 +2,14 @@ export async function mihomoVersion(): Promise<IMihomoVersion> {
return await window.electron.ipcRenderer.invoke('mihomoVersion')
}
export async function mihomoConfig(): Promise<IMihomoConfig> {
return await window.electron.ipcRenderer.invoke('mihomoConfig')
}
export async function patchMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
await window.electron.ipcRenderer.invoke('patchMihomoConfig', patch)
}
export async function checkAutoRun(): Promise<boolean> {
return await window.electron.ipcRenderer.invoke('checkAutoRun')
}