From 940e07d72c55e6fc377e561d9c33612206ec1d0d Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 15 Jun 2023 11:53:28 +0700 Subject: [PATCH] WIP Refactoring methods: Move everything into app.rs --- src/app.rs | 182 +++++++++++++++++++++++++++++++-------------------- src/input.rs | 64 +++++------------- src/ui.rs | 2 +- 3 files changed, 129 insertions(+), 119 deletions(-) diff --git a/src/app.rs b/src/app.rs index 098cd01..b3a31c0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -59,7 +59,7 @@ pub struct State<'a> { pub task_edit_state: Option>, } -impl State<'_> { +impl<'a> State<'a> { /// Creates a new [`State`]. /// /// # Panics @@ -90,11 +90,13 @@ impl State<'_> { pub fn select_previous_column(&mut self) -> &Column { self.selected_column_idx = self.selected_column_idx.saturating_sub(1); + self.db_conn.set_selected_column(self.selected_column_idx); &self.columns[self.selected_column_idx] } pub fn select_next_column(&mut self) -> &Column { self.selected_column_idx = min(self.selected_column_idx + 1, self.columns.len() - 1); + self.db_conn.set_selected_column(self.selected_column_idx); &self.columns[self.selected_column_idx] } @@ -109,7 +111,7 @@ impl State<'_> { }; if cond && !column.tasks.is_empty() { let t = column.tasks.remove(column.selected_task_idx); - column.select_previous_task(); + self.select_previous_task(); if move_next { self.select_next_column(); } else { @@ -117,10 +119,75 @@ impl State<'_> { } let col = self.get_selected_column_mut(); col.tasks.push(t); - col.select_last_task(); + self.select_last_task(); } } + #[must_use] + pub fn get_selected_task(&self) -> Option<&Task> { + let column = self.get_selected_column(); + column.tasks.get(column.selected_task_idx) + } + + #[must_use] + pub fn get_previous_task(&self) -> Option<&Task> { + let column = self.get_selected_column(); + column.tasks.get(column.selected_task_idx - 1) + } + + #[must_use] + pub fn get_next_task(&self) -> Option<&Task> { + let column = self.get_selected_column(); + column.tasks.get(column.selected_task_idx + 1) + } + + pub fn get_selected_task_mut(&mut self) -> Option<&mut Task> { + let column = self.get_selected_column_mut(); + column.tasks.get_mut(column.selected_task_idx) + } + + pub fn select_previous_task(&mut self) { + let column = self.get_selected_column_mut(); + let task_idx = &mut column.selected_task_idx; + *task_idx = task_idx.saturating_sub(1); + let task_idx = column.selected_task_idx; + let col_id = self.get_selected_column().id; + self.db_conn.set_selected_task_for_column(task_idx, col_id); + } + + pub fn select_next_task(&mut self) { + let column = self.get_selected_column_mut(); + let task_idx = &mut column.selected_task_idx; + *task_idx = min(*task_idx + 1, column.tasks.len().saturating_sub(1)); + let task_idx = self.get_selected_column().selected_task_idx; + let col_id = self.get_selected_column().id; + self.db_conn.set_selected_task_for_column(task_idx, col_id); + } + + pub fn select_first_task(&mut self) { + self.get_selected_column_mut().selected_task_idx = 0; + let task_idx = self.get_selected_column().selected_task_idx; + let col_id = self.get_selected_column().id; + self.db_conn.set_selected_task_for_column(task_idx, col_id); + } + + pub fn select_last_task(&mut self) { + let column = self.get_selected_column_mut(); + column.selected_task_idx = column.tasks.len().saturating_sub(1); + let task_idx = column.selected_task_idx; + let col_id = self.get_selected_column().id; + self.db_conn.set_selected_task_for_column(task_idx, col_id); + } + + #[must_use] + pub fn get_task_state_from_current(&self) -> Option> { + self.get_selected_task().map(|t| TaskState { + title: TextArea::from(t.title.lines()), + description: TextArea::from(t.description.lines()), + focus: TaskEditFocus::Title, + is_edit: true, + }) + } /// Returns the move task up of this [`State`]. /// /// # Panics @@ -129,10 +196,12 @@ impl State<'_> { pub fn move_task_up(&mut self) -> bool { let column = self.get_selected_column_mut(); if column.selected_task_idx > 0 { - column.tasks.swap(column.selected_task_idx, column.selected_task_idx - 1); + column + .tasks + .swap(column.selected_task_idx, column.selected_task_idx - 1); column.selected_task_idx -= 1; - let task1_id = column.get_selected_task().unwrap().id; - let task2_id = column.get_next_task().unwrap().id; + let task1_id = self.get_selected_task().unwrap().id; + let task2_id = self.get_next_task().unwrap().id; let col_id = column.id; let task_idx = column.selected_task_idx; self.db_conn.swap_task_order(task1_id, task2_id); @@ -154,8 +223,8 @@ impl State<'_> { let task_idx = column.selected_task_idx; column.tasks.swap(task_idx, task_idx + 1); column.selected_task_idx += 1; - let task1_id = column.get_selected_task().unwrap().id; - let task2_id = column.get_previous_task().unwrap().id; + let task1_id = self.get_selected_task().unwrap().id; + let task2_id = self.get_previous_task().unwrap().id; let col_id = column.id; self.db_conn.swap_task_order(task1_id, task2_id); self.db_conn.set_selected_task_for_column(task_idx, col_id); @@ -172,12 +241,15 @@ impl State<'_> { /// We have conditions to ensure this doesn't panic but we still unwrap() pub fn move_task_previous_column(&mut self) { let first_col = self.get_selected_column_mut(); + if first_col.tasks.is_empty() { + return; + } let task_idx = first_col.selected_task_idx.saturating_sub(1); let col_id = first_col.id; self.db_conn.set_selected_task_for_column(task_idx, col_id); self.move_task_to_column(false); self.db_conn.move_task_to_column( - self.get_selected_column().get_selected_task().unwrap(), + self.get_selected_task().unwrap(), self.get_selected_column(), ); self.db_conn.set_selected_column(self.selected_column_idx); @@ -190,17 +262,40 @@ impl State<'_> { /// We have conditions to ensure this doesn't panic but we still unwrap() pub fn move_task_next_column(&mut self) { let first_col = self.get_selected_column_mut(); + if first_col.tasks.is_empty() { + return; + } let task_idx = first_col.selected_task_idx.saturating_sub(1); let col_id = first_col.id; self.db_conn.set_selected_task_for_column(task_idx, col_id); self.move_task_to_column(true); self.db_conn.move_task_to_column( - self.get_selected_column().get_selected_task().unwrap(), + self.get_selected_task().unwrap(), self.get_selected_column(), ); self.db_conn.set_selected_column(self.selected_column_idx); } + pub fn add_new_task(&mut self, title: String, description: String) { + let column = self.get_selected_column_mut(); + let selected_task_idx = column.selected_task_idx; + let task = self.db_conn.insert_new_task(title, description, column.id); + column.tasks.push(task); + self.select_last_task(); + self.db_conn + .set_selected_task_for_column(selected_task_idx, column.id); + } + + pub fn edit_task(&mut self, title: String, description: String) { + let _column = self.get_selected_column_mut(); + if let Some(selected_task) = self.get_selected_task_mut() { + selected_task.title = title; + selected_task.description = description; + let cloned = selected_task.clone(); + self.db_conn.update_task_text(&cloned); + } + } + /// Returns the delete task of this [`State`]. /// /// # Panics @@ -208,70 +303,15 @@ impl State<'_> { /// We have conditions to ensure this doesn't panic but we still unwrap() pub fn delete_task(&mut self) { let column = self.get_selected_column_mut(); - let task_id = column.get_selected_task().unwrap().id; - column.remove_task(); + if column.tasks.is_empty() { + return + } + let task_id = self.get_selected_task().unwrap().id; + column.tasks.remove(column.selected_task_idx); + self.select_next_task(); let task_idx = column.selected_task_idx; let col_id = self.get_selected_column().id; self.db_conn.delete_task(task_id); self.db_conn.set_selected_task_for_column(task_idx, col_id); } } - -impl<'a> Column { - pub fn add_task(&mut self, task: Task) { - self.tasks.push(task); - self.select_last_task(); - } - - pub fn remove_task(&mut self) { - self.tasks.remove(self.selected_task_idx); - self.select_next_task(); - } - - #[must_use] - pub fn get_selected_task(&self) -> Option<&Task> { - self.tasks.get(self.selected_task_idx) - } - - #[must_use] - pub fn get_previous_task(&self) -> Option<&Task> { - self.tasks.get(self.selected_task_idx - 1) - } - - #[must_use] - pub fn get_next_task(&self) -> Option<&Task> { - self.tasks.get(self.selected_task_idx + 1) - } - - pub fn get_selected_task_mut(&mut self) -> Option<&mut Task> { - self.tasks.get_mut(self.selected_task_idx) - } - - pub fn select_previous_task(&mut self) { - let task_idx = &mut self.selected_task_idx; - *task_idx = task_idx.saturating_sub(1); - } - - pub fn select_next_task(&mut self) { - let task_idx = &mut self.selected_task_idx; - *task_idx = min(*task_idx + 1, self.tasks.len().saturating_sub(1)); - } - - pub fn select_first_task(&mut self) { - self.selected_task_idx = 0; - } - - pub fn select_last_task(&mut self) { - self.selected_task_idx = self.tasks.len().saturating_sub(1); - } - - #[must_use] - pub fn get_task_state_from_current(&self) -> Option> { - self.get_selected_task().map(|t| TaskState { - title: TextArea::from(t.title.lines()), - description: TextArea::from(t.description.lines()), - focus: TaskEditFocus::Title, - is_edit: true, - }) - } -} diff --git a/src/input.rs b/src/input.rs index 0011398..36df82e 100644 --- a/src/input.rs +++ b/src/input.rs @@ -3,10 +3,7 @@ use crossterm::event; use crossterm::event::{Event, KeyCode}; // pub fn handle_task_edit(state: &mut State<'_>, key: event::KeyEvent, mut task: TaskState<'_>) { -pub fn handle_task_edit( - state: &mut State<'_>, - key: event::KeyEvent, -) { +pub fn handle_task_edit(state: &mut State<'_>, key: event::KeyEvent) { if let Some(mut task) = state.task_edit_state.take() { let mut clear_task = false; match task.focus { @@ -33,19 +30,9 @@ pub fn handle_task_edit( let title = task.title.clone().into_lines().join("\n"); let description = task.description.clone().into_lines().join("\n"); if task.is_edit { - let column = state.get_selected_column_mut(); - if let Some(selected_task) = column.get_selected_task_mut() { - selected_task.title = title; - selected_task.description = description; - let cloned = selected_task.clone(); - state.db_conn.update_task_text(&cloned); - } + state.edit_task(title, description); } else { - let col_id = state.get_selected_column().id; - let selected_task_idx = state.get_selected_column().selected_task_idx; - let task = state.db_conn.insert_new_task(title, description, col_id); - state.get_selected_column_mut().add_task(task); - state.db_conn.set_selected_task_for_column(selected_task_idx, col_id); + state.add_new_task(title, description); } clear_task = true; } @@ -67,59 +54,42 @@ pub fn handle_task_edit( } pub fn handle_main(state: &mut State<'_>, key: event::KeyEvent) { - let column = state.get_selected_column_mut(); match key.code { KeyCode::Char('q') => state.quit = true, KeyCode::Char('h') | KeyCode::Left => { state.select_previous_column(); - state.db_conn.set_selected_column(state.selected_column_idx); } KeyCode::Char('j') | KeyCode::Down => { - column.select_next_task(); - let task_idx = column.selected_task_idx; - let col_id = state.get_selected_column().id; - state.db_conn.set_selected_task_for_column(task_idx, col_id); + state.select_next_task(); } KeyCode::Char('k') | KeyCode::Up => { - column.select_previous_task(); - let task_idx = column.selected_task_idx; - let col_id = state.get_selected_column().id; - state.db_conn.set_selected_task_for_column(task_idx, col_id); + state.select_previous_task(); } KeyCode::Char('l') | KeyCode::Right => { state.select_next_column(); - state.db_conn.set_selected_column(state.selected_column_idx); } KeyCode::Char('g') => { - column.select_first_task(); - let task_idx = column.selected_task_idx; - let col_id = state.get_selected_column().id; - state.db_conn.set_selected_task_for_column(task_idx, col_id); + state.select_first_task(); } KeyCode::Char('G') => { - column.select_last_task(); - let task_idx = column.selected_task_idx; - let col_id = state.get_selected_column().id; - state.db_conn.set_selected_task_for_column(task_idx, col_id); + state.select_last_task(); } KeyCode::Char('H') => { - if !column.tasks.is_empty() { - state.move_task_previous_column(); - } + state.move_task_previous_column(); } KeyCode::Char('L') => { - if !column.tasks.is_empty() { - state.move_task_next_column(); - } + state.move_task_next_column(); + } + KeyCode::Char('J') => { + state.move_task_down(); + } + KeyCode::Char('K') => { + state.move_task_up(); } - KeyCode::Char('J') => { state.move_task_down(); }, - KeyCode::Char('K') => { state.move_task_up(); }, KeyCode::Char('n') => state.task_edit_state = Some(TaskState::default()), - KeyCode::Char('e') => state.task_edit_state = column.get_task_state_from_current(), + KeyCode::Char('e') => state.task_edit_state = state.get_task_state_from_current(), KeyCode::Char('D') => { - if !column.tasks.is_empty() { - state.delete_task(); - } + state.delete_task(); } _ => {} } diff --git a/src/ui.rs b/src/ui.rs index d6bd30b..61ad660 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -60,7 +60,7 @@ fn draw_tasks(f: &mut Frame<'_, B>, area: Rect, state: &State<'_>) { fn draw_task_info(f: &mut Frame<'_, B>, area: Rect, state: &State<'_>) { let block = Block::default().title("TASK INFO").borders(Borders::ALL); - if let Some(task) = state.get_selected_column().get_selected_task() { + if let Some(task) = state.get_selected_task() { let p = Paragraph::new(task.description.as_str()) .block(block) .wrap(Wrap { trim: true });