summaryrefslogtreecommitdiff
path: root/makima/src/daemon/tui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/daemon/tui/widgets')
-rw-r--r--makima/src/daemon/tui/widgets/list_view.rs127
-rw-r--r--makima/src/daemon/tui/widgets/mod.rs4
-rw-r--r--makima/src/daemon/tui/widgets/preview_pane.rs21
-rw-r--r--makima/src/daemon/tui/widgets/search_input.rs82
-rw-r--r--makima/src/daemon/tui/widgets/status_bar.rs19
5 files changed, 0 insertions, 253 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);
-}
diff --git a/makima/src/daemon/tui/widgets/mod.rs b/makima/src/daemon/tui/widgets/mod.rs
deleted file mode 100644
index ddea546..0000000
--- a/makima/src/daemon/tui/widgets/mod.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-pub mod list_view;
-pub mod preview_pane;
-pub mod search_input;
-pub mod status_bar;
diff --git a/makima/src/daemon/tui/widgets/preview_pane.rs b/makima/src/daemon/tui/widgets/preview_pane.rs
deleted file mode 100644
index 84095d0..0000000
--- a/makima/src/daemon/tui/widgets/preview_pane.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//! Preview pane widget.
-
-use ratatui::{
- prelude::*,
- widgets::{Block, Borders, Paragraph, Wrap},
-};
-
-use crate::daemon::tui::app::App;
-
-pub fn render(f: &mut Frame, area: Rect, app: &App) {
- let content = app
- .preview_content
- .as_deref()
- .unwrap_or("No preview available");
-
- let preview = Paragraph::new(content)
- .block(Block::default().title(" Preview ").borders(Borders::ALL))
- .wrap(Wrap { trim: true });
-
- f.render_widget(preview, area);
-}
diff --git a/makima/src/daemon/tui/widgets/search_input.rs b/makima/src/daemon/tui/widgets/search_input.rs
deleted file mode 100644
index 311b4f0..0000000
--- a/makima/src/daemon/tui/widgets/search_input.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-//! Search input widget with match count and visual feedback.
-
-use ratatui::{
- prelude::*,
- widgets::{Block, Borders, Paragraph},
-};
-
-use crate::daemon::tui::app::{App, InputMode, ViewMode};
-
-/// Color for the search bar when there are no matches
-const NO_MATCH_COLOR: Color = Color::Red;
-/// Color for the search bar when actively searching
-const SEARCH_ACTIVE_COLOR: Color = Color::Yellow;
-
-pub fn render(f: &mut Frame, area: Rect, app: &App) {
- let view_label = match app.view_mode {
- ViewMode::Tasks => "Tasks",
- ViewMode::Contracts => "Contracts",
- ViewMode::Files => "Files",
- };
-
- let (matched, total) = app.match_count();
- let has_no_matches = app.has_no_matches();
- let is_searching = matches!(app.input_mode, InputMode::Search);
- let has_query = !app.search_query.is_empty();
-
- // Determine border style based on state
- let border_style = if has_no_matches {
- Style::default().fg(NO_MATCH_COLOR)
- } else if is_searching {
- Style::default().fg(SEARCH_ACTIVE_COLOR)
- } else {
- Style::default()
- };
-
- // Build the search input content
- let search_text = if app.search_query.is_empty() {
- if is_searching {
- " Type to search...".to_string()
- } else {
- " Press / to search".to_string()
- }
- } else {
- format!(" {}", app.search_query)
- };
-
- // Build the title with match count
- let title = if has_query {
- if has_no_matches {
- format!(" 🔍 Search [{}] - No matches ", view_label)
- } else {
- format!(" 🔍 Search [{}] - {}/{} matches ", view_label, matched, total)
- }
- } else {
- format!(" 🔍 Search [{}] ", view_label)
- };
-
- // Create input text with appropriate style
- let text_style = if app.search_query.is_empty() && !is_searching {
- Style::default().fg(Color::DarkGray)
- } else if has_no_matches {
- Style::default().fg(NO_MATCH_COLOR)
- } else {
- Style::default()
- };
-
- let input = Paragraph::new(Span::styled(search_text, text_style)).block(
- Block::default()
- .title(title)
- .borders(Borders::ALL)
- .border_style(border_style),
- );
-
- f.render_widget(input, area);
-
- // Show cursor in search mode
- if is_searching {
- // Calculate cursor position based on actual search query length
- let cursor_x = area.x + app.search_query.len() as u16 + 2;
- f.set_cursor_position(Position::new(cursor_x, area.y + 1));
- }
-}
diff --git a/makima/src/daemon/tui/widgets/status_bar.rs b/makima/src/daemon/tui/widgets/status_bar.rs
deleted file mode 100644
index 3357c58..0000000
--- a/makima/src/daemon/tui/widgets/status_bar.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-//! Status bar widget.
-
-use ratatui::{prelude::*, widgets::Paragraph};
-
-use crate::daemon::tui::app::{App, InputMode};
-
-pub fn render(f: &mut Frame, area: Rect, app: &App) {
- let keybindings = match app.input_mode {
- InputMode::Normal => {
- "↑↓:Navigate Enter:View e:Edit d:Delete Tab:Preview /:Search q:Quit"
- }
- InputMode::Search => "Type to search Enter:Select Esc:Cancel",
- InputMode::Confirm => "y:Confirm n:Cancel",
- };
-
- let status = Paragraph::new(keybindings).style(Style::default().bg(Color::DarkGray));
-
- f.render_widget(status, area);
-}