From 31bb3597d299c316cb94e22e57d2b43a311c0a3c Mon Sep 17 00:00:00 2001 From: mike Date: Thu, 5 Feb 2026 09:21:49 -0800 Subject: [PATCH] refactor: improve chat sidebar UI and fix thread ID generation - Simplify ThreadItem component with cleaner hover states - Reset editValue on double-click instead of useEffect sync - Reduce visual noise with smaller icons and tighter spacing - Fix thread ID generation to include counter for uniqueness - Add deduplication logic when loading threads from localStorage Co-Authored-By: Claude Opus 4.5 --- components/features/chat-sidebar.tsx | 294 +++++++++++---------------- lib/hooks/use-chat-threads.ts | 17 +- 2 files changed, 132 insertions(+), 179 deletions(-) diff --git a/components/features/chat-sidebar.tsx b/components/features/chat-sidebar.tsx index 16bf081..5cb7a26 100644 --- a/components/features/chat-sidebar.tsx +++ b/components/features/chat-sidebar.tsx @@ -59,115 +59,91 @@ function ThreadItem({ }; return ( -
- { - e.preventDefault(); - onSelect(); +
+ + + {/* Action buttons - visible on hover */} + {!isEditing && ( +
+ {/* Gradient fade for text truncation */} +
- - {/* Action buttons - visible on hover */} -
- {/* Gradient fade */} -
- - -
+ + +
-
+ )}
); } @@ -192,21 +168,23 @@ function ThreadGroup({ if (threads.length === 0) return null; return ( -
-
- {label} +
+
+ {label} +
+
+ {threads.map((thread) => ( + onSelect(thread.id)} + onDelete={() => onDelete(thread.id)} + onTogglePin={() => onTogglePin(thread.id)} + onRename={(title) => onRename(thread.id, title)} + /> + ))}
- {threads.map((thread) => ( - onSelect(thread.id)} - onDelete={() => onDelete(thread.id)} - onTogglePin={() => onTogglePin(thread.id)} - onRename={(title) => onRename(thread.id, title)} - /> - ))}
); } @@ -220,12 +198,8 @@ export function ChatSidebar({ }: ChatSidebarProps) { const { isSignedIn } = useAuth(); const [searchQuery, setSearchQuery] = useState(""); - const { - groupedThreads, - deleteThread, - togglePin, - renameThread, - } = useChatThreads(); + const { groupedThreads, deleteThread, togglePin, renameThread } = + useChatThreads(); const groups = groupedThreads(); @@ -242,19 +216,14 @@ export function ChatSidebar({ : groups; return ( -
+
{/* Header */} -
+
{/* Logo and close button */} -
+
{/* New Chat button */} -
- -
+ {/* Search */} -
-
- - setSearchQuery(e.target.value)} - className={cn( - "flex-1 bg-transparent", - "text-sm text-foreground placeholder:text-muted-foreground/50", - "focus:outline-none" - )} - /> -
+
+ + setSearchQuery(e.target.value)} + className="flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground/50 focus:outline-none" + />
{/* Thread list */} -
+
{filteredGroups.length > 0 ? ( filteredGroups.map((group) => ( -

+

{searchQuery ? "No matching threads" : "No chat history yet"}

@@ -346,18 +292,13 @@ export function ChatSidebar({ {/* Footer - Login prompt for unauthenticated users */} {!isSignedIn && ( -
+