progress on modules

This commit is contained in:
Guy Sandler 2026-05-20 22:42:59 -07:00
parent 1efcaa4081
commit 25d8e738b9
2 changed files with 224 additions and 123 deletions

View File

@ -6,6 +6,31 @@ function getCurrentCourseId() {
return match ? parseInt(match[1]) : null; return match ? parseInt(match[1]) : null;
} }
function getSidebarLayoutMode() {
if (current_page.match(/^\/courses\/(\d+)(?:\/|$)/)) return "course";
if (current_page === "/" || current_page === "") return "dash";
return "general";
}
function getSidebarStateMode(mode = getSidebarLayoutMode()) {
return mode === "course" ? "course" : "dashboard";
}
function getSidebarStateKey(mode = getSidebarLayoutMode()) {
return `better_sidebar_expanded_${getSidebarStateMode(mode)}`;
}
async function getSidebarExpandedState(mode = getSidebarLayoutMode()) {
const key = getSidebarStateKey(mode);
const storage = await chrome.storage.local.get(key);
if (typeof storage[key] === "boolean") return storage[key];
return mode === "course";
}
function setSidebarExpandedState(mode, expanded) {
chrome.storage.local.set({ [getSidebarStateKey(mode)]: expanded });
}
let assignments = null; let assignments = null;
let grades = null; let grades = null;
let announcements = []; let announcements = [];
@ -14,6 +39,7 @@ let assignmentsDue = [];
let options = {}; let options = {};
let timeCheck = null; let timeCheck = null;
let reminderCheck = null; let reminderCheck = null;
let betterSidebarLoading = false;
//let assignmentData = null; //let assignmentData = null;
/* /*
@ -269,6 +295,7 @@ function startExtension() {
changeFavicon(); changeFavicon();
updateReminders(); updateReminders();
applyCustomBackground(); applyCustomBackground();
ensureBetterSidebar();
//getClassAverages(); //getClassAverages();
@ -403,20 +430,17 @@ function applyOptionsChanges(changes) {
window.location.reload(); window.location.reload();
} }
case "better_sidebar": case "better_sidebar":
if (options.better_sidebar) setupBetterSidebar(); if (options.better_sidebar) {
// else window.location.reload(); ensureBetterSidebar();
else { } else {
document.getElementById("header").style.display = "block"; resetBetterSidebarLayout();
document.querySelector(".ic-Layout-wrapper")?.style.setProperty("margin-left", "54px"); }
document.getElementById("better-sidebar-container").remove();
}
break; break;
case "sidebar_scale": { case "sidebar_scale": {
const existingSidebar = document.getElementById("better-sidebar-container"); const existingSidebar = document.getElementById("better-sidebar-container");
if (existingSidebar) { if (existingSidebar) {
existingSidebar.remove(); const expander = existingSidebar.querySelector(".better-sidebar-expander");
const mode = current_page.match(/^\/courses\/(\d+)\/?$/) ? "course" : "dash"; updateSidebar(existingSidebar.dataset.expanded === "true", existingSidebar, expander);
setupBetterSidebar(mode);
} }
break; break;
} }
@ -424,6 +448,27 @@ function applyOptionsChanges(changes) {
}); });
} }
function resetBetterSidebarLayout() {
document.getElementById("header")?.style.removeProperty("display");
document.querySelector(".ic-Layout-wrapper")?.style.removeProperty("margin-left");
document.querySelector("#main")?.style.removeProperty("margin-left");
document.querySelector(".ic-app-nav-toggle-and-crumbs")?.style.removeProperty("display");
document.querySelector(".ic-Layout-contentWrapper")?.style.removeProperty("display");
document.querySelector(".ic-Layout-contentWrapper")?.style.removeProperty("align-items");
document.querySelector(".ic-Layout-contentWrapper")?.style.removeProperty("min-width");
document.querySelector(".ic-Layout-contentMain")?.style.removeProperty("flex");
document.querySelector(".ic-Layout-contentMain")?.style.removeProperty("min-width");
document.getElementById("left-side")?.style.removeProperty("display");
document.getElementById("better-sidebar-container")?.remove();
}
function ensureBetterSidebar() {
if (!options.better_sidebar) return;
if (document.querySelector("#better-sidebar-container")) return;
if (!document.querySelector("#wrapper") || !document.querySelector(".ic-Layout-contentWrapper")) return;
setupBetterSidebar(getSidebarLayoutMode());
}
function applyCustomBackground() { function applyCustomBackground() {
// let style = document.querySelector("#DashboardCard_Container") // let style = document.querySelector("#DashboardCard_Container")
let style = document.querySelector("#bettercanvas-background") || document.createElement('style'); let style = document.querySelector("#bettercanvas-background") || document.createElement('style');
@ -446,6 +491,52 @@ function applyCustomBackground() {
backdrop-filter: blur(10px) !important; backdrop-filter: blur(10px) !important;
border-radius: 5px; border-radius: 5px;
} }
.header-bar,
.item-group-condensed,
.item-group-container {
background: transparent !important;
background-color: transparent !important;
backdrop-filter: blur(14px) saturate(120%) !important;
-webkit-backdrop-filter: blur(14px) saturate(120%) !important;
border-radius: 12px !important;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12) !important;
}
.item-group-condensed .ig-header,
.item-group-condensed .ig-row,
.item-group-container .ig-header,
.item-group-container .ig-row,
.item-group-condensed .header,
.item-group-container .header {
background: transparent !important;
background-color: transparent !important;
backdrop-filter: blur(14px) saturate(120%) !important;
-webkit-backdrop-filter: blur(14px) saturate(120%) !important;
}
.item-group-condensed .context_module_item,
.item-group-container .context_module_item {
background: transparent !important;
background-color: transparent !important;
backdrop-filter: blur(10px) saturate(115%) !important;
-webkit-backdrop-filter: blur(10px) saturate(115%) !important;
}
.item-group-condensed .context_module_item:hover,
.item-group-container .context_module_item:hover,
.item-group-condensed .context_module_item.context_module_item_hover,
.item-group-container .context_module_item.context_module_item_hover {
background: transparent !important;
background-color: transparent !important;
backdrop-filter: blur(16px) saturate(130%) !important;
-webkit-backdrop-filter: blur(16px) saturate(130%) !important;
border-radius: 10px !important;
}
.item-group-container {
background: transparent !important;
background-color: transparent !important;
backdrop-filter: blur(10px) !important;
-webkit-backdrop-filter: blur(10px) !important;
border-radius: 12px !important;
border: 1px solid color-mix(in srgb, var(--bcborders) 75%, transparent) !important;
}
.bettercanvas-gpa-card {background: var(--bcbackground-0) !important;} .bettercanvas-gpa-card {background: var(--bcbackground-0) !important;}
.bettercanvas-gpa {background: var(--bcbackground-0) !important;} .bettercanvas-gpa {background: var(--bcbackground-0) !important;}
.ic-DashboardCard {background: var(--bcbackground-0) !important;}`; // todo: liquid glass? .ic-DashboardCard {background: var(--bcbackground-0) !important;}`; // todo: liquid glass?
@ -472,49 +563,47 @@ function resetTimer() {
} }
function checkDashboardReady() { function checkDashboardReady() {
let callback; const callback = (mutationList) => {
if (current_page == "/" || current_page == "") { for (const mutation of mutationList) {
console.log("I am dashboard"); if (mutation.type !== "childList") continue;
callback = (mutationList) => { if (current_page == "/" || current_page == "") {
for (const mutation of mutationList) { console.log("I am dashboard");
if (mutation.type === "childList") { if (mutation.target == document.querySelector("#DashboardCard_Container")) {
if (mutation.target == document.querySelector("#DashboardCard_Container")) { let cards = document.querySelectorAll('.ic-DashboardCard');
let cards = document.querySelectorAll('.ic-DashboardCard'); changeGradientCards();
changeGradientCards(); setupCardAssignments();
setupCardAssignments(); loadCardAssignments();
loadCardAssignments(); customizeCards(cards);
customizeCards(cards); insertGrades();
insertGrades(); loadDashboardNotes();
loadDashboardNotes(); setupGPACalc();
setupGPACalc(); showUpdateMsg();
showUpdateMsg(); } else if (mutation.target == document.querySelector('#right-side')) {
} else if (mutation.target == document.querySelector('#right-side')) { if (!mutation.target.querySelector(".bettercanvas-todosidebar")) {
if (!mutation.target.querySelector(".bettercanvas-todosidebar")) { setupBetterTodo();
setupBetterTodo(); setupBetterSidebar();
setupBetterSidebar(); // loadBetterTodo();
// loadBetterTodo(); }
} }
} } else if (current_page.match(/^\/courses\/(\d+)(?:\/|$)/)) {
} if (mutation.target == document.querySelector('#right-side')) {
} if (!mutation.target.querySelector(".bettercanvas-todosidebar")) {
}; setupBetterTodo();
} setupBetterSidebar(getSidebarLayoutMode());
// else return; }
else { // all outside dashboard }
console.log("I am outside", current_page); } else {
if (current_page.match(/^\/courses\/(\d+)\/?$/)) { // course main pages console.log("I am outside", current_page);
callback = (mutationList) => { if (options.better_sidebar) {
for (const mutation of mutationList) { ensureBetterSidebar();
if (mutation.target == document.querySelector('#right-side')) { }
if (!mutation.target.querySelector(".bettercanvas-todosidebar")) { }
setupBetterTodo();
setupBetterSidebar("course"); if (options.better_sidebar) {
} ensureBetterSidebar();
} }
} }
}; };
}
}
const observer = new MutationObserver(callback); const observer = new MutationObserver(callback);
observer.observe(document.querySelector('html'), { childList: true, subtree: true }); observer.observe(document.querySelector('html'), { childList: true, subtree: true });
@ -1362,83 +1451,90 @@ function applySidebarScaleStyles(sidebarList) {
sidebarList.style.setProperty("--bc-sidebar-label-size", `${Math.round(14 * scale)}px`); sidebarList.style.setProperty("--bc-sidebar-label-size", `${Math.round(14 * scale)}px`);
} }
function setupBetterSidebar(mode = "dash") { async function setupBetterSidebar(mode = getSidebarLayoutMode()) {
if (!options.better_sidebar) return; if (!options.better_sidebar) return;
if (document.querySelector('#better-sidebar-container')) return; if (document.querySelector('#better-sidebar-container')) return;
let wrapper = document.querySelector("#wrapper"); let wrapper = document.querySelector("#wrapper");
if (!wrapper) return; if (!wrapper || betterSidebarLoading) return;
betterSidebarLoading = true;
try { try {
const mainWrapper = document.querySelector(".ic-Layout-contentWrapper"); const layoutMode = mode === "course" || mode === "dash" ? mode : getSidebarLayoutMode();
let courseLinks; const mainWrapper = document.querySelector(".ic-Layout-contentWrapper");
let expanded = false; if (!mainWrapper) return;
if (mode == "dash") { let courseLinks;
document.getElementById("header").style.display = "none"; let expanded = await getSidebarExpandedState(layoutMode);
document.querySelector(".ic-Layout-wrapper")?.style.setProperty("margin-left", "0"); mainWrapper.style.display = "flex";
mainWrapper.style.display = "flex"; mainWrapper.style.alignItems = "stretch";
} mainWrapper.style.minWidth = "0";
else if (mode == "course") { if (layoutMode == "dash") {
document.getElementById("header").style.display = "none"; document.getElementById("header")?.style.setProperty("display", "none");
document.querySelector(".ic-Layout-wrapper")?.style.setProperty("margin-left", "0"); document.querySelector(".ic-Layout-wrapper")?.style.setProperty("margin-left", "0");
document.querySelector("#main")?.style.setProperty("margin-left", "0"); }
// document.getElementById("not_right_side").style.display = "flex"; else if (layoutMode == "course") {
mainWrapper.style.display = "flex"; document.getElementById("header")?.style.setProperty("display", "none");
document.querySelector(".ic-Layout-contentMain").style.flex = "1"; document.querySelector(".ic-Layout-wrapper")?.style.setProperty("margin-left", "0");
document.querySelector(".ic-Layout-contentMain").style.minWidth = "0"; document.querySelector("#main")?.style.setProperty("margin-left", "0");
courseLinks = getCourseLinks(); const contentMain = document.querySelector(".ic-Layout-contentMain");
document.querySelector(".ic-app-nav-toggle-and-crumbs").style.display = "none"; if (contentMain) {
const leftSide = document.getElementById("left-side"); contentMain.style.flex = "1";
if (leftSide) leftSide.style.display = "none"; contentMain.style.minWidth = "0";
expanded = true; }
} courseLinks = getCourseLinks();
document.querySelector(".ic-app-nav-toggle-and-crumbs")?.style.setProperty("display", "none");
const leftSide = document.getElementById("left-side");
if (leftSide) leftSide.style.display = "none";
}
let sidebarList = makeElement("div", mainWrapper, { id: "better-sidebar-container", let sidebarList = makeElement("div", mainWrapper, { id: "better-sidebar-container",
style: `display:flex;flex-direction:column;width:50px;justify-content:center;align-items:center;box-sizing:border-box;position:relative;background-color:var(--bcbackground-0);height:100vh;position:sticky;top:0;left:0;` style: `display:flex;flex-direction:column;width:50px;justify-content:center;align-items:center;box-sizing:border-box;position:relative;background-color:var(--bcbackground-0);height:100vh;position:sticky;top:0;left:0;`
}, true); }, true);
let sidebarContent = makeElement("div", sidebarList, { let sidebarContent = makeElement("div", sidebarList, {
style: "display:flex;flex-direction:column;gap:20px;width:100%;flex:1;justify-content:flex-start;align-items:center;margin:40px;" style: "display:flex;flex-direction:column;gap:20px;width:100%;flex:1;justify-content:flex-start;align-items:center;margin:40px;"
}); });
applySidebarScaleStyles(sidebarList); applySidebarScaleStyles(sidebarList);
// Populate sidebar from Canvas navigation menu dynamically sidebarList.dataset.expanded = expanded ? "true" : "false";
populateSidebarFromNav(sidebarContent); // Populate sidebar from Canvas navigation menu dynamically
populateSidebarFromNav(sidebarContent);
if (mode == "course") { if (layoutMode == "course") {
const courseLinksContainer = makeElement("div", sidebarContent, { const courseLinksContainer = makeElement("div", sidebarContent, {
id: "better-course-links", id: "better-course-links",
style: "display:flex;flex-direction:column;gap:12px;width:calc(100% - 16px);align-items:stretch;margin:15px 8px 0;padding:12px;border-radius:8px;background:linear-gradient(135deg, rgba(var(--bc-primary-rgb), 0.08) 0%, rgba(var(--bc-primary-rgb), 0.04) 100%);border:1px solid rgba(var(--bc-primary-rgb), 0.15);" style: "display:flex;flex-direction:column;gap:12px;width:calc(100% - 16px);align-items:stretch;margin:15px 8px 0;padding:12px;border-radius:8px;background:linear-gradient(135deg, rgba(var(--bc-primary-rgb), 0.08) 0%, rgba(var(--bc-primary-rgb), 0.04) 100%);border:1px solid rgba(var(--bc-primary-rgb), 0.15);"
}); });
if (courseLinks && courseLinks.length > 0) { if (courseLinks && courseLinks.length > 0) {
makeElement("div", courseLinksContainer, { makeElement("div", courseLinksContainer, {
id: "better-course-links-title", id: "better-course-links-title",
textContent: "Course Pages", textContent: "Course Pages",
style: "font-size:11px;color:var(--bctext-0);margin:0;font-weight:600;white-space:nowrap;text-align:center;display:block;letter-spacing:0.5px;text-transform:uppercase;opacity:0.8;" style: "font-size:11px;color:var(--bctext-0);margin:0;font-weight:600;white-space:nowrap;text-align:center;display:block;letter-spacing:0.5px;text-transform:uppercase;opacity:0.8;"
}) })
makeElement("div", courseLinksContainer, { makeElement("div", courseLinksContainer, {
style: "height:1px;background:linear-gradient(90deg, transparent, rgba(var(--bctext-0-rgb), 0.2), transparent);margin:2px 0;" style: "height:1px;background:linear-gradient(90deg, transparent, rgba(var(--bctext-0-rgb), 0.2), transparent);margin:2px 0;"
}) })
courseLinks.forEach((link) => { courseLinks.forEach((link) => {
createSidebarButton( createSidebarButton(
link.name, link.name,
domain + link.url, domain + link.url,
courseLinksContainer, courseLinksContainer,
`<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="width:18px;height:18px;"> `<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="width:18px;height:18px;">
<g id="SVGRepo_bgCarrier" stroke-width="0"></g> <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g> <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
<g id="SVGRepo_iconCarrier"> <g id="SVGRepo_iconCarrier">
<path d="M7.05025 1.53553C8.03344 0.552348 9.36692 0 10.7574 0C13.6528 0 16 2.34721 16 5.24264C16 6.63308 15.4477 7.96656 14.4645 8.94975L12.4142 11L11 9.58579L13.0503 7.53553C13.6584 6.92742 14 6.10264 14 5.24264C14 3.45178 12.5482 2 10.7574 2C9.89736 2 9.07258 2.34163 8.46447 2.94975L6.41421 5L5 3.58579L7.05025 1.53553Z" fill="white"></path> <path d="M7.05025 1.53553C8.03344 0.552348 9.36692 0 10.7574 0C13.6528 0 16 2.34721 16 5.24264C16 6.63308 15.4477 7.96656 14.4645 8.94975L12.4142 11L11 9.58579L13.0503 7.53553C13.6584 6.92742 14 6.10264 14 5.24264C14 3.45178 12.5482 2 10.7574 2C9.89736 2 9.07258 2.34163 8.46447 2.94975L6.41421 5L5 3.58579L7.05025 1.53553Z" fill="white"></path>
<path d="M7.53553 13.0503L9.58579 11L11 12.4142L8.94975 14.4645C7.96656 15.4477 6.63308 16 5.24264 16C2.34721 16 0 13.6528 0 10.7574C0 9.36693 0.552347 8.03344 1.53553 7.05025L3.58579 5L5 6.41421L2.94975 8.46447C2.34163 9.07258 2 9.89736 2 10.7574C2 12.5482 3.45178 14 5.24264 14C6.10264 14 6.92742 13.6584 7.53553 13.0503Z" fill="white"></path> <path d="M7.53553 13.0503L9.58579 11L11 12.4142L8.94975 14.4645C7.96656 15.4477 6.63308 16 5.24264 16C2.34721 16 0 13.6528 0 10.7574C0 9.36693 0.552347 8.03344 1.53553 7.05025L3.58579 5L5 6.41421L2.94975 8.46447C2.34163 9.07258 2 9.89736 2 10.7574C2 12.5482 3.45178 14 5.24264 14C6.10264 14 6.92742 13.6584 7.53553 13.0503Z" fill="white"></path>
<path d="M5.70711 11.7071L11.7071 5.70711L10.2929 4.29289L4.29289 10.2929L5.70711 11.7071Z" fill="white"></path> <path d="M5.70711 11.7071L11.7071 5.70711L10.2929 4.29289L4.29289 10.2929L5.70711 11.7071Z" fill="white"></path>
</g> </g>
</svg>` </svg>`
); );
}); });
} }
} }
let expander = makeElement("div", sidebarList, { let expander = makeElement("div", sidebarList, {
style: "display:flex;flex-direction:column;gap:0px;margin-top:auto;width:100%;justify-content:center;align-items:center;cursor:pointer;", className: "better-sidebar-expander",
}); style: "display:flex;flex-direction:column;gap:0px;margin-top:auto;width:100%;justify-content:center;align-items:center;cursor:pointer;",
});
expander.innerHTML = ` expander.innerHTML = `
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width:30px;height:30px;transition:all .3s ease;"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width:30px;height:30px;transition:all .3s ease;">
<g id="SVGRepo_bgCarrier" stroke-width="0"></g> <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
@ -1448,15 +1544,20 @@ function setupBetterSidebar(mode = "dash") {
</g> </g>
</svg> </svg>
` `
updateSidebar(expanded, sidebarList, expander); updateSidebar(expanded, sidebarList, expander);
// const labels = document.querySelectorAll(".better-sidebar-label"); setSidebarExpandedState(layoutMode, expanded);
// labels.forEach(label => label.style.display = "none"); // const labels = document.querySelectorAll(".better-sidebar-label");
expander.addEventListener("click", () => { // labels.forEach(label => label.style.display = "none");
expanded = !expanded; expander.addEventListener("click", () => {
expanded = !expanded;
sidebarList.dataset.expanded = expanded ? "true" : "false";
setSidebarExpandedState(layoutMode, expanded);
updateSidebar(expanded, sidebarList, expander); updateSidebar(expanded, sidebarList, expander);
}) })
} catch (e) { } catch (e) {
logError(e); logError(e);
} finally {
betterSidebarLoading = false;
} }
} }
function createSidebarButton(text, url, parent, icon) { function createSidebarButton(text, url, parent, icon) {

View File

@ -55,7 +55,7 @@ const defaultOptions = {
}, },
"new_install": true, "new_install": true,
"assignments_due": true, "assignments_due": true,
"gpa_calc": true, "gpa_calc": false,
"dark_mode": true, "dark_mode": true,
"gradent_cards": false, "gradent_cards": false,
"disable_color_overlay": false, "disable_color_overlay": false,
@ -65,7 +65,7 @@ const defaultOptions = {
"num_assignments": 4, "num_assignments": 4,
"custom_domain": [""], "custom_domain": [""],
"assignments_done": [], "assignments_done": [],
"dashboard_grades": true, "dashboard_grades": false,
"assignment_date_format": false, "assignment_date_format": false,
"dashboard_notes": false, "dashboard_notes": false,
"dashboard_notes_text": "", "dashboard_notes_text": "",