From dab27d46876da486d2eca0c6265b6a8db160676e Mon Sep 17 00:00:00 2001 From: Guy Sandler Date: Fri, 29 May 2026 19:08:25 -0700 Subject: [PATCH] custom image presets + bugfix --- _locales/en/messages.json | 2 +- css/popup.css | 8 ++- html/popup.html | 17 ++++-- js/background.js | 1 + js/backgrounds.js | 32 ++++++++++++ js/content.js | 105 +++++++++++++++++++++++++++----------- js/popup.js | 67 +++++++++++++++++++++++- 7 files changed, 192 insertions(+), 40 deletions(-) create mode 100644 js/backgrounds.js diff --git a/_locales/en/messages.json b/_locales/en/messages.json index bcaa7f8..763e5c7 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -99,7 +99,7 @@ "message": "Text" }, "full_width": { - "message": "Dashboard Full Width" + "message": "Full Width Fix" }, "report_issue": { "message": "Report Issue" diff --git a/css/popup.css b/css/popup.css index d056256..e1e43f1 100644 --- a/css/popup.css +++ b/css/popup.css @@ -20,8 +20,8 @@ h2 {font-size:24px;} .header {font-size: 16px;display: flex;align-items: center;gap:12px; margin-bottom:14px;} .header h1 { font-weight: 600; font-size:24px; } #bclogo {height: 30px;width:30px;filter: none} -#numAssignmentsSlider, #numTodoItemsSlider, #sidebarScaleSlider {display: block;margin-top: 14px;width: 100%;-webkit-appearance: none; appearance: none;background:var(--inputbg);outline: none;height:6px;border-radius:20px;} -#numAssignmentsSlider::-webkit-slider-thumb, #numTodoItemsSlider::-webkit-slider-thumb, #sidebarScaleSlider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none;height: 18px; width: 18px;background: #727272;cursor: pointer;border-radius:30px;} +#numAssignmentsSlider, #numTodoItemsSlider, #sidebarScaleSlider, #customBackgroundScale {display: block;margin-top: 14px;width: 100%;-webkit-appearance: none; appearance: none;background:var(--inputbg);outline: none;height:6px;border-radius:20px;} +#numAssignmentsSlider::-webkit-slider-thumb, #numTodoItemsSlider::-webkit-slider-thumb, #sidebarScaleSlider::-webkit-slider-thumb, #customBackgroundScale::-webkit-slider-thumb {-webkit-appearance: none; appearance: none;height: 18px; width: 18px;background: #727272;cursor: pointer;border-radius:30px;} .option-container {font-size: 14px; margin-top: 8px;background: var(--containerbg);padding: 18px;border-radius: 14px;box-sizing:border-box} .options .option-container {padding: 14px;} a.option-container {display: block;color:#5ca5f6;font-size: 14px;} @@ -96,6 +96,10 @@ h2 {margin-top: 20px;font-weight:600} .theme-button:hover {background-size: 120%; background-position:center;} .theme-button-creator {font-size:10px;white-space:nowrap} .theme-button-title {font-weight: 600;font-size:12px;white-space:nowrap;} +.background-preset-grid {display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 10px;} +.background-preset-card {min-height: 96px; display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start; border-radius: 8px;} +.background-preset-card.selected {outline: 2px solid #56Caf0; outline-offset: 2px;} +.background-preset-scale {font-size:10px;white-space:nowrap;opacity:0.9;} .theme-sort-btn {padding:10px 30px 10px 20px;border-radius:7px;background:none;border:none;color: #9d9d9d;font-size:12px;font-weight:600;text-align: left;cursor: pointer;transition:.18s color} .theme-sort-btn:hover {color: #fff;} .theme-header {display:flex;justify-content: space-between;margin-bottom:10px;align-items:center} diff --git a/html/popup.html b/html/popup.html index 100e43c..5840264 100644 --- a/html/popup.html +++ b/html/popup.html @@ -1,5 +1,5 @@ - + Canvas Refined @@ -301,7 +301,7 @@
- Dashboard full width + Full Width Fix -
+ + diff --git a/js/background.js b/js/background.js index 904e81a..e9a9c23 100644 --- a/js/background.js +++ b/js/background.js @@ -103,6 +103,7 @@ chrome.runtime.onInstalled.addListener(function () { "cardHeight": 250, "customCardStyles": false, "customBackgroundLink": "", + "customBackgroundScale": 100, } }; diff --git a/js/backgrounds.js b/js/backgrounds.js new file mode 100644 index 0000000..8fe99a0 --- /dev/null +++ b/js/backgrounds.js @@ -0,0 +1,32 @@ +const backgroundPresets = [ + { + title: "Nature 1", + credit: "Kalen Emsley", + url: "https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?q=80&w=2670&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", + scale: 120, + }, + { + title: "Nature 2", + credit: "John Fowler", + url: "https://images.unsplash.com/photo-1537819191377-d3305ffddce4?q=80&w=2621&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", + scale: 115, + }, + { + title: "Nature 3", + credit: "HeiKiwi", + url: "https://cdn.pixabay.com/photo/2023/08/23/18/39/dahlia-8209085_1280.jpg", + scale: 110, + }, + { + title: "Moon", + credit: "NASA", + url: "https://images-assets.nasa.gov/image/art002e021283/art002e021283~large.jpg?w=1920&h=1280&fit=clip&crop=faces%2Cfocalpoint", + scale: 140, + }, + { + title: "Illustration 1", + credit: "ahmetyuksek.", + url: "https://cdn.pixabay.com/photo/2025/09/19/05/48/mountain-range-9842371_1280.jpg", + scale: 100, + }, +] \ No newline at end of file diff --git a/js/content.js b/js/content.js index f5cc428..e5956db 100644 --- a/js/content.js +++ b/js/content.js @@ -516,6 +516,9 @@ function applyOptionsChanges(changes) { case "custom_styles": applyAestheticChanges(); break; + case "customBackgroundScale": + applyCustomBackground(); + break; // case "show_updates": // showUpdateMsg(); // break; @@ -624,10 +627,13 @@ function applyCustomBackground() { style.id = "canvasrefined-background"; if (options.customBackgroundLink && options.customBackgroundLink !== "") { + const backgroundScale = Number(options.customBackgroundScale) || 100; style.textContent = ` #wrapper { background-image: url('${options.customBackgroundLink}') !important; - background-size: cover !important; + background-size: ${backgroundScale}% auto !important; + background-repeat: no-repeat !important; + background-position: center center !important; background-attachment: fixed !important; } .ic-Dashboard-header__layout { @@ -3706,43 +3712,80 @@ function setupGPACalc() { try { grades?.then(result => { - if (!document.querySelector(".ic-DashboardCard__box__container")) return; + const dashboardContainer = document.querySelector(".ic-DashboardCard__box__container"); + if (!dashboardContainer) return; - let container2 = document.querySelector(".canvasrefined-gpa-card") || document.createElement("div"); - container2.className = "canvasrefined-gpa-card"; - container2.style.display = options.gpa_calc === true ? "inline-block" : "none"; + let container2 = document.querySelector(".canvasrefined-gpa-card"); + let container = document.querySelector(".canvasrefined-gpa"); + const alreadyRendered = container2?.dataset?.canvasrefinedGpaRendered === "true" && container?.dataset?.canvasrefinedGpaRendered === "true"; - container2.innerHTML = `

GPA

Current

Weighted

Cumulative

`; - let editBtn = makeElement("button", container2, { "className": "canvasrefined-gpa-edit-btn", "textContent": "Edit Calculator" }); - - let container = document.querySelector(".canvasrefined-gpa") || document.createElement("div"); - container.className = "canvasrefined-gpa"; - container.innerHTML = '

GPA Calculator

'; - - if (options.gpa_calc_prepend === true) { - document.querySelector(".ic-DashboardCard__box__container").prepend(container2); - document.querySelector(".ic-DashboardCard__box__container").prepend(container); - } else { - document.querySelector(".ic-DashboardCard__box__container").appendChild(container2); - document.querySelector(".ic-DashboardCard__box__container").appendChild(container); + if (!container2) { + container2 = document.createElement("div"); + container2.className = "canvasrefined-gpa-card"; + } + if (!container) { + container = document.createElement("div"); + container.className = "canvasrefined-gpa"; } - let location = document.querySelector(".canvasrefined-gpa-courses"); - let cumulative = createGPACalcCourse(location, { "id": "cumulative", "enrollments": [{ "has_grading_periods": true, "current_period_computed_current_score": 0 }] }); - cumulative.id = "canvasrefined-cumulative-gpa"; - result.forEach(course => createGPACalcCourse(location, course)); + container2.style.display = options.gpa_calc === true ? "inline-block" : "none"; - container.style.display = "none"; + if (!alreadyRendered) { + container2.innerHTML = `

GPA

Current

Weighted

Cumulative

`; + let editBtn = makeElement("button", container2, { "className": "canvasrefined-gpa-edit-btn", "textContent": "Edit Calculator" }); - editBtn.addEventListener("click", () => { - if (container.style.display === "none") { - container.style.display = "inline-block"; - editBtn.textContent = "Close Calculator"; + container.innerHTML = '

GPA Calculator

'; + + if (options.gpa_calc_prepend === true) { + dashboardContainer.prepend(container2); + dashboardContainer.prepend(container); } else { - container.style.display = "none"; - editBtn.textContent = "Edit Calculator"; + dashboardContainer.appendChild(container2); + dashboardContainer.appendChild(container); } - }); + + let location = document.querySelector(".canvasrefined-gpa-courses"); + if (!location) return; + + let cumulative = createGPACalcCourse(location, { "id": "cumulative", "enrollments": [{ "has_grading_periods": true, "current_period_computed_current_score": 0 }] }); + cumulative.id = "canvasrefined-cumulative-gpa"; + result.forEach(course => createGPACalcCourse(location, course)); + + container.style.display = "none"; + + editBtn.addEventListener("click", () => { + if (container.style.display === "none") { + container.style.display = "inline-block"; + editBtn.textContent = "Close Calculator"; + } else { + container.style.display = "none"; + editBtn.textContent = "Edit Calculator"; + } + }); + + container2.dataset.canvasrefinedGpaRendered = "true"; + container.dataset.canvasrefinedGpaRendered = "true"; + } else { + const weighted = container2.querySelector("#canvasrefined-gpa-weighted")?.parentElement; + const cumulative = container2.querySelector("#canvasrefined-gpa-cumulative")?.parentElement; + if (weighted) weighted.style.display = options.gpa_calc_weighted ? "block" : "none"; + if (cumulative) cumulative.style.display = options.gpa_calc_cumulative ? "block" : "none"; + + const shouldPrepend = options.gpa_calc_prepend === true; + const firstCard = shouldPrepend ? container : container2; + const secondCard = shouldPrepend ? container2 : container; + + if (firstCard.parentElement !== dashboardContainer) { + dashboardContainer.prepend(firstCard); + } + if (secondCard.parentElement !== dashboardContainer) { + if (shouldPrepend) { + dashboardContainer.prepend(secondCard); + } else { + dashboardContainer.appendChild(secondCard); + } + } + } calculateGPA2(); }); @@ -3835,7 +3878,7 @@ function applyAestheticChanges() { if (options.remlogo === true) style.textContent += ".ic-app-header__logomark-container{display:none}"; if (options.disable_color_overlay === true) style.textContent += ".ic-DashboardCard__header_hero{opacity: 0!important} .ic-DashboardCard__header-button-bg{opacity: 1!important}"; if (options.hide_feedback === true) style.textContent += ".recent_feedback {display: none}"; - if (options.full_width === true) style.textContent += ".ic-Layout-wrapper{max-width:100%!important}"; + if (options.full_width === true) style.textContent += "#wrapper,.ic-Layout-wrapper{max-width:100%!important}"; if (options.customCardStyles === true) { if (options.imageSize !== undefined && options.imageSize !== 100) style.textContent += `.ic-DashboardCard__header_image {transform: scale(${options.imageSize / 100})!important; }`; diff --git a/js/popup.js b/js/popup.js index d95bbae..4742a54 100644 --- a/js/popup.js +++ b/js/popup.js @@ -28,6 +28,7 @@ const syncedSubOptions = [ "cardWidth", "cardHeight", "customBackgroundLink", + "customBackgroundScale", "sidebar_scale", ]; const localSwitches = []; @@ -130,6 +131,7 @@ const defaultOptions = { "cardHeight": 250, "customCardStyles": false, "customBackgroundLink": "", + "customBackgroundScale": 100, } }; @@ -293,9 +295,61 @@ function setupCustomBackgroundLink(initial) { el.value = initial || ""; el.addEventListener("input", (e) => { chrome.storage.sync.set({ "customBackgroundLink": e.target.value }); + renderBackgroundPresetSelection(); }) } +function setupCustomBackgroundScale(initial) { + const el = document.querySelector("#customBackgroundScale"); + const output = document.querySelector("#customBackgroundScaleValue"); + if (!el || !output) return; + const value = Number(initial) || 100; + el.value = value; + output.textContent = `${value}%`; + el.addEventListener("input", (e) => { + const nextValue = parseInt(e.target.value); + output.textContent = `${nextValue}%`; + chrome.storage.sync.set({ "customBackgroundScale": nextValue }); + renderBackgroundPresetSelection(); + }); +} + +function renderBackgroundPresetSelection() { + const currentLink = document.querySelector("#customBackgroundLink")?.value || ""; + const currentScale = String(document.querySelector("#customBackgroundScale")?.value || "100"); + document.querySelectorAll(".background-preset-card").forEach(button => { + const matchesLink = button.dataset.backgroundUrl === currentLink; + const matchesScale = button.dataset.backgroundScale === currentScale; + button.classList.toggle("selected", matchesLink && matchesScale); + }); +} + +function displayBackgroundPresets() { + const container = document.querySelector("#background-presets"); + if (!container || container.dataset.rendered === "true" || typeof backgroundPresets === "undefined") return; + container.dataset.rendered = "true"; + container.innerHTML = backgroundPresets.map(preset => ` + + `).join(""); + + container.querySelectorAll(".background-preset-card").forEach(button => { + button.addEventListener("click", () => { + const backgroundUrl = button.dataset.backgroundUrl; + const backgroundScale = parseInt(button.dataset.backgroundScale); + document.querySelector("#customBackgroundLink").value = backgroundUrl; + document.querySelector("#customBackgroundScale").value = backgroundScale; + document.querySelector("#customBackgroundScaleValue").textContent = `${backgroundScale}%`; + chrome.storage.sync.set({ "customBackgroundLink": backgroundUrl, "customBackgroundScale": backgroundScale }); + renderBackgroundPresetSelection(); + }); + }); + renderBackgroundPresetSelection(); +} + function setup() { const menu = { @@ -415,6 +469,10 @@ function setup() { identifier: "customBackgroundLink", setup: (initial) => setupCustomBackgroundLink(initial), }, + { + identifier: "customBackgroundScale", + setup: (initial) => setupCustomBackgroundScale(initial), + }, ], }; @@ -456,6 +514,7 @@ function setup() { document.querySelector("#todo_hr24").checked = result.todo_hr24 == true; */ toggleDarkModeDisable(sync.auto_dark); + displayBackgroundPresets(); }); const specialOptions = menu.special.map(obj => obj.identifier); @@ -602,7 +661,7 @@ function setup() { final = { ...final, ...(await getExport(storage, ["custom_styles"])) }; break; case "export-background": - final = { ...final, ...(await getExport(storage, ["customBackgroundLink"])) }; + final = { ...final, ...(await getExport(storage, ["customBackgroundLink", "customBackgroundScale"])) }; break; } } @@ -857,8 +916,11 @@ function setup() { }); document.getElementById("clearCustomBackground").addEventListener("click", () => { - chrome.storage.sync.set({ "customBackgroundLink": "" }); + chrome.storage.sync.set({ "customBackgroundLink": "", "customBackgroundScale": 100 }); document.querySelector("#customBackgroundLink").value = ""; + document.querySelector("#customBackgroundScale").value = 100; + document.querySelector("#customBackgroundScaleValue").textContent = "100%"; + renderBackgroundPresetSelection(); sendFromPopup("updateBackground"); }); @@ -1206,6 +1268,7 @@ function saveCurrentTheme() { "cardWidth": current["cardWidth"], "cardHeight": current["cardHeight"], "customBackgroundLink": current["customBackgroundLink"], + "customBackgroundScale": current["customBackgroundScale"], } const now = new Date(); local["saved_themes"][now.getTime()] = trimmed;