From c00500a4e1c2ce4e547fe95f9fd5c85c5553f7a8 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 14 Jun 2023 21:53:38 +0700 Subject: [PATCH] WIP Refactoring methods: Move stuff from input to app --- src/app.rs | 86 ++++++++++++++++++++++-------- src/db.rs | 36 ++++++++----- src/input.rs | 145 +++++++++++++++++++-------------------------------- 3 files changed, 138 insertions(+), 129 deletions(-) diff --git a/src/app.rs b/src/app.rs index 3ab5766..e5ee782 100644 --- a/src/app.rs +++ b/src/app.rs @@ -12,7 +12,7 @@ mod tests; #[derive(Debug, Serialize, Deserialize)] pub struct Column { - pub id: i32, + pub id: i64, pub name: String, pub selected_task_idx: usize, pub tasks: Vec, @@ -116,12 +116,74 @@ 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.selected_task_idx -= 1; + let task1_id = column.get_selected_task().unwrap().id; + let task2_id = column.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); + self.db_conn.set_selected_task_for_column(task_idx, col_id); + true + } else { + false + } + } + + pub fn move_task_down(&mut self) -> bool { + let column = self.get_selected_column_mut(); + if column.selected_task_idx < column.tasks.len().saturating_sub(1) { + 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 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); + true + } else { + false + } + } + pub fn move_task_previous_column(&mut self) { + let first_col = self.get_selected_column_mut(); + 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_column(), + ); + self.db_conn.set_selected_column(self.selected_column_idx); } pub fn move_task_next_column(&mut self) { + let first_col = self.get_selected_column_mut(); + 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_column(), + ); + self.db_conn.set_selected_column(self.selected_column_idx); + } + + 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(); + 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); } } @@ -173,28 +235,6 @@ impl<'a> Column { self.selected_task_idx = self.tasks.len().saturating_sub(1); } - pub fn move_task_up(&mut self) -> bool { - if self.selected_task_idx > 0 { - self.tasks - .swap(self.selected_task_idx, self.selected_task_idx - 1); - self.selected_task_idx -= 1; - true - } else { - false - } - } - - pub fn move_task_down(&mut self) -> bool { - if self.selected_task_idx < self.tasks.len().saturating_sub(1) { - self.tasks - .swap(self.selected_task_idx, self.selected_task_idx + 1); - self.selected_task_idx += 1; - true - } else { - false - } - } - #[must_use] pub fn get_task_state_from_current(&self) -> Option> { self.get_selected_task().map(|t| TaskState { diff --git a/src/db.rs b/src/db.rs index 07c594f..f74898e 100644 --- a/src/db.rs +++ b/src/db.rs @@ -42,7 +42,9 @@ impl DBConn { /// /// This function will return an error if there are issues with the SQL pub fn get_all_columns(&self) -> Result> { - let mut stmt = self.0.prepare("select id, name, selected_task from kb_column")?; + let mut stmt = self + .0 + .prepare("select id, name, selected_task from kb_column")?; let columns = stmt .query_map((), |row| { let name = row.get(1)?; @@ -83,9 +85,9 @@ impl DBConn { /// # Panics /// /// Panics if something goes wrong with the SQL - pub fn delete_task(&self, task: &Task) { + pub fn delete_task(&self, task_id: i64) { let mut stmt = self.0.prepare("delete from task where id = ?1").unwrap(); - stmt.execute([task.id]).unwrap(); + stmt.execute([task_id]).unwrap(); } /// . @@ -94,7 +96,8 @@ impl DBConn { /// /// Panics if something goes wrong with the SQL pub fn update_task_text(&self, task: &Task) { - let mut stmt = self.0 + let mut stmt = self + .0 .prepare("update task set title = ?2, description = ?3 where id = ?1") .unwrap(); stmt.execute((&task.id, &task.title, &task.description)) @@ -107,7 +110,8 @@ impl DBConn { /// /// Panics if something goes wrong with the SQL pub fn move_task_to_column(&self, task: &Task, target_column: &Column) { - let mut stmt = self.0 + let mut stmt = self + .0 .prepare( "update task set @@ -128,25 +132,25 @@ impl DBConn { /// # Panics /// /// Panics if something goes wrong with the SQL - pub fn swap_task_order(&mut self, task1: &Task, task2: &Task) { + pub fn swap_task_order(&mut self, task1_id: i64, task2_id: i64) { let tx = self.0.transaction().unwrap(); tx.execute( "create temp table temp_order as select sort_order from task where id = ?1", - [&task1.id], + [&task1_id], ) .unwrap(); tx.execute( "update task set sort_order = (select sort_order from task where id = ?2) where id = ?1", - (task1.id, task2.id), + (task1_id, task2_id), ) .unwrap(); tx.execute( "update task set sort_order = (select sort_order from temp_order) where id = ?1", - [&task2.id], + [&task2_id], ) .unwrap(); tx.execute("drop table temp_order", ()).unwrap(); @@ -158,7 +162,8 @@ impl DBConn { /// /// Panics if something goes wrong with the SQL pub fn set_selected_column(&self, column_id: usize) { - let mut stmt = self.0 + let mut stmt = self + .0 .prepare("insert or replace into app_state(key, value) values (?1, ?2)") .unwrap(); stmt.execute((&"selected_column", column_id.to_string())) @@ -169,7 +174,8 @@ impl DBConn { /// /// Panics if something goes wrong with the SQL pub fn get_selected_column(&self) -> usize { - let mut stmt = self.0 + let mut stmt = self + .0 .prepare("select value from app_state where key = ?1") .unwrap(); stmt.query_row(["selected_column"], |row| { @@ -182,8 +188,9 @@ impl DBConn { /// # Panics /// /// Panics if something goes wrong with the SQL - pub fn set_selected_task_for_column(&self, task_idx: usize, column_id: i32) { - let mut stmt = self.0 + pub fn set_selected_task_for_column(&self, task_idx: usize, column_id: i64) { + let mut stmt = self + .0 .prepare("update kb_column set selected_task = ?2 where id = ?1") .unwrap(); stmt.execute((column_id, task_idx)).unwrap(); @@ -193,7 +200,8 @@ impl DBConn { /// /// Panics if something goes wrong with the SQL pub fn get_selected_task_for_column(&self, column_id: i32) -> usize { - let mut stmt = self.0 + let mut stmt = self + .0 .prepare("select selected_task from kb_column where key = ?1") .unwrap(); stmt.query_row([column_id], |row| row.get(0)).unwrap() diff --git a/src/input.rs b/src/input.rs index 9b7b078..9a78dab 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,63 +1,62 @@ use crate::app::{State, TaskEditFocus, TaskState}; -use crate::{db, Column}; 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( - db_conn: &db::DBConn, - column: &mut Column, + state: &mut State<'_>, key: event::KeyEvent, - task_opt: &mut Option>, ) { - let mut task = task_opt.as_mut().unwrap(); - match task.focus { - // TODO: Handle wrapping around the enum rather than doing it manually - TaskEditFocus::Title => match key.code { - KeyCode::Tab => task.focus = TaskEditFocus::Description, - KeyCode::BackTab => task.focus = TaskEditFocus::CancelBtn, - KeyCode::Enter => (), - _ => { - task.title.input(key); - } - }, - TaskEditFocus::Description => match key.code { - KeyCode::Tab => task.focus = TaskEditFocus::ConfirmBtn, - KeyCode::BackTab => task.focus = TaskEditFocus::Title, - _ => { - task.description.input(key); - } - }, - TaskEditFocus::ConfirmBtn => match key.code { - KeyCode::Tab => task.focus = TaskEditFocus::CancelBtn, - KeyCode::BackTab => task.focus = TaskEditFocus::Description, - KeyCode::Enter => { - let title = task.title.clone().into_lines().join("\n"); - let description = task.description.clone().into_lines().join("\n"); - if task.is_edit { - if let Some(selected_task) = column.get_selected_task_mut() { - selected_task.title = title; - selected_task.description = description; - db_conn.update_task_text(selected_task); - } - } else { - let task = db_conn.insert_new_task(title, description, column); - column.add_task(task); - db_conn.set_selected_task_for_column(column.selected_task_idx, column.id); + if let Some(task) = &mut state.task_edit_state { + match task.focus { + // TODO: Handle wrapping around the enum rather than doing it manually + TaskEditFocus::Title => match key.code { + KeyCode::Tab => task.focus = TaskEditFocus::Description, + KeyCode::BackTab => task.focus = TaskEditFocus::CancelBtn, + KeyCode::Enter => (), + _ => { + task.title.input(key); } - *task_opt = None; - } - _ => (), - }, - TaskEditFocus::CancelBtn => match key.code { - KeyCode::Tab => task.focus = TaskEditFocus::Title, - KeyCode::BackTab => task.focus = TaskEditFocus::ConfirmBtn, - KeyCode::Enter => { - *task_opt = None; - } - _ => (), - }, - }; + }, + TaskEditFocus::Description => match key.code { + KeyCode::Tab => task.focus = TaskEditFocus::ConfirmBtn, + KeyCode::BackTab => task.focus = TaskEditFocus::Title, + _ => { + task.description.input(key); + } + }, + TaskEditFocus::ConfirmBtn => match key.code { + KeyCode::Tab => task.focus = TaskEditFocus::CancelBtn, + KeyCode::BackTab => task.focus = TaskEditFocus::Description, + KeyCode::Enter => { + let title = task.title.clone().into_lines().join("\n"); + let description = task.description.clone().into_lines().join("\n"); + let column = state.get_selected_column_mut(); + if task.is_edit { + if let Some(selected_task) = column.get_selected_task_mut() { + selected_task.title = title; + selected_task.description = description; + state.db_conn.update_task_text(selected_task); + } + } else { + let task = state.db_conn.insert_new_task(title, description, column); + column.add_task(task); + state.db_conn.set_selected_task_for_column(column.selected_task_idx, column.id); + } + state.task_edit_state = None; + } + _ => (), + }, + TaskEditFocus::CancelBtn => match key.code { + KeyCode::Tab => task.focus = TaskEditFocus::Title, + KeyCode::BackTab => task.focus = TaskEditFocus::ConfirmBtn, + KeyCode::Enter => { + state.task_edit_state = None; + } + _ => (), + }, + } + } } pub fn handle_main(state: &mut State<'_>, key: event::KeyEvent) { @@ -98,57 +97,20 @@ pub fn handle_main(state: &mut State<'_>, key: event::KeyEvent) { } KeyCode::Char('H') => { if !column.tasks.is_empty() { - let first_col = state.get_selected_column_mut(); - let task_idx = first_col.selected_task_idx.saturating_sub(1); - state.db_conn.set_selected_task_for_column(task_idx, first_col.id); state.move_task_previous_column(); - let col = state.get_selected_column(); - let t = col.get_selected_task().unwrap(); - state.db_conn.move_task_to_column(t, col); - state.db_conn.set_selected_column(state.selected_column_idx); } } KeyCode::Char('L') => { if !column.tasks.is_empty() { - let first_col = state.get_selected_column_mut(); - let task_idx = first_col.selected_task_idx.saturating_sub(1); - state.db_conn.set_selected_task_for_column(task_idx, first_col.id); state.move_task_next_column(); - let col = state.get_selected_column(); - let t = col.get_selected_task().unwrap(); - state.db_conn.move_task_to_column(t, col); - state.db_conn.set_selected_column(state.selected_column_idx); - } - } - KeyCode::Char('J') => { - if column.move_task_down() { - let task1 = column.get_selected_task().unwrap(); - let task2 = column.get_previous_task().unwrap(); - state.db_conn.swap_task_order(task1, task2); - 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); - } - } - KeyCode::Char('K') => { - if column.move_task_up() { - let task1 = column.get_selected_task().unwrap(); - let task2 = column.get_next_task().unwrap(); - state.db_conn.swap_task_order(task1, task2); - 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); } } + 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('D') => { if !column.tasks.is_empty() { - state.db_conn.delete_task(column.get_selected_task().unwrap()); - column.remove_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); } } _ => {} @@ -165,8 +127,7 @@ pub fn handle_main(state: &mut State<'_>, key: event::KeyEvent) { pub fn handle(state: &mut State<'_>) -> Result<(), std::io::Error> { if let Event::Key(key) = event::read()? { if state.task_edit_state.is_some() { - let column = state.get_selected_column_mut(); - handle_task_edit(&state.db_conn, column, key, &mut state.task_edit_state); + handle_task_edit(state, key); } else { handle_main(state, key); }