/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type React from 'react';
import { Box, Text } from 'ink';
import { Colors } from '../../colors.js';
import { theme } from '../../semantic-colors.js';
import type { SessionBrowserState } from '../SessionBrowser.js';
import type { SessionInfo } from '../../../utils/sessionUtils.js';
import { MatchSnippetDisplay } from './MatchSnippetDisplay.js';
const FIXED_SESSION_COLUMNS_WIDTH = 30;
/**
* Individual session row component.
*/
export const SessionItem = ({
session,
state,
terminalWidth,
formatRelativeTime,
}: {
session: SessionInfo;
state: SessionBrowserState;
terminalWidth: number;
formatRelativeTime: (dateString: string, style: 'short' | 'long') => string;
}): React.JSX.Element => {
const originalIndex =
state.startIndex + state.visibleSessions.indexOf(session);
const isActive = originalIndex === state.activeIndex;
const isDisabled = session.isCurrentSession;
const textColor = (c: string = Colors.Foreground) => {
if (isDisabled) {
return Colors.Gray;
}
return isActive ? theme.ui.focus : c;
};
const prefix = isActive ? '❯ ' : ' ';
let additionalInfo = '';
let matchDisplay = null;
// Add "(current)" label for the current session
if (session.isCurrentSession) {
additionalInfo = ' (current)';
}
// Show match snippets if searching and matches exist
if (
state.searchQuery &&
session.matchSnippets &&
session.matchSnippets.length > 0
) {
matchDisplay = (
);
if (session.matchCount && session.matchCount > 1) {
additionalInfo += ` (+${session.matchCount - 1} more)`;
}
}
// Reserve a few characters for metadata like " (current)" so the name doesn't wrap awkwardly.
const reservedForMeta = additionalInfo ? additionalInfo.length + 1 : 0;
const availableMessageWidth = Math.max(
20,
terminalWidth - FIXED_SESSION_COLUMNS_WIDTH - reservedForMeta,
);
const truncatedMessage =
matchDisplay ||
(session.displayName.length === 0 ? (
(No messages)
) : session.displayName.length > availableMessageWidth ? (
session.displayName.slice(0, availableMessageWidth - 1) + '…'
) : (
session.displayName
));
return (
{prefix}
#{originalIndex + 1}
{' '}
│{' '}
{session.messageCount}
{' '}
│{' '}
{formatRelativeTime(session.lastUpdated, 'short')}
{' '}
│{' '}
{truncatedMessage}
{additionalInfo && (
{additionalInfo}
)}
);
};