diff --git a/src/client/components/SearchBar.tsx b/src/client/components/SearchBar.tsx index 779fbba..6e5d9d1 100644 --- a/src/client/components/SearchBar.tsx +++ b/src/client/components/SearchBar.tsx @@ -107,7 +107,7 @@ export function SearchBar({ const showControls = !!localQuery || !!query; return ( -
+
{/* Unified search container */}
setIsFocused(true)} onBlur={() => setIsFocused(false)} placeholder="Search messages..." - className="flex-1 min-w-0 bg-transparent px-2.5 py-2 text-body text-foreground + className="flex-1 min-w-0 bg-transparent pl-3 pr-2.5 py-2 text-body text-foreground placeholder:text-foreground-muted focus:outline-none" /> diff --git a/src/client/components/SessionList.tsx b/src/client/components/SessionList.tsx index 0de3bf9..375cd05 100644 --- a/src/client/components/SessionList.tsx +++ b/src/client/components/SessionList.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useMemo } from "react"; import type { SessionEntry } from "../lib/types"; interface Props { @@ -11,13 +11,16 @@ interface Props { export function SessionList({ sessions, loading, selectedId, onSelect }: Props) { const [selectedProject, setSelectedProject] = useState(null); - // Group by project - const grouped = new Map(); - for (const session of sessions) { - const group = grouped.get(session.project) || []; - group.push(session); - grouped.set(session.project, group); - } + // Group by project (memoized to avoid recomputing on unrelated rerenders) + const grouped = useMemo(() => { + const map = new Map(); + for (const session of sessions) { + const group = map.get(session.project) || []; + group.push(session); + map.set(session.project, group); + } + return map; + }, [sessions]); // Auto-select project when selectedId changes useEffect(() => { @@ -73,7 +76,7 @@ export function SessionList({ sessions, loading, selectedId, onSelect }: Props)
{formatProjectName(selectedProject)}
-
+
{projectSessions.map((session, idx) => { const isSelected = selectedId === session.id; return ( @@ -81,13 +84,13 @@ export function SessionList({ sessions, loading, selectedId, onSelect }: Props) key={session.id} onClick={() => onSelect(session.id)} className={` - w-full text-left mx-2 my-0.5 px-3 py-2.5 rounded-lg transition-all duration-200 + w-full text-left my-0.5 px-3 py-2.5 rounded-lg transition-all duration-200 ${isSelected ? "bg-accent-light shadow-glow-accent ring-1 ring-accent/25" : "hover:bg-surface-overlay" } `} - style={{ width: "calc(100% - 1rem)", animationDelay: `${idx * 30}ms` }} + style={{ animationDelay: `${idx * 30}ms` }} >
{session.summary || session.firstPrompt || "Untitled Session"} @@ -113,7 +116,7 @@ export function SessionList({ sessions, loading, selectedId, onSelect }: Props) // Project list return ( -
+
{[...grouped.entries()].map(([project, projectSessions]) => { const latest = projectSessions.reduce((a, b) => (a.modified || a.created) > (b.modified || b.created) ? a : b @@ -123,8 +126,7 @@ export function SessionList({ sessions, loading, selectedId, onSelect }: Props)