fin app
This commit is contained in:
		
							
								
								
									
										104
									
								
								src/db.rs
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								src/db.rs
									
									
									
									
									
								
							@@ -1,24 +1,58 @@
 | 
				
			|||||||
use crate::todo::{ChangeType, TaskColumn};
 | 
					use crate::todo;
 | 
				
			||||||
 | 
					use crate::todo::{ChangeType, TaskColumn, TaskListDB};
 | 
				
			||||||
use rusqlite::{params, Connection, Error, Result};
 | 
					use rusqlite::{params, Connection, Error, Result};
 | 
				
			||||||
use std::path::Path;
 | 
					use std::path::Path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn startup(path: &Path) -> Result<(Connection)> {
 | 
					pub(crate) fn startup(path: &Path) -> std::result::Result<Connection, Error> {
 | 
				
			||||||
    let conn = Connection::open(path)?;
 | 
					    let conn = Connection::open(path)?;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    conn.execute(
 | 
					    conn.execute(
 | 
				
			||||||
        "CREATE TABLE IF NOT EXISTS tasks (
 | 
					        "CREATE TABLE IF NOT EXISTS task_group (
 | 
				
			||||||
                id INTEGER PRIMARY KEY,
 | 
					                id INTEGER PRIMARY KEY,
 | 
				
			||||||
                checked INTEGER NOT NULL,
 | 
					                value TEXT NOT NULL,
 | 
				
			||||||
                value TEXT NOT NULL
 | 
					                UNIQUE(value)
 | 
				
			||||||
        )",
 | 
					        )",
 | 
				
			||||||
        ()
 | 
					        ()
 | 
				
			||||||
    )?;
 | 
					    )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conn.execute(
 | 
				
			||||||
 | 
					        "INSERT OR IGNORE INTO task_group (value) VALUES (?1)",
 | 
				
			||||||
 | 
					        (&todo::DEFAULT_NAME,)
 | 
				
			||||||
 | 
					    )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Err(e) = create_tasklist_tables(&conn) {
 | 
				
			||||||
 | 
					        eprintln!("[ERROR] Failed to create tasklist tables:\n{e}");
 | 
				
			||||||
 | 
					        return Err(e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Ok(conn)
 | 
					    Ok(conn)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn get_tasks(conn: &Connection) -> std::result::Result<Vec<TaskColumn>, Error> {
 | 
					fn create_tasklist_tables(conn: &Connection) -> Result<()> {
 | 
				
			||||||
    let mut stmt = conn.prepare("SELECT id, checked, value FROM tasks")?;
 | 
					    let tl = get_tasklists(&conn)?;
 | 
				
			||||||
 | 
					    if tl.len() < 1 {
 | 
				
			||||||
 | 
					        return Ok(());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for item in 1..tl.len()+1 {
 | 
				
			||||||
 | 
					        let stmt = format!("CREATE TABLE IF NOT EXISTS t{item} (
 | 
				
			||||||
 | 
					                id INTEGER PRIMARY KEY,
 | 
				
			||||||
 | 
					                checked INTEGER NOT NULL,
 | 
				
			||||||
 | 
					                value TEXT NOT NULL
 | 
				
			||||||
 | 
					        )");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        conn.execute(
 | 
				
			||||||
 | 
					            &stmt.to_string(),
 | 
				
			||||||
 | 
					            ()
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(crate) fn get_tasks(conn: &Connection, tl_id: usize) -> std::result::Result<Vec<TaskColumn>, Error> {
 | 
				
			||||||
 | 
					    let stmt_format = format!("SELECT id, checked, value FROM t{tl_id}");
 | 
				
			||||||
 | 
					    let mut stmt = conn.prepare(stmt_format.as_ref())?;
 | 
				
			||||||
    let tasks_iter = stmt.query_map([], |row| {
 | 
					    let tasks_iter = stmt.query_map([], |row| {
 | 
				
			||||||
        Ok(TaskColumn {
 | 
					        Ok(TaskColumn {
 | 
				
			||||||
            id: row.get(0)?,
 | 
					            id: row.get(0)?,
 | 
				
			||||||
@@ -36,22 +70,27 @@ pub(crate) fn get_tasks(conn: &Connection) -> std::result::Result<Vec<TaskColumn
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn insert_task(conn: &Connection, task: TaskColumn) -> Result<i64> {
 | 
					pub(crate) fn insert_task(conn: &Connection, task: TaskColumn) -> Result<i64> {
 | 
				
			||||||
 | 
					    let stmt = format!("INSERT INTO t{} (checked, value) VALUES (?1, ?2)", &task.id);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    conn.execute(
 | 
					    conn.execute(
 | 
				
			||||||
        "INSERT INTO tasks (checked, value) VALUES (?1, ?2)",
 | 
					        &stmt,
 | 
				
			||||||
        (&task.checked, &task.value),
 | 
					        (&task.checked, &task.value),
 | 
				
			||||||
    )?;
 | 
					    )?;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Ok(conn.last_insert_rowid())
 | 
					    Ok(conn.last_insert_rowid())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn update_task(conn: &Connection, task: TaskColumn, change: ChangeType) -> Result<()> {
 | 
					pub(crate) fn update_task(conn: &Connection, task: TaskColumn, change: ChangeType, tl_id: usize) -> Result<()> {
 | 
				
			||||||
 | 
					    let val = format!("UPDATE t{tl_id} SET value = ?1 WHERE id = ?2");
 | 
				
			||||||
 | 
					    let check = format!("UPDATE t{tl_id} SET checked = ?1 WHERE id = ?2");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    let (query, params) = match change {
 | 
					    let (query, params) = match change {
 | 
				
			||||||
        ChangeType::Checked => (
 | 
					        ChangeType::Checked => (
 | 
				
			||||||
            "UPDATE tasks SET checked = ?1 WHERE id = ?2",
 | 
					            check.as_ref(),
 | 
				
			||||||
            params![&task.checked, &task.id]
 | 
					            params![&task.checked, &task.id]
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        ChangeType::Value => (
 | 
					        ChangeType::Value => (
 | 
				
			||||||
            "UPDATE tasks SET value = ?1 WHERE id = ?2",
 | 
					            val.as_ref(),
 | 
				
			||||||
            params![&task.value, &task.id]
 | 
					            params![&task.value, &task.id]
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@@ -60,27 +99,58 @@ pub(crate) fn update_task(conn: &Connection, task: TaskColumn, change: ChangeTyp
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn update_unselect_tasks(conn: &Connection, checked: bool) -> Result<()> {
 | 
					pub(crate) fn update_unselect_tasks(conn: &Connection, checked: bool, tl_id: usize) -> Result<()> {
 | 
				
			||||||
 | 
					    let stmt = format!("UPDATE t{tl_id} SET checked = ?1");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    conn.execute(
 | 
					    conn.execute(
 | 
				
			||||||
        "UPDATE tasks SET checked = ?1",
 | 
					        stmt.as_ref(),
 | 
				
			||||||
        (&checked,)
 | 
					        (&checked,)
 | 
				
			||||||
    )?;
 | 
					    )?;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn delete_tasks(conn: &Connection, id: Option<usize>) -> Result<()> {
 | 
					pub(crate) fn delete_tasks(conn: &Connection, id: Option<usize>, tl_id: usize) -> Result<()> {
 | 
				
			||||||
 | 
					    let del_id = format!("DELETE FROM t{tl_id} WHERE id = ?1").to_string();
 | 
				
			||||||
 | 
					    let full_del = format!("DELETE FROM t{tl_id}").to_string();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    let (query, params) = match id { 
 | 
					    let (query, params) = match id { 
 | 
				
			||||||
        Some(t) => (
 | 
					        Some(t) => (
 | 
				
			||||||
            "DELETE FROM tasks WHERE id = ?1",
 | 
					            del_id.as_ref(),
 | 
				
			||||||
            params![t.clone()]
 | 
					            params![t.clone()]
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        None => (
 | 
					        None => (
 | 
				
			||||||
            "DELETE FROM tasks",
 | 
					            full_del.as_ref(),
 | 
				
			||||||
            params![]
 | 
					            params![]
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    conn.execute(query, params)?;
 | 
					    conn.execute(query, params)?;
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(crate) fn insert_tasklist(conn: &Connection, task_name: &str) -> Result<i64> {
 | 
				
			||||||
 | 
					    conn.execute(
 | 
				
			||||||
 | 
					        "INSERT OR IGNORE INTO task_group (value) VALUES (?1)",
 | 
				
			||||||
 | 
					        (&task_name,)
 | 
				
			||||||
 | 
					    )?;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Ok(conn.last_insert_rowid())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(super) fn get_tasklists(conn: &Connection) -> std::result::Result<Vec<TaskListDB>, Error> {
 | 
				
			||||||
 | 
					    let mut stmt = conn.prepare("SELECT id, value FROM task_group")?;
 | 
				
			||||||
 | 
					    let tasks_iter = stmt.query_map([], |row| {
 | 
				
			||||||
 | 
					        Ok(TaskListDB {
 | 
				
			||||||
 | 
					            id: row.get(0)?,
 | 
				
			||||||
 | 
					            value: row.get(1)?,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    })?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut tasks = Vec::new();
 | 
				
			||||||
 | 
					    for task in tasks_iter {
 | 
				
			||||||
 | 
					        tasks.push(task?);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(tasks)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										135
									
								
								src/todo.rs
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								src/todo.rs
									
									
									
									
									
								
							@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					use std::default::Default;
 | 
				
			||||||
use crate::db;
 | 
					use crate::db;
 | 
				
			||||||
use iced::keyboard::key;
 | 
					use iced::keyboard::key;
 | 
				
			||||||
use iced::widget::text::danger;
 | 
					use iced::widget::text::danger;
 | 
				
			||||||
@@ -29,13 +30,13 @@ pub(crate) struct Todo {
 | 
				
			|||||||
    updated_task: String,
 | 
					    updated_task: String,
 | 
				
			||||||
    tasks: Vec<TaskData>,
 | 
					    tasks: Vec<TaskData>,
 | 
				
			||||||
    completed_tasks: usize,
 | 
					    completed_tasks: usize,
 | 
				
			||||||
    local_storage: bool,
 | 
					 | 
				
			||||||
    conn: Connection,
 | 
					    conn: Connection,
 | 
				
			||||||
    select_all: bool,
 | 
					    select_all: bool,
 | 
				
			||||||
    task_list_input: String,
 | 
					    task_list_input: String,
 | 
				
			||||||
    task_list_state: combo_box::State<String>,
 | 
					    task_list_state: combo_box::State<String>,
 | 
				
			||||||
    task_list: Vec<String>,
 | 
					    task_list: Vec<TaskListDB>,
 | 
				
			||||||
    current_task_group: Option<String>,
 | 
					    current_task_list: Option<String>,
 | 
				
			||||||
 | 
					    curr_tl_id: usize,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
@@ -48,7 +49,6 @@ pub enum Message {
 | 
				
			|||||||
    ContentUpdated(ContentType, String),
 | 
					    ContentUpdated(ContentType, String),
 | 
				
			||||||
    Event(Event),
 | 
					    Event(Event),
 | 
				
			||||||
    TaskPush(Option<usize>),
 | 
					    TaskPush(Option<usize>),
 | 
				
			||||||
    StorageToggle(bool),
 | 
					 | 
				
			||||||
    ToggleUnselect(bool),
 | 
					    ToggleUnselect(bool),
 | 
				
			||||||
    SelectedTaskList(String),
 | 
					    SelectedTaskList(String),
 | 
				
			||||||
    AddTaskList,
 | 
					    AddTaskList,
 | 
				
			||||||
@@ -66,12 +66,19 @@ enum ContentType {
 | 
				
			|||||||
    NewList,
 | 
					    NewList,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(crate) struct TaskListDB {
 | 
				
			||||||
 | 
					    pub(crate) id: usize,
 | 
				
			||||||
 | 
					    pub(crate) value: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for Todo {
 | 
					impl Default for Todo {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Todo::new()
 | 
					        Todo::new()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub const DEFAULT_NAME: &str = "general";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Todo {
 | 
					impl Todo {
 | 
				
			||||||
    fn new() -> Self {
 | 
					    fn new() -> Self {
 | 
				
			||||||
        let mut init = Self {
 | 
					        let mut init = Self {
 | 
				
			||||||
@@ -79,31 +86,35 @@ impl Todo {
 | 
				
			|||||||
            updated_task: String::new(),
 | 
					            updated_task: String::new(),
 | 
				
			||||||
            tasks: Vec::new(),
 | 
					            tasks: Vec::new(),
 | 
				
			||||||
            completed_tasks: 0,
 | 
					            completed_tasks: 0,
 | 
				
			||||||
            local_storage: true, // todo eventually get this info from db - if no db set it to true
 | 
					            conn: db::startup("./todolist-db.db3".as_ref()).expect("[ERROR] Failed to access the local storage"),
 | 
				
			||||||
            conn: db::startup("./todolist-db.db3".as_ref())
 | 
					 | 
				
			||||||
                .expect("[ERROR] Failed to access the local storage"),
 | 
					 | 
				
			||||||
            select_all: false,
 | 
					            select_all: false,
 | 
				
			||||||
            task_list_input: String::from(""),
 | 
					            task_list_input: String::new(),
 | 
				
			||||||
            task_list_state: Default::default(),
 | 
					            task_list_state: Default::default(),
 | 
				
			||||||
            task_list: vec![String::from("general")],
 | 
					            task_list: Vec::new(),
 | 
				
			||||||
            current_task_group: Some(String::from("")),
 | 
					            current_task_list: None,
 | 
				
			||||||
 | 
					            curr_tl_id: 1,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Self::set_task_list(&mut init);
 | 
				
			||||||
        Self::load_data_from_db(&mut init);
 | 
					        Self::load_data_from_db(&mut init);
 | 
				
			||||||
        init.task_list_state = combo_box::State::new(init.task_list.clone());
 | 
					        
 | 
				
			||||||
        init.current_task_group = Some(init.task_list[0].clone());
 | 
					        let mut combo_state = Vec::new();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        for item in &init.task_list {
 | 
				
			||||||
 | 
					            combo_state.push(item.value.clone());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        init.task_list_state = combo_box::State::new(combo_state);
 | 
				
			||||||
 | 
					        if !init.task_list.is_empty() {
 | 
				
			||||||
 | 
					            init.current_task_list = Some(init.task_list[0].value.clone());
 | 
				
			||||||
 | 
					            init.curr_tl_id = init.task_list[0].id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        init
 | 
					        init
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    pub(crate) fn update(&mut self, message: Message) -> Task<Message> {
 | 
					    pub(crate) fn update(&mut self, message: Message) -> Task<Message> {
 | 
				
			||||||
        match message {
 | 
					        match message {
 | 
				
			||||||
            Message::ContentUpdated(new, value) => {
 | 
					            Message::ContentUpdated(new, value) => {
 | 
				
			||||||
                /*if new {
 | 
					 | 
				
			||||||
                    self.new_task = String::from(&value);
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    self.updated_task = String::from(&value)
 | 
					 | 
				
			||||||
                }*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                match new {
 | 
					                match new {
 | 
				
			||||||
                    ContentType::NewTask => self.new_task = String::from(&value),
 | 
					                    ContentType::NewTask => self.new_task = String::from(&value),
 | 
				
			||||||
                    ContentType::ExistingTask => self.updated_task = String::from(&value),
 | 
					                    ContentType::ExistingTask => self.updated_task = String::from(&value),
 | 
				
			||||||
@@ -130,7 +141,7 @@ impl Todo {
 | 
				
			|||||||
                let result = db::insert_task(
 | 
					                let result = db::insert_task(
 | 
				
			||||||
                    &self.conn,
 | 
					                    &self.conn,
 | 
				
			||||||
                    TaskColumn {
 | 
					                    TaskColumn {
 | 
				
			||||||
                        id: 0,
 | 
					                        id: self.curr_tl_id,
 | 
				
			||||||
                        checked: false,
 | 
					                        checked: false,
 | 
				
			||||||
                        value: self.new_task.to_string(),
 | 
					                        value: self.new_task.to_string(),
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
@@ -161,7 +172,7 @@ impl Todo {
 | 
				
			|||||||
                    self.completed_tasks -= 1;
 | 
					                    self.completed_tasks -= 1;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if let Err(e) = db::delete_tasks(&self.conn, Some(self.tasks[index].db_id)) {
 | 
					                if let Err(e) = db::delete_tasks(&self.conn, Some(self.tasks[index].db_id), self.curr_tl_id) {
 | 
				
			||||||
                    eprintln!(
 | 
					                    eprintln!(
 | 
				
			||||||
                        "[ERROR] Failed to delete task '{}':\n{e}",
 | 
					                        "[ERROR] Failed to delete task '{}':\n{e}",
 | 
				
			||||||
                        self.tasks[index].value
 | 
					                        self.tasks[index].value
 | 
				
			||||||
@@ -188,6 +199,7 @@ impl Todo {
 | 
				
			|||||||
                        value: self.tasks[id].value.to_string(),
 | 
					                        value: self.tasks[id].value.to_string(),
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    ChangeType::Checked,
 | 
					                    ChangeType::Checked,
 | 
				
			||||||
 | 
					                    self.curr_tl_id,
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if let Err(e) = result {
 | 
					                if let Err(e) = result {
 | 
				
			||||||
@@ -216,6 +228,7 @@ impl Todo {
 | 
				
			|||||||
                            value: self.tasks[index].value.to_string(),
 | 
					                            value: self.tasks[index].value.to_string(),
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                        ChangeType::Value,
 | 
					                        ChangeType::Value,
 | 
				
			||||||
 | 
					                        self.curr_tl_id,
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if let Err(e) = result {
 | 
					                    if let Err(e) = result {
 | 
				
			||||||
@@ -243,7 +256,7 @@ impl Todo {
 | 
				
			|||||||
                widget::focus_previous()
 | 
					                widget::focus_previous()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Message::DeleteAll => {
 | 
					            Message::DeleteAll => {
 | 
				
			||||||
                if let Err(e) = db::delete_tasks(&self.conn, None) {
 | 
					                if let Err(e) = db::delete_tasks(&self.conn, None, self.curr_tl_id) {
 | 
				
			||||||
                    eprintln!("[ERROR] Failed to delete all tasks:\n{e}")
 | 
					                    eprintln!("[ERROR] Failed to delete all tasks:\n{e}")
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -283,20 +296,6 @@ impl Todo {
 | 
				
			|||||||
                Some(i) => Task::perform(async move { Message::EditTask(i) }, |result| result),
 | 
					                Some(i) => Task::perform(async move { Message::EditTask(i) }, |result| result),
 | 
				
			||||||
                None => Task::perform(async { Message::AddTask }, |result| result),
 | 
					                None => Task::perform(async { Message::AddTask }, |result| result),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            Message::StorageToggle(_toggle) => {
 | 
					 | 
				
			||||||
                // todo must be enabled eventually
 | 
					 | 
				
			||||||
                //self.local_storage = toggle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                /*
 | 
					 | 
				
			||||||
                todo
 | 
					 | 
				
			||||||
                here we only call for storage change not implement the whole system
 | 
					 | 
				
			||||||
                as the system should be running since the program startup
 | 
					 | 
				
			||||||
                */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // also how do we even implement that
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Task::none()
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Message::ToggleUnselect(toggle) => {
 | 
					            Message::ToggleUnselect(toggle) => {
 | 
				
			||||||
                self.select_all = toggle;
 | 
					                self.select_all = toggle;
 | 
				
			||||||
                for task in &mut self.tasks {
 | 
					                for task in &mut self.tasks {
 | 
				
			||||||
@@ -309,21 +308,50 @@ impl Todo {
 | 
				
			|||||||
                    self.completed_tasks = 0;
 | 
					                    self.completed_tasks = 0;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if let Err(e) = db::update_unselect_tasks(&self.conn, toggle) {
 | 
					                if let Err(e) = db::update_unselect_tasks(&self.conn, toggle, self.curr_tl_id) {
 | 
				
			||||||
                    eprintln!("[ERROR] Failed to update un/select all operation in database:\n{e}");
 | 
					                    eprintln!("[ERROR] Failed to update un/select all operation in database:\n{e}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Task::none()
 | 
					                Task::none()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Message::SelectedTaskList(task) => {
 | 
					            Message::SelectedTaskList(task) => {
 | 
				
			||||||
                self.current_task_group = Some(task);
 | 
					                for item in &self.task_list {
 | 
				
			||||||
 | 
					                    if item.value == task {
 | 
				
			||||||
 | 
					                        self.curr_tl_id = item.id;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                self.current_task_list = Some(task);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                // reload tasks
 | 
				
			||||||
 | 
					                self.tasks.clear();
 | 
				
			||||||
 | 
					                self.completed_tasks = 0;
 | 
				
			||||||
 | 
					                let _ = self.load_data_from_db();
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                Task::none()
 | 
					                Task::none()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Message::AddTaskList => {
 | 
					            Message::AddTaskList => {
 | 
				
			||||||
                if self.task_list_input.is_empty() { return Task::none(); }
 | 
					                if self.task_list_input.is_empty() { return Task::none(); }
 | 
				
			||||||
                self.task_list.push(self.task_list_input.clone());
 | 
					                let mut combo_state_vec = Vec::new();
 | 
				
			||||||
                self.task_list_state = combo_box::State::new(self.task_list.clone());
 | 
					
 | 
				
			||||||
                self.task_list_input = String::from("");
 | 
					                match db::insert_tasklist(&self.conn, &self.task_list_input) {
 | 
				
			||||||
 | 
					                    Ok(t) => {
 | 
				
			||||||
 | 
					                        self.task_list.push(TaskListDB {
 | 
				
			||||||
 | 
					                            id: t as usize,
 | 
				
			||||||
 | 
					                            value: self.task_list_input.clone(),
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					                        self.current_task_list = Some(self.task_list_input.clone());
 | 
				
			||||||
 | 
					                        self.task_list_input = String::from("");
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        for item in &self.task_list {
 | 
				
			||||||
 | 
					                            combo_state_vec.push(item.value.clone());
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        self.task_list_state = combo_box::State::new(combo_state_vec);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Err(e) => {
 | 
				
			||||||
 | 
					                        eprintln!("[ERROR] tasklist insertion failed:\n{e}");
 | 
				
			||||||
 | 
					                        return Task::none();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                Task::none()
 | 
					                Task::none()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -388,8 +416,8 @@ impl Todo {
 | 
				
			|||||||
        let status = Text::new(format!("{} / {}", self.completed_tasks, self.tasks.len()));
 | 
					        let status = Text::new(format!("{} / {}", self.completed_tasks, self.tasks.len()));
 | 
				
			||||||
        let tasklist = combo_box(
 | 
					        let tasklist = combo_box(
 | 
				
			||||||
            &self.task_list_state,
 | 
					            &self.task_list_state,
 | 
				
			||||||
            "Test...",
 | 
					            "Enter desired task list ...",
 | 
				
			||||||
            self.current_task_group.as_ref(),
 | 
					            self.current_task_list.as_ref(),
 | 
				
			||||||
            Message::SelectedTaskList,
 | 
					            Message::SelectedTaskList,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        .on_input(|str| Message::ContentUpdated(ContentType::NewList, str));
 | 
					        .on_input(|str| Message::ContentUpdated(ContentType::NewList, str));
 | 
				
			||||||
@@ -397,13 +425,10 @@ impl Todo {
 | 
				
			|||||||
        let tasklist_group = row![tasklist.width(Length::Fill), add_tasklist].spacing(5);
 | 
					        let tasklist_group = row![tasklist.width(Length::Fill), add_tasklist].spacing(5);
 | 
				
			||||||
        let unselect =
 | 
					        let unselect =
 | 
				
			||||||
            checkbox("Select all", self.select_all).on_toggle(Message::ToggleUnselect);
 | 
					            checkbox("Select all", self.select_all).on_toggle(Message::ToggleUnselect);
 | 
				
			||||||
        let storage =
 | 
					 | 
				
			||||||
            checkbox("Local storage", self.local_storage).on_toggle(Message::StorageToggle);
 | 
					 | 
				
			||||||
        let footer = row![
 | 
					        let footer = row![
 | 
				
			||||||
            status, 
 | 
					            status, 
 | 
				
			||||||
            tasklist_group,
 | 
					            tasklist_group,
 | 
				
			||||||
            unselect, 
 | 
					            unselect,
 | 
				
			||||||
            storage
 | 
					 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        .padding(10)
 | 
					        .padding(10)
 | 
				
			||||||
        .spacing(10);
 | 
					        .spacing(10);
 | 
				
			||||||
@@ -437,7 +462,7 @@ impl Todo {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn load_data_from_db(&mut self) {
 | 
					    fn load_data_from_db(&mut self) {
 | 
				
			||||||
        if let Ok(t) = db::get_tasks(&self.conn) {
 | 
					        if let Ok(t) = db::get_tasks(&self.conn, self.curr_tl_id) {
 | 
				
			||||||
            for item in t {
 | 
					            for item in t {
 | 
				
			||||||
                let data = TaskData {
 | 
					                let data = TaskData {
 | 
				
			||||||
                    db_id: item.id,
 | 
					                    db_id: item.id,
 | 
				
			||||||
@@ -474,4 +499,18 @@ impl Todo {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        false
 | 
					        false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn set_task_list(&mut self) {
 | 
				
			||||||
 | 
					        match db::get_tasklists(&self.conn) {
 | 
				
			||||||
 | 
					            Ok(tl_db) => {
 | 
				
			||||||
 | 
					                for item in tl_db {
 | 
				
			||||||
 | 
					                    self.task_list.push(TaskListDB {
 | 
				
			||||||
 | 
					                        id: item.id,
 | 
				
			||||||
 | 
					                        value: item.value,
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Err(e) => eprintln!("[ERROR] Failed to get tasklists from DB:\n{e}"),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user