Refactor TUI scrolling logic: replace manual scroll calculations with AutoScroll abstraction, enhance line wrapping, and improve viewport handling.

This commit is contained in:
2025-09-29 22:12:45 +02:00
parent a4ba9adf8f
commit c17af3fee5
2 changed files with 86 additions and 62 deletions

View File

@@ -357,6 +357,7 @@ fn render_messages(frame: &mut Frame<'_>, area: Rect, app: &mut ChatApp) {
// Reserve space for borders and the message indent so text fits within the block
formatter.set_wrap_width(usize::from(content_width));
// Build the lines for messages
let mut lines: Vec<Line> = Vec::new();
for (message_index, message) in conversation.messages.iter().enumerate() {
let role = &message.role;
@@ -434,16 +435,34 @@ fn render_messages(frame: &mut Frame<'_>, area: Rect, app: &mut ChatApp) {
lines.push(Line::from("No messages yet. Press 'i' to start typing."));
}
let mut paragraph = Paragraph::new(lines)
// Wrap lines to get accurate content height
let wrapped: Vec<Line> = {
use textwrap::wrap;
let mut out = Vec::new();
for l in &lines {
let s = l.to_string();
for w in wrap(&s, content_width as usize) {
out.push(Line::from(w.into_owned()));
}
}
out
};
// Update AutoScroll state with accurate content length
let auto_scroll = app.auto_scroll_mut();
auto_scroll.content_len = wrapped.len();
auto_scroll.on_viewport(viewport_height);
let scroll_position = app.scroll().min(u16::MAX as usize) as u16;
let paragraph = Paragraph::new(wrapped)
.block(
Block::default()
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::Rgb(95, 20, 135))),
)
.wrap(Wrap { trim: false });
let scroll = app.scroll().min(u16::MAX as usize) as u16;
paragraph = paragraph.scroll((scroll, 0));
.wrap(Wrap { trim: false })
.scroll((scroll_position, 0));
frame.render_widget(paragraph, area);
}