From 1bde70d4249423247afc94714e314879dd3ed586 Mon Sep 17 00:00:00 2001 From: Guy Sandler Date: Tue, 21 Apr 2026 18:55:33 -0700 Subject: [PATCH] better todolist 3 filtering is better --- js/content.js | 112 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 28 deletions(-) diff --git a/js/content.js b/js/content.js index f4b1633..d094ccd 100644 --- a/js/content.js +++ b/js/content.js @@ -833,6 +833,13 @@ function convertToDueDate(dueAt) { final += " at " + date.toLocaleString("en-US", { hour: "numeric", minute: "numeric", hour12: true }); return final; } +function updateIndicator(element) { + const rect = element.getBoundingClientRect(); + const parentRect = element.parentElement.getBoundingClientRect(); + const indicator = document.getElementById("better-todo-indicator"); + indicator.style.width = `${element.offsetWidth*2}px`; + indicator.style.left = `${element.offsetLeft - (element.offsetWidth * .5)}px`; +} // better todo html betterTodoFilter = "tasks"; let domContainers = {}; @@ -849,27 +856,58 @@ async function createTodoSections(location) { `; let filterControl = makeElement("div", location, { "id": "better-todo-filter" }); - filterControl.innerHTML = `
- - - -
`; + filterControl.innerHTML = ` +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + + +
+
+
+
+ `; + setTimeout(() => updateIndicator(document.getElementById("better-todo-assignments")), 10); - document.getElementById("announcement").addEventListener("click", () => { + document.getElementById("better-todo-announcement").addEventListener("click", (e) => { betterTodoFilter = "announcements"; moreAnnouncementCount = 0; + updateIndicator(e.currentTarget); clearTodoList(); createTodoSections(location); }); - document.getElementById("assignments").addEventListener("click", () => { + document.getElementById("better-todo-assignments").addEventListener("click", (e) => { betterTodoFilter = "tasks"; moreAssignmentCount = 0; + updateIndicator(e.currentTarget); clearTodoList(); createTodoSections(location); }); - document.getElementById("completed").addEventListener("click", () => { + document.getElementById("better-todo-completed").addEventListener("click", (e) => { betterTodoFilter = "completed"; moreCompletedCount = 0; + updateIndicator(e.currentTarget); clearTodoList(); createTodoSections(location); }); @@ -877,45 +915,56 @@ async function createTodoSections(location) { let mainSection = makeElement("div", location, { id: "better-todo-main", }); - mainSection.style = "display:flex;flex-direction:column;gap:10px;"; + mainSection.style = "display:flex;flex-direction:column;"; } let mainSection = location.querySelector("#better-todo-main"); assignments.then(data => { - console.log(data); + // console.log(data); data.forEach(item => { announcements = data.filter(item => item.plannable_type == "announcement"); assignmentsDue = data.filter((item) => (item.plannable_type == "assignment" || item.plannable_type == "planner_note") && !item.submissions?.submitted && !item.planner_override?.marked_complete && !item.submissions.graded); completed = data.filter(item => (item.plannable_type == "assignment" || item.plannable_type == "planner_note") && (item.submissions.submitted || item.planner_override?.marked_complete || item.submissions.graded)); }); console.log(assignmentsDue); + console.log(announcements); domContainers = {}; - const groupKeys = ["-1", "0", "1", "2", "3", "4", "5", "6", "7", "14", "21", "30", "Later"]; + const groupKeys = ["-1", "0", "1", "2", "3", "4", "5", "6", "7", "14", "21", "30", "Later", "New", "Seen", "Ungraded", "Graded"]; for (const key of groupKeys) { let wrapper = makeElement("div", mainSection, { style: "display:none;margin-top:10px;", - className: "better-todo-dueheader" - }) - let label = "Due Later"; - if (key == "-1") label = "Overdue"; - else if (key == "0") label = "Due Today"; - else if (key == "1") label = "Tommorow"; - else if (key >= 2 && key < 7) label = "Due in " + key + " days"; - else if (key >= 14 && key < 30) label = "Due in " + key + " months"; - else if (key == 30) label = "Due in 1 month"; + className: "better-todo-dueheader", + }); + let label = ""; + if (key == "Later") label = "Due Later"; + if (key == "-1") label = "Overdue"; + else if (key == "0") label = "Due Today"; + else if (key == "1") label = "Due Tommorow"; + else if (key >= 2 && key < 7) label = "Due " + key + " days"; + else if (key >= 7 && key < 30) label = "Due " + key/7 + " weeks"; + else if (key == "30") label = "Due 1 month"; + else label = "" + key + ""; makeElement("div", wrapper, { - textContent: label, - style: "display:flex;flex-direction:column;gap:10px;" + innerHTML: "" + label + "", + style: "display:flex;flex-direction:column;gap:10px;font-size:12px;" // TODO: might not be theme compatible }) let listContainer = makeElement("div", wrapper, { className: "todo-group-list" }); - listContainer.style = "display:flex;flex-direction:column;gap:10px;margin-top:10px;"; + listContainer.style = "display:flex;flex-direction:column;gap:10px;"; domContainers[key] = { wrapper, listContainer }; } + + if (betterTodoFilter == "tasks") { populateAssignments(); } + if (betterTodoFilter == "announcements") { + populateAnnouncements(); + } + if (betterTodoFilter == "completed") { + populateAssignments(true); + } }); } @@ -928,11 +977,12 @@ function clearTodoList() { }); } -function populateAssignments() { +function populateAssignments(iscompleted = false) { const today = new Date(); today.setHours(0,0,0,0); + let assignments = iscompleted ? completed : assignmentsDue; - assignmentsDue.forEach((item) => { + assignments.forEach((item) => { let dueGroup = -1; let dueDate = new Date(item.plannable_date); dueDate.setHours(0,0,0,0); @@ -968,7 +1018,8 @@ function populateAssignments() { - + +
@@ -987,7 +1038,7 @@ function populateAnnouncements() { const today = new Date(); today.setHours(0,0,0,0); - announcementsDue.forEach((item) => { + announcements.forEach((item) => { let dueGroup = -1; let dueDate = new Date(item.plannable_date); dueDate.setHours(0,0,0,0); @@ -1015,8 +1066,13 @@ function populateAnnouncements() { options.custom_cards_3?.[item.plannable.course_id]?.color ?? "#cccccc"; + let filter = ""; + if (item.plannable.read_state == "read") { + filter = "filter: grayscale(40%);" + } + announcement.innerHTML = ` -
+