1
1
import { isToday , isYesterday , isWithinInterval , subDays } from "date-fns" ;
2
- import { dummyThreads } from "../utils/dummy" ;
3
2
import { TooltipIconButton } from "./ui/assistant-ui/tooltip-icon-button" ;
4
3
import { Button } from "./ui/button" ;
5
- import { SquarePen , History } from "lucide-react" ;
4
+ import { SquarePen , History , Trash2 } from "lucide-react" ;
6
5
import { Sheet , SheetContent , SheetTrigger } from "./ui/sheet" ;
7
6
import { ThreadActual } from "../hooks/useThreads" ;
8
7
import { useToast } from "../hooks/use-toast" ;
9
8
import { Skeleton } from "./ui/skeleton" ;
9
+ import { useEffect , useState } from "react" ;
10
10
11
11
interface ThreadHistoryProps {
12
12
isUserThreadsLoading : boolean ;
@@ -15,46 +15,76 @@ interface ThreadHistoryProps {
15
15
userThreads : ThreadActual [ ] ;
16
16
userId : string | undefined ;
17
17
createThread : ( id : string ) => Promise < any > ;
18
+ clearMessages : ( ) => void ;
18
19
assistantId : string | undefined ;
19
20
switchSelectedThread : ( thread : ThreadActual ) => void ;
20
21
getUserThreads : ( id : string ) => Promise < void > ;
22
+ deleteThread : ( id : string ) => Promise < void > ;
21
23
}
22
24
23
25
interface ThreadProps {
24
26
id : string ;
25
27
onClick : ( ) => void ;
28
+ onDelete : ( ) => void ;
26
29
label : string ;
27
30
createdAt : Date ;
28
31
}
29
32
30
- const Thread = ( props : ThreadProps ) => (
31
- < Button
32
- className = "px-2 hover:bg-[#393939] hover:text-white justify-start"
33
- size = "sm"
34
- variant = "ghost"
35
- onClick = { props . onClick }
36
- >
37
- < p className = "truncate ... text-sm font-light" > { props . label } </ p >
38
- </ Button >
39
- ) ;
33
+ const Thread = ( props : ThreadProps ) => {
34
+ const [ isHovering , setIsHovering ] = useState ( false ) ;
35
+
36
+ return (
37
+ < div
38
+ className = "flex flex-row gap-0 items-center justify-start w-full"
39
+ onMouseEnter = { ( ) => setIsHovering ( true ) }
40
+ onMouseLeave = { ( ) => setIsHovering ( false ) }
41
+ >
42
+ < Button
43
+ className = "px-2 hover:bg-[#393939] hover:text-white justify-start items-center flex-grow min-w-[191px] pr-0"
44
+ size = "sm"
45
+ variant = "ghost"
46
+ onClick = { props . onClick }
47
+ >
48
+ < p className = "truncate text-sm font-light w-full text-left" >
49
+ { props . label }
50
+ </ p >
51
+ </ Button >
52
+ { isHovering && (
53
+ < TooltipIconButton
54
+ tooltip = "Delete thread"
55
+ variant = "ghost"
56
+ className = "hover:bg-[#373737] flex-shrink-0 p-2"
57
+ onClick = { props . onDelete }
58
+ >
59
+ < Trash2 className = "w-4 h-4 text-[#575757] hover:text-red-500 transition-colors ease-in" />
60
+ </ TooltipIconButton >
61
+ ) }
62
+ </ div >
63
+ ) ;
64
+ } ;
40
65
41
66
const LoadingThread = ( ) => < Skeleton className = "w-full h-8 bg-[#373737]" /> ;
42
67
43
68
const convertThreadActualToThreadProps = (
44
69
thread : ThreadActual ,
45
70
switchSelectedThread : ( thread : ThreadActual ) => void ,
71
+ deleteThread : ( id : string ) => void ,
46
72
) : ThreadProps => ( {
47
73
id : thread . thread_id ,
48
74
label : thread . values ?. messages ?. [ 0 ] . content || "Untitled" ,
49
75
createdAt : new Date ( thread . created_at ) ,
50
76
onClick : ( ) => {
51
77
return switchSelectedThread ( thread ) ;
52
78
} ,
79
+ onDelete : ( ) => {
80
+ return deleteThread ( thread . thread_id ) ;
81
+ } ,
53
82
} ) ;
54
83
55
84
const groupThreads = (
56
85
threads : ThreadActual [ ] ,
57
86
switchSelectedThread : ( thread : ThreadActual ) => void ,
87
+ deleteThread : ( id : string ) => void ,
58
88
) => {
59
89
const today = new Date ( ) ;
60
90
const yesterday = subDays ( today , 1 ) ;
@@ -67,14 +97,18 @@ const groupThreads = (
67
97
( a , b ) =>
68
98
new Date ( b . created_at ) . getTime ( ) - new Date ( a . created_at ) . getTime ( ) ,
69
99
)
70
- . map ( ( t ) => convertThreadActualToThreadProps ( t , switchSelectedThread ) ) ,
100
+ . map ( ( t ) =>
101
+ convertThreadActualToThreadProps ( t , switchSelectedThread , deleteThread ) ,
102
+ ) ,
71
103
yesterday : threads
72
104
. filter ( ( thread ) => isYesterday ( new Date ( thread . created_at ) ) )
73
105
. sort (
74
106
( a , b ) =>
75
107
new Date ( b . created_at ) . getTime ( ) - new Date ( a . created_at ) . getTime ( ) ,
76
108
)
77
- . map ( ( t ) => convertThreadActualToThreadProps ( t , switchSelectedThread ) ) ,
109
+ . map ( ( t ) =>
110
+ convertThreadActualToThreadProps ( t , switchSelectedThread , deleteThread ) ,
111
+ ) ,
78
112
lastSevenDays : threads
79
113
. filter ( ( thread ) =>
80
114
isWithinInterval ( new Date ( thread . created_at ) , {
@@ -86,14 +120,18 @@ const groupThreads = (
86
120
( a , b ) =>
87
121
new Date ( b . created_at ) . getTime ( ) - new Date ( a . created_at ) . getTime ( ) ,
88
122
)
89
- . map ( ( t ) => convertThreadActualToThreadProps ( t , switchSelectedThread ) ) ,
123
+ . map ( ( t ) =>
124
+ convertThreadActualToThreadProps ( t , switchSelectedThread , deleteThread ) ,
125
+ ) ,
90
126
older : threads
91
127
. filter ( ( thread ) => new Date ( thread . created_at ) < sevenDaysAgo )
92
128
. sort (
93
129
( a , b ) =>
94
130
new Date ( b . created_at ) . getTime ( ) - new Date ( a . created_at ) . getTime ( ) ,
95
131
)
96
- . map ( ( t ) => convertThreadActualToThreadProps ( t , switchSelectedThread ) ) ,
132
+ . map ( ( t ) =>
133
+ convertThreadActualToThreadProps ( t , switchSelectedThread , deleteThread ) ,
134
+ ) ,
97
135
} ;
98
136
} ;
99
137
@@ -147,6 +185,7 @@ export function ThreadHistory(props: ThreadHistoryProps) {
147
185
const groupedThreads = groupThreads (
148
186
props . userThreads ,
149
187
props . switchSelectedThread ,
188
+ props . deleteThread ,
150
189
) ;
151
190
152
191
const createThread = async ( ) => {
@@ -163,6 +202,8 @@ export function ThreadHistory(props: ThreadHistoryProps) {
163
202
if ( currentThread && ! currentThread . values && props . isEmpty ) {
164
203
return ;
165
204
}
205
+
206
+ props . clearMessages ( ) ;
166
207
await props . createThread ( props . userId ) ;
167
208
// Re-fetch threads so that the new thread shows up.
168
209
await props . getUserThreads ( props . userId ) ;
0 commit comments