//! Overlay: Rewind / session history — shows recent messages and lets the user //! pick a point to rewind the transcript back to. use crate::view::theme::Theme; use ratatui::style::{Modifier, Style}; use ratatui::text::{Line, Span}; use ratatui::widgets::{Block, Paragraph}; use ratatui::Frame; use tracing::debug; use zesdex_domain::core::Role; /// Render the Rewind overlay. #[tracing::instrument(skip_all)] pub fn render( frame: &mut Frame, area: ratatui::layout::Rect, block: Block<'static>, state: &crate::state::AppStateRest, ) { let msg_count = state.transcript_cache.messages.len(); debug!("Rendering Rewind overlay, {} messages", msg_count); let block = block .title(Span::styled( " Rewind ", Style::default() .fg(Theme::ACCENT_ORANGE) .add_modifier(Modifier::BOLD), )) .border_style(Style::default().fg(Theme::ACCENT_ORANGE)); let mut lines: Vec = vec![ Line::from(Span::styled( " Use ↑↓ to navigate, Enter to rewind to that point", Style::default().fg(Theme::TEXT_DIM), )), Line::from(Span::raw("")), ]; let messages = &state.transcript_cache.messages; if messages.is_empty() { lines.push(Line::from(Span::styled( " No messages in current session.", Style::default().fg(Theme::TEXT_DIM), ))); } else { let start = if messages.len() > 8 { messages.len() - 8 } else { 0 }; for msg in messages.iter().skip(start) { let role_str = match msg.role { Role::User => "User", Role::Assistant => "Asst", Role::System => "Sys", Role::Tool => "Tool", }; let preview: String = msg.content.chars().take(70).collect(); lines.push(Line::from(Span::styled( format!(" [{role_str}] {preview}"), Style::default().fg(if msg.role == Role::User { Theme::INFO } else { Theme::TEXT }), ))); } if messages.len() > 8 { lines.push(Line::from(Span::styled( format!(" ... and {} more messages", messages.len() - 8), Style::default().fg(Theme::TEXT_DIM), ))); } } let paragraph = Paragraph::new(lines).block(block); frame.render_widget(paragraph, area); }