mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 13:10:30 +08:00
support interfaces info
This commit is contained in:
parent
7b4d60e280
commit
4aeac0ebb3
@ -1,3 +1,4 @@
|
|||||||
### New Features
|
### New Features
|
||||||
|
|
||||||
- 添加覆写脚本执行日志功能
|
- 添加覆写脚本执行日志功能
|
||||||
|
- 支持查看局域网网络信息
|
||||||
|
|||||||
5
src/main/sys/interface.ts
Normal file
5
src/main/sys/interface.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import os from 'os'
|
||||||
|
|
||||||
|
export function getInterfaces(): NodeJS.Dict<NetworkInterfaceInfo[]> {
|
||||||
|
return os.networkInterfaces()
|
||||||
|
}
|
||||||
@ -51,6 +51,7 @@ import { getFilePath, openUWPTool, readTextFile, setupFirewall } from '../sys/mi
|
|||||||
import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory'
|
import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory'
|
||||||
import { isPortable, setPortable } from './dirs'
|
import { isPortable, setPortable } from './dirs'
|
||||||
import { listWebdavBackups, webdavBackup, webdavRestore } from '../resolve/backup'
|
import { listWebdavBackups, webdavBackup, webdavRestore } from '../resolve/backup'
|
||||||
|
import { getInterfaces } from '../sys/interface'
|
||||||
|
|
||||||
function ipcErrorWrapper<T>( // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
function ipcErrorWrapper<T>( // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
fn: (...args: any[]) => Promise<T> // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
fn: (...args: any[]) => Promise<T> // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@ -139,6 +140,7 @@ export function registerIpcMainHandlers(): void {
|
|||||||
ipcMain.handle('platform', () => process.platform)
|
ipcMain.handle('platform', () => process.platform)
|
||||||
ipcMain.handle('openUWPTool', ipcErrorWrapper(openUWPTool))
|
ipcMain.handle('openUWPTool', ipcErrorWrapper(openUWPTool))
|
||||||
ipcMain.handle('setupFirewall', ipcErrorWrapper(setupFirewall))
|
ipcMain.handle('setupFirewall', ipcErrorWrapper(setupFirewall))
|
||||||
|
ipcMain.handle('getInterfaces', getInterfaces)
|
||||||
ipcMain.handle('setPortable', (_e, portable) => ipcErrorWrapper(setPortable)(portable))
|
ipcMain.handle('setPortable', (_e, portable) => ipcErrorWrapper(setPortable)(portable))
|
||||||
ipcMain.handle('isPortable', isPortable)
|
ipcMain.handle('isPortable', isPortable)
|
||||||
ipcMain.handle('webdavBackup', ipcErrorWrapper(webdavBackup))
|
ipcMain.handle('webdavBackup', ipcErrorWrapper(webdavBackup))
|
||||||
|
|||||||
67
src/renderer/src/components/mihomo/interface-modal.tsx
Normal file
67
src/renderer/src/components/mihomo/interface-modal.tsx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import {
|
||||||
|
Modal,
|
||||||
|
ModalContent,
|
||||||
|
ModalHeader,
|
||||||
|
ModalBody,
|
||||||
|
ModalFooter,
|
||||||
|
Button,
|
||||||
|
Snippet
|
||||||
|
} from '@nextui-org/react'
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { getInterfaces } from '@renderer/utils/ipc'
|
||||||
|
interface Props {
|
||||||
|
onClose: () => void
|
||||||
|
}
|
||||||
|
const InterfaceModal: React.FC<Props> = (props) => {
|
||||||
|
const { onClose } = props
|
||||||
|
const [info, setInfo] = useState<Record<string, NetworkInterfaceInfo[]>>({})
|
||||||
|
const getInfo = async (): Promise<void> => {
|
||||||
|
setInfo(await getInterfaces())
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getInfo()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
backdrop="blur"
|
||||||
|
hideCloseButton
|
||||||
|
isOpen={true}
|
||||||
|
onOpenChange={onClose}
|
||||||
|
scrollBehavior="inside"
|
||||||
|
>
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader className="flex">网络信息</ModalHeader>
|
||||||
|
<ModalBody>
|
||||||
|
{Object.entries(info).map(([key, value]) => {
|
||||||
|
return (
|
||||||
|
<div key={key}>
|
||||||
|
<h4 className="font-bold">{key}</h4>
|
||||||
|
{value.map((v) => {
|
||||||
|
return (
|
||||||
|
<div key={v.address}>
|
||||||
|
<div className="mt-2 flex justify-between">
|
||||||
|
{v.family}
|
||||||
|
<Snippet symbol="" size="sm">
|
||||||
|
{v.address}
|
||||||
|
</Snippet>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button variant="light" onPress={onClose}>
|
||||||
|
关闭
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InterfaceModal
|
||||||
@ -5,8 +5,10 @@ import SettingItem from '@renderer/components/base/base-setting-item'
|
|||||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||||
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
||||||
import { platform } from '@renderer/utils/init'
|
import { platform } from '@renderer/utils/init'
|
||||||
|
import { FaNetworkWired } from 'react-icons/fa'
|
||||||
import { restartCore } from '@renderer/utils/ipc'
|
import { restartCore } from '@renderer/utils/ipc'
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
|
import InterfaceModal from '@renderer/components/mihomo/interface-modal'
|
||||||
|
|
||||||
const CoreMap = {
|
const CoreMap = {
|
||||||
mihomo: '稳定版',
|
mihomo: '稳定版',
|
||||||
@ -43,12 +45,16 @@ const Mihomo: React.FC = () => {
|
|||||||
const [externalControllerInput, setExternalControllerInput] = useState(externalController)
|
const [externalControllerInput, setExternalControllerInput] = useState(externalController)
|
||||||
const [secretInput, setSecretInput] = useState(secret)
|
const [secretInput, setSecretInput] = useState(secret)
|
||||||
|
|
||||||
|
const [lanOpen, setLanOpen] = useState(false)
|
||||||
|
|
||||||
const onChangeNeedRestart = async (patch: Partial<IMihomoConfig>): Promise<void> => {
|
const onChangeNeedRestart = async (patch: Partial<IMihomoConfig>): Promise<void> => {
|
||||||
await patchControledMihomoConfig(patch)
|
await patchControledMihomoConfig(patch)
|
||||||
await restartCore()
|
await restartCore()
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{lanOpen && <InterfaceModal onClose={() => setLanOpen(false)} />}
|
||||||
<BasePage title="内核设置">
|
<BasePage title="内核设置">
|
||||||
<SettingCard>
|
<SettingCard>
|
||||||
<SettingItem title="内核版本" divider>
|
<SettingItem title="内核版本" divider>
|
||||||
@ -273,7 +279,23 @@ const Mihomo: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
<SettingItem title="允许局域网连接" divider>
|
<SettingItem
|
||||||
|
title="允许局域网连接"
|
||||||
|
actions={
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
isIconOnly
|
||||||
|
variant="light"
|
||||||
|
className="ml-2"
|
||||||
|
onPress={() => {
|
||||||
|
setLanOpen(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FaNetworkWired className="text-lg" />
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
divider
|
||||||
|
>
|
||||||
<Switch
|
<Switch
|
||||||
size="sm"
|
size="sm"
|
||||||
isSelected={allowLan}
|
isSelected={allowLan}
|
||||||
@ -350,6 +372,7 @@ const Mihomo: React.FC = () => {
|
|||||||
</SettingItem>
|
</SettingItem>
|
||||||
</SettingCard>
|
</SettingCard>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -251,6 +251,10 @@ export async function setupFirewall(): Promise<void> {
|
|||||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setupFirewall'))
|
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setupFirewall'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getInterfaces(): Promise<Record<string, NetworkInterfaceInfo[]>> {
|
||||||
|
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('getInterfaces'))
|
||||||
|
}
|
||||||
|
|
||||||
export async function setPortable(portable: boolean): Promise<void> {
|
export async function setPortable(portable: boolean): Promise<void> {
|
||||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setPortable', portable))
|
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setPortable', portable))
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/shared/types.d.ts
vendored
1
src/shared/types.d.ts
vendored
@ -36,6 +36,7 @@ type MihomoProxyType =
|
|||||||
type TunStack = 'gvisor' | 'mixed' | 'system'
|
type TunStack = 'gvisor' | 'mixed' | 'system'
|
||||||
type FindProcessMode = 'off' | 'strict' | 'always'
|
type FindProcessMode = 'off' | 'strict' | 'always'
|
||||||
type DnsMode = 'normal' | 'fake-ip' | 'redir-host'
|
type DnsMode = 'normal' | 'fake-ip' | 'redir-host'
|
||||||
|
type NetworkInterfaceInfo = os.NetworkInterfaceInfo
|
||||||
|
|
||||||
interface IAppVersion {
|
interface IAppVersion {
|
||||||
version: string
|
version: string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user