|
import * as Dialog from '@radix-ui/react-dialog'; |
|
import { useEffect, useRef, useState } from 'react'; |
|
import { type ChatHistoryItem } from '~/lib/persistence'; |
|
|
|
interface HistoryItemProps { |
|
item: ChatHistoryItem; |
|
onDelete?: (event: React.UIEvent) => void; |
|
} |
|
|
|
export function HistoryItem({ item, onDelete }: HistoryItemProps) { |
|
const [hovering, setHovering] = useState(false); |
|
const hoverRef = useRef<HTMLDivElement>(null); |
|
|
|
useEffect(() => { |
|
let timeout: NodeJS.Timeout | undefined; |
|
|
|
function mouseEnter() { |
|
setHovering(true); |
|
|
|
if (timeout) { |
|
clearTimeout(timeout); |
|
} |
|
} |
|
|
|
function mouseLeave() { |
|
setHovering(false); |
|
} |
|
|
|
hoverRef.current?.addEventListener('mouseenter', mouseEnter); |
|
hoverRef.current?.addEventListener('mouseleave', mouseLeave); |
|
|
|
return () => { |
|
hoverRef.current?.removeEventListener('mouseenter', mouseEnter); |
|
hoverRef.current?.removeEventListener('mouseleave', mouseLeave); |
|
}; |
|
}, []); |
|
|
|
return ( |
|
<div |
|
ref={hoverRef} |
|
className="group rounded-md text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary hover:bg-bolt-elements-background-depth-3 overflow-hidden flex justify-between items-center px-2 py-1" |
|
> |
|
<a href={`/chat/${item.urlId}`} className="flex w-full relative truncate block"> |
|
{item.description} |
|
<div className="absolute right-0 z-1 top-0 bottom-0 bg-gradient-to-l from-bolt-elements-background-depth-2 group-hover:from-bolt-elements-background-depth-3 to-transparent w-10 flex justify-end group-hover:w-15 group-hover:from-45%"> |
|
{hovering && ( |
|
<div className="flex items-center p-1 text-bolt-elements-textSecondary hover:text-bolt-elements-item-contentDanger"> |
|
<Dialog.Trigger asChild> |
|
<button |
|
className="i-ph:trash scale-110" |
|
onClick={(event) => { |
|
// we prevent the default so we don't trigger the anchor above |
|
event.preventDefault(); |
|
onDelete?.(event); |
|
}} |
|
/> |
|
</Dialog.Trigger> |
|
</div> |
|
)} |
|
</div> |
|
</a> |
|
</div> |
|
); |
|
} |
|
|