11import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
22import { useExtensionState } from "@/context/ExtensionStateContext"
33import { vscode } from "@/utils/vscode"
4- import { memo } from "react"
4+ import { memo , useState } from "react"
55import { TaskServiceClient } from "@/services/grpc-client"
66import { formatLargeNumber } from "@/utils/format"
77
@@ -11,10 +11,16 @@ type HistoryPreviewProps = {
1111
1212const HistoryPreview = ( { showHistoryView } : HistoryPreviewProps ) => {
1313 const { taskHistory } = useExtensionState ( )
14+ const [ isExpanded , setIsExpanded ] = useState ( true )
15+
1416 const handleHistorySelect = ( id : string ) => {
1517 TaskServiceClient . showTaskWithId ( { value : id } ) . catch ( ( error ) => console . error ( "Error showing task:" , error ) )
1618 }
1719
20+ const toggleExpanded = ( ) => {
21+ setIsExpanded ( ! isExpanded )
22+ }
23+
1824 const formatDate = ( timestamp : number ) => {
1925 const date = new Date ( timestamp )
2026 return date
@@ -48,16 +54,31 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => {
4854 opacity: 1;
4955 pointer-events: auto;
5056 }
57+ .history-header {
58+ cursor: pointer;
59+ user-select: none;
60+ }
61+ .history-header:hover {
62+ opacity: 0.8;
63+ }
5164 ` }
5265 </ style >
5366
5467 < div
68+ className = "history-header"
69+ onClick = { toggleExpanded }
5570 style = { {
5671 color : "var(--vscode-descriptionForeground)" ,
5772 margin : "10px 20px 10px 20px" ,
5873 display : "flex" ,
5974 alignItems : "center" ,
6075 } } >
76+ < span
77+ className = { `codicon codicon-chevron-${ isExpanded ? "down" : "right" } ` }
78+ style = { {
79+ marginRight : "4px" ,
80+ transform : "scale(0.9)" ,
81+ } } > </ span >
6182 < span
6283 className = "codicon codicon-comment-discussion"
6384 style = { {
@@ -74,102 +95,122 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => {
7495 </ span >
7596 </ div >
7697
77- < div style = { { padding : "0px 20px 0 20px" } } >
78- { taskHistory
79- . filter ( ( item ) => item . ts && item . task )
80- . slice ( 0 , 3 )
81- . map ( ( item ) => (
82- < div key = { item . id } className = "history-preview-item" onClick = { ( ) => handleHistorySelect ( item . id ) } >
83- < div style = { { padding : "12px" } } >
84- < div style = { { marginBottom : "8px" } } >
85- < span
86- style = { {
87- color : "var(--vscode-descriptionForeground)" ,
88- fontWeight : 500 ,
89- fontSize : "0.85em" ,
90- textTransform : "uppercase" ,
91- } } >
92- { formatDate ( item . ts ) }
93- </ span >
94- </ div >
95- { item . isFavorited && (
98+ { isExpanded && (
99+ < div style = { { padding : "0px 20px 0 20px" } } >
100+ { taskHistory . filter ( ( item ) => item . ts && item . task ) . length > 0 ? (
101+ < >
102+ { taskHistory
103+ . filter ( ( item ) => item . ts && item . task )
104+ . slice ( 0 , 3 )
105+ . map ( ( item ) => (
96106 < div
97- style = { {
98- position : "absolute" ,
99- top : "12px" ,
100- right : "12px" ,
101- color : "var(--vscode-button-background)" ,
102- } } >
103- < span className = "codicon codicon-star-full" aria-label = "Favorited" />
104- </ div >
105- ) }
107+ key = { item . id }
108+ className = "history-preview-item"
109+ onClick = { ( ) => handleHistorySelect ( item . id ) } >
110+ < div style = { { padding : "12px" } } >
111+ < div style = { { marginBottom : "8px" } } >
112+ < span
113+ style = { {
114+ color : "var(--vscode-descriptionForeground)" ,
115+ fontWeight : 500 ,
116+ fontSize : "0.85em" ,
117+ textTransform : "uppercase" ,
118+ } } >
119+ { formatDate ( item . ts ) }
120+ </ span >
121+ </ div >
122+ { item . isFavorited && (
123+ < div
124+ style = { {
125+ position : "absolute" ,
126+ top : "12px" ,
127+ right : "12px" ,
128+ color : "var(--vscode-button-background)" ,
129+ } } >
130+ < span className = "codicon codicon-star-full" aria-label = "Favorited" />
131+ </ div >
132+ ) }
106133
107- < div
108- id = { `history-preview-task-${ item . id } ` }
109- className = "history-preview-task"
110- style = { {
111- fontSize : "var(--vscode-font-size)" ,
112- color : "var(--vscode-descriptionForeground)" ,
113- marginBottom : "8px" ,
114- display : "-webkit-box" ,
115- WebkitLineClamp : 3 ,
116- WebkitBoxOrient : "vertical" ,
117- overflow : "hidden" ,
118- whiteSpace : "pre-wrap" ,
119- wordBreak : "break-word" ,
120- overflowWrap : "anywhere" ,
121- } } >
122- < span className = "ph-no-capture" > { item . task } </ span >
123- </ div >
124- < div
134+ < div
135+ id = { `history-preview-task-${ item . id } ` }
136+ className = "history-preview-task"
137+ style = { {
138+ fontSize : "var(--vscode-font-size)" ,
139+ color : "var(--vscode-descriptionForeground)" ,
140+ marginBottom : "8px" ,
141+ display : "-webkit-box" ,
142+ WebkitLineClamp : 3 ,
143+ WebkitBoxOrient : "vertical" ,
144+ overflow : "hidden" ,
145+ whiteSpace : "pre-wrap" ,
146+ wordBreak : "break-word" ,
147+ overflowWrap : "anywhere" ,
148+ } } >
149+ < span className = "ph-no-capture" > { item . task } </ span >
150+ </ div >
151+ < div
152+ style = { {
153+ fontSize : "0.85em" ,
154+ color : "var(--vscode-descriptionForeground)" ,
155+ } } >
156+ < span >
157+ Tokens: ↑{ formatLargeNumber ( item . tokensIn || 0 ) } ↓
158+ { formatLargeNumber ( item . tokensOut || 0 ) }
159+ </ span >
160+ { ! ! item . cacheWrites && (
161+ < >
162+ { " • " }
163+ < span >
164+ Cache: +{ formatLargeNumber ( item . cacheWrites || 0 ) } →{ " " }
165+ { formatLargeNumber ( item . cacheReads || 0 ) }
166+ </ span >
167+ </ >
168+ ) }
169+ { ! ! item . totalCost && (
170+ < >
171+ { " • " }
172+ < span > API Cost: ${ item . totalCost ?. toFixed ( 4 ) } </ span >
173+ </ >
174+ ) }
175+ </ div >
176+ </ div >
177+ </ div >
178+ ) ) }
179+ < div
180+ style = { {
181+ display : "flex" ,
182+ alignItems : "center" ,
183+ justifyContent : "center" ,
184+ } } >
185+ < VSCodeButton
186+ appearance = "icon"
187+ onClick = { ( ) => showHistoryView ( ) }
125188 style = { {
126- fontSize : "0.85em" ,
127- color : "var(--vscode-descriptionForeground)" ,
189+ opacity : 0.9 ,
128190 } } >
129- < span >
130- Tokens: ↑{ formatLargeNumber ( item . tokensIn || 0 ) } ↓{ formatLargeNumber ( item . tokensOut || 0 ) }
131- </ span >
132- { ! ! item . cacheWrites && (
133- < >
134- { " • " }
135- < span >
136- Cache: +{ formatLargeNumber ( item . cacheWrites || 0 ) } →{ " " }
137- { formatLargeNumber ( item . cacheReads || 0 ) }
138- </ span >
139- </ >
140- ) }
141- { ! ! item . totalCost && (
142- < >
143- { " • " }
144- < span > API Cost: ${ item . totalCost ?. toFixed ( 4 ) } </ span >
145- </ >
146- ) }
147- </ div >
191+ < div
192+ style = { {
193+ fontSize : "var(--vscode-font-size)" ,
194+ color : "var(--vscode-descriptionForeground)" ,
195+ } } >
196+ View all history
197+ </ div >
198+ </ VSCodeButton >
148199 </ div >
149- </ div >
150- ) ) }
151- < div
152- style = { {
153- display : "flex" ,
154- alignItems : "center" ,
155- justifyContent : "center" ,
156- } } >
157- < VSCodeButton
158- appearance = "icon"
159- onClick = { ( ) => showHistoryView ( ) }
160- style = { {
161- opacity : 0.9 ,
162- } } >
200+ </ >
201+ ) : (
163202 < div
164203 style = { {
165- fontSize : "var(--vscode-font-size) " ,
204+ textAlign : "center " ,
166205 color : "var(--vscode-descriptionForeground)" ,
206+ fontSize : "var(--vscode-font-size)" ,
207+ padding : "10px 0" ,
167208 } } >
168- View all history
209+ No recent tasks
169210 </ div >
170- </ VSCodeButton >
211+ ) }
171212 </ div >
172- </ div >
213+ ) }
173214 </ div >
174215 )
175216}
0 commit comments