diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index fb80cb6..91df7f5 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -6,11 +6,13 @@ import { Plus, PanelLeft, Trash2, MoreHorizontal, Loader2, Pencil, Check, X, Bot import { UserMenu } from '@/components/ui/UserMenu'; import { NewChatModal } from '@/components/features/NewChatModal'; import { SearchModal } from '@/components/features/SearchModal'; +import { TagFilter } from '@/components/features/Tags'; import { cn } from '@/lib/utils'; import { useConversations } from '@/hooks/useConversations'; +import { useTagFilter } from '@/hooks/useTags'; import { useAuth } from '@/providers/AuthProvider'; import type { Conversation } from '@/drizzle/schema'; -import { useState, useRef, useEffect, useCallback } from 'react'; +import { useState, useRef, useEffect, useCallback, useMemo } from 'react'; import { useHotkeys } from '@/hooks/useHotkeys'; interface SidebarProps { @@ -22,6 +24,7 @@ export function Sidebar({ isOpen = true }: SidebarProps) { const pathname = usePathname(); const router = useRouter(); const { conversations, loading, deleteConversation, updateConversation } = useConversations(); + const { selectedTags, selectTag, clearFilter, matchesFilter } = useTagFilter(); const { user } = useAuth(); const [menuOpen, setMenuOpen] = useState(null); const [editingId, setEditingId] = useState(null); @@ -32,6 +35,12 @@ export function Sidebar({ isOpen = true }: SidebarProps) { const inputRef = useRef(null); const menuRef = useRef(null); + // 根据标签筛选对话 + const filteredConversations = useMemo(() => { + if (selectedTags.length === 0) return conversations; + return conversations.filter((conv) => matchesFilter(conv.tags as string[] | null)); + }, [conversations, selectedTags, matchesFilter]); + // 聚焦输入框 useEffect(() => { if (editingId && inputRef.current) { @@ -157,8 +166,8 @@ export function Sidebar({ isOpen = true }: SidebarProps) { } }; - // 按时间分组对话 - const groupedConversations = groupConversationsByTime(conversations); + // 按时间分组对话(使用筛选后的列表) + const groupedConversations = groupConversationsByTime(filteredConversations); return ( <> @@ -200,6 +209,17 @@ export function Sidebar({ isOpen = true }: SidebarProps) { + {/* 标签筛选 */} + { + if (tags.length > 0) { + selectTag(tags[0]); + } else { + clearFilter(); + } + }} + /> + {/* 助手库入口 */}
- {conversation.title} +
{conversation.title}
+ {/* 标签 - 极简文字式 */} + {conversation.tags && (conversation.tags as string[]).length > 0 && ( +
+ {(conversation.tags as string[]).slice(0, 3).map((tag, index) => ( + + #{tag}{index < Math.min((conversation.tags as string[]).length, 3) - 1 ? ' ' : ''} + + ))} +
+ )} )}