Refactor TUI scrolling logic: replace manual scroll calculations with AutoScroll abstraction, enhance line wrapping, and improve viewport handling.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user