cuj-tui 0.1.0

cui — a read-only TUI browser for cuj vaults
Documentation
//! The left panel: the jot list for the current source ∩ scope.

use metatheca::format_iso8601_secs;
use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::style::{Color, Modifier, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::{Block, List, ListItem};

use crate::state::{AppState, Focus};
use crate::ui::border_style;

pub fn draw(f: &mut Frame, area: Rect, state: &mut AppState) {
    state.list_height = area.height.saturating_sub(2);

    let scope = state.profile.clone();
    let scope = scope.as_deref();
    let items: Vec<ListItem> = state
        .visible
        .iter()
        .map(|&i| {
            let row = &state.snapshot.rows[i];
            let mut spans = vec![
                Span::styled(
                    format!("{:>9}", row.short_ref(scope)),
                    Style::new().fg(Color::Cyan),
                ),
                Span::raw("  "),
            ];
            if let Some(score) = state.source.score_of(row.entry) {
                spans.push(Span::styled(
                    format!("{score:6.3}  "),
                    Style::new().fg(Color::Magenta),
                ));
            } else {
                let date = row
                    .created_at_ns
                    .map(|ns| format_iso8601_secs(ns)[..10].to_string())
                    .unwrap_or_else(|| "          ".into());
                spans.push(Span::styled(date, Style::new().add_modifier(Modifier::DIM)));
                spans.push(Span::raw("  "));
            }
            spans.push(Span::raw(row.summary.clone()));
            ListItem::new(Line::from(spans))
        })
        .collect();

    let title = state.source.title(state.visible.len(), scope);
    let block = Block::bordered()
        .title(title)
        .border_style(border_style(state.focus == Focus::List));
    let list = List::new(items)
        .block(block)
        .highlight_style(Style::new().add_modifier(Modifier::REVERSED));
    f.render_stateful_widget(list, area, &mut state.list);
}