feat(desktop): align UI with SwiftUI

This commit is contained in:
NimBold
2026-06-12 20:59:49 +03:30
parent a5022fbf8a
commit 4c21a36083
8 changed files with 329 additions and 234 deletions
+62 -59
View File
@@ -2,11 +2,11 @@ import React from 'react';
import {
Inbox, Zap, CheckCircle2, CircleDashed,
Film, Music, FileText, Box, Image as ImageIcon, Archive, FileQuestion,
List, CalendarClock, Gauge, Settings
List, CalendarClock, Gauge, Settings, Plus
} from 'lucide-react';
import { useDownloadStore, DownloadCategory } from '../store/useDownloadStore';
import { useSettingsStore } from '../store/useSettingsStore';
import { getCurrentWindow } from '@tauri-apps/api/window';
import { WindowDragRegion } from './WindowDragRegion';
export type SidebarFilter = 'all' | 'active' | 'completed' | 'unfinished' | DownloadCategory | 'settings';
@@ -31,49 +31,46 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
}
};
const NavItem = ({ icon: Icon, label, filter }: { icon: any, label: string, filter: SidebarFilter }) => (
<div
className={`flex items-center px-3 py-1.5 rounded-md text-[13px] cursor-default transition-colors mb-[2px] ${
selectedFilter === filter
? 'bg-[#3B66DE] text-white shadow-sm font-medium'
: 'text-text-secondary hover:bg-item-hover hover:text-text-primary font-medium'
}`}
onClick={() => onSelectFilter(filter)}
>
<Icon className={`w-4 h-4 mr-2.5 ${selectedFilter === filter ? 'opacity-100 text-white' : 'opacity-70'}`} strokeWidth={selectedFilter === filter ? 2.5 : 2} />
<span>{label}</span>
{getCount(filter) > 0 && (
<span className={`ml-auto text-[11px] font-bold px-1.5 py-0.5 rounded-full ${
selectedFilter === filter
? 'bg-black/20 text-white'
: 'bg-item-hover text-text-muted group-hover:bg-black/10'
}`}>
{getCount(filter)}
</span>
)}
</div>
);
const NavItem = ({ icon: Icon, label, filter }: { icon: any, label: string, filter: SidebarFilter }) => {
const isSelected = activeView === 'downloads' && selectedFilter === filter;
return (
<button
type="button"
className={`group flex w-full items-center px-2.5 py-1.5 rounded-lg text-[13px] text-left cursor-default transition-colors mb-0.5 ${
isSelected
? 'bg-accent text-white font-medium'
: 'text-text-primary hover:bg-item-hover'
}`}
onClick={() => onSelectFilter(filter)}
>
<Icon className={`w-4 h-4 mr-2 ${isSelected ? 'text-white' : 'text-text-secondary'}`} strokeWidth={isSelected ? 2.25 : 2} />
<span className="truncate">{label}</span>
{getCount(filter) > 0 && (
<span className={`ml-auto min-w-5 px-1.5 py-0.5 rounded-full text-center text-[10px] leading-none font-semibold ${
isSelected ? 'bg-black/20 text-white' : 'bg-item-hover text-text-secondary'
}`}>
{getCount(filter)}
</span>
)}
</button>
);
};
return (
<div className="w-[220px] min-w-[190px] max-w-[260px] bg-[#1E1E20] border-r border-border-color flex flex-col p-2.5 pt-8 pb-4 relative shrink-0">
<div
className="absolute top-0 left-0 right-0 h-10 z-50"
data-tauri-drag-region
onPointerDown={(e) => {
if (e.button === 0) getCurrentWindow().startDragging();
}}
/>
<div className="overflow-y-auto flex-1 flex flex-col hide-scrollbar">
<div className="mb-5 shrink-0 mt-2">
<div className="text-[10px] font-bold text-text-muted/60 tracking-widest px-3 mb-2">LIBRARY</div>
<aside className="w-[220px] min-w-[190px] max-w-[260px] bg-sidebar-bg border-r border-border-color flex flex-col relative shrink-0">
<WindowDragRegion />
<div className="overflow-y-auto flex-1 px-2 pb-3">
<section className="mb-4">
<div className="text-[11px] font-semibold text-text-muted px-2.5 mb-1.5">Library</div>
<NavItem icon={Inbox} label="All" filter="all" />
<NavItem icon={Zap} label="Active" filter="active" />
<NavItem icon={CheckCircle2} label="Completed" filter="completed" />
<NavItem icon={CircleDashed} label="Unfinished" filter="unfinished" />
</div>
</section>
<div className="mb-5 shrink-0">
<div className="text-[10px] font-bold text-text-muted/60 tracking-widest px-3 mb-2">FOLDERS</div>
<section className="mb-4">
<div className="text-[11px] font-semibold text-text-muted px-2.5 mb-1.5">Folders</div>
<NavItem icon={Film} label="Video" filter="Video" />
<NavItem icon={Music} label="Audio" filter="Audio" />
<NavItem icon={FileText} label="Documents" filter="Documents" />
@@ -81,39 +78,45 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
<NavItem icon={ImageIcon} label="Images" filter="Images" />
<NavItem icon={Archive} label="Archives" filter="Archives" />
<NavItem icon={FileQuestion} label="Other" filter="Other" />
</div>
</section>
<div className="mb-5 shrink-0">
<div className="text-[10px] font-bold text-text-muted/60 tracking-widest px-3 mb-2">QUEUES</div>
<div className="flex items-center px-3 py-1.5 rounded-md text-[13px] font-medium text-text-secondary hover:bg-item-hover hover:text-text-primary cursor-default transition-colors mb-[2px]">
<List className="w-4 h-4 mr-2.5 opacity-70" strokeWidth={2} />
<section className="mb-4">
<div className="text-[11px] font-semibold text-text-muted px-2.5 mb-1.5">Queues</div>
<div className="flex items-center px-2.5 py-1.5 rounded-lg text-[13px] text-text-primary hover:bg-item-hover cursor-default transition-colors mb-0.5">
<List className="w-4 h-4 mr-2 text-text-secondary" strokeWidth={2} />
<span>Main Queue</span>
</div>
</div>
<div className="flex items-center px-2.5 py-1.5 rounded-lg text-[13px] text-text-secondary hover:bg-item-hover cursor-default transition-colors">
<Plus className="w-4 h-4 mr-2" strokeWidth={2} />
<span>Add new queue</span>
</div>
</section>
<div className="shrink-0 pb-2">
<div className="text-[10px] font-bold text-text-muted/60 tracking-widest px-3 mb-2">TOOLS</div>
<div className="flex items-center px-3 py-1.5 rounded-md text-[13px] font-medium text-text-secondary hover:bg-item-hover hover:text-text-primary cursor-default transition-colors mb-[2px]">
<CalendarClock className="w-4 h-4 mr-2.5 opacity-70" strokeWidth={2} /><span>Scheduler</span>
<section>
<div className="text-[11px] font-semibold text-text-muted px-2.5 mb-1.5">Tools</div>
<div className="flex items-center px-2.5 py-1.5 rounded-lg text-[13px] text-text-primary hover:bg-item-hover cursor-default transition-colors mb-0.5">
<CalendarClock className="w-4 h-4 mr-2 text-text-secondary" strokeWidth={2} /><span>Scheduler</span>
</div>
<div className="flex items-center px-3 py-1.5 rounded-md text-[13px] font-medium text-text-secondary hover:bg-item-hover hover:text-text-primary cursor-default transition-colors mb-[2px]">
<Gauge className="w-4 h-4 mr-2.5 opacity-70" strokeWidth={2} /><span>Speed Limiter</span>
<div className="flex items-center px-2.5 py-1.5 rounded-lg text-[13px] text-text-primary hover:bg-item-hover cursor-default transition-colors">
<Gauge className="w-4 h-4 mr-2 text-text-secondary" strokeWidth={2} /><span>Speed Limiter</span>
</div>
</div>
</section>
</div>
<div className="shrink-0 pt-4 mt-auto">
<div
<div className="shrink-0 border-t border-border-color bg-sidebar-glass px-2 py-2 backdrop-blur-xl">
<button
type="button"
onClick={() => useSettingsStore.getState().setActiveView('settings')}
className={`flex items-center px-3 py-2 rounded-md text-[13px] font-medium cursor-pointer transition-colors ${
className={`flex w-full items-center px-2.5 py-2 rounded-lg text-[13px] text-left cursor-default transition-colors ${
activeView === 'settings'
? 'bg-[#3B66DE] text-white shadow-sm'
: 'text-text-secondary hover:bg-[#2A2C2F] hover:text-text-primary'
? 'bg-accent text-white font-medium'
: 'text-text-primary hover:bg-item-hover'
}`}
>
<Settings className={`w-4 h-4 mr-2.5 ${activeView === 'settings' ? 'opacity-100' : 'opacity-70'}`} strokeWidth={activeView === 'settings' ? 2.5 : 2} /><span>Settings</span>
</div>
<Settings className={`w-4 h-4 mr-2 ${activeView === 'settings' ? 'text-white' : 'text-text-secondary'}`} strokeWidth={activeView === 'settings' ? 2.25 : 2} />
<span>Settings</span>
</button>
</div>
</div>
</aside>
);
};