mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 05:00:30 +08:00
logs page
This commit is contained in:
parent
ae35d6a4a1
commit
e3fc01dcf0
@ -44,7 +44,7 @@ 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 overflow-y-auto no-scrollbar">
|
<div className="side w-[250px] h-full overflow-y-auto no-scrollbar">
|
||||||
<div className="sticky top-0 z-40 backdrop-blur bg-background/70 h-[48px]">
|
<div className="sticky top-0 z-40 backdrop-blur bg-background/40 h-[48px]">
|
||||||
<div className="flex justify-between p-2">
|
<div className="flex justify-between p-2">
|
||||||
<h3 className="select-none text-lg font-bold leading-[32px]">Mihomo Party</h3>
|
<h3 className="select-none text-lg font-bold leading-[32px]">Mihomo Party</h3>
|
||||||
<Button
|
<Button
|
||||||
@ -58,19 +58,14 @@ const App: React.FC = () => {
|
|||||||
startContent={<IoSettings className="text-[20px]" />}
|
startContent={<IoSettings className="text-[20px]" />}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Divider />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="m-2">
|
<div className="m-2">
|
||||||
<OutboundModeSwitcher />
|
<OutboundModeSwitcher />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* <h3 className="select-none text-lg font-bold m-2">代理模式</h3> */}
|
|
||||||
<div className="flex justify-between mx-2 mb-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> */}
|
|
||||||
{/* <div className="w-full h-[calc(100%-260px)]"> */}
|
|
||||||
<div className="mx-2">
|
<div className="mx-2">
|
||||||
<ProfileCard />
|
<ProfileCard />
|
||||||
<ProxyCard />
|
<ProxyCard />
|
||||||
@ -86,7 +81,6 @@ const App: React.FC = () => {
|
|||||||
<TestCard />
|
<TestCard />
|
||||||
<OverrideCard />
|
<OverrideCard />
|
||||||
</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>
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Divider } from '@nextui-org/divider'
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title?: React.ReactNode
|
title?: React.ReactNode
|
||||||
header?: React.ReactNode
|
header?: React.ReactNode
|
||||||
@ -10,12 +9,11 @@ interface Props {
|
|||||||
const BasePage: React.FC<Props> = (props) => {
|
const BasePage: React.FC<Props> = (props) => {
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full overflow-y-auto custom-scrollbar">
|
<div className="w-full h-full overflow-y-auto custom-scrollbar">
|
||||||
<div className="sticky top-0 z-40 h-[48px] w-full backdrop-blur bg-background/70">
|
<div className="sticky top-0 z-40 h-[48px] w-full backdrop-blur bg-background/40">
|
||||||
<div className="p-2 flex justify-between">
|
<div className="p-2 flex justify-between">
|
||||||
<div className="select-none title h-full text-lg leading-[32px]">{props.title}</div>
|
<div className="select-none title h-full text-lg leading-[32px]">{props.title}</div>
|
||||||
<div className="header h-full">{props.header}</div>
|
<div className="header h-full">{props.header}</div>
|
||||||
</div>
|
</div>
|
||||||
<Divider />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="content">{props.children}</div>
|
<div className="content">{props.children}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
25
src/renderer/src/components/logs/log-item.tsx
Normal file
25
src/renderer/src/components/logs/log-item.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Card, CardBody, CardHeader } from '@nextui-org/react'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const colorMap = {
|
||||||
|
error: 'danger',
|
||||||
|
warn: 'warning',
|
||||||
|
info: 'primary',
|
||||||
|
debug: 'default'
|
||||||
|
}
|
||||||
|
const LogItem: React.FC<IMihomoLogInfo> = (props) => {
|
||||||
|
const { type, payload, time } = props
|
||||||
|
return (
|
||||||
|
<Card className="m-2">
|
||||||
|
<CardHeader className="pb-0 pt-1 select-none">
|
||||||
|
<div className={`mr-2 text-lg font-bold text-${colorMap[type]}`}>
|
||||||
|
{props.type.toUpperCase()}
|
||||||
|
</div>
|
||||||
|
<small className="text-default-500">{time}</small>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody className="pt-0">{payload}</CardBody>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LogItem
|
||||||
@ -40,7 +40,7 @@ const ConnCard: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<IoLink color="default" className="text-[20px]" />
|
<IoLink color="default" className="text-[20px]" />
|
||||||
</Button>
|
</Button>
|
||||||
<div className="p-2 w-full">
|
<div className="p-2 w-full select-none">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<div className="w-full text-right mr-2">{calcTraffic(upload)}/s</div>
|
<div className="w-full text-right mr-2">{calcTraffic(upload)}/s</div>
|
||||||
<FaCircleArrowUp className="h-[24px] leading-[24px]" />
|
<FaCircleArrowUp className="h-[24px] leading-[24px]" />
|
||||||
|
|||||||
@ -1,21 +1,61 @@
|
|||||||
import BasePage from '@renderer/components/base/base-page'
|
import BasePage from '@renderer/components/base/base-page'
|
||||||
import { startMihomoLogs, stopMihomoLogs } from '@renderer/utils/ipc'
|
import { startMihomoLogs, stopMihomoLogs } from '@renderer/utils/ipc'
|
||||||
import { useEffect } from 'react'
|
import LogItem from '@renderer/components/logs/log-item'
|
||||||
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
|
import { Input } from '@nextui-org/react'
|
||||||
|
|
||||||
const Logs: React.FC = () => {
|
const Logs: React.FC = () => {
|
||||||
|
const [logs, setLogs] = useState<IMihomoLogInfo[]>([])
|
||||||
|
const [filter, setFilter] = useState('')
|
||||||
|
|
||||||
|
const filteredLogs = useMemo(() => {
|
||||||
|
if (filter === '') return logs
|
||||||
|
return logs.filter((log) => {
|
||||||
|
return log.payload.includes(filter)
|
||||||
|
})
|
||||||
|
}, [logs, filter])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
startMihomoLogs()
|
startMihomoLogs()
|
||||||
window.electron.ipcRenderer.on('mihomoLogs', (_e, log: IMihomoLogInfo) => {
|
window.electron.ipcRenderer.on('mihomoLogs', (_e, log: IMihomoLogInfo) => {
|
||||||
console.log(log)
|
log.time = new Date().toISOString()
|
||||||
|
setLogs((prevLogs) => {
|
||||||
|
if (prevLogs.length >= 200) {
|
||||||
|
prevLogs.shift()
|
||||||
|
}
|
||||||
|
return [...prevLogs, log]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return (): void => {
|
return (): void => {
|
||||||
stopMihomoLogs()
|
stopMihomoLogs()
|
||||||
window.electron.ipcRenderer.removeAllListeners('mihomoTraffic')
|
window.electron.ipcRenderer.removeAllListeners('mihomoLogs')
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return <BasePage title="实时日志"></BasePage>
|
return (
|
||||||
|
<BasePage title="实时日志">
|
||||||
|
<div className="sticky top-[48px] z-40 backdrop-blur bg-background/40 flex p-2">
|
||||||
|
<Input
|
||||||
|
variant="bordered"
|
||||||
|
size="sm"
|
||||||
|
value={filter}
|
||||||
|
placeholder="筛选过滤"
|
||||||
|
onValueChange={setFilter}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{filteredLogs.map((log, index) => {
|
||||||
|
return (
|
||||||
|
<LogItem
|
||||||
|
key={log.payload + index}
|
||||||
|
time={log.time}
|
||||||
|
type={log.type}
|
||||||
|
payload={log.payload}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</BasePage>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Logs
|
export default Logs
|
||||||
|
|||||||
@ -24,7 +24,7 @@ const Profiles: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<BasePage title="订阅管理">
|
<BasePage title="订阅管理">
|
||||||
<div className="sticky top-[48px] z-40 backdrop-blur bg-background/70 flex p-2">
|
<div className="sticky top-[48px] z-40 backdrop-blur bg-background/40 flex p-2">
|
||||||
<Input
|
<Input
|
||||||
variant="bordered"
|
variant="bordered"
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
|
|||||||
1
src/shared/types.d.ts
vendored
1
src/shared/types.d.ts
vendored
@ -14,6 +14,7 @@ interface IMihomoTrafficInfo {
|
|||||||
interface IMihomoLogInfo {
|
interface IMihomoLogInfo {
|
||||||
type: LogLevel
|
type: LogLevel
|
||||||
payload: string
|
payload: string
|
||||||
|
time?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IMihomoRulesInfo {
|
interface IMihomoRulesInfo {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user