capsule-ai-cli
Version:
The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing
79 lines • 3.66 kB
JavaScript
import React, { useState } from 'react';
import { Box, Text, useInput } from 'ink';
import chalk from 'chalk';
export const ChatSelector = ({ contexts, currentContextId, onSelect, onClose }) => {
const [selectedIndex, setSelectedIndex] = useState(0);
const maxVisible = 10;
const [scrollOffset, setScrollOffset] = useState(0);
useInput((_input, key) => {
if (key.escape) {
onClose();
}
else if (key.upArrow) {
setSelectedIndex(prev => {
const newIndex = Math.max(0, prev - 1);
if (newIndex < scrollOffset) {
setScrollOffset(newIndex);
}
return newIndex;
});
}
else if (key.downArrow) {
setSelectedIndex(prev => {
const newIndex = Math.min(contexts.length - 1, prev + 1);
if (newIndex >= scrollOffset + maxVisible) {
setScrollOffset(newIndex - maxVisible + 1);
}
return newIndex;
});
}
else if (key.return) {
onSelect(contexts[selectedIndex].id);
}
});
const formatDate = (date) => {
const now = new Date();
const diff = now.getTime() - date.getTime();
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor(diff / (1000 * 60 * 60));
const minutes = Math.floor(diff / (1000 * 60));
if (days > 0)
return `${days}d ago`;
if (hours > 0)
return `${hours}h ago`;
if (minutes > 0)
return `${minutes}m ago`;
return 'just now';
};
const visibleContexts = contexts.slice(scrollOffset, scrollOffset + maxVisible);
const hasMore = contexts.length > maxVisible;
const showScrollIndicators = hasMore;
return (React.createElement(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", paddingX: 1 },
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { color: "cyan" },
"\uD83D\uDCAC Previous Chats (",
contexts.length,
")")),
React.createElement(Box, null,
React.createElement(Text, { dimColor: true }, "Select a chat to resume:")),
showScrollIndicators && scrollOffset > 0 && (React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { dimColor: true }, "\u2191 More above"))),
React.createElement(Box, { marginTop: 1, flexDirection: "column" }, visibleContexts.map((ctx, index) => {
const absoluteIndex = scrollOffset + index;
const isSelected = absoluteIndex === selectedIndex;
const isCurrent = ctx.id === currentContextId;
return (React.createElement(Box, { key: ctx.id },
React.createElement(Text, { color: isSelected ? 'cyan' : undefined, inverse: isSelected },
isSelected ? '▶ ' : ' ',
isCurrent ? chalk.green('● ') : ' ',
formatDate(ctx.created),
" - ",
ctx.messageCount,
" messages")));
})),
showScrollIndicators && scrollOffset + maxVisible < contexts.length && (React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { dimColor: true }, "\u2193 More below"))),
React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { dimColor: true }, "\u2191\u2193 Navigate \u2022 Enter Select \u2022 ESC Cancel"))));
};
//# sourceMappingURL=ChatSelector.js.map