diff options
Diffstat (limited to 'src/tui')
| -rw-r--r-- | src/tui/app.rs | 14 | ||||
| -rw-r--r-- | src/tui/ui.rs | 24 |
2 files changed, 10 insertions, 28 deletions
diff --git a/src/tui/app.rs b/src/tui/app.rs index 1e7d021..0b5d77e 100644 --- a/src/tui/app.rs +++ b/src/tui/app.rs @@ -1,6 +1,3 @@ -/// Compile-time channel to join on startup -pub const CHANNEL: &str = "#speakez"; - /// A single chat message in the log #[derive(Clone)] pub struct ChatLine { @@ -28,8 +25,6 @@ pub struct AppState { pub input: String, /// Cursor position within `input` (byte index) pub cursor: usize, - /// Scroll offset from the bottom (0 = pinned to latest) - pub scroll: usize, /// Status line text (connection state, errors, etc.) pub status: String, /// Whether we've fully registered @@ -37,16 +32,15 @@ pub struct AppState { } impl AppState { - pub fn new(nick: impl Into<String>, channel: impl Into<String>) -> Self { + pub fn new() -> Self { Self { - nick: nick.into(), - channel: channel.into(), + nick: String::new(), + channel: String::new(), messages: Vec::new(), members: Vec::new(), input: String::new(), cursor: 0, - scroll: 0, - status: "Connecting...".into(), + status: "Set nick with /nick to connect.".into(), connected: false, } } diff --git a/src/tui/ui.rs b/src/tui/ui.rs index a38834a..4a243ad 100644 --- a/src/tui/ui.rs +++ b/src/tui/ui.rs @@ -90,37 +90,25 @@ fn draw_center(f: &mut Frame, area: Rect, state: &AppState) { } fn draw_chat_log(f: &mut Frame, area: Rect, state: &AppState) { - let inner_height = area.height.saturating_sub(2) as usize; // subtract borders - - // Build all rendered lines first so we can scroll from the bottom let lines: Vec<Line> = state .messages .iter() .map(|msg| render_chat_line(msg)) .collect(); - // Apply scroll offset - // scroll=0 means pinned to bottom (newest). scroll=N means N lines back from bottom. - let total = lines.len(); - let max_scroll = total.saturating_sub(inner_height); - let scroll = state.scroll.min(max_scroll); - let visible_start = total.saturating_sub(inner_height + scroll); - let visible: Vec<Line> = lines - .into_iter() - .skip(visible_start) - .take(inner_height) - .collect(); - let block = Block::default() .borders(Borders::ALL) .border_type(BorderType::Plain) .border_style(Style::default().fg(ORANGE)) .style(Style::default().bg(BG)); + let inner_height = area.height.saturating_sub(2) as usize; + let scroll = lines.len().saturating_sub(inner_height); f.render_widget( - Paragraph::new(Text::from(visible)) + Paragraph::new(Text::from(lines)) .block(block) - .wrap(Wrap { trim: false }), + .wrap(Wrap { trim: false }) + .scroll((scroll as u16, 0)), area, ); } @@ -232,7 +220,7 @@ fn draw_statusbar(f: &mut Frame, area: Rect, state: &AppState) { Span::styled(" │ ", Style::default().fg(FG)), Span::styled(&state.status, Style::default().fg(FG)), Span::styled(" │ ", Style::default().fg(FG)), - Span::styled("PgUp/Dn scroll Ctrl-C quit", Style::default().fg(FG)), + Span::styled("Ctrl-C quit", Style::default().fg(FG)), ]); f.render_widget(Paragraph::new(line).style(Style::default()), area); |
