about summary refs log tree commit diff
path: root/src/ui/tasks_page.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/tasks_page.rs')
-rw-r--r--src/ui/tasks_page.rs147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/ui/tasks_page.rs b/src/ui/tasks_page.rs
new file mode 100644
index 0000000..fbbaf0c
--- /dev/null
+++ b/src/ui/tasks_page.rs
@@ -0,0 +1,147 @@
+// Furtherance - Track your time without being tracked
+// Copyright (C) 2022  Ricky Kresslein <rk@lakoliu.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+use adw::subclass::prelude::*;
+use adw::prelude::{PreferencesPageExt, PreferencesGroupExt};
+use gtk::subclass::prelude::*;
+use gtk::{glib, prelude::*};
+use chrono::{DateTime, Local, Duration};
+
+use crate::ui::FurTasksGroup;
+use crate::database;
+
+mod imp {
+    use super::*;
+    use glib::subclass;
+    use gtk::CompositeTemplate;
+    use std::cell::RefCell;
+
+    #[derive(Default, Debug, CompositeTemplate)]
+    #[template(resource = "/com/lakoliu/Furtherance/gtk/tasks_page.ui")]
+    pub struct FurTasksPage {
+        pub all_groups: RefCell<Vec<FurTasksGroup>>,
+    }
+
+
+    #[glib::object_subclass]
+    impl ObjectSubclass for FurTasksPage {
+        const NAME: &'static str = "FurTasksPage";
+        type ParentType = adw::PreferencesPage;
+        type Type = super::FurTasksPage;
+
+        fn class_init(klass: &mut Self::Class) {
+            Self::bind_template(klass);
+        }
+
+        fn instance_init(obj: &subclass::InitializingObject<Self>) {
+            obj.init_template();
+        }
+    }
+
+    impl ObjectImpl for FurTasksPage {
+        fn constructed(&self, obj: &Self::Type) {
+            obj.setup_widgets();
+            self.parent_constructed(obj);
+        }
+    }
+
+    impl WidgetImpl for FurTasksPage {}
+    impl PreferencesPageImpl for FurTasksPage {}
+}
+
+glib::wrapper! {
+    pub struct FurTasksPage(
+        ObjectSubclass<imp::FurTasksPage>)
+        @extends gtk::Widget, adw::PreferencesPage;
+}
+
+impl FurTasksPage {
+    fn setup_widgets(&self) {
+        self.build_task_list();
+    }
+
+    pub fn clear_task_list(&self) {
+        let imp = imp::FurTasksPage::from_instance(&self);
+
+        for group in &*imp.all_groups.borrow() {
+            self.remove(group);
+        }
+
+        imp.all_groups.borrow_mut().clear();
+    }
+
+    pub fn build_task_list(&self) {
+        let imp = imp::FurTasksPage::from_instance(&self);
+
+        let mut tasks_list = database::retrieve().unwrap();
+
+        // Reversing chronological order of tasks_list
+        tasks_list.reverse();
+        let mut uniq_date_list: Vec<String> = Vec::new();
+        let mut same_date_list: Vec<database::Task> = Vec::new();
+        let mut tasks_sorted_by_day: Vec<Vec<database::Task>> = Vec::new();
+
+        // Go through tasks list and look at all dates
+        let mut i: u32 = 1;
+        let len = tasks_list.len() as u32;
+        for task in tasks_list {
+            let task_clone = task.clone();
+            let date = DateTime::parse_from_rfc3339(&task.start_time).unwrap();
+            let date = date.format("%h %e").to_string();
+            if !uniq_date_list.contains(&date) {
+                // if same_date_list is empty, push "date" to it
+                // if it is not empty, push it to a vec of vecs, and then clear it
+                // and push "date" to it
+                if same_date_list.is_empty() {
+                    same_date_list.push(task_clone);
+                } else {
+                    tasks_sorted_by_day.push(same_date_list.clone());
+                    same_date_list.clear();
+                    same_date_list.push(task_clone);
+                }
+                uniq_date_list.push(date);
+            } else {
+                // otherwise push the task to the list of others with the same date
+                same_date_list.push(task_clone);
+            }
+            // If this is the last iteration, push the list of objects to sorted_by_day
+            if i == len {
+                tasks_sorted_by_day.push(same_date_list.clone());
+            }
+            i += 1;
+        }
+
+        // Create FurTasksGroups for all unique days
+        let now = Local::now();
+        let yesterday = now - Duration::days(1);
+        let yesterday = yesterday.format("%h %e").to_string();
+        let today = now.format("%h %e").to_string();
+        for i in 0..uniq_date_list.len() {
+            let group = FurTasksGroup::new();
+            if uniq_date_list[i] == today {
+                group.set_title("Today")
+            } else if uniq_date_list[i] == yesterday{
+                group.set_title("Yesterday")
+            } else {
+                group.set_title(&uniq_date_list[i])
+            }
+            self.add(&group);
+            group.add_task_model(tasks_sorted_by_day[i].clone());
+            imp.all_groups.borrow_mut().push(group);
+        }
+    }
+}
+