/** * @license * Copyright 2025 Qwen Code * SPDX-License-Identifier: Apache-2.0 */ import { useState, useEffect, useRef } from 'react'; import { Box, Text } from 'ink'; import { SessionService, getGitBranch } from '@qwen-code/qwen-code-core'; import { theme } from '../semantic-colors.js'; import { useSessionPicker } from '../hooks/useSessionPicker.js'; import { SessionListItemView } from './SessionListItem.js'; export interface ResumeSessionDialogProps { cwd: string; onSelect: (sessionId: string) => void; onCancel: () => void; availableTerminalHeight?: number; } export function ResumeSessionDialog({ cwd, onSelect, onCancel, availableTerminalHeight, }: ResumeSessionDialogProps): React.JSX.Element { const sessionServiceRef = useRef(null); const [currentBranch, setCurrentBranch] = useState(); const [isReady, setIsReady] = useState(false); // Initialize session service useEffect(() => { sessionServiceRef.current = new SessionService(cwd); setCurrentBranch(getGitBranch(cwd)); setIsReady(true); }, [cwd]); // Calculate visible items based on terminal height const maxVisibleItems = availableTerminalHeight ? Math.max(3, Math.floor((availableTerminalHeight - 6) / 3)) : 5; const picker = useSessionPicker({ sessionService: sessionServiceRef.current, currentBranch, onSelect, onCancel, maxVisibleItems, centerSelection: false, isActive: isReady, }); if (!isReady || picker.isLoading) { return ( Resume Session Loading sessions... ); } return ( {/* Header */} Resume Session {picker.filterByBranch && currentBranch && ( (branch: {currentBranch}) )} {/* Session List */} {picker.filteredSessions.length === 0 ? ( {picker.filterByBranch ? `No sessions found for branch "${currentBranch}"` : 'No sessions found'} ) : ( picker.visibleSessions.map((session, visibleIndex) => { const actualIndex = picker.scrollOffset + visibleIndex; return ( ); }) )} {/* Footer */} {currentBranch && ( <> B {' to toggle branch · '} )} {'↑↓ to navigate · Enter to select · Esc to cancel'} ); }