Add background-aware styling to sidebar and usage pie

Updated sidebar, navigation list, and usage pie components to adjust their styles based on the presence of a custom background image. This improves visual integration when a background image is set, ensuring text and UI elements remain readable and aesthetically consistent.
This commit is contained in:
手瓜一十雪 2025-12-24 18:14:04 +08:00
parent a34a86288b
commit afed164ba1
4 changed files with 33 additions and 6 deletions

View File

@ -1,9 +1,11 @@
import { Input } from '@heroui/input';
import { useLocalStorage } from '@uidotdev/usehooks';
import clsx from 'clsx';
import { AnimatePresence, motion } from 'motion/react';
import { useMemo, useState } from 'react';
import { TbChevronRight, TbFolder, TbSearch } from 'react-icons/tb';
import key from '@/const/key';
import oneBotHttpApiGroup from '@/const/ob_api/group';
import oneBotHttpApiMessage from '@/const/ob_api/message';
import oneBotHttpApiSystem from '@/const/ob_api/system';
@ -22,6 +24,8 @@ const OneBotApiNavList: React.FC<OneBotApiNavListProps> = (props) => {
const { data, selectedApi, onSelect, openSideBar, onToggle } = props;
const [searchValue, setSearchValue] = useState('');
const [expandedGroups, setExpandedGroups] = useState<string[]>([]);
const [backgroundImage] = useLocalStorage<string>(key.backgroundImage, '');
const hasBackground = !!backgroundImage;
const groups = useMemo(() => {
const rawGroups = [
@ -70,7 +74,9 @@ const OneBotApiNavList: React.FC<OneBotApiNavListProps> = (props) => {
// Mobile: absolute position, drawer style
// Desktop: relative position, pushing content
'absolute md:relative left-0 top-0',
'bg-white/80 dark:bg-black/80 md:bg-transparent backdrop-blur-2xl md:backdrop-blur-none'
hasBackground
? 'bg-white/10 dark:bg-black/40 backdrop-blur-xl md:bg-transparent md:backdrop-blur-none'
: 'bg-white/80 dark:bg-black/40 backdrop-blur-xl md:bg-transparent md:backdrop-blur-none'
)}
initial={false}
animate={{
@ -139,7 +145,7 @@ const OneBotApiNavList: React.FC<OneBotApiNavListProps> = (props) => {
className={clsx(
'flex flex-col gap-0.5 px-3 py-2 rounded-lg cursor-pointer transition-all border border-transparent select-none',
isSelected
? 'bg-primary/20 border-primary/20 shadow-sm'
? (hasBackground ? '' : 'bg-primary/20 border-primary/20 shadow-sm')
: 'hover:bg-white/5'
)}
>

View File

@ -1,10 +1,12 @@
import { Button } from '@heroui/button';
import { useLocalStorage } from '@uidotdev/usehooks';
import clsx from 'clsx';
import { AnimatePresence, motion } from 'motion/react';
import React from 'react';
import { IoMdLogOut } from 'react-icons/io';
import { MdDarkMode, MdLightMode } from 'react-icons/md';
import key from '@/const/key';
import useAuth from '@/hooks/auth';
import useDialog from '@/hooks/use-dialog';
import { useTheme } from '@/hooks/use-theme';
@ -23,6 +25,9 @@ const SideBar: React.FC<SideBarProps> = (props) => {
const { toggleTheme, isDark } = useTheme();
const { revokeAuth } = useAuth();
const dialog = useDialog();
const [backgroundImage] = useLocalStorage<string>(key.backgroundImage, '');
const hasBackground = !!backgroundImage;
const onRevokeAuth = () => {
dialog.confirm({
title: '退出登录',
@ -48,7 +53,9 @@ const SideBar: React.FC<SideBarProps> = (props) => {
<motion.div
className={clsx(
'overflow-hidden fixed top-0 left-0 h-full z-50 md:static md:shadow-none rounded-r-2xl md:rounded-none',
'bg-content1/70 backdrop-blur-xl backdrop-saturate-150 shadow-xl',
hasBackground
? 'bg-transparent backdrop-blur-md'
: 'bg-content1/70 backdrop-blur-xl backdrop-saturate-150 shadow-xl',
'md:bg-transparent md:backdrop-blur-none md:backdrop-saturate-100 md:shadow-none'
)}
initial={{ width: 0 }}

View File

@ -142,11 +142,13 @@ const SystemStatusDisplay: React.FC<SystemStatusDisplayProps> = ({ data }) => {
systemUsage={Number(data?.cpu.usage.system) || 0}
processUsage={Number(data?.cpu.usage.qq) || 0}
title='CPU占用'
hasBackground={hasBackground}
/>
<UsagePie
systemUsage={memoryUsage.system}
processUsage={memoryUsage.qq}
title='内存占用'
hasBackground={hasBackground}
/>
</div>
</CardBody>

View File

@ -1,4 +1,5 @@
import React, { useMemo } from 'react';
import clsx from 'clsx';
import { useTheme } from '@/hooks/use-theme';
@ -6,12 +7,14 @@ interface UsagePieProps {
systemUsage: number;
processUsage: number;
title?: string;
hasBackground?: boolean;
}
const UsagePie: React.FC<UsagePieProps> = ({
systemUsage,
processUsage,
title,
hasBackground,
}) => {
const { theme } = useTheme();
@ -91,15 +94,24 @@ const UsagePie: React.FC<UsagePieProps> = ({
{/* Center Content */}
<div className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none select-none">
{title && (
<span className="text-[10px] text-default-500 font-medium mb-0.5 opacity-80 uppercase tracking-widest scale-90">
<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="text-2xl font-bold font-mono tracking-tight text-default-900 dark:text-gray-100">
<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="text-xs text-default-400 font-bold">%</span>
<span className={clsx(
"text-xs font-bold",
hasBackground ? 'text-white/60' : 'text-default-400 dark:text-default-500'
)}>%</span>
</div>
</div>
</div>