This commit is contained in:
Martin Vrhovšek 2025-02-02 14:35:43 +01:00
parent 339cf9d119
commit 33207c2620

View File

@ -1,6 +1,7 @@
use iced::{event, keyboard, widget, Center, Element, Event, Length, Subscription, Task, Theme};
use iced::keyboard::key;
use iced::widget::{button, center, checkbox, column, row, scrollable, text_input, Space, Text};
use iced::widget::text::danger;
use rusqlite::Connection;
use crate::db;
@ -12,12 +13,13 @@ pub struct TaskColumn {
}
pub struct TaskData {
id: usize,
db_id: usize,
checked: bool,
value: String,
edit: bool,
can_update: bool,
can_delete: bool,
already_exists: bool,
}
pub(crate) struct Todo {
@ -75,17 +77,21 @@ impl Todo {
match message {
Message::ContentUpdated(new, value) => {
if new {
self.new_task = value
self.new_task = String::from(&value);
} else {
self.updated_task = value
self.updated_task = String::from(&value)
}
for task in &mut self.tasks {
task.already_exists = task.value == value.to_string();
}
Task::none()
}
Message::AddTask => {
if self.new_task.is_empty() { return Task::none(); }
if self.duplicate_exists(None) { return Task::none(); }
let result = db::insert_task(&self.conn, TaskColumn {
id: 0,
checked: false,
@ -95,12 +101,13 @@ impl Todo {
match result {
Ok(t) => {
let data = TaskData {
id: t as usize,
db_id: t as usize,
checked: false,
value: self.new_task.to_string(),
edit: false,
can_update: true,
can_delete: true,
already_exists: false,
};
self.tasks.push(data);
},
@ -116,7 +123,7 @@ impl Todo {
self.completed_tasks -= 1;
}
if let Err(e) = db::delete_tasks(&self.conn, Some(self.tasks[index].id)) {
if let Err(e) = db::delete_tasks(&self.conn, Some(self.tasks[index].db_id)) {
eprintln!("[ERROR] Failed to delete task '{}':\n{e}", self.tasks[index].value);
}
@ -130,7 +137,7 @@ impl Todo {
self.tasks[id].checked = choice;
let result = db::update_task(&self.conn, TaskColumn {
id: self.tasks[id].id,
id: self.tasks[id].db_id,
checked: self.tasks[id].checked,
value: self.tasks[id].value.to_string(),
}, ChangeType::Checked);
@ -141,36 +148,41 @@ impl Todo {
Task::none()
},
Message::EditTask(id) => {
Message::EditTask(index) => {
let set_update;
if self.tasks[id].edit {
if self.updated_task.is_empty() {
return Task::none();
}
if self.tasks[index].edit {
if self.updated_task.is_empty() { return Task::none(); }
if self.duplicate_exists(Some(&self.tasks[index].value)) { return Task::none(); }
self.tasks[id].value = self.updated_task.clone();
self.tasks[index].value = self.updated_task.clone();
let result = db::update_task(&self.conn, TaskColumn {
id: self.tasks[id].id,
checked: self.tasks[id].checked,
value: self.tasks[id].value.to_string(),
id: self.tasks[index].db_id,
checked: self.tasks[index].checked,
value: self.tasks[index].value.to_string(),
}, ChangeType::Value);
if let Err(e) = result {
eprintln!("[ERROR] Failed to update task '{}' in local storage:\n{e}", self.tasks[id].value);
eprintln!("[ERROR] Failed to update task '{}' in local storage:\n{e}", self.tasks[index].value);
}
set_update = true;
self.updated_task = String::new();
for item in &mut self.tasks {
if item.already_exists {
item.already_exists = false;
}
}
} else {
set_update = false;
}
self.tasks[id].edit = !self.tasks[id].edit;
self.set_other_update(id, set_update);
self.tasks[index].edit = !self.tasks[index].edit;
self.set_other_update(index, set_update);
widget::focus_previous()
},
}
Message::DeleteAll => {
if let Err(e) = db::delete_tasks(&self.conn, None) {
eprintln!("[ERROR] Failed to delete all tasks:\n{e}")
@ -280,7 +292,10 @@ impl Todo {
for (i, task) in self.tasks.iter().enumerate() {
let chk = checkbox("", task.checked).size(25).on_toggle(move |b| Message::CheckTask(b, i));
let label = Text::new(&task.value).width(200);
let mut label = Text::new(&task.value).width(200);
if task.already_exists {
label = label.style(danger);
}
let input = text_input("Enter new name", &self.updated_task)
.width(200)
.on_input(|str| Message::ContentUpdated(false, str))
@ -333,12 +348,13 @@ impl Todo {
if let Ok(t) = db::get_tasks(&self.conn) {
for item in t {
let data = TaskData {
id: item.id,
db_id: item.id,
checked: item.checked,
value: item.value,
edit: false,
can_update: true,
can_delete: true,
already_exists: false,
};
if item.checked {
@ -349,4 +365,20 @@ impl Todo {
}
}
}
fn duplicate_exists(&self, task_name: Option<&String>) -> bool {
for task in &self.tasks {
if task.already_exists {
match task_name {
Some(t) => {
if task.value != *t { return true; }
},
None => return true,
}
}
}
false
}
}