@@ -7,7 +7,11 @@ import { SelectableList } from './selectable-list'
77import { useSearchableList } from '../hooks/use-searchable-list'
88import { useTerminalLayout } from '../hooks/use-terminal-layout'
99import { useTheme } from '../hooks/use-theme'
10- import { getAllChats , formatRelativeTime } from '../utils/chat-history'
10+ import {
11+ deleteChatSession ,
12+ formatRelativeTime ,
13+ getAllChats ,
14+ } from '../utils/chat-history'
1115
1216import type { SelectableListItem } from './selectable-list'
1317
@@ -21,6 +25,7 @@ const LAYOUT = {
2125 MAX_RENDERED_CHATS : 100 , // Only render this many in the list
2226 TIME_COL_WIDTH : 12 , // e.g., "2 hours ago"
2327 MSGS_COL_WIDTH : 8 , // e.g., "99 msgs"
28+ DELETE_COL_WIDTH : 8 , // e.g., " Delete "
2429 GAP_WIDTH : 3 , // gap between columns
2530} as const
2631
@@ -42,34 +47,37 @@ export const ChatHistoryScreen: React.FC<ChatHistoryScreenProps> = ({
4247 const contentWidth = terminalWidth - LAYOUT . CONTENT_PADDING
4348
4449 // Two-phase loading: load initial chats immediately, then more in background
45- const initialChats = useMemo ( ( ) => getAllChats ( LAYOUT . INITIAL_CHATS ) , [ ] )
46- const [ backgroundChats , setBackgroundChats ] = useState < typeof initialChats > (
47- [ ] ,
48- )
50+ const [ chats , setChats ] = useState ( ( ) => getAllChats ( LAYOUT . INITIAL_CHATS ) )
51+ const [ statusMessage , setStatusMessage ] = useState < string | null > ( null )
4952
5053 // Load more chats in the background after initial render
5154 useEffect ( ( ) => {
5255 // Use setTimeout to defer the expensive loading to after first paint
5356 const timer = setTimeout ( ( ) => {
54- const moreChats = getAllChats (
55- LAYOUT . INITIAL_CHATS + LAYOUT . BACKGROUND_CHATS ,
56- )
57- // Only keep the chats beyond the initial set
58- setBackgroundChats ( moreChats . slice ( LAYOUT . INITIAL_CHATS ) )
57+ setChats ( getAllChats ( LAYOUT . INITIAL_CHATS + LAYOUT . BACKGROUND_CHATS ) )
5958 } , 0 )
6059 return ( ) => clearTimeout ( timer )
6160 } , [ ] )
6261
63- // Combine initial and background chats
64- const chats = useMemo (
65- ( ) => [ ...initialChats , ...backgroundChats ] ,
66- [ initialChats , backgroundChats ] ,
67- )
62+ const handleDeleteChat = useCallback ( ( chatId : string ) => {
63+ const deleted = deleteChatSession ( chatId )
64+ if ( deleted ) {
65+ setChats ( ( prev ) => prev . filter ( ( chat ) => chat . chatId !== chatId ) )
66+ setStatusMessage ( 'Chat deleted' )
67+ return
68+ }
69+
70+ setStatusMessage ( 'Could not delete chat' )
71+ } , [ ] )
6872
6973 // Calculate available width for the prompt text (last column, variable width)
70- // Format: "[time] [msgs] [prompt...]"
74+ // Format: "[time] [msgs] [prompt...] [Delete] "
7175 const reservedWidth =
72- LAYOUT . TIME_COL_WIDTH + LAYOUT . MSGS_COL_WIDTH + LAYOUT . GAP_WIDTH * 2 + 2 // +2 for padding
76+ LAYOUT . TIME_COL_WIDTH +
77+ LAYOUT . MSGS_COL_WIDTH +
78+ LAYOUT . DELETE_COL_WIDTH +
79+ LAYOUT . GAP_WIDTH * 2 +
80+ 2 // +2 for padding
7381 const maxPromptWidth = Math . max ( 20 , contentWidth - reservedWidth )
7482
7583 // Truncate text to fit single line
@@ -146,6 +154,13 @@ export const ChatHistoryScreen: React.FC<ChatHistoryScreenProps> = ({
146154 [ onSelectChat ] ,
147155 )
148156
157+ const handleChatDelete = useCallback (
158+ ( item : SelectableListItem ) => {
159+ handleDeleteChat ( item . id )
160+ } ,
161+ [ handleDeleteChat ] ,
162+ )
163+
149164 // Handle keyboard input
150165 const handleKeyIntercept = useCallback (
151166 ( key : { name ?: string ; shift ?: boolean ; ctrl ?: boolean } ) => {
@@ -275,9 +290,11 @@ export const ChatHistoryScreen: React.FC<ChatHistoryScreenProps> = ({
275290 items = { filteredItems . slice ( 0 , LAYOUT . MAX_RENDERED_CHATS ) }
276291 focusedIndex = { focusedIndex }
277292 onSelect = { handleChatSelect }
293+ actionLabel = "Delete"
294+ onAction = { handleChatDelete }
278295 onFocusChange = { handleFocusChange }
279296 emptyMessage = {
280- initialChats . length === 0
297+ chats . length === 0
281298 ? 'No chat history yet'
282299 : searchQuery
283300 ? 'No matching chats'
@@ -314,8 +331,14 @@ export const ChatHistoryScreen: React.FC<ChatHistoryScreenProps> = ({
314331 { /* Help text */ }
315332 < box style = { { flexGrow : 1 , flexShrink : 1 } } >
316333 < text style = { { fg : theme . muted } } >
317- ↑↓ navigate · Enter select · Esc cancel
334+ ↑↓ navigate · Enter select · Click Delete to remove · Esc cancel
318335 </ text >
336+ { statusMessage && (
337+ < text style = { { fg : theme . muted } } >
338+ { ' · ' }
339+ { statusMessage }
340+ </ text >
341+ ) }
319342 </ box >
320343
321344 { /* Buttons - hidden on narrow screens */ }
0 commit comments