mirror of
https://github.com/nimbold/Firelink.git
synced 2026-09-04 15:05:22 +00:00
feat(desktop): align UI with SwiftUI
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user