mirror of
https://github.com/GuySandler/CanvasRefined.git
synced 2026-08-05 02:37:10 +02:00
started dashboard v2
This commit is contained in:
parent
fb5651eda9
commit
16c3666e0b
@ -175,4 +175,101 @@
|
||||
50% {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dashboard V2 */
|
||||
#canvasrefined-v2-container + .canvasrefined-gpa-card {
|
||||
margin-top: 18px;
|
||||
}
|
||||
#canvasrefined-v2-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
padding: 0 12px 20px;
|
||||
box-sizing: border-box;
|
||||
max-width: 1200px;
|
||||
margin: 25px auto 0;
|
||||
}
|
||||
#DashboardCard_Container .ic-Dashboard-header {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.canvasrefined-v2-active .ic-DashboardCard__box__container {
|
||||
display: none !important;
|
||||
}
|
||||
.canvasrefined-v2-card {
|
||||
display: block;
|
||||
width: 262px;
|
||||
box-sizing: border-box;
|
||||
cursor: grab;
|
||||
margin: 0 !important;
|
||||
}
|
||||
#canvasrefined-v2-container.drag-active > * > * {
|
||||
pointer-events: none;
|
||||
}
|
||||
.canvasrefined-v2-card[draggable="true"]:active {
|
||||
cursor: grabbing;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.canvasrefined-v2-card.dragging {
|
||||
opacity: 0.4;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
.canvasrefined-v2-card.drag-over {
|
||||
outline: 2px solid var(--bclinks, #56Caf0);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.canvasrefined-v2-card .ic-DashboardCard__action-layout svg {
|
||||
fill: var(--bctext-1, #333);
|
||||
}
|
||||
.canvasrefined-v2-card .ic-DashboardCard__action {
|
||||
color: var(--bctext-1, #333);
|
||||
}
|
||||
#canvasrefined-v2-container .canvasrefined-gpa-card {
|
||||
margin: 0;
|
||||
width: 262px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
background: var(--bcbackground-1, #2d2d2d);
|
||||
align-self: flex-start;
|
||||
}
|
||||
#canvasrefined-v2-container .canvasrefined-gpa-edit-btn {
|
||||
background: var(--bcbackground-2, #3a3a3a);
|
||||
border: 1px solid var(--bcbackground-2, #555);
|
||||
color: var(--bctext-0, #f5f5f5);
|
||||
}
|
||||
#canvasrefined-v2-container .canvasrefined-gpa-header {
|
||||
color: var(--bctext-0, #f5f5f5);
|
||||
}
|
||||
#canvasrefined-v2-container .canvasrefined-gpa p {
|
||||
color: var(--bctext-1, #ccc);
|
||||
}
|
||||
#canvasrefined-v2-container .canvasrefined-gpa {
|
||||
background: var(--bcbackground-1, #2d2d2d);
|
||||
border-radius: 0 0 4px 4px;
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
}
|
||||
#canvasrefined-v2-container .canvasrefined-gpa-course {
|
||||
border-color: var(--bcbackground-2, #444);
|
||||
}
|
||||
body.canvasrefined-limit-assignments .canvasrefined-card-assignment {
|
||||
max-height: 160px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
body.canvasrefined-truncate-names .canvasrefined-card-assignment {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
body.canvasrefined-truncate-names .canvasrefined-assignment-link {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 240px;
|
||||
display: block;
|
||||
}
|
||||
#canvasrefined-v2-container .canvasrefined-gpa-courses-container {
|
||||
max-height: 220px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@ -58,6 +58,10 @@
|
||||
<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="M12 9v4"></path><path d="M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0z"></path><path d="M12 16h.01"></path></svg>
|
||||
<span data-i18n="report_issue">Report issue</span>
|
||||
</button>
|
||||
<button id="experimental-btn" class="big-button tab-btn">
|
||||
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" width="15" height="15"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <rect width="48" height="48" fill="white" fill-opacity="0.01"></rect> <path fill-rule="evenodd" clip-rule="evenodd" d="M18.019 4V15.0386L6.27437 39.3014C5.48686 40.9283 6.16731 42.8855 7.79421 43.673C8.23876 43.8882 8.72624 44 9.22013 44H38.7874C40.5949 44 42.0602 42.5347 42.0602 40.7273C42.0602 40.2348 41.949 39.7488 41.7351 39.3052L30.0282 15.0386V4H18.019Z" stroke="currentColor" stroke-width="4" stroke-linejoin="round"></path> <path d="M10.9604 29.9998C13.1241 31.3401 15.2893 32.0103 17.4559 32.0103C19.6226 32.0103 21.7908 31.3401 23.9605 29.9998C26.1088 28.6735 28.2664 28.0103 30.433 28.0103C32.5997 28.0103 34.7755 28.6735 36.9604 29.9998" stroke="currentColor" stroke-width="4" stroke-linecap="round"></path> </g></svg>
|
||||
<span>Experimental</span>
|
||||
</button>
|
||||
<!-- <button id="updates-btn" class="big-button tab-btn">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4" /><path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4" /></svg>
|
||||
<span data-i18n="updates">Updates</span>
|
||||
@ -124,6 +128,14 @@
|
||||
<input type="checkbox" id="relative_dues" name="relative_dues">
|
||||
<label for="relative_dues" class="sub-text" data-i18n="relative_due_dates">Relative due dates</label>
|
||||
</div>
|
||||
<div class="sub-option">
|
||||
<input type="checkbox" id="v2_limit_assignments" name="v2_limit_assignments">
|
||||
<label for="v2_limit_assignments" class="sub-text">Limited height</label>
|
||||
</div>
|
||||
<div class="sub-option">
|
||||
<input type="checkbox" id="v2_truncate_names" name="v2_truncate_names">
|
||||
<label for="v2_truncate_names" class="sub-text">Truncate names</label>
|
||||
</div>
|
||||
<div style="margin-top: 5px">
|
||||
<span class="sub-text" data-i18n="max_items">Max items to show: </span><span
|
||||
id="numAssignments"></span>
|
||||
@ -981,6 +993,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="experimental tab" style="display:none">
|
||||
<div class="tab-header">
|
||||
<div>
|
||||
<h2 style="margin-top: 0">Experimental</h2>
|
||||
</div>
|
||||
<button class="big-button back-btn" data-i18n="back">Back</button>
|
||||
</div>
|
||||
<div class="options">
|
||||
<div class="option-container">
|
||||
<div class="option" id="dashboard_v2">
|
||||
<input type="radio" id="off" name="dashboard_v2">
|
||||
<input type="radio" id="on" name="dashboard_v2">
|
||||
<div class="slider">
|
||||
<div class="sliderknob"></div>
|
||||
<div class="sliderbg"></div>
|
||||
</div>
|
||||
<span class="option-name">Dashboard V2</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="report-issue-container tab">
|
||||
<div class="tab-header">
|
||||
<div>
|
||||
|
||||
@ -105,6 +105,7 @@ chrome.runtime.onInstalled.addListener(function () {
|
||||
"customCardStyles": false,
|
||||
"customBackgroundLink": "",
|
||||
"customBackgroundScale": 100,
|
||||
"dashboard_v2": false,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
569
js/content.js
569
js/content.js
@ -196,6 +196,7 @@ let timeCheck = null;
|
||||
let reminderCheck = null;
|
||||
let betterSidebarLoading = false;
|
||||
let dashboardReadyTimer = null;
|
||||
let v2DragSetup = false;
|
||||
//let assignmentData = null;
|
||||
|
||||
/*
|
||||
@ -460,6 +461,8 @@ function startExtension() {
|
||||
watchSequenceFooter();
|
||||
watchSubmissionPageButton();
|
||||
watchProfileLogoutPageButton();
|
||||
document.body?.classList.toggle("canvasrefined-limit-assignments", options.v2_limit_assignments);
|
||||
document.body?.classList.toggle("canvasrefined-truncate-names", options.v2_truncate_names);
|
||||
|
||||
//getClassAverages();
|
||||
|
||||
@ -499,7 +502,7 @@ function applyOptionsChanges(changes) {
|
||||
toggleAutoDarkMode();
|
||||
break;
|
||||
case "gradient_cards":
|
||||
changeGradientCards();
|
||||
if (!isDashboardV2Active()) changeGradientCards();
|
||||
break;
|
||||
case "widget_clock":
|
||||
loadWidgets();
|
||||
@ -510,7 +513,11 @@ function applyOptionsChanges(changes) {
|
||||
case "dashboard_grades":
|
||||
case "grade_hover":
|
||||
if (!grades) getGrades();
|
||||
insertGrades();
|
||||
if (isDashboardV2Active()) {
|
||||
renderDashboardV2();
|
||||
} else {
|
||||
insertGrades();
|
||||
}
|
||||
break;
|
||||
case "assignments_due":
|
||||
case "num_assignments":
|
||||
@ -520,19 +527,31 @@ function applyOptionsChanges(changes) {
|
||||
.length === 0
|
||||
)
|
||||
setupCardAssignments();
|
||||
loadCardAssignments();
|
||||
if (isDashboardV2Active()) {
|
||||
loadV2Assignments();
|
||||
} else {
|
||||
loadCardAssignments();
|
||||
}
|
||||
break;
|
||||
case "custom_assignments":
|
||||
case "assignment_date_format":
|
||||
case "card_overdues":
|
||||
case "relative_dues":
|
||||
cardAssignments = preloadAssignmentEls();
|
||||
loadCardAssignments();
|
||||
if (isDashboardV2Active()) {
|
||||
renderDashboardV2();
|
||||
} else {
|
||||
loadCardAssignments();
|
||||
}
|
||||
break;
|
||||
case "custom_cards":
|
||||
case "custom_cards_2":
|
||||
case "custom_cards_3":
|
||||
customizeCards();
|
||||
if (isDashboardV2Active()) {
|
||||
renderDashboardV2();
|
||||
} else {
|
||||
customizeCards();
|
||||
}
|
||||
break;
|
||||
case "todo_hr24":
|
||||
case "todo_separate_scrollbar":
|
||||
@ -637,6 +656,29 @@ function applyOptionsChanges(changes) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "dashboard_v2":
|
||||
if (options.dashboard_v2) {
|
||||
renderDashboardV2();
|
||||
document.body.classList.toggle("canvasrefined-limit-assignments", options.v2_limit_assignments);
|
||||
document.body.classList.toggle("canvasrefined-truncate-names", options.v2_truncate_names);
|
||||
moveGPACardToV2();
|
||||
} else {
|
||||
removeDashboardV2();
|
||||
document.body.classList.remove("canvasrefined-limit-assignments", "canvasrefined-truncate-names");
|
||||
moveGPACardOutOfV2();
|
||||
let cards = document.querySelectorAll(".ic-DashboardCard");
|
||||
changeGradientCards();
|
||||
loadCardAssignments();
|
||||
customizeCards(cards);
|
||||
insertGrades();
|
||||
}
|
||||
break;
|
||||
case "v2_limit_assignments":
|
||||
document.body.classList.toggle("canvasrefined-limit-assignments", options.v2_limit_assignments);
|
||||
break;
|
||||
case "v2_truncate_names":
|
||||
document.body.classList.toggle("canvasrefined-truncate-names", options.v2_truncate_names);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -898,13 +940,22 @@ function checkDashboardReady() {
|
||||
|
||||
const c = document.querySelector("#DashboardCard_Container");
|
||||
if (c) {
|
||||
let cards = document.querySelectorAll(".ic-DashboardCard");
|
||||
loadWidgets();
|
||||
changeGradientCards();
|
||||
setupCardAssignments();
|
||||
loadCardAssignments();
|
||||
customizeCards(cards);
|
||||
insertGrades();
|
||||
if (isDashboardV2Active()) {
|
||||
const v2 = document.querySelector("#canvasrefined-v2-container");
|
||||
if (!v2 || v2.dataset.rendered !== "true") {
|
||||
loadWidgets();
|
||||
setupCardAssignments();
|
||||
renderDashboardV2();
|
||||
}
|
||||
} else {
|
||||
let cards = document.querySelectorAll(".ic-DashboardCard");
|
||||
loadWidgets();
|
||||
changeGradientCards();
|
||||
setupCardAssignments();
|
||||
loadCardAssignments();
|
||||
customizeCards(cards);
|
||||
insertGrades();
|
||||
}
|
||||
loadDashboardNotes();
|
||||
setupGPACalc();
|
||||
showUpdateMsg();
|
||||
@ -3824,7 +3875,10 @@ function setupGPACalc() {
|
||||
|
||||
container.innerHTML = '<h3 class="canvasrefined-gpa-header">GPA Calculator</h3><div class="canvasrefined-gpa-courses-container"><div class="canvasrefined-gpa-courses"></div></div>';
|
||||
|
||||
if (options.gpa_calc_prepend === true) {
|
||||
const v2Container = document.querySelector("#canvasrefined-v2-container");
|
||||
if (isDashboardV2Active() && v2Container) {
|
||||
// Don't append here — moveGPACardToV2() in renderDashboardV2 handles placement
|
||||
} else if (options.gpa_calc_prepend === true) {
|
||||
dashboardContainer.prepend(container2);
|
||||
dashboardContainer.prepend(container);
|
||||
} else {
|
||||
@ -3859,18 +3913,24 @@ function setupGPACalc() {
|
||||
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;
|
||||
const v2Container = document.querySelector("#canvasrefined-v2-container");
|
||||
if (isDashboardV2Active() && v2Container) {
|
||||
if (container2.parentElement !== v2Container) v2Container.appendChild(container2);
|
||||
if (container.parentElement !== v2Container) v2Container.appendChild(container);
|
||||
} else {
|
||||
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);
|
||||
if (firstCard.parentElement !== dashboardContainer) {
|
||||
dashboardContainer.prepend(firstCard);
|
||||
}
|
||||
if (secondCard.parentElement !== dashboardContainer) {
|
||||
if (shouldPrepend) {
|
||||
dashboardContainer.prepend(secondCard);
|
||||
} else {
|
||||
dashboardContainer.appendChild(secondCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4228,7 +4288,7 @@ function getGrades() {
|
||||
}
|
||||
|
||||
function getColors() {
|
||||
if (options.tab_icons || options.better_todo || options.better_sidebar) {
|
||||
if (options.tab_icons || options.better_todo || options.better_sidebar || options.dashboard_v2) {
|
||||
return getData(`${domain}/api/v1/users/self/colors`).then(data => {
|
||||
let cards = options.custom_cards_3;
|
||||
Object.keys(cards).forEach(key => {
|
||||
@ -4259,7 +4319,7 @@ function getAssignments() {
|
||||
}
|
||||
|
||||
function getApiData() {
|
||||
if (current_page === "/" || current_page === "" || options.better_todo || options.better_sidebar) {
|
||||
if (current_page === "/" || current_page === "" || options.better_todo || options.better_sidebar || options.dashboard_v2) {
|
||||
getAssignments();
|
||||
getGrades();
|
||||
getColors();
|
||||
@ -4381,6 +4441,463 @@ function formatCardDue(date) {
|
||||
return options.assignment_date_format ? (due.getDate()) + "/" + (due.getMonth() + 1) : (due.getMonth() + 1) + "/" + (due.getDate());
|
||||
}
|
||||
|
||||
function setupV2DragAndDrop() {
|
||||
if (v2DragSetup) return;
|
||||
v2DragSetup = true;
|
||||
|
||||
let dragState = null;
|
||||
|
||||
function onMouseDown(e) {
|
||||
if (e.button !== 0) return;
|
||||
if (e.target.closest("a, button")) return;
|
||||
|
||||
const card = e.target.closest(".canvasrefined-v2-card, .canvasrefined-gpa-card");
|
||||
if (!card) return;
|
||||
|
||||
const header = e.target.closest(".ic-DashboardCard__header");
|
||||
if (!header) return;
|
||||
|
||||
const v2Container = document.querySelector("#canvasrefined-v2-container");
|
||||
if (!v2Container || v2Container.dataset.rendered !== "true") return;
|
||||
|
||||
dragState = {
|
||||
card: card,
|
||||
courseId: card.dataset.courseId,
|
||||
startX: e.clientX,
|
||||
startY: e.clientY,
|
||||
ghost: null,
|
||||
dragging: false,
|
||||
v2Container: v2Container
|
||||
};
|
||||
}
|
||||
|
||||
function onMouseMove(e) {
|
||||
if (!dragState) return;
|
||||
|
||||
const dx = e.clientX - dragState.startX;
|
||||
const dy = e.clientY - dragState.startY;
|
||||
|
||||
if (!dragState.dragging) {
|
||||
if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
|
||||
dragState.dragging = true;
|
||||
dragState.card.classList.add("dragging");
|
||||
dragState.v2Container.classList.add("drag-active");
|
||||
|
||||
const ghost = dragState.card.cloneNode(true);
|
||||
ghost.classList.add("canvasrefined-v2-ghost");
|
||||
ghost.style.position = "fixed";
|
||||
ghost.style.opacity = "0.8";
|
||||
ghost.style.pointerEvents = "none";
|
||||
ghost.style.zIndex = "9999";
|
||||
ghost.style.width = dragState.card.offsetWidth + "px";
|
||||
ghost.style.left = (e.clientX - dragState.card.offsetWidth / 2) + "px";
|
||||
ghost.style.top = (e.clientY - 20) + "px";
|
||||
document.body.appendChild(ghost);
|
||||
dragState.ghost = ghost;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (dragState.ghost) {
|
||||
dragState.ghost.style.left = (e.clientX - dragState.card.offsetWidth / 2) + "px";
|
||||
dragState.ghost.style.top = (e.clientY - 20) + "px";
|
||||
}
|
||||
|
||||
const v2Container = dragState.v2Container;
|
||||
v2Container.querySelectorAll(".drag-over").forEach(c => c.classList.remove("drag-over"));
|
||||
|
||||
const cards = Array.from(v2Container.querySelectorAll(".canvasrefined-v2-card, .canvasrefined-gpa-card"));
|
||||
for (const targetCard of cards) {
|
||||
if (targetCard === dragState.card) continue;
|
||||
const rect = targetCard.getBoundingClientRect();
|
||||
const midX = rect.left + rect.width / 2;
|
||||
if (e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom) {
|
||||
targetCard.classList.add("drag-over");
|
||||
if (e.clientX < midX) {
|
||||
v2Container.insertBefore(dragState.card, targetCard);
|
||||
} else {
|
||||
v2Container.insertBefore(dragState.card, targetCard.nextSibling);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseUp(e) {
|
||||
if (!dragState) return;
|
||||
|
||||
if (dragState.dragging) {
|
||||
if (dragState.ghost) {
|
||||
dragState.ghost.remove();
|
||||
}
|
||||
dragState.card.classList.remove("dragging");
|
||||
dragState.v2Container.classList.remove("drag-active");
|
||||
dragState.v2Container.querySelectorAll(".drag-over").forEach(c => c.classList.remove("drag-over"));
|
||||
|
||||
if (dragState.courseId === "gpa") {
|
||||
const gpaEdit = document.querySelector(".canvasrefined-gpa");
|
||||
if (gpaEdit) dragState.v2Container.appendChild(gpaEdit);
|
||||
}
|
||||
|
||||
saveV2CardOrder();
|
||||
}
|
||||
|
||||
dragState = null;
|
||||
}
|
||||
|
||||
document.addEventListener("mousedown", onMouseDown, true);
|
||||
document.addEventListener("mousemove", onMouseMove, true);
|
||||
document.addEventListener("mouseup", onMouseUp, true);
|
||||
}
|
||||
|
||||
function renderDashboardV2() {
|
||||
const dashboardContainer = document.querySelector("#DashboardCard_Container");
|
||||
if (!dashboardContainer) return;
|
||||
|
||||
dashboardContainer.classList.add("canvasrefined-v2-active");
|
||||
const originalCards = document.querySelector(".ic-DashboardCard__box__container");
|
||||
if (originalCards) originalCards.style.display = "none";
|
||||
|
||||
let v2Container = document.querySelector("#canvasrefined-v2-container");
|
||||
if (!v2Container) {
|
||||
v2Container = document.createElement("div");
|
||||
v2Container.id = "canvasrefined-v2-container";
|
||||
dashboardContainer.prepend(v2Container);
|
||||
|
||||
v2Container.addEventListener("dragover", (e) => {
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = "move";
|
||||
});
|
||||
}
|
||||
|
||||
if (v2Container.dataset.rendered === "true") return;
|
||||
|
||||
setupV2DragAndDrop();
|
||||
|
||||
v2Container.dataset.rendered = "true";
|
||||
v2Container.innerHTML = "";
|
||||
|
||||
const cards = options.custom_cards || {};
|
||||
const cardLinks = options.custom_cards_2 || {};
|
||||
const cardColors = options.custom_cards_3 || {};
|
||||
|
||||
const courseIds = Object.keys(cards);
|
||||
if (courseIds.length === 0) {
|
||||
v2Container.innerHTML = '<div class="canvasrefined-v2-empty">No courses found. Try refreshing the page.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
courseIds.forEach(courseId => {
|
||||
const cardOpts = cards[courseId] || {};
|
||||
const linkOpts = cardLinks[courseId] || {};
|
||||
const colorData = cardColors[courseId] || {};
|
||||
const courseColor = colorData.color || "#394b58";
|
||||
|
||||
if (cardOpts.hidden === true) return;
|
||||
|
||||
const card = document.createElement("div");
|
||||
card.className = "ic-DashboardCard canvasrefined-v2-card";
|
||||
card.dataset.courseId = courseId;
|
||||
card.setAttribute("aria-label", cardOpts.name || cardOpts.default || "Course");
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.className = "ic-DashboardCard__header";
|
||||
if (cardOpts.img && cardOpts.img !== "" && cardOpts.img !== "none") {
|
||||
const headerImage = document.createElement("div");
|
||||
headerImage.className = "ic-DashboardCard__header_image";
|
||||
headerImage.style.backgroundImage = "url(\"" + cardOpts.img + "\")";
|
||||
const hero = document.createElement("div");
|
||||
hero.className = "ic-DashboardCard__header_hero";
|
||||
hero.setAttribute("aria-hidden", "true");
|
||||
hero.style.backgroundColor = courseColor;
|
||||
hero.style.opacity = "0.6";
|
||||
headerImage.appendChild(hero);
|
||||
header.appendChild(headerImage);
|
||||
} else {
|
||||
const hero = document.createElement("div");
|
||||
hero.className = "ic-DashboardCard__header_hero";
|
||||
hero.setAttribute("aria-hidden", "true");
|
||||
hero.style.backgroundColor = courseColor;
|
||||
hero.style.opacity = "0.8";
|
||||
header.appendChild(hero);
|
||||
}
|
||||
|
||||
const headerLink = document.createElement("a");
|
||||
headerLink.className = "ic-DashboardCard__link";
|
||||
headerLink.href = domain + "/courses/" + courseId;
|
||||
headerLink.setAttribute("draggable", "false");
|
||||
|
||||
const headerContent = document.createElement("div");
|
||||
headerContent.className = "ic-DashboardCard__header_content";
|
||||
|
||||
const title = document.createElement("h2");
|
||||
title.className = "ic-DashboardCard__header-title ellipsis";
|
||||
const titleSpan = document.createElement("span");
|
||||
titleSpan.style.color = courseColor;
|
||||
titleSpan.textContent = cardOpts.name || cardOpts.default || ("Course " + courseId);
|
||||
title.appendChild(titleSpan);
|
||||
headerContent.appendChild(title);
|
||||
|
||||
const subtitle = document.createElement("div");
|
||||
subtitle.className = "ic-DashboardCard__header-subtitle ellipsis";
|
||||
subtitle.title = cardOpts.default || "";
|
||||
subtitle.textContent = cardOpts.default || "";
|
||||
headerContent.appendChild(subtitle);
|
||||
|
||||
const term = document.createElement("div");
|
||||
term.className = "ic-DashboardCard__header-term ellipsis";
|
||||
headerContent.appendChild(term);
|
||||
|
||||
headerLink.appendChild(headerContent);
|
||||
header.appendChild(headerLink);
|
||||
|
||||
if (options.dashboard_grades === true) {
|
||||
const gradeLink = document.createElement("a");
|
||||
gradeLink.className = "canvasrefined-card-grade";
|
||||
gradeLink.href = domain + "/courses/" + courseId + "/grades";
|
||||
gradeLink.textContent = "--%";
|
||||
header.appendChild(gradeLink);
|
||||
}
|
||||
|
||||
card.appendChild(header);
|
||||
|
||||
const actions = document.createElement("nav");
|
||||
actions.className = "ic-DashboardCard__action-container";
|
||||
actions.setAttribute("aria-label", "Actions for course " + courseId);
|
||||
|
||||
const defaultLinks = [
|
||||
{ path: "/announcements", label: "Announcements", icon: '<svg viewBox="0 0 1920 1920" width="19" height="19"><path d="M1587.162 31.278c11.52-23.491 37.27-35.689 63.473-29.816 25.525 6.099 43.483 28.8 43.483 55.002V570.46C1822.87 596.662 1920 710.733 1920 847.053c0 136.32-97.13 250.503-225.882 276.705v513.883c0 26.202-17.958 49.016-43.483 55.002a57.279 57.279 0 0 1-12.988 1.468c-21.12 0-40.772-11.745-50.485-31.171C1379.238 1247.203 964.18 1242.347 960 1242.347H564.706v564.706h87.755c-11.859-90.127-17.506-247.003 63.473-350.683 52.405-67.087 129.657-101.082 229.948-101.082v112.941c-64.49 0-110.57 18.861-140.837 57.487-68.781 87.868-45.064 263.83-30.269 324.254 4.18 16.828.34 34.673-10.277 48.34-10.73 13.665-27.219 21.684-44.499 21.684H508.235c-31.171 0-56.47-25.186-56.47-56.47v-621.177h-56.47c-155.747 0-282.354-126.607-282.354-282.353v-56.47h-56.47C25.299 903.523 0 878.336 0 847.052c0-31.172 25.299-56.471 56.47-56.471h56.471v-56.47c0-155.634 126.607-282.354 282.353-282.354h564.593c16.941-.112 420.48-7.002 627.275-420.48Zm-5.986 218.429c-194.71 242.371-452.216 298.164-564.705 311.04v572.724c112.489 12.876 369.995 68.556 564.705 311.04ZM903.53 564.7H395.294c-93.402 0-169.412 76.01-169.412 169.411v225.883c0 93.402 76.01 169.412 169.412 169.412H903.53V564.7Zm790.589 123.444v317.93c65.618-23.379 112.94-85.497 112.94-159.021 0-73.525-47.322-135.53-112.94-158.909Z" fill-rule="evenodd"></path></svg>' },
|
||||
{ path: "/assignments", label: "Assignments", icon: '<svg viewBox="0 0 1920 1920" width="19" height="19"><path d="M1468.214 0v564.698h-112.94V112.94H112.94v1694.092h1242.334v-225.879h112.94v338.819H0V0h1468.214Zm129.428 581.311c22.137-22.136 57.825-22.136 79.962 0l225.879 225.879c22.023 22.023 22.023 57.712 0 79.848l-677.638 677.637c-10.616 10.504-24.96 16.49-39.98 16.49h-225.88c-31.17 0-56.469-25.299-56.469-56.47v-225.88c0-15.02 5.986-29.364 16.49-39.867Zm-155.291 314.988-425.895 425.895v146.031h146.03l425.895-425.895-146.03-146.03Zm-764.714 346.047v112.94H338.82v-112.94h338.818Zm225.88-225.88v112.94H338.818v-112.94h564.697Zm734.106-315.44-115.424 115.425 146.03 146.03 115.425-115.423-146.031-146.031ZM1129.395 338.83v451.758H338.82V338.83h790.576Zm-112.94 112.94H451.759v225.878h564.698V451.77Z" fill-rule="evenodd"></path></svg>' },
|
||||
{ path: "/discussion_topics", label: "Discussions", icon: '<svg viewBox="0 0 1920 1920" width="19" height="19"><path d="M677.647 16v338.936h112.941V129.054h1016.47V919.53h-225.994v259.765L1321.412 919.53h-79.172V467.878H0v1016.47h338.71v418.9l417.996-418.9h485.534v-451.877h32.753l419.125 419.124v-419.124H1920V16H677.647ZM338.79 919.563h564.706v-112.94H338.79v112.94Zm0 225.883h338.936v-113.054H338.79v113.054Zm-225.85-564.74h1016.47v790.701H710.4L451.652 1631.06v-259.652h-338.71V580.706Z" fill-rule="evenodd"></path></svg>' },
|
||||
{ path: "/files", label: "Files", icon: '<svg viewBox="0 0 1920 1920" width="19" height="19"><path d="M1807.059 1637.706c0 31.172-25.412 56.47-56.47 56.47H169.411c-31.06 0-56.47-25.298-56.47-56.47V225.94h590.907L854.4 451.824H225.882v112.94H1807.06v1072.942ZM990.269 451.824 764.385 113H0v1524.706c0 93.402 76.01 169.412 169.412 169.412h1581.176c93.403 0 169.412-76.01 169.412-169.412V451.824H990.268Z" fill-rule="evenodd"></path></svg>' }
|
||||
];
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const action = document.createElement("a");
|
||||
action.className = "ic-DashboardCard__action";
|
||||
action.setAttribute("draggable", "false");
|
||||
action.style.display = "inherit";
|
||||
|
||||
const customLink = linkOpts.links && linkOpts.links[i];
|
||||
const img = document.createElement("img");
|
||||
img.className = "canvasrefined-link-image";
|
||||
img.style.display = "none";
|
||||
action.appendChild(img);
|
||||
|
||||
if (customLink && customLink.path === "none") {
|
||||
action.style.display = "none";
|
||||
} else if (customLink && !customLink.is_default && customLink.path) {
|
||||
action.href = customLink.path;
|
||||
action.target = "_blank";
|
||||
img.src = getCustomLinkImage(customLink.path);
|
||||
img.style.display = "block";
|
||||
img.onerror = () => { img.src = "https://www.instructure.com/favicon.ico"; };
|
||||
} else {
|
||||
action.href = domain + "/courses/" + courseId + defaultLinks[i].path;
|
||||
const layout = document.createElement("span");
|
||||
layout.className = "ic-DashboardCard__action-layout";
|
||||
layout.innerHTML = defaultLinks[i].icon;
|
||||
action.appendChild(layout);
|
||||
}
|
||||
actions.appendChild(action);
|
||||
}
|
||||
|
||||
card.appendChild(actions);
|
||||
|
||||
if (options.assignments_due === true) {
|
||||
const assignmentsDiv = document.createElement("div");
|
||||
assignmentsDiv.className = "canvasrefined-card-assignment";
|
||||
assignmentsDiv.style.display = "block";
|
||||
|
||||
const headerContainer = document.createElement("div");
|
||||
headerContainer.className = "canvasrefined-card-header-container";
|
||||
const header3 = document.createElement("h3");
|
||||
header3.className = "canvasrefined-card-header";
|
||||
header3.textContent = "Due";
|
||||
headerContainer.appendChild(header3);
|
||||
assignmentsDiv.appendChild(headerContainer);
|
||||
|
||||
const assignmentsContainer = document.createElement("div");
|
||||
assignmentsContainer.className = "canvasrefined-card-container";
|
||||
assignmentsContainer.dataset.courseId = courseId;
|
||||
|
||||
const assignmentInner = document.createElement("div");
|
||||
assignmentInner.className = "canvasrefined-assignment-container";
|
||||
const noneLink = document.createElement("a");
|
||||
noneLink.className = "canvasrefined-assignment-link";
|
||||
noneLink.textContent = "None";
|
||||
assignmentInner.appendChild(noneLink);
|
||||
assignmentsContainer.appendChild(assignmentInner);
|
||||
|
||||
assignmentsDiv.appendChild(assignmentsContainer);
|
||||
card.appendChild(assignmentsDiv);
|
||||
}
|
||||
|
||||
v2Container.appendChild(card);
|
||||
});
|
||||
|
||||
loadV2Assignments();
|
||||
loadV2Grades();
|
||||
|
||||
moveGPACardToV2();
|
||||
|
||||
chrome.storage.sync.get("v2_card_order", (result) => {
|
||||
if (result.v2_card_order && result.v2_card_order.length > 0) {
|
||||
const order = result.v2_card_order;
|
||||
const cardMap = {};
|
||||
v2Container.querySelectorAll(".canvasrefined-v2-card, .canvasrefined-gpa-card").forEach(card => {
|
||||
cardMap[card.dataset.courseId] = card;
|
||||
});
|
||||
order.forEach(id => {
|
||||
if (cardMap[id]) {
|
||||
v2Container.appendChild(cardMap[id]);
|
||||
if (id === "gpa") {
|
||||
const gpaEdit = document.querySelector(".canvasrefined-gpa");
|
||||
if (gpaEdit) v2Container.appendChild(gpaEdit);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadV2Grades() {
|
||||
if (!options.dashboard_grades || !grades) return;
|
||||
grades.then(data => {
|
||||
document.querySelectorAll(".canvasrefined-v2-card").forEach(card => {
|
||||
const courseId = card.dataset.courseId;
|
||||
const gradeLink = card.querySelector(".canvasrefined-card-grade");
|
||||
if (!gradeLink) return;
|
||||
data.forEach(course => {
|
||||
if (parseInt(courseId) === course.id) {
|
||||
const score = course.enrollments[0].has_grading_periods
|
||||
? course.enrollments[0].current_period_computed_current_score
|
||||
: course.enrollments[0].computed_current_score;
|
||||
gradeLink.textContent = (score || "--") + "%";
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function loadV2Assignments() {
|
||||
if (!options.assignments_due || !cardAssignments) return;
|
||||
const now = new Date();
|
||||
cardAssignments.then(els => {
|
||||
document.querySelectorAll(".canvasrefined-v2-card").forEach(card => {
|
||||
const courseId = card.dataset.courseId;
|
||||
const container = card.querySelector(".canvasrefined-card-container");
|
||||
if (!container) return;
|
||||
container.innerHTML = "";
|
||||
|
||||
if (els[courseId]) {
|
||||
let count = 0;
|
||||
els[courseId].forEach(assignment => {
|
||||
if (count >= options.num_assignments) return;
|
||||
if (options.card_overdues !== true && now >= assignment.due) return;
|
||||
if (assignment.submitted === true) return;
|
||||
if (assignment.type !== "assignment" && assignment.type !== "quiz" && assignment.type !== "discussion_topic") return;
|
||||
if (assignment.override === true) return;
|
||||
|
||||
const row = document.createElement("div");
|
||||
row.className = "canvasrefined-assignment-container";
|
||||
|
||||
const linkEl = document.createElement("a");
|
||||
linkEl.className = "canvasrefined-assignment-link";
|
||||
linkEl.href = assignment.el.querySelector(".canvasrefined-assignment-link").href;
|
||||
linkEl.textContent = assignment.el.querySelector(".canvasrefined-assignment-link").textContent;
|
||||
linkEl.target = "_blank";
|
||||
row.appendChild(linkEl);
|
||||
|
||||
const dueSpan = document.createElement("span");
|
||||
dueSpan.className = "canvasrefined-assignment-dueat";
|
||||
dueSpan.textContent = assignment.el.querySelector(".canvasrefined-assignment-dueat").textContent;
|
||||
row.appendChild(dueSpan);
|
||||
|
||||
container.appendChild(row);
|
||||
count++;
|
||||
});
|
||||
}
|
||||
|
||||
if (container.children.length === 0) {
|
||||
const row = document.createElement("div");
|
||||
row.className = "canvasrefined-assignment-container";
|
||||
const link = document.createElement("a");
|
||||
link.className = "canvasrefined-assignment-link";
|
||||
link.textContent = "None";
|
||||
row.appendChild(link);
|
||||
container.appendChild(row);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function moveGPACardToV2() {
|
||||
const v2Container = document.querySelector("#canvasrefined-v2-container");
|
||||
const gpaCard = document.querySelector(".canvasrefined-gpa-card");
|
||||
const gpaEdit = document.querySelector(".canvasrefined-gpa");
|
||||
if (!v2Container || !gpaCard) return;
|
||||
if (gpaCard.parentElement === v2Container) return;
|
||||
|
||||
gpaCard.dataset.courseId = "gpa";
|
||||
gpaCard.dataset.widgetType = "gpa";
|
||||
|
||||
if (gpaEdit) {
|
||||
gpaEdit.dataset.courseId = "gpa";
|
||||
gpaEdit.dataset.widgetType = "gpa";
|
||||
v2Container.appendChild(gpaCard);
|
||||
v2Container.appendChild(gpaEdit);
|
||||
} else {
|
||||
v2Container.appendChild(gpaCard);
|
||||
}
|
||||
}
|
||||
|
||||
function moveGPACardOutOfV2() {
|
||||
const dashboardContainer = document.querySelector("#DashboardCard_Container");
|
||||
const gpaCard = document.querySelector(".canvasrefined-gpa-card");
|
||||
const gpaEdit = document.querySelector(".canvasrefined-gpa");
|
||||
if (!dashboardContainer || !gpaCard) return;
|
||||
|
||||
gpaCard.removeAttribute("draggable");
|
||||
gpaCard.removeAttribute("data-testid");
|
||||
gpaCard.removeAttribute("aria-label");
|
||||
delete gpaCard.dataset.courseId;
|
||||
delete gpaCard.dataset.widgetType;
|
||||
|
||||
if (options.gpa_calc_prepend === true) {
|
||||
dashboardContainer.prepend(gpaCard);
|
||||
if (gpaEdit) dashboardContainer.prepend(gpaEdit);
|
||||
} else {
|
||||
dashboardContainer.appendChild(gpaCard);
|
||||
if (gpaEdit) dashboardContainer.appendChild(gpaEdit);
|
||||
}
|
||||
}
|
||||
|
||||
function saveV2CardOrder() {
|
||||
const v2Container = document.querySelector("#canvasrefined-v2-container");
|
||||
if (!v2Container) return;
|
||||
const order = [];
|
||||
v2Container.querySelectorAll(".canvasrefined-v2-card, .canvasrefined-gpa-card").forEach(c => {
|
||||
order.push(c.dataset.courseId);
|
||||
});
|
||||
chrome.storage.sync.set({ "v2_card_order": order });
|
||||
}
|
||||
|
||||
function removeDashboardV2() {
|
||||
const dashboardContainer = document.querySelector("#DashboardCard_Container");
|
||||
if (dashboardContainer) dashboardContainer.classList.remove("canvasrefined-v2-active");
|
||||
|
||||
const v2Container = document.querySelector("#canvasrefined-v2-container");
|
||||
if (v2Container) v2Container.remove();
|
||||
|
||||
const originalCards = document.querySelector(".ic-DashboardCard__box__container");
|
||||
if (originalCards) originalCards.style.display = "";
|
||||
}
|
||||
|
||||
function isDashboardV2Active() {
|
||||
return options.dashboard_v2 === true;
|
||||
}
|
||||
|
||||
function logError(e) {
|
||||
chrome.storage.local.get("errors", storage => {
|
||||
if (storage.errors.length > 20) {
|
||||
|
||||
20
js/popup.js
20
js/popup.js
@ -1,4 +1,4 @@
|
||||
const syncedSwitches = ['remind', 'tab_icons', 'hide_feedback', 'dark_mode', 'remlogo', 'full_width', 'auto_dark', 'assignments_due', 'gpa_calc', 'gradient_cards', 'disable_color_overlay', 'dashboard_grades', 'dashboard_notes', 'better_todo', 'better_sidebar', 'condensed_cards', 'widget_clock'];
|
||||
const syncedSwitches = ['remind', 'tab_icons', 'hide_feedback', 'dark_mode', 'remlogo', 'full_width', 'auto_dark', 'assignments_due', 'gpa_calc', 'gradient_cards', 'disable_color_overlay', 'dashboard_grades', 'dashboard_notes', 'better_todo', 'better_sidebar', 'condensed_cards', 'widget_clock', 'dashboard_v2'];
|
||||
const syncedSubOptions = [
|
||||
"todo_hide_feedback",
|
||||
"todo_full_height",
|
||||
@ -6,6 +6,8 @@ const syncedSubOptions = [
|
||||
"device_dark",
|
||||
"relative_dues",
|
||||
"card_overdues",
|
||||
"v2_limit_assignments",
|
||||
"v2_truncate_names",
|
||||
// "todo_overdues",
|
||||
"gpa_calc_prepend",
|
||||
"auto_dark",
|
||||
@ -130,10 +132,12 @@ const defaultOptions = {
|
||||
"cardSpacing": 0,
|
||||
"cardWidth": 262,
|
||||
"cardHeight": 250,
|
||||
"customCardStyles": false,
|
||||
"customBackgroundLink": "",
|
||||
"customBackgroundScale": 100,
|
||||
"widget_clock": false,
|
||||
"customCardStyles": false,
|
||||
"customBackgroundLink": "",
|
||||
"customBackgroundScale": 100,
|
||||
"widget_clock": false,
|
||||
"v2_limit_assignments": true,
|
||||
"v2_truncate_names": false,
|
||||
}
|
||||
};
|
||||
|
||||
@ -379,6 +383,8 @@ function setup() {
|
||||
"hover_preview",
|
||||
// "scheduledReminder",
|
||||
"customCardStyles",
|
||||
"v2_limit_assignments",
|
||||
"v2_truncate_names",
|
||||
],
|
||||
tabs: {
|
||||
"advanced-settings": {
|
||||
@ -410,6 +416,10 @@ function setup() {
|
||||
setup: displayErrors,
|
||||
tab: ".report-issue-container",
|
||||
},
|
||||
"experimental-btn": {
|
||||
setup: null,
|
||||
tab: ".experimental",
|
||||
},
|
||||
"updates-btn": { setup: null, tab: ".updates-container" },
|
||||
},
|
||||
special: [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user