import { type ReactNode } from 'react'; import { Folder, MessageSquare, Search } from 'lucide-react'; import type { TFunction } from 'i18next'; import { ScrollArea } from '../../../../shared/view/ui'; import type { Project } from '../../../../types/app'; import type { ReleaseInfo } from '../../../../types/sharedTypes'; import type { ConversationSearchResults, SearchProgress } from '../../hooks/useSidebarController'; import SidebarFooter from './SidebarFooter'; import SidebarHeader from './SidebarHeader'; import SidebarProjectList, { type SidebarProjectListProps } from './SidebarProjectList'; type SearchMode = 'projects' | 'conversations'; function HighlightedSnippet({ snippet, highlights }: { snippet: string; highlights: { start: number; end: number }[] }) { const parts: ReactNode[] = []; let cursor = 0; for (const h of highlights) { if (h.start > cursor) { parts.push(snippet.slice(cursor, h.start)); } parts.push( {snippet.slice(h.start, h.end)} ); cursor = h.end; } if (cursor < snippet.length) { parts.push(snippet.slice(cursor)); } return ( {parts} ); } type SidebarContentProps = { isPWA: boolean; isMobile: boolean; isLoading: boolean; projects: Project[]; searchFilter: string; onSearchFilterChange: (value: string) => void; onClearSearchFilter: () => void; searchMode: SearchMode; onSearchModeChange: (mode: SearchMode) => void; conversationResults: ConversationSearchResults | null; isSearching: boolean; searchProgress: SearchProgress | null; onConversationResultClick: (projectName: string, sessionId: string, provider: string, messageTimestamp?: string | null, messageSnippet?: string | null) => void; onRefresh: () => void; isRefreshing: boolean; onCreateProject: () => void; onCollapseSidebar: () => void; updateAvailable: boolean; releaseInfo: ReleaseInfo | null; latestVersion: string | null; currentVersion: string; onShowVersionModal: () => void; onShowSettings: () => void; projectListProps: SidebarProjectListProps; t: TFunction; }; export default function SidebarContent({ isPWA, isMobile, isLoading, projects, searchFilter, onSearchFilterChange, onClearSearchFilter, searchMode, onSearchModeChange, conversationResults, isSearching, searchProgress, onConversationResultClick, onRefresh, isRefreshing, onCreateProject, onCollapseSidebar, updateAvailable, releaseInfo, latestVersion, currentVersion, onShowVersionModal, onShowSettings, projectListProps, t, }: SidebarContentProps) { const showConversationSearch = searchMode === 'conversations' && searchFilter.trim().length >= 2; const hasPartialResults = conversationResults && conversationResults.results.length > 0; return (
{t('search.searching')}
{searchProgress && ({t('search.projectsScanned', { count: searchProgress.scannedProjects })}/{searchProgress.totalProjects}
)}{t('search.tryDifferentQuery')}
{t('search.matches', { count: conversationResults.totalMatches })}
{isSearching && searchProgress && ({searchProgress.scannedProjects}/{searchProgress.totalProjects}