mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-03-02 00:30:25 +00:00
feat: 优化webui界面和文件管理器 (#1472)
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user