diff --git a/web/app/src/components/conversations/ConversationSplitView.tsx b/web/app/src/components/conversations/ConversationSplitView.tsx index ce0cf795d5..545b1affa3 100644 --- a/web/app/src/components/conversations/ConversationSplitView.tsx +++ b/web/app/src/components/conversations/ConversationSplitView.tsx @@ -3,7 +3,7 @@ import { useState, useEffect, useCallback, useMemo, useRef } from 'react'; import { useSearchParams } from 'next/navigation'; import { motion, AnimatePresence } from 'framer-motion'; -import { MessageSquare, Search as SearchIcon, CheckSquare, X } from 'lucide-react'; +import { MessageSquare, Search as SearchIcon, CheckSquare, X, FilterX } from 'lucide-react'; import { cn } from '@/lib/utils'; import { useConversations } from '@/hooks/useConversations'; import { useConversation } from '@/hooks/useConversation'; @@ -70,6 +70,9 @@ export function ConversationSplitView() { // Resizable panel width const [panelWidth, setPanelWidth] = useLocalStorage('omi-panel-width', DEFAULT_PANEL_WIDTH); + // Filter state for short conversations + const [hideShort, setHideShort] = useLocalStorage('omi-hide-short', true); + // Selection mode state (for merge feature) const [isSelectionMode, setIsSelectionMode] = useState(false); const [selectedIds, setSelectedIds] = useState>(new Set()); @@ -184,6 +187,11 @@ export function ConversationSplitView() { if (!isSearching || searchResults.length === 0) return {}; return searchResults.reduce((groups, conversation) => { + // Filter out short conversations if enabled + if (hideShort && conversation.transcript_segments.length < 5) { + return groups; + } + const date = new Date(conversation.started_at || conversation.created_at); const dateKey = formatRelativeDate(date); @@ -193,23 +201,37 @@ export function ConversationSplitView() { groups[dateKey].push(conversation); return groups; }, {} as Record); - }, [isSearching, searchResults]); + }, [isSearching, searchResults, hideShort]); - // Filter conversations for starred folder const displayedGroupedConversations = useMemo(() => { + let filteredGroups: Record = {}; + if (selectedFolderId === FOLDER_STARRED) { // Filter for starred conversations only - const starredGroups: Record = {}; for (const [date, convs] of Object.entries(groupedConversations)) { const starredConvs = convs.filter(c => c.starred); if (starredConvs.length > 0) { - starredGroups[date] = starredConvs; + filteredGroups[date] = starredConvs; } } - return starredGroups; + } else { + filteredGroups = groupedConversations; } - return groupedConversations; - }, [selectedFolderId, groupedConversations]); + + // Apply "hide short" filter if enabled + if (hideShort) { + const shortFiltered: Record = {}; + for (const [date, convs] of Object.entries(filteredGroups)) { + const keptConvs = convs.filter(c => c.transcript_segments.length >= 5); + if (keptConvs.length > 0) { + shortFiltered[date] = keptConvs; + } + } + return shortFiltered; + } + + return filteredGroups; + }, [selectedFolderId, groupedConversations, hideShort]); // Get the conversations to display (search results or regular list, with folder filtering) const displayedConversations = isSearching ? searchGroupedConversations : displayedGroupedConversations; @@ -568,6 +590,19 @@ export function ConversationSplitView() { placeholder="Search conversations..." className="flex-1" /> + {/* Hide Short Conversations Toggle */} + )}