mirror of
https://github.com/pompurin404/mihomo-party.git
synced 2024-11-15 19:22:31 +08:00
adjust the sidebar
This commit is contained in:
parent
574bdb05be
commit
3dd436d837
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 6px;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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' : ''}`}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -12,7 +12,7 @@ export const useAppConfig = (): RetuenType => {
|
|||
|
||||
const patchAppConfig = async (value: Partial<IAppConfig>): Promise<void> => {
|
||||
await setAppConfig(value)
|
||||
await mutateAppConfig()
|
||||
mutateAppConfig()
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -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 {
|
||||
|
|
5
src/renderer/src/pages/mihomo.tsx
Normal file
5
src/renderer/src/pages/mihomo.tsx
Normal file
|
@ -0,0 +1,5 @@
|
|||
const Mihomo: React.FC = () => {
|
||||
return <div>Mihomo</div>
|
||||
}
|
||||
|
||||
export default Mihomo
|
|
@ -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>
|
||||
|
|
5
src/renderer/src/pages/syspeoxy.tsx
Normal file
5
src/renderer/src/pages/syspeoxy.tsx
Normal file
|
@ -0,0 +1,5 @@
|
|||
const Sysproxy: React.FC = () => {
|
||||
return <div>Sysproxy</div>
|
||||
}
|
||||
|
||||
export default Sysproxy
|
5
src/renderer/src/pages/tun.tsx
Normal file
5
src/renderer/src/pages/tun.tsx
Normal file
|
@ -0,0 +1,5 @@
|
|||
const Tun: React.FC = () => {
|
||||
return <div>Tun</div>
|
||||
}
|
||||
|
||||
export default Tun
|
|
@ -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 />
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user