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 @@
-
+
+
-
Use an image url or upload an image file
+
Pick a preset or use your own image url.
+
+
+
+ Image scale
+ 100%
+
+
+
@@ -1019,6 +1027,7 @@
+
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 = `
`;
- 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 = '
';
-
- 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 = `
`;
+ 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 = '
';
+
+ 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;