import React, { useState, useEffect, useRef } from 'react'; import { Inbox, Zap, CheckCircle2, CircleDashed, Film, Music, FileText, Box, Image as ImageIcon, Archive, FileQuestion, List, CalendarClock, Gauge, Settings, Plus, Play, Pause, Edit2, Trash2, PanelLeft, type LucideIcon } from 'lucide-react'; import { useDownloadStore, DownloadCategory, Queue } from '../store/useDownloadStore'; import { ActiveView, useSettingsStore } from '../store/useSettingsStore'; import { WindowDragRegion } from './WindowDragRegion'; export type SidebarFilter = 'all' | 'active' | 'completed' | 'unfinished' | DownloadCategory | 'settings' | string; interface SidebarProps { selectedFilter: SidebarFilter; onSelectFilter: (filter: SidebarFilter) => void; } export const Sidebar: React.FC = (props) => { const { selectedFilter, onSelectFilter } = props; const { downloads, queues, addQueue, renameQueue, removeQueue, startQueue, pauseQueue } = useDownloadStore(); const { activeView, setActiveView, toggleSidebar } = useSettingsStore(); const [isAddingQueue, setIsAddingQueue] = useState(false); const [newQueueName, setNewQueueName] = useState(''); const [renamingQueueId, setRenamingQueueId] = useState(null); const [editingQueueName, setEditingQueueName] = useState(''); const [contextMenu, setContextMenu] = useState<{ x: number; y: number; id: string } | null>(null); const addInputRef = useRef(null); const renameInputRef = useRef(null); useEffect(() => { const handleCloseMenu = () => setContextMenu(null); window.addEventListener('click', handleCloseMenu); return () => window.removeEventListener('click', handleCloseMenu); }, []); useEffect(() => { if (isAddingQueue) addInputRef.current?.focus(); }, [isAddingQueue]); useEffect(() => { if (renamingQueueId) renameInputRef.current?.focus(); }, [renamingQueueId]); const getCount = (filter: SidebarFilter) => { if (filter.startsWith('queue:')) { const qid = filter.replace('queue:', ''); return downloads.filter(d => d.queueId === qid).length; } switch (filter) { case 'all': return downloads.length; case 'active': return downloads.filter(d => d.status === 'downloading').length; case 'completed': return downloads.filter(d => d.status === 'completed').length; case 'unfinished': return downloads.filter(d => d.status !== 'completed').length; default: return downloads.filter(d => d.category === filter as DownloadCategory).length; } }; const NavItem = ({ icon: Icon, label, filter }: { icon: LucideIcon, label: string, filter: SidebarFilter }) => { const isSelected = activeView === 'downloads' && selectedFilter === filter; return ( ); }; const handleQueueContextMenu = (e: React.MouseEvent, id: string) => { e.preventDefault(); e.stopPropagation(); setContextMenu({ x: e.clientX, y: e.clientY, id }); }; const handleAddQueueSubmit = () => { if (newQueueName.trim()) addQueue(newQueueName.trim()); setNewQueueName(''); setIsAddingQueue(false); }; const handleRenameQueueSubmit = () => { if (renamingQueueId && editingQueueName.trim()) { renameQueue(renamingQueueId, editingQueueName.trim()); } setRenamingQueueId(null); }; const QueueItem = ({ queue }: { queue: Queue }) => { const filterId = `queue:${queue.id}`; const isSelected = activeView === 'downloads' && selectedFilter === filterId; const isRenaming = renamingQueueId === queue.id; if (isRenaming) { return (
setEditingQueueName(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') handleRenameQueueSubmit(); if (e.key === 'Escape') setRenamingQueueId(null); }} onBlur={handleRenameQueueSubmit} />
); } return ( ); }; const ToolItem = ({ icon: Icon, label, view }: { icon: LucideIcon; label: string; view: ActiveView }) => { const isSelected = activeView === view; return ( ); }; return ( ); };