From c95e34c6bad67596c6bb8f67c94bf7888d5e582d Mon Sep 17 00:00:00 2001 From: YK Date: Wed, 17 Jul 2024 11:12:02 +0300 Subject: [PATCH] remove filtering logic from display code --- src/app.rs | 6 ++++-- src/app/filter.rs | 8 +++++++- src/app/main.rs | 36 ++++++++++++++++++------------------ src/main.rs | 1 + 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/app.rs b/src/app.rs index 8cb1301..1f81fdf 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,3 @@ - use std::collections::HashSet; use crossterm::event::{ self, Event, KeyCode, KeyEvent, KeyEventKind }; @@ -182,7 +181,10 @@ impl Widget for &App { impl Screen { fn render (&self, app: &App, area: Rect, buf: &mut Buffer) -> () { match self { - Self::Main { inner, cursor } => main::screen(app, *inner, *cursor, area, buf), + Self::Main { inner, cursor } => { + let tasks = inner.get_filtered_tasks(&app.tasks); + main::screen(tasks, *inner, &app.selection, *cursor, area, buf) + }, _ => () } } diff --git a/src/app/filter.rs b/src/app/filter.rs index 13a1bdd..600116d 100644 --- a/src/app/filter.rs +++ b/src/app/filter.rs @@ -5,8 +5,10 @@ use crate::prelude::*; use super::MainScreen; +type Filter = impl Fn(&&Task) -> bool; + impl MainScreen { - pub fn task_filter (self) -> impl Fn(&&Task) -> bool { + pub fn task_filter (self) -> Filter { move |task: &&Task| match self { Self::All => true, Self::Cancelled => task.status == TaskStatus::Cancelled, @@ -16,4 +18,8 @@ impl MainScreen { Self::Recurring => std::mem::discriminant(&task.kind) == std::mem::discriminant(&TaskKind::Recurring { parent: Uuid::default() }), } } + + pub fn get_filtered_tasks <'a> (self, tasks: &'a [Task]) -> Vec<&'a Task> { + tasks.iter().filter(self.task_filter()).collect() + } } diff --git a/src/app/main.rs b/src/app/main.rs index c3e3bfe..582b1a8 100644 --- a/src/app/main.rs +++ b/src/app/main.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use crate::{app::{Cursor, Screen}, prelude::*}; use super::MainScreen; @@ -12,7 +14,10 @@ use utils::truncate_with_ellipsis as tc; use itertools::Itertools; use strum::IntoEnumIterator; -pub fn screen (app: &App, ms: MainScreen, cursor: Cursor, area: Rect, buf: &mut Buffer) { +pub fn screen (tasks: Vec<&Task>, tab: MainScreen, selection: &HashSet, cursor: Cursor, area: Rect, buf: &mut Buffer) { + let count = tasks.len(); + let w = area.width; + let layout = Layout::default() .direction(Direction::Vertical) .constraints(vec![ @@ -23,9 +28,9 @@ pub fn screen (app: &App, ms: MainScreen, cursor: Cursor, area: Rect, buf: &mut .split(area); Paragraph::new(Line::from( - MainScreen::iter().map(|e| { - let text = format!(" {e} "); - if e == ms { + MainScreen::iter().map(|scr| { + let text = format!(" {scr} "); + if scr == tab { Span::styled(text, Style::default().fg(Color::White).bg(Color::from_u32(0x550055))) } else { Span::styled(text, Style::default().fg(Color::White)) @@ -36,7 +41,6 @@ pub fn screen (app: &App, ms: MainScreen, cursor: Cursor, area: Rect, buf: &mut ).centered()).block(Block::default().borders(Borders::BOTTOM).padding(Padding::top(1))).render(layout[0], buf); let mut list_items = Vec::::new(); - let w = area.width; macro_rules! wx { ($i: literal) => { @@ -54,19 +58,15 @@ pub fn screen (app: &App, ms: MainScreen, cursor: Cursor, area: Rect, buf: &mut ]; - let th = |col: usize| if col == cursor.col % cw.len() { Style::default().bold().bg(Color::from_u32(0x253325)) } else { Style::default() }; let delimiter = || Span::styled("|", Style::default()); let header: Vec = cw.iter().enumerate().map(|(idx, (width, h, _))| Span::styled(format!("{: ^width$}", h, width = width), th(idx))).intersperse_with(delimiter).collect_vec(); - let iterator = || app.tasks.iter().filter(ms.task_filter()); - let item_count = iterator().count(); - let td = |row: usize, col: usize| match (row, col) { - (r, c) if r == cursor.row % item_count && c == cursor.col % cw.len() => Style::default().bg(Color::from_u32(0x007700)), - (r, _) if r == cursor.row % item_count => Style::default().bg(Color::from_u32(0x005500)), + (r, c) if r == cursor.row % count && c == cursor.col % cw.len() => Style::default().bg(Color::from_u32(0x007700)), + (r, _) if r == cursor.row % count => Style::default().bg(Color::from_u32(0x005500)), // (_, c) if c == app.cursor.1 % cw.len() => Style::default().bg(Color::from_u32(0x001500)), _ => Style::default() }; @@ -76,12 +76,12 @@ pub fn screen (app: &App, ms: MainScreen, cursor: Cursor, area: Rect, buf: &mut list_items.push(ListItem::new(Line::from(header))); list_items.push(ListItem::new(Line::from(Span::from("-".repeat(w as usize))))); - for s @ (idx, _task) in iterator().enumerate() { - let idx = idx % item_count; + for s @ (idx, _task) in tasks.into_iter().enumerate() { + let idx = idx % count; let td = tr(idx); - let bg = if app.selection.contains(&idx) { + let bg = if selection.contains(&idx) { Color::from_u32(0x000044) - } else if idx == cursor.row % item_count { + } else if idx == cursor.row % count { Color::from_u32(0x002200) } else { Color::default() @@ -103,9 +103,9 @@ pub fn screen (app: &App, ms: MainScreen, cursor: Cursor, area: Rect, buf: &mut ]) .split(layout[2]); - if !app.selection.is_empty() { - let total = item_count; - let selected = app.selection.len(); + if !selection.is_empty() { + let total = count; + let selected = selection.len(); Paragraph::new(Line::from(Span::styled(format!("[{selected}/{total}]"), Style::default()))).block(Block::default().borders(Borders::ALL)).render(footer[2], buf); } diff --git a/src/main.rs b/src/main.rs index 75cac3d..d9a61a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![feature(variant_count)] #![feature(let_chains)] +#![feature(type_alias_impl_trait)] use color_eyre::Result;