ui revamp 1

started making a new cards ui and refactored styles
This commit is contained in:
Guy Sandler 2026-02-11 22:12:35 -08:00
parent 30ccf9db1d
commit 81f200e5b7
14 changed files with 319 additions and 227 deletions

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "Karten" "message": "Karten"
}, },
"custom_font": { "styles": {
"message": "Schriftarten" "message": "Stile"
}, },
"useddmm": { "useddmm": {
"message": "Verwenden Sie tt/mm" "message": "Verwenden Sie tt/mm"

View File

@ -41,7 +41,7 @@
"card_customization": { "card_customization": {
"message": "Cards" "message": "Cards"
}, },
"custom_font": { "styles": {
"message": "Styles" "message": "Styles"
}, },
"useddmm": { "useddmm": {

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "Personalización de tarjetas" "message": "Personalización de tarjetas"
}, },
"custom_font": { "styles": {
"message": "Fuente personalizada" "message": "Estilos"
}, },
"useddmm": { "useddmm": {
"message": "Usar dd/mm" "message": "Usar dd/mm"

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "Cartes" "message": "Cartes"
}, },
"custom_font": { "styles": {
"message": "Polices de caractères" "message": "Styles"
}, },
"useddmm": { "useddmm": {
"message": "Utiliser jj/mm" "message": "Utiliser jj/mm"

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "Carte" "message": "Carte"
}, },
"custom_font": { "styles": {
"message": "Caratteri" "message": "Stili"
}, },
"useddmm": { "useddmm": {
"message": "Usa gg/mm" "message": "Usa gg/mm"

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "カード" "message": "カード"
}, },
"custom_font": { "styles": {
"message": "フォント" "message": "スタイル"
}, },
"useddmm": { "useddmm": {
"message": "を使用 dd/mm" "message": "を使用 dd/mm"

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "Cartões" "message": "Cartões"
}, },
"custom_font": { "styles": {
"message": "Fontes" "message": "Estilos"
}, },
"useddmm": { "useddmm": {
"message": "Usar dd/mm" "message": "Usar dd/mm"

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "Карты" "message": "Карты"
}, },
"custom_font": { "styles": {
"message": "Шрифты" "message": "Стили"
}, },
"useddmm": { "useddmm": {
"message": "Используйте дд/мм" "message": "Используйте дд/мм"

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "Kort" "message": "Kort"
}, },
"custom_font": { "styles": {
"message": "Teckensnitt" "message": "Stilar"
}, },
"useddmm": { "useddmm": {
"message": "Använd dd/mm" "message": "Använd dd/mm"

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "牌" "message": "牌"
}, },
"custom_font": { "styles": {
"message": "字体" "message": "样式"
}, },
"useddmm": { "useddmm": {
"message": "使用日/毫米" "message": "使用日/毫米"

View File

@ -41,8 +41,8 @@
"card_customization": { "card_customization": {
"message": "牌" "message": "牌"
}, },
"custom_font": { "styles": {
"message": "字体" "message": "样式"
}, },
"useddmm": { "useddmm": {
"message": "使用日/毫米" "message": "使用日/毫米"

View File

@ -201,6 +201,91 @@ input[type="checkbox"]:checked {background: #8dd28d;}
::-webkit-scrollbar-thumb {background: #323232;border-radius:2px;} ::-webkit-scrollbar-thumb {background: #323232;border-radius:2px;}
::-webkit-scrollbar-button {background: #161616; height: 4px} ::-webkit-scrollbar-button {background: #161616; height: 4px}
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 10px;
margin-bottom: 20px;
}
.course-card-button {
background: var(--inputbg);
border: 1px solid var(--borders);
border-radius: 8px;
padding: 15px 10px;
color: #e2e2e2;
font-family: inherit;
font-size: 12px;
font-weight: 600;
cursor: pointer;
transition: 0.2s all ease;
text-align: center;
min-height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
.course-card-button:hover {
background: #adbcc724;
border-color: #56Caf0;
}
.course-card-button.active {
background: #56Caf0;
color: #000;
}
.card-edit-menu {
background: var(--containerbg);
border-radius: 10px;
padding: 20px;
margin-top: 15px;
}
.card-edit-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.card-edit-title {
font-size: 16px;
font-weight: 600;
color: #fff;
}
.card-close-btn {
background: none;
border: none;
color: #999;
font-size: 18px;
cursor: pointer;
padding: 5px;
}
.card-edit-section {
margin-bottom: 15px;
}
.card-edit-label {
font-size: 13px;
color: #c7c7c7;
margin-bottom: 5px;
display: block;
}
.card-image-preview {
width: 100px;
height: 60px;
background-size: cover;
background-position: center;
border-radius: 6px;
margin-top: 8px;
border: 1px solid var(--borders);
}
@keyframes like { @keyframes like {
0% { 0% {
transform: scale(1); transform: scale(1);

View File

@ -44,7 +44,7 @@
</button> </button>
<button id="custom-font-btn" class="big-button tab-btn"> <button id="custom-font-btn" class="big-button tab-btn">
<svg width="15px" height="15px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M15.5 8.5H15.51M10.5 7.5H10.51M7.5 11.5H7.51M12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12C21 13.6569 19.6569 15 18 15H17.4C17.0284 15 16.8426 15 16.6871 15.0246C15.8313 15.1602 15.1602 15.8313 15.0246 16.6871C15 16.8426 15 17.0284 15 17.4V18C15 19.6569 13.6569 21 12 21ZM16 8.5C16 8.77614 15.7761 9 15.5 9C15.2239 9 15 8.77614 15 8.5C15 8.22386 15.2239 8 15.5 8C15.7761 8 16 8.22386 16 8.5ZM11 7.5C11 7.77614 10.7761 8 10.5 8C10.2239 8 10 7.77614 10 7.5C10 7.22386 10.2239 7 10.5 7C10.7761 7 11 7.22386 11 7.5ZM8 11.5C8 11.7761 7.77614 12 7.5 12C7.22386 12 7 11.7761 7 11.5C7 11.2239 7.22386 11 7.5 11C7.77614 11 8 11.2239 8 11.5Z" stroke="#ffffff" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"></path> </g></svg> <svg width="15px" height="15px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M15.5 8.5H15.51M10.5 7.5H10.51M7.5 11.5H7.51M12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12C21 13.6569 19.6569 15 18 15H17.4C17.0284 15 16.8426 15 16.6871 15.0246C15.8313 15.1602 15.1602 15.8313 15.0246 16.6871C15 16.8426 15 17.0284 15 17.4V18C15 19.6569 13.6569 21 12 21ZM16 8.5C16 8.77614 15.7761 9 15.5 9C15.2239 9 15 8.77614 15 8.5C15 8.22386 15.2239 8 15.5 8C15.7761 8 16 8.22386 16 8.5ZM11 7.5C11 7.77614 10.7761 8 10.5 8C10.2239 8 10 7.77614 10 7.5C10 7.22386 10.2239 7 10.5 7C10.7761 7 11 7.22386 11 7.5ZM8 11.5C8 11.7761 7.77614 12 7.5 12C7.22386 12 7 11.7761 7 11.5C7 11.2239 7.22386 11 7.5 11C7.77614 11 8 11.2239 8 11.5Z" stroke="#ffffff" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"></path> </g></svg>
<span data-i18n="custom_font">Styles</span> <span data-i18n="styles">Styles</span>
</button> </button>
<button id="gpa-bounds-btn" class="big-button tab-btn"> <button id="gpa-bounds-btn" class="big-button tab-btn">
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M22 9l-10 -4l-10 4l10 4l10 -4v6"></path><path d="M6 10.6v5.4a6 3 0 0 0 12 0v-5.4"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M22 9l-10 -4l-10 4l10 4l10 -4v6"></path><path d="M6 10.6v5.4a6 3 0 0 0 12 0v-5.4"></path></svg>
@ -673,10 +673,18 @@
<button class="big-button back-btn" data-i18n="back">Back</button> <button class="big-button back-btn" data-i18n="back">Back</button>
</div> </div>
<p class="option-container sub-text" style="margin: 5px 0">Enter <b>"none"</b> to hide images and links.<br>You may need to refresh the page to see some changes.</p> <p class="option-container sub-text" style="margin: 5px 0">Enter <b>"none"</b> to hide images and links.<br>You may need to refresh the page to see some changes.</p>
<div class="advanced-cards"> <!-- <div class="advanced-cards">
<div id="advanced-current"></div> <div id="advanced-current"></div>
<div id="advanced-past"></div> <div id="advanced-past"></div>
</div> </div> -->
<div class="advanced-cards">
<div class="card-grid" id="card-grid">
</div>
<div class="card-edit-menu" id="card-edit-menu" style="display:none;">
</div>
</div>
<div class="option-container"> <div class="option-container">
<h3 class="header-small">More Card Styles</h3> <h3 class="header-small">More Card Styles</h3>
@ -757,7 +765,7 @@
<!-- TODO: make this a dropdown --> <!-- TODO: make this a dropdown -->
<div class="tab-header"> <div class="tab-header">
<div> <div>
<h2 style="margin-top: 0" data-i18n="custom_font">Styles</h2> <h2 style="margin-top: 0" data-i18n="styles">Styles</h2>
</div> </div>
<button class="big-button back-btn" data-i18n="back">Back</button> <button class="big-button back-btn" data-i18n="back">Back</button>
</div> </div>

View File

@ -916,28 +916,6 @@ function clickout() {
}, 10); }, 10);
} }
/*
function sortThemes(method) {
const sortMethods = ["Popular", "ABC", "New", "Old"];
const index = sortMethods.indexOf(method);
const next = index + 1 === sortMethods.length ? 0 : index + 1;
current_sort = sortMethods[next];
allThemes = themeSortFn(current_sort);
document.querySelectorAll(".theme-sort-btn").forEach(btn => {
if (btn.id.includes(method)) {
btn.style.color = "#fff";
btn.style.background = "var(--inputbg)"
} else {
btn.style.color = "#adadad";
btn.style.background = "none"
}
});
current_page_num = 1;
displayThemeList(0);
//cache = {};
}
*/
// shuffle function for the score sorting so theres no order bias // shuffle function for the score sorting so theres no order bias
function shuffle (arr) { function shuffle (arr) {
var j, x, index; var j, x, index;
@ -1546,129 +1524,216 @@ function setCustomImage(key, val) {
function displayAdvancedCards() { function displayAdvancedCards() {
sendFromPopup("getCards"); sendFromPopup("getCards");
chrome.storage.sync.get(["custom_cards", "custom_cards_2"], storage => { chrome.storage.sync.get(["custom_cards", "custom_cards_2"], storage => {
document.querySelector(".advanced-cards").innerHTML = '<div id="advanced-current"></div><div id="advanced-past"><h2>Past Courses</h2></div>'; // document.querySelector(".advanced-cards").innerHTML = '<div id="advanced-current"></div><div id="advanced-past"><h2>Past Courses</h2></div>';
const keys = storage["custom_cards"] ? Object.keys(storage["custom_cards"]) : []; // const keys = storage["custom_cards"] ? Object.keys(storage["custom_cards"]) : [];
if (keys.length > 0) { // if (keys.length > 0) {
let currentEnrollment = keys.reduce((max, key) => storage["custom_cards"][key]?.eid > max ? storage["custom_cards"][key].eid : max, -1); // let currentEnrollment = keys.reduce((max, key) => storage["custom_cards"][key]?.eid > max ? storage["custom_cards"][key].eid : max, -1);
keys.forEach(key => { // keys.forEach(key => {
let term = document.querySelector("#advanced-past"); // let term = document.querySelector("#advanced-past");
if (storage["custom_cards"][key].eid === currentEnrollment) { // if (storage["custom_cards"][key].eid === currentEnrollment) {
term = document.querySelector("#advanced-current"); // term = document.querySelector("#advanced-current");
} // }
let card = storage["custom_cards"][key]; // let card = storage["custom_cards"][key];
let card_2 = storage["custom_cards_2"][key] || {}; // let card_2 = storage["custom_cards_2"][key] || {};
if (!card || !card_2 || !card_2["links"] || card_2["links"]["custom"]) { // if (!card || !card_2 || !card_2["links"] || card_2["links"]["custom"]) {
console.log(key + " error..."); // console.log(key + " error...");
console.log("card = ", card, "card_2", card_2, "links", card_2["links"]); // console.log("card = ", card, "card_2", card_2, "links", card_2["links"]);
} else { // } else {
let container = makeElement("div", term, { "className": "custom-card" }); // let container = makeElement("div", term, { "className": "custom-card" });
container.classList.add("option-container"); // container.classList.add("option-container");
container.innerHTML = '<div class="custom-card-header"><p class="custom-card-title"></p><div class="custom-card-hide"><p class="custom-key">Hide</p></div></div><div class="custom-card-inputs"><div class="custom-card-left"><div class="custom-card-image"><span class="custom-key">Image</span></div><div class="custom-card-name"><span class="custom-key">Name</span></div><div class="custom-card-code"><span class="custom-key">Code</span></div></div><div class="custom-links-container"><p class="custom-key">Links</p><div class="custom-links"></div></div></div>'; // container.innerHTML = '<div class="custom-card-header"><p class="custom-card-title"></p><div class="custom-card-hide"><p class="custom-key">Hide</p></div></div><div class="custom-card-inputs"><div class="custom-card-left"><div class="custom-card-image"><span class="custom-key">Image</span></div><div class="custom-card-name"><span class="custom-key">Name</span></div><div class="custom-card-code"><span class="custom-key">Code</span></div></div><div class="custom-links-container"><p class="custom-key">Links</p><div class="custom-links"></div></div></div>';
let imgInput = makeElement("input", container.querySelector(".custom-card-image"), { "className": "card-input" }); // let imgInput = makeElement("input", container.querySelector(".custom-card-image"), { "className": "card-input" });
let nameInput = makeElement("input", container.querySelector(".custom-card-name"), { "className": "card-input" }); // let nameInput = makeElement("input", container.querySelector(".custom-card-name"), { "className": "card-input" });
let codeInput = makeElement("input", container.querySelector(".custom-card-code"), { "className": "card-input" }); // let codeInput = makeElement("input", container.querySelector(".custom-card-code"), { "className": "card-input" });
let hideInput = makeElement("input", container.querySelector(".custom-card-hide"), { "className": "card-input-checkbox" }); // let hideInput = makeElement("input", container.querySelector(".custom-card-hide"), { "className": "card-input-checkbox" });
imgInput.placeholder = "Image url"; // imgInput.placeholder = "Image url";
nameInput.placeholder = "Custom name"; // nameInput.placeholder = "Custom name";
codeInput.placeholder = "Custom code"; // codeInput.placeholder = "Custom code";
hideInput.type = "checkbox"; // hideInput.type = "checkbox";
imgInput.value = card.img; // imgInput.value = card.img;
nameInput.value = card.name; // nameInput.value = card.name;
codeInput.value = card.code; // codeInput.value = card.code;
hideInput.checked = card.hidden; // hideInput.checked = card.hidden;
if (card.img && card.img !== "") container.style.background = "linear-gradient(155deg, #1e1e1eeb 20%, #1e1e1ecc), url(\"" + card.img + "\") center / cover no-repeat"; // if (card.img && card.img !== "") container.style.background = "linear-gradient(155deg, #1e1e1eeb 20%, #1e1e1ecc), url(\"" + card.img + "\") center / cover no-repeat";
imgInput.addEventListener("change", e => { // imgInput.addEventListener("change", e => {
setCustomImage(key, e.target.value); // setCustomImage(key, e.target.value);
container.style.background = e.target.value === "" ? "var(--containerbg)" : "linear-gradient(155deg, #1e1e1eeb 20%, #1e1e1ecc), url(\"" + e.target.value + "\") center / cover no-repeat"; // container.style.background = e.target.value === "" ? "var(--containerbg)" : "linear-gradient(155deg, #1e1e1eeb 20%, #1e1e1ecc), url(\"" + e.target.value + "\") center / cover no-repeat";
}); // });
nameInput.addEventListener("change", function (e) { updateCards(key, { "name": e.target.value }) }); // nameInput.addEventListener("change", function (e) { updateCards(key, { "name": e.target.value }) });
codeInput.addEventListener("change", function (e) { updateCards(key, { "code": e.target.value }) }); // codeInput.addEventListener("change", function (e) { updateCards(key, { "code": e.target.value }) });
hideInput.addEventListener("change", function (e) { updateCards(key, { "hidden": e.target.checked }) }); // hideInput.addEventListener("change", function (e) { updateCards(key, { "hidden": e.target.checked }) });
container.querySelector(".custom-card-title").textContent = card.default; // container.querySelector(".custom-card-title").textContent = card.default;
for (let i = 0; i < 4; i++) { // for (let i = 0; i < 4; i++) {
let customLink = makeElement("input", container.querySelector(".custom-links"), { "className": "card-input" }); // let customLink = makeElement("input", container.querySelector(".custom-links"), { "className": "card-input" });
customLink.value = card_2.links[i].is_default ? "default" : card_2.links[i].path; // customLink.value = card_2.links[i].is_default ? "default" : card_2.links[i].path;
customLink.addEventListener("change", function (e) { // customLink.addEventListener("change", function (e) {
chrome.storage.sync.get("custom_cards_2", storage => { // chrome.storage.sync.get("custom_cards_2", storage => {
let newLinks = storage.custom_cards_2[key].links; // let newLinks = storage.custom_cards_2[key].links;
if (e.target.value === "" || e.target.value === "default") { // if (e.target.value === "" || e.target.value === "default") {
console.log("this value is empty....") // console.log("this value is empty....")
//newLinks[i] = { "type": storage.custom_cards_2[key].links.default[i].type, "default": true }; // //newLinks[i] = { "type": storage.custom_cards_2[key].links.default[i].type, "default": true };
newLinks[i] = { "default": newLinks[i].default, "is_default": true, "path": newLinks[i].default }; // newLinks[i] = { "default": newLinks[i].default, "is_default": true, "path": newLinks[i].default };
customLink.value = "default"; // customLink.value = "default";
} else { // } else {
//newLinks[i] = { "type": getLinkType(e.target.value), "path": e.target.value, "default": false }; // //newLinks[i] = { "type": getLinkType(e.target.value), "path": e.target.value, "default": false };
let val = e.target.value; // let val = e.target.value;
if (!e.target.value.includes("https://") && e.target.value !== "none") val = "https://" + val; // if (!e.target.value.includes("https://") && e.target.value !== "none") val = "https://" + val;
newLinks[i] = { "default": newLinks[i].default, "is_default": false, "path": val }; // newLinks[i] = { "default": newLinks[i].default, "is_default": false, "path": val };
customLink.value = val; // customLink.value = val;
} // }
chrome.storage.sync.set({ "custom_cards_2": { ...storage.custom_cards_2, [key]: { ...storage.custom_cards_2[key], "links": newLinks } } }) // chrome.storage.sync.set({ "custom_cards_2": { ...storage.custom_cards_2, [key]: { ...storage.custom_cards_2[key], "links": newLinks } } })
}); // });
}); // });
} // }
}; // };
}); // });
} else { // } else {
document.querySelector(".advanced-cards").innerHTML = `<div class="option-container"><h3>Couldn't find your cards!<br/>You may need to refresh your Canvas page and/or this menu page.<br/><br/>If you're having issues please contact me - sandlerguy5@gmail.com</h3></div>`; // document.querySelector(".advanced-cards").innerHTML = `<div class="option-container"><h3>Couldn't find your cards!<br/>You may need to refresh your Canvas page and/or this menu page.<br/><br/>If you're having issues please contact me - sandlerguy5@gmail.com</h3></div>`;
// }
const cardGrid = document.getElementById("card-grid");
if (!cardGrid) {
console.error("Card grid element not found");
return;
} }
cardGrid.innerHTML = "";
const customCards = storage.custom_cards || {};
const customCards2 = storage.custom_cards_2 || {};
const allCards = { ...customCards, ...customCards2 };
if (Object.keys(allCards).length === 0) {
cardGrid.innerHTML = '<p style="text-align: center; color: #999; padding: 20px;">No course cards found. Visit your Canvas dashboard to load courses.</p>';
return;
}
Object.keys(allCards).forEach(courseId => {
const course = allCards[courseId];
if (course && typeof course === 'object') {
const courseButton = createCourseButton(courseId, course);
cardGrid.appendChild(courseButton);
}
});
const editMenu = document.getElementById("card-edit-menu");
if (editMenu) {
editMenu.style.display = "none";
}
document.getElementById("card-edit-menu").style.display = "none";
}); });
sendFromPopup("getCards");
} }
/* function createCourseButton(courseId, courseData) {
chrome.runtime.onMessage.addListener(message => { const button = document.createElement("button");
if (message === "getCardsComplete") { button.className = "course-card-button";
displayAdvancedCards(); button.textContent = courseData.name || `Course ${courseId}`;
} button.dataset.courseId = courseId;
});
*/
/* button.addEventListener("click", () => {
syncedSwitches.forEach(function (option) { document.querySelectorAll(".course-card-button").forEach(btn => btn.classList.remove("active"));
let optionSwitch = document.querySelector('#' + option); button.classList.add("active");
chrome.storage.sync.get(option, function (result) { showCardEditMenu(courseId, courseData);
let status = result[option] === true ? "#on" : "#off"; });
optionSwitch.querySelector(status).checked = true;
optionSwitch.querySelector(status).classList.add('checked');
});
optionSwitch.querySelector(".slider").addEventListener('mouseup', function () { return button;
optionSwitch.querySelector("#on").checked = !optionSwitch.querySelector("#on").checked; }
optionSwitch.querySelector("#on").classList.toggle('checked');
optionSwitch.querySelector("#off").classList.toggle('checked');
let status = optionSwitch.querySelector("#on").checked;
chrome.storage.sync.set({ [option]: status });
if (option === "auto_dark") {
toggleDarkModeDisable(status);
}
});
});
*/
/* function showCardEditMenu(courseId, courseData) {
localSwitches.forEach(option => { const editMenu = document.getElementById("card-edit-menu");
let optionSwitch = document.querySelector('#' + option); editMenu.style.display = "block";
chrome.storage.local.get(option, function (result) {
let status = result[option] === true ? "#on" : "#off";
optionSwitch.querySelector(status).checked = true;
optionSwitch.querySelector(status).classList.add('checked');
});
optionSwitch.querySelector(".slider").addEventListener('mouseup', function () {
optionSwitch.querySelector("#on").checked = !optionSwitch.querySelector("#on").checked;
optionSwitch.querySelector("#on").classList.toggle('checked');
optionSwitch.querySelector("#off").classList.toggle('checked');
let status = optionSwitch.querySelector("#on").checked;
chrome.storage.local.set({ [option]: status });
/* editMenu.innerHTML = `
switch (option) { <div class="card-edit-header">
case 'dark_mode': chrome.storage.local.set({ dark_mode: status }); sendFromPopup("darkmode"); break; <h3 class="card-edit-title">${courseData.name || `Course ${courseId}`}</h3>
} <button class="card-close-btn" onclick="hideCardEditMenu()">×</button>
/ </div>
});
}); <div class="card-edit-section">
*/ <label class="card-edit-label">Card Image URL</label>
<input type="text" class="card-input" id="card-image-input"
value="${courseData.img || ""}" placeholder="Enter image URL or 'none'">
<div class="card-image-preview" id="card-image-preview"></div>
</div>
<div class="card-edit-section">
<label class="card-edit-label">Course Link</label>
<input type="text" class="card-input" id="card-link-input"
value="${courseData.link || ""}" placeholder="Enter custom link or 'none'">
</div>
<div class="card-edit-section">
<label class="card-edit-label">Hide Card</label>
<div style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="card-hide-input" ${courseData.hide ? "checked" : ""}>
<span>Hide this card from dashboard</span>
</div>
</div>
<div style="display: flex; gap: 10px; margin-top: 20px;">
<button class="big-button" onclick="saveCardChanges('${courseId}')">Save Changes</button>
<button class="customization-button" onclick="resetCardToDefault('${courseId}')">Reset to Default</button>
</div>
`;
updateImagePreview();
document.getElementById("card-image-input").addEventListener("input", updateImagePreview);
}
function updateImagePreview() {
const imageInput = document.getElementById("card-image-input");
const preview = document.getElementById("card-image-preview");
if (imageInput && preview) {
const imageUrl = imageInput.value;
if (imageUrl && imageUrl !== "none" && imageUrl.trim() !== "") {
preview.style.backgroundImage = `url(${imageUrl})`;
preview.style.display = "block";
} else {
preview.style.backgroundImage = "none";
preview.style.display = "none";
}
}
}
function saveCardChanges(courseId) {
const imageInput = document.getElementById("card-image-input");
const linkInput = document.getElementById("card-link-input");
const hideInput = document.getElementById("card-hide-input");
const updates = {
img: imageInput.value,
link: linkInput.value,
hide: hideInput.checked,
};
updateCards(courseId, updates);
displayAlert(false, "Card settings saved successfully!");
setTimeout(() => {
displayAdvancedCards();
}, 500);
}
function resetCardToDefault(courseId) {
updateCards(courseId, { img: "", link: "", hide: false });
displayAlert(false, "Card reset to default settings!");
setTimeout(() => {
displayAdvancedCards();
}, 500);
}
function hideCardEditMenu() {
document.getElementById("card-edit-menu").style.display = "none";
document.querySelectorAll(".course-card-button").forEach((btn) => {
btn.classList.remove("active");
});
}
function toggleDarkModeDisable(disabled) { function toggleDarkModeDisable(disabled) {
let darkSwitch = document.querySelector('#dark_mode'); let darkSwitch = document.querySelector('#dark_mode');
@ -1727,54 +1792,6 @@ function getColorInGradient(d, from, to) {
return "#" + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]); return "#" + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
} }
/*
function getColors(preset) {
console.log(preset)
Object.keys(preset).forEach(key => {
try {
let c = document.querySelector("#dp_" + key);
let color = c.querySelector('input[type="color"]');
let text = c.querySelector('input[type="text"]');
[color, text].forEach(changer => {
changer.value = preset[key];
changer.addEventListener("change", function (e) {
changeCSS(key, e.target.value);
});
});
} catch (e) {
console.log("couldn't get " + key)
console.log(e);
}
});
}
*/
/*
function getColors2(data) {
const colors = data.split(":root")[1].split("--bcstop")[0];
const backgroundcolors = document.querySelector("#option-background");
const textcolors = document.querySelector("#option-text");
colors.split(";").forEach(function (color) {
const type = color.split(":")[0].replace("{", "").replace("}", "");
const currentColor = color.split(":")[1];
if (type) {
let container = makeElement("div", "changer-container", type.includes("background") ? backgroundcolors : textcolors);
let colorChange = makeElement("input", "card-input", container);
let colorChangeText = makeElement("input", "card-input", container);
colorChangeText.type = "text";
colorChangeText.value = currentColor;
colorChange.type = "color";
colorChange.value = currentColor;
[colorChange, colorChangeText].forEach(changer => {
changer.addEventListener("change", function (e) {
changeCSS(type, e.target.value);
});
});
}
})
}
*/
function displaySidebarMode(mode, style) { function displaySidebarMode(mode, style) {
style = style.replace(" ", ""); style = style.replace(" ", "");
let match = style.match(/linear-gradient\((?<color1>\#\w*),(?<color2>\#\w*)\)/); let match = style.match(/linear-gradient\((?<color1>\#\w*),(?<color2>\#\w*)\)/);
@ -1904,24 +1921,6 @@ function applyPreset(preset) {
chrome.storage.sync.set({ "dark_preset": preset }).then(() => refreshColors()); chrome.storage.sync.set({ "dark_preset": preset }).then(() => refreshColors());
} }
/*
function setToDefaults() {
fetch(chrome.runtime.getURL('js/darkcss.json'))
.then((resp) => resp.json())
.then(function (result) {
chrome.storage.local.set({ "dark_css": result["dark_css"], "dark_preset": { "background-0": "#161616", "background-1": "#1e1e1e", "background-2": "#262626", "borders": "#3c3c3c", "text-0": "#f5f5f5", "text-1": "#e2e2e2", "text-2": "#ababab", "links": "#56Caf0", "sidebar": "#1e1e1e", "sidebar-text": "#f5f5f5" } }).then(() => refreshColors());
});
}
*/
/*
function makeElement(element, elclass, location, text) {
let creation = document.createElement(element);
creation.className = elclass;
creation.textContent = text;
location.appendChild(creation);
return creation
}*/
function makeElement(element, location, options) { function makeElement(element, location, options) {
let creation = document.createElement(element); let creation = document.createElement(element);
Object.keys(options).forEach(key => { Object.keys(options).forEach(key => {