feat: 优化webui界面和文件管理器 (#1472)

This commit is contained in:
时瑾
2026-01-01 21:40:39 +08:00
committed by GitHub
parent 928e38c00d
commit 14c21b9463
19 changed files with 281 additions and 217 deletions

View File

@@ -1,5 +1,6 @@
import React, { useMemo } from 'react';
import clsx from 'clsx';
import { Tooltip } from '@heroui/tooltip';
import { useTheme } from '@/hooks/use-theme';
@@ -18,9 +19,13 @@ const UsagePie: React.FC<UsagePieProps> = ({
}) => {
const { theme } = useTheme();
// Ensure values are clean
const cleanSystem = Math.min(Math.max(systemUsage || 0, 0), 100);
const cleanProcess = Math.min(Math.max(processUsage || 0, 0), cleanSystem);
// Ensure values are clean and consistent
// Process usage cannot exceed system usage, and system usage cannot be less than process usage.
const rawSystem = Math.max(systemUsage || 0, 0);
const rawProcess = Math.max(processUsage || 0, 0);
const cleanSystem = Math.min(Math.max(rawSystem, rawProcess), 100);
const cleanProcess = Math.min(rawProcess, cleanSystem);
// SVG Config
const size = 100;
@@ -47,75 +52,102 @@ const UsagePie: React.FC<UsagePieProps> = ({
return `${(cleanProcess / 100) * circumference} ${circumference}`;
}, [cleanProcess, circumference]);
return (
<div className="relative w-36 h-36 flex items-center justify-center">
<svg
className="w-full h-full -rotate-90"
viewBox={`0 0 ${size} ${size}`}
>
{/* Track / Free Space */}
<circle
cx={center}
cy={center}
r={radius}
fill="none"
stroke={colors.track}
strokeWidth={strokeWidth}
strokeLinecap="round"
/>
// 计算其他进程占用(系统总占用 - QQ占用
const otherUsage = Math.max(cleanSystem - cleanProcess, 0);
{/* System Usage (Background for QQ) - effectively "Others" + "QQ" */}
<circle
cx={center}
cy={center}
r={radius}
fill="none"
stroke={colors.other}
strokeWidth={strokeWidth}
strokeLinecap="round"
strokeDasharray={systemDash}
className="transition-all duration-700 ease-out"
/>
{/* QQ Usage - Layered on top */}
<circle
cx={center}
cy={center}
r={radius}
fill="none"
stroke={colors.qq}
strokeWidth={strokeWidth}
strokeLinecap="round"
strokeDasharray={processDash}
className="transition-all duration-700 ease-out"
/>
</svg>
{/* Center Content */}
<div className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none select-none">
{title && (
<span className={clsx(
"text-[10px] font-medium mb-0.5 opacity-80 uppercase tracking-widest scale-90",
hasBackground ? 'text-white/80' : 'text-default-500 dark:text-default-400'
)}>
{title}
</span>
)}
<div className="flex items-baseline gap-0.5">
<span className={clsx(
"text-2xl font-bold font-mono tracking-tight",
hasBackground ? 'text-white' : 'text-default-900 dark:text-white'
)}>
{Math.round(cleanSystem)}
</span>
<span className={clsx(
"text-xs font-bold",
hasBackground ? 'text-white/60' : 'text-default-400 dark:text-default-500'
)}>%</span>
</div>
// Tooltip 内容
const tooltipContent = (
<div className='flex flex-col gap-1 p-1 text-xs'>
<div className='flex items-center gap-2'>
<span className='w-2 h-2 rounded-full' style={{ backgroundColor: colors.qq }} />
<span>QQ进程: {cleanProcess.toFixed(1)}%</span>
</div>
<div className='flex items-center gap-2'>
<span className='w-2 h-2 rounded-full' style={{ backgroundColor: colors.other }} />
<span>: {otherUsage.toFixed(1)}%</span>
</div>
<div className='flex items-center gap-2'>
<span className='w-2 h-2 rounded-full' style={{ backgroundColor: colors.track }} />
<span>: {(100 - cleanSystem).toFixed(1)}%</span>
</div>
</div>
);
return (
<Tooltip content={tooltipContent} placement='top'>
<div className='relative w-36 h-36 flex items-center justify-center cursor-pointer'>
<svg
className='w-full h-full -rotate-90'
viewBox={`0 0 ${size} ${size}`}
>
{/* Track / Free Space */}
<circle
cx={center}
cy={center}
r={radius}
fill='none'
stroke={colors.track}
strokeWidth={strokeWidth}
strokeLinecap='round'
/>
{/* System Usage (Background for QQ) - effectively "Others" + "QQ" */}
<circle
cx={center}
cy={center}
r={radius}
fill='none'
stroke={colors.other}
strokeWidth={strokeWidth}
strokeLinecap='round'
strokeDasharray={systemDash}
className='transition-all duration-700 ease-out'
/>
{/* QQ Usage - Layered on top */}
<circle
cx={center}
cy={center}
r={radius}
fill='none'
stroke={colors.qq}
strokeWidth={strokeWidth}
strokeLinecap='round'
strokeDasharray={processDash}
className='transition-all duration-700 ease-out'
/>
</svg>
{/* Center Content */}
<div className='absolute inset-0 flex flex-col items-center justify-center pointer-events-none select-none'>
{title && (
<span className={clsx(
'text-[10px] font-medium mb-0.5 opacity-80 uppercase tracking-widest scale-90',
hasBackground ? 'text-white/80' : 'text-default-500 dark:text-default-400'
)}
>
{title}
</span>
)}
<div className='flex items-baseline gap-0.5'>
<span className={clsx(
'text-2xl font-bold font-mono tracking-tight',
hasBackground ? 'text-white' : 'text-default-900 dark:text-white'
)}
>
{Math.round(cleanSystem)}
</span>
<span className={clsx(
'text-xs font-bold',
hasBackground ? 'text-white/60' : 'text-default-400 dark:text-default-500'
)}
>%
</span>
</div>
</div>
</div>
</Tooltip>
);
};
export default UsagePie;