feat(desktop): modernize download management

This commit is contained in:
NimBold
2026-06-12 20:33:17 +03:30
parent 3074438147
commit a5022fbf8a
9 changed files with 492 additions and 383 deletions
+63 -50
View File
@@ -1,7 +1,6 @@
import React from 'react';
// Force Vite HMR rebuild
import {
Inbox, Zap, CheckCircle2, CircleDashed,
import {
Inbox, Zap, CheckCircle2, CircleDashed,
Film, Music, FileText, Box, Image as ImageIcon, Archive, FileQuestion,
List, CalendarClock, Gauge, Settings
} from 'lucide-react';
@@ -16,8 +15,11 @@ interface SidebarProps {
onSelectFilter: (filter: SidebarFilter) => void;
}
export const Sidebar: React.FC<SidebarProps> = ({ selectedFilter, onSelectFilter }) => {
export const Sidebar: React.FC<SidebarProps> = (props) => {
const selectedFilter = props.selectedFilter;
const onSelectFilter = props.onSelectFilter;
const downloads = useDownloadStore(state => state.downloads);
const activeView = useSettingsStore(state => state.activeView);
const getCount = (filter: SidebarFilter) => {
switch (filter) {
@@ -30,18 +32,22 @@ export const Sidebar: React.FC<SidebarProps> = ({ selectedFilter, onSelectFilter
};
const NavItem = ({ icon: Icon, label, filter }: { icon: any, label: string, filter: SidebarFilter }) => (
<div
className={`flex items-center px-2 py-1.5 rounded-md text-[13px] cursor-default transition-colors mb-0.5 ${
selectedFilter === filter
? 'bg-blue-500/20 text-blue-500'
: 'text-text-secondary hover:bg-item-hover'
<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 ${selectedFilter === filter ? 'opacity-100' : 'opacity-80'}`} />
<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] text-text-muted bg-item-hover px-1.5 py-0.5 rounded-full">
<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>
)}
@@ -49,56 +55,63 @@ export const Sidebar: React.FC<SidebarProps> = ({ selectedFilter, onSelectFilter
);
return (
<div className="w-[220px] min-w-[190px] max-w-[260px] bg-sidebar-bg/80 backdrop-blur-xl border-r border-border-color flex flex-col p-3 pt-8 pb-4 overflow-y-auto relative shrink-0">
<div
className="absolute top-0 left-0 right-0 h-10 z-50"
<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="mb-4 shrink-0 mt-2">
<div className="text-[11px] font-semibold text-text-muted/80 uppercase tracking-wider px-2 mb-1">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>
<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>
<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>
<div className="mb-4 shrink-0">
<div className="text-[11px] font-semibold text-text-muted/80 uppercase tracking-wider px-2 mb-1">Folders</div>
<NavItem icon={Film} label="Video" filter="Video" />
<NavItem icon={Music} label="Audio" filter="Audio" />
<NavItem icon={FileText} label="Documents" filter="Documents" />
<NavItem icon={Box} label="Apps" filter="Apps" />
<NavItem icon={ImageIcon} label="Images" filter="Images" />
<NavItem icon={Archive} label="Archives" filter="Archives" />
<NavItem icon={FileQuestion} label="Other" filter="Other" />
</div>
<div className="mb-5 shrink-0">
<div className="text-[10px] font-bold text-text-muted/60 tracking-widest px-3 mb-2">FOLDERS</div>
<NavItem icon={Film} label="Video" filter="Video" />
<NavItem icon={Music} label="Audio" filter="Audio" />
<NavItem icon={FileText} label="Documents" filter="Documents" />
<NavItem icon={Box} label="Apps" filter="Apps" />
<NavItem icon={ImageIcon} label="Images" filter="Images" />
<NavItem icon={Archive} label="Archives" filter="Archives" />
<NavItem icon={FileQuestion} label="Other" filter="Other" />
</div>
<div className="mb-4 shrink-0">
<div className="text-[11px] font-semibold text-text-muted/80 uppercase tracking-wider px-2 mb-1">Queues</div>
<div className="flex items-center px-2 py-1.5 rounded-md text-[13px] text-text-secondary hover:bg-item-hover cursor-default transition-colors mb-0.5">
<List className="w-4 h-4 mr-2 opacity-80" />
<span>Main Queue</span>
<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} />
<span>Main Queue</span>
</div>
</div>
<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>
</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>
</div>
</div>
<div className="flex-1 min-h-[16px]"></div>
<div className="shrink-0 pb-2">
<div className="text-[11px] font-semibold text-text-muted/80 uppercase tracking-wider px-2 mb-1">Tools</div>
<div className="flex items-center px-2 py-1.5 rounded-md text-[13px] text-text-secondary hover:bg-item-hover cursor-default transition-colors mb-0.5">
<CalendarClock className="w-4 h-4 mr-2 opacity-80" /><span>Scheduler</span>
</div>
<div className="flex items-center px-2 py-1.5 rounded-md text-[13px] text-text-secondary hover:bg-item-hover cursor-default transition-colors mb-0.5">
<Gauge className="w-4 h-4 mr-2 opacity-80" /><span>Speed Limiter</span>
</div>
<div
onClick={() => useSettingsStore.getState().toggleSettingsModal(true)}
className="flex items-center px-2 py-1.5 rounded-md text-[13px] text-text-secondary hover:bg-item-hover cursor-pointer transition-colors"
<div className="shrink-0 pt-4 mt-auto">
<div
onClick={() => useSettingsStore.getState().setActiveView('settings')}
className={`flex items-center px-3 py-2 rounded-md text-[13px] font-medium cursor-pointer transition-colors ${
activeView === 'settings'
? 'bg-[#3B66DE] text-white shadow-sm'
: 'text-text-secondary hover:bg-[#2A2C2F] hover:text-text-primary'
}`}
>
<Settings className="w-4 h-4 mr-2 opacity-80" /><span>Settings</span>
<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>
</div>
</div>