summaryrefslogtreecommitdiff
path: root/makima/src/daemon/tui/widgets/list_view.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/daemon/tui/widgets/list_view.rs')
-rw-r--r--makima/src/daemon/tui/widgets/list_view.rs127
1 files changed, 0 insertions, 127 deletions
diff --git a/makima/src/daemon/tui/widgets/list_view.rs b/makima/src/daemon/tui/widgets/list_view.rs
deleted file mode 100644
index ff8269a..0000000
--- a/makima/src/daemon/tui/widgets/list_view.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-//! List view widget with fuzzy match highlighting.
-
-use std::collections::HashSet;
-
-use ratatui::{
- prelude::*,
- widgets::{Block, Borders, List, ListItem, ListState},
-};
-
-use crate::daemon::tui::app::{App, ViewMode};
-
-/// Style for matched characters in search results
-const MATCH_HIGHLIGHT_COLOR: Color = Color::Yellow;
-const MATCH_HIGHLIGHT_MODIFIER: Modifier = Modifier::BOLD;
-
-/// Build a Line with highlighted characters based on matched indices
-fn build_highlighted_name(name: &str, matched_indices: &[usize]) -> Vec<Span<'static>> {
- if matched_indices.is_empty() {
- return vec![Span::raw(name.to_string())];
- }
-
- let matched_set: HashSet<usize> = matched_indices.iter().cloned().collect();
- let mut spans = Vec::new();
- let mut current_run = String::new();
- let mut is_highlighted = false;
-
- for (byte_idx, ch) in name.char_indices() {
- let should_highlight = matched_set.contains(&byte_idx);
-
- if should_highlight != is_highlighted {
- // Flush current run
- if !current_run.is_empty() {
- if is_highlighted {
- spans.push(Span::styled(
- current_run.clone(),
- Style::default()
- .fg(MATCH_HIGHLIGHT_COLOR)
- .add_modifier(MATCH_HIGHLIGHT_MODIFIER),
- ));
- } else {
- spans.push(Span::raw(current_run.clone()));
- }
- current_run.clear();
- }
- is_highlighted = should_highlight;
- }
-
- current_run.push(ch);
- }
-
- // Flush remaining
- if !current_run.is_empty() {
- if is_highlighted {
- spans.push(Span::styled(
- current_run,
- Style::default()
- .fg(MATCH_HIGHLIGHT_COLOR)
- .add_modifier(MATCH_HIGHLIGHT_MODIFIER),
- ));
- } else {
- spans.push(Span::raw(current_run));
- }
- }
-
- spans
-}
-
-/// Get status icon and color for an item
-fn get_status_display(status: Option<&str>) -> (&'static str, Color) {
- match status {
- Some("running") => ("▸", Color::Green),
- Some("done") => ("✓", Color::Blue),
- Some("failed") => ("✗", Color::Red),
- Some("pending") => ("○", Color::Yellow),
- Some("paused") => ("⏸", Color::Cyan),
- _ => (" ", Color::Gray),
- }
-}
-
-pub fn render(f: &mut Frame, area: Rect, app: &mut App) {
- let items: Vec<ListItem> = app
- .filtered_items
- .iter()
- .map(|filtered_item| {
- let item = &app.items[filtered_item.index];
- let (status_icon, status_color) = get_status_display(item.status.as_deref());
-
- // Build spans with highlighted matched characters
- let mut spans = vec![Span::styled(
- format!("{} ", status_icon),
- Style::default().fg(status_color),
- )];
-
- // Add name with match highlighting
- spans.extend(build_highlighted_name(&item.name, &filtered_item.matched_indices));
-
- ListItem::new(Line::from(spans))
- })
- .collect();
-
- let view_label = match app.view_mode {
- ViewMode::Tasks => "Tasks",
- ViewMode::Contracts => "Contracts",
- ViewMode::Files => "Files",
- };
-
- let title = format!(
- " {} ({}{}) ",
- view_label,
- app.filtered_items.len(),
- if app.filtered_items.len() != app.items.len() {
- format!("/{}", app.items.len())
- } else {
- String::new()
- }
- );
-
- let list = List::new(items)
- .block(Block::default().title(title).borders(Borders::ALL))
- .highlight_style(Style::default().add_modifier(Modifier::REVERSED))
- .highlight_symbol("> ");
-
- let mut state = ListState::default();
- state.select(Some(app.selected_index));
-
- f.render_stateful_widget(list, area, &mut state);
-}