From 1590f04dc2219864a73b2d704869c3e8326ff9d3 Mon Sep 17 00:00:00 2001 From: matt Date: Fri, 20 Feb 2026 12:53:08 +0900 Subject: [PATCH] feat: add copy functionality to session context menu - Introduced new options to copy Session ID and Resume Command in the SessionContextMenu component. - Added visual feedback for copied actions with appropriate icons and labels. - Updated menu height to accommodate new items and maintain layout consistency. --- .../components/sidebar/SessionContextMenu.tsx | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/sidebar/SessionContextMenu.tsx b/src/renderer/components/sidebar/SessionContextMenu.tsx index 9aa1073b..4adbf6ee 100644 --- a/src/renderer/components/sidebar/SessionContextMenu.tsx +++ b/src/renderer/components/sidebar/SessionContextMenu.tsx @@ -4,10 +4,10 @@ * Shows keyboard shortcut hints for actions that have them. */ -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { MAX_PANES } from '@renderer/types/panes'; -import { Eye, EyeOff, Pin, PinOff } from 'lucide-react'; +import { Check, ClipboardCopy, Eye, EyeOff, Pin, PinOff, Terminal } from 'lucide-react'; interface SessionContextMenuProps { x: number; @@ -29,6 +29,7 @@ interface SessionContextMenuProps { export const SessionContextMenu = ({ x, y, + sessionId, paneCount, isPinned, isHidden, @@ -40,6 +41,7 @@ export const SessionContextMenu = ({ onToggleHide, }: SessionContextMenuProps): React.JSX.Element => { const menuRef = useRef(null); + const [copiedField, setCopiedField] = useState<'id' | 'command' | null>(null); useEffect(() => { const handleMouseDown = (e: MouseEvent): void => { @@ -59,7 +61,7 @@ export const SessionContextMenu = ({ }, [onClose]); const menuWidth = 240; - const menuHeight = 204; + const menuHeight = 290; const clampedX = Math.min(x, window.innerWidth - menuWidth - 8); const clampedY = Math.min(y, window.innerHeight - menuHeight - 8); @@ -68,6 +70,19 @@ export const SessionContextMenu = ({ onClose(); }; + const handleCopy = (text: string, field: 'id' | 'command') => async () => { + try { + await navigator.clipboard.writeText(text); + setCopiedField(field); + setTimeout(() => { + setCopiedField(null); + onClose(); + }, 600); + } catch { + // Silently fail + } + }; + const atMaxPanes = paneCount >= MAX_PANES; return ( @@ -101,6 +116,29 @@ export const SessionContextMenu = ({ icon={isHidden ? : } onClick={handleClick(onToggleHide)} /> +
+ + ) : ( + + ) + } + onClick={handleCopy(sessionId, 'id')} + /> + + ) : ( + + ) + } + onClick={handleCopy(`claude --resume ${sessionId}`, 'command')} + />
); };