根据用户反馈的截图,当输入大量文本(包括日志)后,发送消息后显示框出现了以下问题:
- 布局对齐问题:消息框的边框和内容出现错位
- 文本溢出:长文本超出容器边界,导致显示破损
- 换行处理不当:超长行没有正确换行,影响整体布局
- 左边距问题:文本没有考虑App.tsx中设置的90%宽度布局,导致文本贴到终端左边缘
经过深入分析,发现主要问题是宽度计算和布局层级的混乱:
- App.tsx设置了整体宽度为90%:
<Box flexDirection="column" width="90%"> - mainAreaWidth已经是调整后的宽度:
mainAreaWidth = Math.floor(terminalWidth * 0.9) - 消息组件重复设置宽度:UserMessage等组件又设置了
width={terminalWidth} - 双重宽度限制:导致内容被过度压缩,文本超出边框
核心修复:
- 移除外层宽度限制:不再设置
width={terminalWidth},让内容自然流动 - 简化宽度计算:直接使用传入的已调整宽度,避免双重限制
- 预处理文本换行:使用
forceWrapText函数确保文本不会超出边界 - 移除Ink的wrap属性:因为已经预处理了文本
修复前的问题:
// 错误:双重宽度限制
<Box flexDirection="column" width={terminalWidth}> // 第一层限制
<Box width={maxMessageWidth}> // 第二层限制修复后:
// 正确:让内容自然流动,只在消息框层面限制宽度
<Box flexDirection="column"> // 不设置宽度
<Box width={maxMessageWidth}> // 只在这里限制问题:
- 原本设置了固定宽度,导致和App.tsx的90%宽度冲突
修复:
// 修复前:设置固定宽度
<Box width={safeWidth} {...containerProps}>
// 修复后:不设置宽度,让内容自然流动
<Box {...containerProps}>主要改进:
- 更新
SafeMessageContainer调用,移除不必要的宽度参数 - 保持
terminalWidth传递给MarkdownDisplay的逻辑
功能:
- 智能文本换行处理
- 支持保留空白字符选项
- 可配置的最大宽度限制
功能:
- 防止内容溢出的安全容器
- 自动计算安全的容器宽度
- 可配置的最小/最大宽度限制
smartTruncateText函数:
export function smartTruncateText(text: string, maxLines = 15): string {
// 对于非常长的文本,保留开头和结尾
const headLines = Math.floor(maxLines * 0.6);
const tailLines = Math.floor(maxLines * 0.3);
const remainingLines = totalLines - headLines - tailLines;
const headPart = lines.slice(0, headLines).join('\n');
const tailPart = lines.slice(-tailLines).join('\n');
return `${headPart}\n\n... (${remainingLines} lines omitted) ...\n\n${tailPart}`;
}wrapLongLines函数:
export function wrapLongLines(text: string, maxWidth: number): string {
// 智能换行处理,确保每行不超过指定宽度
}主要改进:
- 为文本块添加
width和flexShrink属性 - 确保内容不会超出指定的终端宽度
// UserMessage组件中的宽度计算
const borderAndPaddingWidth = 4; // 左右边框 + 左右padding
const userIndicatorWidth = 3; // 用户指示器的大概宽度
const marginWidth = 2; // 左右margin
const availableWidth = Math.max(
(terminalWidth || 80) - borderAndPaddingWidth - userIndicatorWidth - marginWidth - prefixWidth,
20 // 最小宽度保证
);- 检测长文本:使用
isLongText函数判断是否需要特殊处理 - 智能截断:对超长文本使用
smartTruncateText进行截断 - 换行处理:使用
TextContainer组件进行智能换行 - 安全容器:使用
SafeMessageContainer防止溢出
// 确保正确的flex行为
<Box flexGrow={1} flexShrink={1}>
<TextContainer
text={finalDisplayText}
maxWidth={availableWidth}
color={Colors.Gray}
wrap={true}
/>
</Box>- 布局稳定性:消息框边框保持完整,不会出现破损
- 文本显示:长文本正确换行,不会超出容器边界
- 用户体验:保持良好的视觉对齐和可读性
- 性能优化:避免渲染超长内容导致的性能问题
- 测试超长单行文本的显示效果
- 测试多行日志文本的布局
- 测试混合内容(文本+代码块)的显示
- 在不同终端宽度下测试布局稳定性
- 保持与现有API的完全兼容
- 不影响其他消息类型的显示
- 渐进式增强,不会破坏现有功能