chore: uptick
This commit is contained in:
@@ -18,7 +18,6 @@ import { Skeleton } from '@/components/ui/skeleton'
|
||||
import type { SessionInfo } from '@/hermes'
|
||||
import { cn } from '@/lib/utils'
|
||||
import {
|
||||
$isSidebarResizing,
|
||||
$pinnedSessionIds,
|
||||
$sidebarOpen,
|
||||
$sidebarPinsOpen,
|
||||
@@ -66,10 +65,10 @@ export function ChatSidebar({
|
||||
}: ChatSidebarProps) {
|
||||
const sidebarOpen = useStore($sidebarOpen)
|
||||
const pinnedSessionIds = useStore($pinnedSessionIds)
|
||||
const isSidebarResizing = useStore($isSidebarResizing)
|
||||
const pinsOpen = useStore($sidebarPinsOpen)
|
||||
const recentsOpen = useStore($sidebarRecentsOpen)
|
||||
const selectedSessionId = useStore($selectedStoredSessionId)
|
||||
const activeSidebarSessionId = currentView === 'chat' ? selectedSessionId : null
|
||||
const sessions = useStore($sessions)
|
||||
const sessionsLoading = useStore($sessionsLoading)
|
||||
const workingSessionIds = useStore($workingSessionIds)
|
||||
@@ -101,13 +100,10 @@ export function ChatSidebar({
|
||||
return (
|
||||
<Sidebar
|
||||
className={cn(
|
||||
'relative h-screen min-w-0 overflow-hidden border-r border-t-0 border-b-0 border-l-0 text-foreground [backdrop-filter:blur(1.5rem)_saturate(1.08)]',
|
||||
isSidebarResizing
|
||||
? 'transition-none'
|
||||
: 'transition-[opacity,transform,border-color,background-color] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]',
|
||||
'relative h-screen min-w-0 overflow-hidden border-r border-t-0 border-b-0 border-l-0 text-foreground transition-none [backdrop-filter:blur(1.5rem)_saturate(1.08)]',
|
||||
sidebarOpen
|
||||
? 'translate-x-0 border-(--sidebar-edge-border) bg-[color-mix(in_srgb,var(--dt-sidebar-bg)_97%,transparent)] opacity-100'
|
||||
: 'pointer-events-none -translate-x-2 border-transparent bg-transparent opacity-0'
|
||||
? 'border-(--sidebar-edge-border) bg-[color-mix(in_srgb,var(--dt-sidebar-bg)_97%,transparent)] opacity-100'
|
||||
: 'pointer-events-none border-transparent bg-transparent opacity-0'
|
||||
)}
|
||||
collapsible="none"
|
||||
>
|
||||
@@ -159,7 +155,7 @@ export function ChatSidebar({
|
||||
{pinnedSessions.map(session => (
|
||||
<SidebarSessionRow
|
||||
isPinned
|
||||
isSelected={session.id === selectedSessionId}
|
||||
isSelected={session.id === activeSidebarSessionId}
|
||||
isWorking={workingSessionIdSet.has(session.id)}
|
||||
key={session.id}
|
||||
onDelete={() => onDeleteSession(session.id)}
|
||||
@@ -207,7 +203,7 @@ export function ChatSidebar({
|
||||
{recentSessions.map(session => (
|
||||
<SidebarSessionRow
|
||||
isPinned={false}
|
||||
isSelected={session.id === selectedSessionId}
|
||||
isSelected={session.id === activeSidebarSessionId}
|
||||
isWorking={workingSessionIdSet.has(session.id)}
|
||||
key={session.id}
|
||||
onDelete={() => onDeleteSession(session.id)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Archive, Pencil, Pin, Trash2 } from 'lucide-react'
|
||||
import { Archive, Copy, Pencil, Pin, Trash2 } from 'lucide-react'
|
||||
import type * as React from 'react'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import { triggerHaptic } from '@/lib/haptics'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { notify, notifyError } from '@/store/notifications'
|
||||
|
||||
interface SessionActionsMenuProps extends Pick<
|
||||
React.ComponentProps<typeof DropdownMenuContent>,
|
||||
@@ -18,6 +19,7 @@ interface SessionActionsMenuProps extends Pick<
|
||||
> {
|
||||
children: ReactNode
|
||||
title: string
|
||||
sessionId: string
|
||||
pinned?: boolean
|
||||
onPin?: () => void
|
||||
onDelete?: () => void
|
||||
@@ -26,6 +28,7 @@ interface SessionActionsMenuProps extends Pick<
|
||||
export function SessionActionsMenu({
|
||||
children,
|
||||
title,
|
||||
sessionId,
|
||||
pinned = false,
|
||||
onPin,
|
||||
onDelete,
|
||||
@@ -34,6 +37,17 @@ export function SessionActionsMenu({
|
||||
}: SessionActionsMenuProps) {
|
||||
const itemClass = 'gap-2.5 text-foreground focus:bg-accent [&_svg]:size-4'
|
||||
|
||||
const copyId = async () => {
|
||||
triggerHaptic('selection')
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(sessionId)
|
||||
notify({ kind: 'success', message: 'Session ID copied', durationMs: 2_000 })
|
||||
} catch (err) {
|
||||
notifyError(err, 'Could not copy session ID')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>{children}</DropdownMenuTrigger>
|
||||
@@ -49,6 +63,10 @@ export function SessionActionsMenu({
|
||||
<Pin />
|
||||
<span>{pinned ? 'Unpin' : 'Pin'}</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className={itemClass} onSelect={() => void copyId()}>
|
||||
<Copy />
|
||||
<span>Copy ID</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className={itemClass}>
|
||||
<Pencil />
|
||||
<span>Rename</span>
|
||||
|
||||
@@ -72,7 +72,7 @@ export function SidebarSessionRow({
|
||||
<span className="truncate text-sm font-medium text-foreground/90">{title}</span>
|
||||
</button>
|
||||
<div className="relative z-2 grid w-6 place-items-center">
|
||||
<SessionActionsMenu onDelete={onDelete} onPin={onPin} pinned={isPinned} title={title}>
|
||||
<SessionActionsMenu onDelete={onDelete} onPin={onPin} pinned={isPinned} sessionId={session.id} title={title}>
|
||||
<Button
|
||||
aria-label={`Actions for ${title}`}
|
||||
className="size-6 rounded-md bg-transparent text-transparent transition-colors duration-150 hover:bg-accent hover:text-foreground data-[state=open]:bg-accent data-[state=open]:text-foreground group-hover:text-muted-foreground"
|
||||
|
||||
Reference in New Issue
Block a user