use std::collections::VecDeque;
use ratatui::prelude::*;
use ratatui::widgets::Paragraph;
use crate::app::App;
use crate::theme::hex_to_color;
pub fn render(frame: &mut Frame, area: Rect, app: &App) {
if app
.state
.active_buffer()
.is_some_and(|b| b.buffer_type == crate::state::buffer::BufferType::Shell)
{
super::shell_view::render(frame, area, app);
return;
}
let colors = &app.theme.colors;
let bg = hex_to_color(&colors.bg).unwrap_or(Color::Reset);
let fg_muted = hex_to_color(&colors.fg_muted).unwrap_or(Color::DarkGray);
if let Some(buf) = app.state.active_buffer() {
let current_nick = app
.state
.connections
.get(&buf.connection_id)
.map_or("", |c| c.nick.as_str());
let total_width = area.width as usize;
let visible_height = area.height as usize;
if total_width == 0 || visible_height == 0 {
return;
}
let indent = app.wrap_indent;
let needed = visible_height + app.scroll_offset;
let mut visual_lines: VecDeque<Line<'_>> = VecDeque::new();
for msg in buf.messages.iter().rev() {
let is_own = msg.nick.as_deref() == Some(current_nick);
let nick_fg = if app.config.display.nick_colors && !is_own && !msg.highlight {
msg.nick.as_deref().map(|n| {
crate::nick_color::nick_color(
n,
app.color_support,
app.config.display.nick_color_saturation,
app.config.display.nick_color_lightness,
)
})
} else {
None
};
let line = super::message_line::render_message(msg, is_own, &app.theme, &app.config, nick_fg);
let wrapped = super::wrap_line(line, total_width, indent);
for wl in wrapped.into_iter().rev() {
visual_lines.push_front(wl);
}
if visual_lines.len() > needed {
break;
}
}
let total = visual_lines.len();
let max_scroll = total.saturating_sub(visible_height);
let scroll = app.scroll_offset.min(max_scroll);
let skip = total.saturating_sub(visible_height + scroll);
let visible_lines: Vec<Line<'_>> = visual_lines
.into_iter()
.skip(skip)
.take(visible_height)
.collect();
let paragraph = Paragraph::new(visible_lines).style(Style::default().bg(bg));
frame.render_widget(paragraph, area);
} else {
let paragraph = Paragraph::new("No active buffer")
.style(Style::default().fg(fg_muted).bg(bg))
.alignment(Alignment::Center);
frame.render_widget(paragraph, area);
}
}