mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 13:10:30 +08:00
adjust the sidebar
This commit is contained in:
parent
574bdb05be
commit
3dd436d837
@ -1,5 +1,5 @@
|
|||||||
import { ipcMain } from 'electron'
|
import { ipcMain } from 'electron'
|
||||||
import { mihomoVersion } from './mihomo-api'
|
import { mihomoConfig, mihomoVersion, patchMihomoConfig } from './mihomo-api'
|
||||||
import { checkAutoRun, disableAutoRun, enableAutoRun } from './autoRun'
|
import { checkAutoRun, disableAutoRun, enableAutoRun } from './autoRun'
|
||||||
import {
|
import {
|
||||||
getAppConfig,
|
getAppConfig,
|
||||||
@ -12,17 +12,15 @@ import { restartCore } from './manager'
|
|||||||
|
|
||||||
export function registerIpcMainHandlers(): void {
|
export function registerIpcMainHandlers(): void {
|
||||||
ipcMain.handle('mihomoVersion', mihomoVersion)
|
ipcMain.handle('mihomoVersion', mihomoVersion)
|
||||||
|
ipcMain.handle('mihomoConfig', mihomoConfig)
|
||||||
|
ipcMain.handle('patchMihomoConfig', async (_e, patch) => await patchMihomoConfig(patch))
|
||||||
ipcMain.handle('checkAutoRun', checkAutoRun)
|
ipcMain.handle('checkAutoRun', checkAutoRun)
|
||||||
ipcMain.handle('enableAutoRun', enableAutoRun)
|
ipcMain.handle('enableAutoRun', enableAutoRun)
|
||||||
ipcMain.handle('disableAutoRun', disableAutoRun)
|
ipcMain.handle('disableAutoRun', disableAutoRun)
|
||||||
ipcMain.handle('getAppConfig', (_e, force) => getAppConfig(force))
|
ipcMain.handle('getAppConfig', (_e, force) => getAppConfig(force))
|
||||||
ipcMain.handle('setAppConfig', (_e, config) => {
|
ipcMain.handle('setAppConfig', (_e, config) => setAppConfig(config))
|
||||||
setAppConfig(config)
|
|
||||||
})
|
|
||||||
ipcMain.handle('getControledMihomoConfig', (_e, force) => getControledMihomoConfig(force))
|
ipcMain.handle('getControledMihomoConfig', (_e, force) => getControledMihomoConfig(force))
|
||||||
ipcMain.handle('setControledMihomoConfig', (_e, config) => {
|
ipcMain.handle('setControledMihomoConfig', (_e, config) => setControledMihomoConfig(config))
|
||||||
setControledMihomoConfig(config)
|
|
||||||
})
|
|
||||||
ipcMain.handle('getProfileConfig', (_e, force) => getProfileConfig(force))
|
ipcMain.handle('getProfileConfig', (_e, force) => getProfileConfig(force))
|
||||||
ipcMain.handle('restartCore', () => restartCore())
|
ipcMain.handle('restartCore', () => restartCore())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,3 +26,14 @@ export async function mihomoVersion(): Promise<IMihomoVersion> {
|
|||||||
const instance = await getAxios()
|
const instance = await getAxios()
|
||||||
return instance.get('/version') as Promise<IMihomoVersion>
|
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,9 +42,10 @@ const App: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-[100vh] flex">
|
<div className="w-full h-[100vh] flex">
|
||||||
<div className="side w-[250px] h-full">
|
<div className="side w-[250px] h-full overflow-y-auto no-scrollbar">
|
||||||
<div className="flex justify-between h-[32px] m-2">
|
<div className="sticky top-0 z-40 backdrop-blur h-[48px]">
|
||||||
<h3 className="select-none text-lg font-bold leading-[32px]">出站模式</h3>
|
<div className="flex justify-between p-2">
|
||||||
|
<h3 className="select-none text-lg font-bold leading-[32px]">Mihomo Party</h3>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
isIconOnly
|
isIconOnly
|
||||||
@ -56,21 +57,23 @@ const App: React.FC = () => {
|
|||||||
startContent={<IoSettings className="text-[20px]" />}
|
startContent={<IoSettings className="text-[20px]" />}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-2">
|
<Divider />
|
||||||
|
</div>
|
||||||
|
<div className="m-2">
|
||||||
<OutboundModeSwitcher />
|
<OutboundModeSwitcher />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 className="select-none text-lg font-bold m-2">代理模式</h3>
|
{/* <h3 className="select-none text-lg font-bold m-2">代理模式</h3> */}
|
||||||
<div className="flex justify-between mx-2">
|
<div className="flex justify-between mx-2 mb-2">
|
||||||
<SysproxySwitcher />
|
<SysproxySwitcher />
|
||||||
<TunSwitcher />
|
<TunSwitcher />
|
||||||
</div>
|
</div>
|
||||||
<h3 className="select-none text-lg font-bold m-2">配置</h3>
|
{/* <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="w-full h-[calc(100%-260px)]"> */}
|
||||||
<div className="mx-2">
|
<div className="mx-2">
|
||||||
<MihomoCoreCard />
|
|
||||||
<ProfileCard />
|
<ProfileCard />
|
||||||
<ProxyCard />
|
<ProxyCard />
|
||||||
|
<MihomoCoreCard />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-between mx-2">
|
<div className="flex justify-between mx-2">
|
||||||
@ -81,7 +84,7 @@ const App: React.FC = () => {
|
|||||||
<RuleCard />
|
<RuleCard />
|
||||||
<OverrideCard />
|
<OverrideCard />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/* </div> */}
|
||||||
</div>
|
</div>
|
||||||
<Divider orientation="vertical" />
|
<Divider orientation="vertical" />
|
||||||
<div className="main w-[calc(100%-251px)] h-full overflow-y-auto">{page}</div>
|
<div className="main w-[calc(100%-251px)] h-full overflow-y-auto">{page}</div>
|
||||||
|
|||||||
@ -2,6 +2,10 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
.no-scrollbar::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
*::-webkit-scrollbar {
|
*::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
|
|||||||
@ -11,22 +11,27 @@ import {
|
|||||||
import { useAppConfig } from '@renderer/hooks/use-config'
|
import { useAppConfig } from '@renderer/hooks/use-config'
|
||||||
import { mihomoVersion, restartCore } from '@renderer/utils/ipc'
|
import { mihomoVersion, restartCore } from '@renderer/utils/ipc'
|
||||||
import { IoMdRefresh } from 'react-icons/io'
|
import { IoMdRefresh } from 'react-icons/io'
|
||||||
|
import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
|
|
||||||
const CoreMap = {
|
const CoreMap = {
|
||||||
mihomo: 'Mihomo',
|
mihomo: '稳定版',
|
||||||
'mihomo-alpha': 'Mihomo Alpha'
|
'mihomo-alpha': '预览版'
|
||||||
}
|
}
|
||||||
|
|
||||||
const MihomoCoreCard: React.FC = () => {
|
const MihomoCoreCard: React.FC = () => {
|
||||||
const { data: version, mutate } = useSWR('mihomoVersion', mihomoVersion)
|
const { data: version, mutate } = useSWR('mihomoVersion', mihomoVersion)
|
||||||
const { appConfig, patchAppConfig } = useAppConfig()
|
const { appConfig, patchAppConfig } = useAppConfig()
|
||||||
const { core } = appConfig || {}
|
const { core } = appConfig || {}
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
fullWidth
|
fullWidth
|
||||||
className={`mb-2 ${location.pathname.includes('/profiles') ? 'bg-primary' : ''}`}
|
isPressable
|
||||||
|
onPress={() => navigate('/mihomo')}
|
||||||
|
className={`mb-2 ${location.pathname.includes('/mihomo') ? 'bg-primary' : ''}`}
|
||||||
>
|
>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<div className="flex justify-between h-[32px]">
|
<div className="flex justify-between h-[32px]">
|
||||||
@ -49,7 +54,7 @@ const MihomoCoreCard: React.FC = () => {
|
|||||||
<CardFooter className="pt-1">
|
<CardFooter className="pt-1">
|
||||||
<Dropdown>
|
<Dropdown>
|
||||||
<DropdownTrigger>
|
<DropdownTrigger>
|
||||||
<Button variant="faded" fullWidth>
|
<Button fullWidth size="sm" variant="solid">
|
||||||
{core ? CoreMap[core] : ''}
|
{core ? CoreMap[core] : ''}
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownTrigger>
|
</DropdownTrigger>
|
||||||
@ -60,8 +65,8 @@ const MihomoCoreCard: React.FC = () => {
|
|||||||
await mutate()
|
await mutate()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DropdownItem key="mihomo">Mihomo </DropdownItem>
|
<DropdownItem key="mihomo">{CoreMap['mihomo']}</DropdownItem>
|
||||||
<DropdownItem key="mihomo-alpha">Mihomo Alpha</DropdownItem>
|
<DropdownItem key="mihomo-alpha">{CoreMap['mihomo-alpha']}</DropdownItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
|
|||||||
@ -1,17 +1,23 @@
|
|||||||
import { Tabs, Tab } from '@nextui-org/react'
|
import { Tabs, Tab } from '@nextui-org/react'
|
||||||
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
||||||
|
import { patchMihomoConfig } from '@renderer/utils/ipc'
|
||||||
import { Key } from 'react'
|
import { Key } from 'react'
|
||||||
|
|
||||||
const OutboundModeSwitcher: React.FC = () => {
|
const OutboundModeSwitcher: React.FC = () => {
|
||||||
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
||||||
const { mode } = controledMihomoConfig || {}
|
const { mode } = controledMihomoConfig || {}
|
||||||
|
|
||||||
|
const onChangeMode = async (mode: OutboundMode): Promise<void> => {
|
||||||
|
await patchControledMihomoConfig({ mode })
|
||||||
|
await patchMihomoConfig({ mode })
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
fullWidth
|
fullWidth
|
||||||
color="primary"
|
color="primary"
|
||||||
selectedKey={mode}
|
selectedKey={mode}
|
||||||
onSelectionChange={(key: Key) => patchControledMihomoConfig({ mode: key as OutboundMode })}
|
onSelectionChange={(key: Key) => onChangeMode(key as OutboundMode)}
|
||||||
>
|
>
|
||||||
<Tab
|
<Tab
|
||||||
className={`select-none ${mode === 'rule' ? 'font-bold' : ''}`}
|
className={`select-none ${mode === 'rule' ? 'font-bold' : ''}`}
|
||||||
|
|||||||
@ -1,13 +1,26 @@
|
|||||||
import { Button, Card, CardBody, CardFooter, Switch } from '@nextui-org/react'
|
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 SysproxySwitcher: React.FC = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
return (
|
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">
|
<CardBody className="pb-1 pt-0 px-0">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<Button isIconOnly className="bg-transparent" variant="flat" color="default">
|
<Button
|
||||||
<IoSettings color="default" className="text-lg" />
|
isIconOnly
|
||||||
|
className="bg-transparent pointer-events-none"
|
||||||
|
variant="flat"
|
||||||
|
color="default"
|
||||||
|
>
|
||||||
|
<AiOutlineGlobal color="default" className="text-[24px]" />
|
||||||
</Button>
|
</Button>
|
||||||
<Switch size="sm" />
|
<Switch size="sm" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,13 +1,21 @@
|
|||||||
import { Button, Card, CardBody, CardFooter, Switch } from '@nextui-org/react'
|
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 TunSwitcher: React.FC = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
return (
|
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">
|
<CardBody className="pb-1 pt-0 px-0">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<Button isIconOnly className="bg-transparent" variant="flat" color="default">
|
<Button isIconOnly className="bg-transparent" variant="flat" color="default">
|
||||||
<IoSettings color="default" className="text-lg" />
|
<TbDeviceIpadHorizontalBolt color="default" className="text-[24px] font-bold" />
|
||||||
</Button>
|
</Button>
|
||||||
<Switch size="sm" />
|
<Switch size="sm" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export const useAppConfig = (): RetuenType => {
|
|||||||
|
|
||||||
const patchAppConfig = async (value: Partial<IAppConfig>): Promise<void> => {
|
const patchAppConfig = async (value: Partial<IAppConfig>): Promise<void> => {
|
||||||
await setAppConfig(value)
|
await setAppConfig(value)
|
||||||
await mutateAppConfig()
|
mutateAppConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { getControledMihomoConfig, setControledMihomoConfig } from '@renderer/ut
|
|||||||
interface RetuenType {
|
interface RetuenType {
|
||||||
controledMihomoConfig: Partial<IMihomoConfig> | undefined
|
controledMihomoConfig: Partial<IMihomoConfig> | undefined
|
||||||
mutateControledMihomoConfig: () => void
|
mutateControledMihomoConfig: () => void
|
||||||
patchControledMihomoConfig: (value: Partial<IMihomoConfig>) => void
|
patchControledMihomoConfig: (value: Partial<IMihomoConfig>) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useControledMihomoConfig = (): RetuenType => {
|
export const useControledMihomoConfig = (): RetuenType => {
|
||||||
@ -15,7 +15,7 @@ export const useControledMihomoConfig = (): RetuenType => {
|
|||||||
|
|
||||||
const patchControledMihomoConfig = async (value: Partial<IMihomoConfig>): Promise<void> => {
|
const patchControledMihomoConfig = async (value: Partial<IMihomoConfig>): Promise<void> => {
|
||||||
await setControledMihomoConfig(value)
|
await setControledMihomoConfig(value)
|
||||||
await mutateControledMihomoConfig()
|
mutateControledMihomoConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
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 {
|
} else {
|
||||||
disableAutoRun()
|
disableAutoRun()
|
||||||
}
|
}
|
||||||
mutate(v)
|
mutate()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
@ -53,7 +53,6 @@ const Settings: React.FC = () => {
|
|||||||
isSelected={silentStart}
|
isSelected={silentStart}
|
||||||
onValueChange={(v) => {
|
onValueChange={(v) => {
|
||||||
patchAppConfig({ silentStart: v })
|
patchAppConfig({ silentStart: v })
|
||||||
mutate()
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SettingItem>
|
</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 Profiles from '@renderer/pages/profiles'
|
||||||
import Logs from '@renderer/pages/logs'
|
import Logs from '@renderer/pages/logs'
|
||||||
import Connections from '@renderer/pages/connections'
|
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 = [
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '/mihomo',
|
||||||
|
element: <Mihomo />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/sysproxy',
|
||||||
|
element: <Sysproxy />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/tun',
|
||||||
|
element: <Tun />
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/proxies',
|
path: '/proxies',
|
||||||
element: <Proxies />
|
element: <Proxies />
|
||||||
|
|||||||
@ -2,6 +2,14 @@ export async function mihomoVersion(): Promise<IMihomoVersion> {
|
|||||||
return await window.electron.ipcRenderer.invoke('mihomoVersion')
|
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> {
|
export async function checkAutoRun(): Promise<boolean> {
|
||||||
return await window.electron.ipcRenderer.invoke('checkAutoRun')
|
return await window.electron.ipcRenderer.invoke('checkAutoRun')
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user