diff --git a/src/frontends/tui/components/MessageList.tsx b/src/frontends/tui/components/MessageList.tsx index 7d5729a..efcaf8a 100644 --- a/src/frontends/tui/components/MessageList.tsx +++ b/src/frontends/tui/components/MessageList.tsx @@ -1,29 +1,57 @@ import React from 'react'; import { Box, Text } from 'ink'; import type { Message } from '../../../models/types.js'; +import { renderMarkdown } from '../markdown.js'; export interface MessageListProps { messages: Message[]; - maxHeight?: number; + scrollOffset?: number; + streamingContent?: string; } -export function MessageList({ messages, maxHeight = 20 }: MessageListProps): React.ReactElement { - // Show only recent messages that fit - const visibleMessages = messages.slice(-maxHeight); +export function MessageList({ + messages, + scrollOffset = 0, + streamingContent, +}: MessageListProps): React.ReactElement { + // Calculate visible area (approximate, Ink handles overflow) + const visibleMessages = messages.slice(scrollOffset); return ( - - {visibleMessages.length === 0 ? ( + + {visibleMessages.length === 0 && !streamingContent ? ( No messages yet. Start typing to chat with Flynn. ) : ( - visibleMessages.map((message, index) => ( - - - {message.role === 'user' ? 'You: ' : 'Flynn: '} - - {message.content} - - )) + <> + {visibleMessages.map((message, index) => ( + + + {message.role === 'user' ? 'You:' : 'Flynn:'} + + + + {message.role === 'assistant' + ? renderMarkdown(message.content) + : message.content} + + + + ))} + {streamingContent && ( + + Flynn: + + {streamingContent} + | + + + )} + + )} + {messages.length > 0 && scrollOffset > 0 && ( + + {scrollOffset} more above + )} );