timeframe for better todo

This commit is contained in:
Guy Sandler 2026-08-25 15:38:00 -07:00
parent cedb83d3d3
commit fcdfe41e84
4 changed files with 70 additions and 2 deletions

View File

@ -69,6 +69,10 @@ h2 {margin-top: 20px;font-weight:600}
#todo_progress_rings option {background:#1e1e1e;color:#e2e2e2;}
#todo_progress_rings option:checked,
#todo_progress_rings option:hover {background:#2e2e2e;color:#fff;}
#todo_timeframe {font-size: 12px;background: var(--inputbg);color:#e2e2e2;border:none;border-radius:7px;padding:6px 8px;font-family:inherit;width:100%;box-sizing:border-box;margin-top:2px;color-scheme:dark;}
#todo_timeframe option {background:#1e1e1e;color:#e2e2e2;}
#todo_timeframe option:checked,
#todo_timeframe option:hover {background:#2e2e2e;color:#fff;}
#advanced-settings, #gpa-bounds-btn, #custom-font-btn, #customize-dark-btn, #card-colors-btn {width: 100%;}
.back-btn {width: 120px;height:100%;margin-top:0}
.big-button {border: none;border-radius: 7px;background: var(--containerbg);color: #fff;font-family: inherit;padding: 12px 10px;font-weight:600}

View File

@ -259,6 +259,16 @@
<option value="line">One line</option>
</select>
</div>
<div class="sub-option" style="flex-direction:column;align-items:stretch;gap:4px;">
<label for="todo_timeframe" class="sub-text">Time frame</label>
<select id="todo_timeframe" name="todo_timeframe">
<option value="all">All time</option>
<option value="1week">1 week</option>
<option value="2week">2 weeks</option>
<option value="month">Month</option>
<option value="2month">2 months</option>
</select>
</div>
<div class="sub-option">
<input type="checkbox" id="todo_confetti" name="todo_confetti">
<label for="todo_confetti" class="sub-text">Show confetti on complete</label>

View File

@ -671,6 +671,10 @@ function applyOptionsChanges(changes) {
)
setupCardAssignments();
loadCardAssignments();
// The card overflow fix in applyAestheticChanges() depends on
// assignments_due, so re-run it when that option toggles to keep
// the overflow rule in sync without a page reload.
applyAestheticChanges();
break;
case "custom_assignments":
case "assignment_date_format":
@ -692,6 +696,7 @@ function applyOptionsChanges(changes) {
case "todo_separate_scrollbar":
case "num_todo_items":
case "hover_preview":
case "todo_timeframe":
// case "todo_overdues":
case "todo_hide_feedback":
case "todo_full_height":
@ -1524,6 +1529,17 @@ function updateIndicator(element) {
}
// better todo html
betterTodoFilter = "tasks";
// Timeframe filter for the upcoming Tasks tab. "all" = no limit; otherwise
// items are limited to those due on/before now+range (which also keeps
// overdue items). Only affects the Tasks (upcoming) tab; announcements and
// completed are unaffected because their dates are in the past.
let betterTodoTimeframe = "all";
const BETTER_TODO_TIMEFRAME_DAYS = {
"1week": 7,
"2week": 14,
"month": 30,
"2month": 60,
};
// null = show every class; a string courseId = only that class's tasks.
let betterTodoProgressFilter = null;
let domContainers = {};
@ -2656,6 +2672,15 @@ async function createTodoSections(location) {
announcements = displayData.filter(item => item.plannable_type == "announcement");
assignmentsDue = displayData.filter(item => (item.plannable_type == "assignment" || item.plannable_type == "planner_note") && !item.submissions?.submitted && !item.planner_override?.marked_complete);
completed = displayData.filter(item => (item.plannable_type == "assignment" || item.plannable_type == "planner_note") && (item.submissions?.submitted || item.planner_override?.marked_complete));
// The timeframe is a persisted Better Todo List sub-option set in the
// popup. Read the current value each render so popup changes apply on
// the next render. Keeps items due on/before now+range (overdue items
// are before now, so they are kept too). Only the Tasks tab is affected.
betterTodoTimeframe = (options.todo_timeframe && Object.prototype.hasOwnProperty.call(BETTER_TODO_TIMEFRAME_DAYS, options.todo_timeframe)) ? options.todo_timeframe : "all";
if (betterTodoTimeframe !== "all") {
const cutoff = Date.now() + (BETTER_TODO_TIMEFRAME_DAYS[betterTodoTimeframe] * 24 * 60 * 60 * 1000);
assignmentsDue = assignmentsDue.filter(item => new Date(item.plannable_date).getTime() <= cutoff);
}
// console.log("assignments", assignmentsDue);
// console.log("announcements", announcements);
// console.log("completed", completed);
@ -5188,7 +5213,16 @@ function applyAestheticChanges() {
// Content-sized cards plus the dashboard reflow loop trigger Firefox scroll
// anchoring to yank the viewport back up while scrolling. A fixed height
// (even the default 250px) keeps layout stable.
if (options.cardHeight !== undefined && options.cardHeight !== null && options.cardHeight !== "") style.textContent += `.ic-DashboardCard {height: ${options.cardHeight}px!important;}`;
if (options.cardHeight !== undefined && options.cardHeight !== null && options.cardHeight !== "") {
style.textContent += `.ic-DashboardCard {height: ${options.cardHeight}px!important;}`;
// Canvas sets overflow:hidden on .ic-DashboardCard. With a fixed
// height that clips the appended .canvasrefined-card-assignment area
// (the assignment rows live at the bottom of the card), making the
// .canvasrefined-assignment-link anchors unclickable for users with
// custom card styles enabled. Allow overflow so those rows stay
// visible and interactive when card assignments are shown.
if (options.assignments_due === true) style.textContent += `.ic-DashboardCard {overflow: visible!important;}`;
}
}
style.textContent += ".ic-app-nav-toggle-and-crumbs{display:none!important}";

View File

@ -4,6 +4,7 @@ const syncedSubOptions = [
"todo_full_height",
"todo_confetti",
"todo_progress_rings",
"todo_timeframe",
"device_dark",
"relative_dues",
"card_overdues",
@ -49,7 +50,7 @@ const exportCardColorToggles = ["gradient_cards", "disable_color_overlay"];
const exportCardStyles = ["customCardStyles", "imageSize", "cardRoundness", "cardSpacing", "cardWidth", "cardHeight"];
const exportLayout = ["full_width", "center_cards", "condensed_cards", "equal_height_cards", "remlogo", "hide_new_canvas", "hide_feedback", "tab_icons"];
const exportSidebar = ["better_sidebar", "sidebar_scale"];
const exportTodo = ["better_todo", "todo_hide_feedback", "todo_full_height", "todo_confetti", "todo_progress_rings", "todo_hr24", "todo_separate_scrollbar", "todo_alternate_colors", "hover_preview"];
const exportTodo = ["better_todo", "todo_hide_feedback", "todo_full_height", "todo_confetti", "todo_progress_rings", "todo_timeframe", "todo_hr24", "todo_separate_scrollbar", "todo_alternate_colors", "hover_preview"];
const exportGpa = ["gpa_calc", "gpa_calc_prepend", "gpa_calc_cumulative", "gpa_calc_weighted"];
const exportBackground = ["customBackgroundLink", "customBackgroundScale", "customBackgroundDaily", "customBackgroundNasaDaily", "fitImageToScreen", "bg_opacity", "sidebar_opacity", "bg_blur", "sidebar_blur"];
// Master "On/off toggles" = every visual toggle (no GPA, no dark-mode schedule,
@ -147,6 +148,7 @@ const defaultOptions = {
"todo_hide_feedback": false,
"todo_full_height": false,
"todo_progress_rings": "rings",
"todo_timeframe": "all",
"todo_confetti": true,
"device_dark": false,
"cumulative_gpa": { "name": "Cumulative GPA", "hidden": false, "weight": "dnc", "credits": 999, "gr": 3.21 },
@ -308,6 +310,19 @@ function setupProgressRingsSelect(initial) {
});
}
// Timeframe dropdown for the upcoming Tasks tab. Persisted so the Better Todo
// List remembers the selected range across sessions.
function setupTimeframeSelect(initial) {
const el = document.querySelector("#todo_timeframe");
if (!el) return;
const allowed = ["all", "1week", "2week", "month", "2month"];
let value = allowed.includes(initial) ? initial : "all";
el.value = value;
el.addEventListener("change", function () {
chrome.storage.sync.set({ "todo_timeframe": this.value });
});
}
function setupAutoDarkInput(initial, time) {
let el = document.querySelector('#' + time);
el.value = initial.hour + ":" + initial.minute;
@ -963,6 +978,10 @@ function setup() {
identifier: "todo_progress_rings",
setup: (initial) => setupProgressRingsSelect(initial),
},
{
identifier: "todo_timeframe",
setup: (initial) => setupTimeframeSelect(initial),
},
],
};
@ -1658,6 +1677,7 @@ function saveCurrentTheme() {
"todo_full_height": current["todo_full_height"],
"todo_confetti": current["todo_confetti"],
"todo_progress_rings": current["todo_progress_rings"],
"todo_timeframe": current["todo_timeframe"],
"todo_hr24": current["todo_hr24"],
"todo_separate_scrollbar": current["todo_separate_scrollbar"],
"better_sidebar": current["better_sidebar"],