diff --git a/Cargo.toml b/Cargo.toml index 4483130..a691493 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ version = "0.4" features = ["std"] [dependencies.todo-txt] -version = "4.0" +version = "4.1" features = ["config", "extended"] [build-dependencies] diff --git a/resources/resource.xml b/resources/resource.xml index 09457a6..45293c7 100644 --- a/resources/resource.xml +++ b/resources/resource.xml @@ -8,6 +8,7 @@ inbox.png projects.png search.png + tags.png style.css style_dark.css style_light.css diff --git a/resources/tags.png b/resources/tags.png new file mode 100644 index 0000000..1ec4e6f Binary files /dev/null and b/resources/tags.png differ diff --git a/src/application/mod.rs b/src/application/mod.rs index 10180e4..efccc82 100644 --- a/src/application/mod.rs +++ b/src/application/mod.rs @@ -22,6 +22,7 @@ enum Page { Flag, Done, Search, + Tags, } impl From for Page { @@ -30,10 +31,11 @@ impl From for Page { 0 => Page::Inbox, 1 => Page::Projects, 2 => Page::Contexts, - 3 => Page::Agenda, - 4 => Page::Flag, - 5 => Page::Done, - 6 => Page::Search, + 3 => Page::Tags, + 4 => Page::Agenda, + 5 => Page::Flag, + 6 => Page::Done, + 7 => Page::Search, _ => panic!("Invalid page {n}"), } } @@ -67,6 +69,7 @@ pub struct Model { logger: relm4::Controller, projects: relm4::Controller, search: relm4::Controller, + tags: relm4::Controller, } impl Model { @@ -120,6 +123,7 @@ impl Model { Page::Flag => "flag", Page::Done => "done", Page::Search => "search", + Page::Tags => "tags", }; let image = gtk::Image::from_icon_name(title); @@ -250,6 +254,7 @@ impl Model { self.flag.sender().emit(crate::flag::Msg::Update); self.inbox.sender().emit(crate::inbox::Msg::Update); self.search.sender().emit(crate::search::MsgInput::Update); + self.tags.sender().emit(crate::widgets::tags::MsgInput::Update); } fn watch(&self, sender: relm4::ComponentSender) { @@ -348,6 +353,13 @@ impl relm4::Component for Model { crate::widgets::task::MsgOutput::Edit(task) => Msg::Edit(task), }); + let tags = crate::widgets::tags::Model::builder() + .launch(crate::widgets::tags::Type::Hashtags) + .forward(sender.input_sender(), |output| match output { + crate::widgets::tags::MsgOutput::Complete(task) => Msg::Complete(task), + crate::widgets::tags::MsgOutput::Edit(task) => Msg::Edit(task), + }); + let model = Self { agenda, config: init, @@ -359,6 +371,7 @@ impl relm4::Component for Model { logger, projects, search, + tags, }; let widgets = view_output!(); @@ -468,6 +481,7 @@ impl relm4::Component for Model { append_page: (model.inbox.widget(), None::<>k::Label>), append_page: (model.projects.widget(), None::<>k::Label>), append_page: (model.contexts.widget(), None::<>k::Label>), + append_page: (model.tags.widget(), None::<>k::Label>), append_page: (model.agenda.widget(), None::<>k::Label>), append_page: (model.flag.widget(), None::<>k::Label>), append_page: (model.done.widget(), None::<>k::Label>), diff --git a/src/inbox.rs b/src/inbox.rs index 5a262b6..d8d5700 100644 --- a/src/inbox.rs +++ b/src/inbox.rs @@ -22,7 +22,7 @@ impl Model { .iter() .filter(|x| { !x.finished - && x.projects().is_empty() + && x.projects.is_empty() && (preferences.defered || x.threshold_date.is_none() || x.threshold_date.unwrap() <= today) diff --git a/src/tasks/task.rs b/src/tasks/task.rs index 236bc96..0945e6c 100644 --- a/src/tasks/task.rs +++ b/src/tasks/task.rs @@ -25,7 +25,7 @@ impl Task { }) .into_owned(); - let regex = regex::Regex::new(r"(?P^|[\s])(?P[\+@][\w\-\\]+)").unwrap(); + let regex = regex::Regex::new(r"(?P^|[\s])(?P[\+@#][\w\-\\]+)").unwrap(); subject = regex .replace_all(&subject, "$space$tag") .into_owned(); diff --git a/src/widgets/tags.rs b/src/widgets/tags.rs index 37f1500..34839ac 100644 --- a/src/widgets/tags.rs +++ b/src/widgets/tags.rs @@ -5,6 +5,7 @@ use relm4::ComponentController as _; pub enum Type { Projects, Contexts, + Hashtags, } #[derive(Debug)] @@ -32,6 +33,7 @@ impl Model { let tags = match self.tag { Type::Projects => list.projects(), Type::Contexts => list.contexts(), + Type::Hashtags => list.hashtags(), }; let tags = tags @@ -78,7 +80,7 @@ impl Model { (preferences.done || !x.finished) && !tags.is_empty() - && Self::has_filter(tags, filters) + && Self::has_filter(&tags, filters) && (preferences.defered || x.threshold_date.is_none() || x.threshold_date.unwrap() <= today) @@ -92,8 +94,9 @@ impl Model { fn tags<'a>(&self, task: &'a crate::tasks::Task) -> &'a [String] { match self.tag { - Type::Projects => task.projects(), - Type::Contexts => task.contexts(), + Type::Projects => &task.projects, + Type::Contexts => &task.contexts, + Type::Hashtags => &task.hashtags, } }