Skip to content

Instantly share code, notes, and snippets.

@dcdunkan
Last active February 27, 2025 13:30
Show Gist options
  • Save dcdunkan/37a5d23ceccfb42084de917eeec1538c to your computer and use it in GitHub Desktop.
Save dcdunkan/37a5d23ceccfb42084de917eeec1538c to your computer and use it in GitHub Desktop.
"Focus for Etlab" UserScript for TKMCE Etlab, which declutters the dashboard and gives focus to most frequently used items.
// ==UserScript==
// @name Focus for Etlab
// @namespace Utilities for Etlab
// @match https://tkmce.etlab.in/user/dashboard*
// @include https://tkmce.etlab.in/
// @grant GM_getValue
// @grant GM_setValue
// @version 0.3
// @run-at document-end
// @author Dunkan <https://github.com/dcdunkan>
// @description "Focus for Etlab" UserScript for TKMCE Etlab, which declutters the dashboard and gives focus to most frequently used items.
// @homepageURL https://gist.github.com/dcdunkan/37a5d23ceccfb42084de917eeec1538c
// @downloadURL https://gist.githubusercontent.com/dcdunkan/37a5d23ceccfb42084de917eeec1538c/raw/etlab-focus.userscript.js
// ==/UserScript==
const pathSegments = window.location.pathname
.split("/").slice(1)
.filter((segment) => segment.length > 0);
const WORK_ITEM_TITLES = ["Assignments", "Homeworks", "Tutorials"];
const DATA_ITEM_TITLES = ["My Profile", "Results", "Attendance"];
(function () {
if (
pathSegments.length > 0 &&
(pathSegments[0] !== "user" || pathSegments[1] !== "dashboard")
) return;
console.info("Focs for Etlab is active");
const hasNotified = GM_getValue("hasNotified", false);
if (!hasNotified) {
window.alert("Focus for Etlab is now active. This will re-arrange the dashboard. Click on the focus button to enable it");
GM_setValue("hasNotified", true);
}
const mainContent = document.getElementById("breadcrumb").nextElementSibling;
const focusToggleButton = document.createElement("button");
focusToggleButton.onclick = function () {
let current = localStorage.getItem("focusEnabled") === "true";
localStorage.setItem("focusEnabled", String(!current));
focusToggleButton.innerHTML = current ? "Focus" : "Unfocus";
if (!current) startFocusing();
else window.location.reload();
}
mainContent.prepend(focusToggleButton);
let shouldFocus = localStorage.getItem("focusEnabled") === "true";
focusToggleButton.innerHTML = shouldFocus ? "Unfocus" : "Focus";
if (shouldFocus) {
startFocusing();
}
})();
function startFocusing() {
console.log("Focus was enabled.");
// Declutter the paragraphs, that no one cares for.
const uselessSections = [
document.evaluate("//h3[contains(., 'Vision of the College')]", document, null, XPathResult.ANY_TYPE, null).iterateNext(),
document.evaluate("//h3[contains(., 'Mission of the College')]", document, null, XPathResult.ANY_TYPE, null).iterateNext(),
].filter((section) => section != null);
for (const section of uselessSections) {
if (section.parentNode != null) {
const target = section.parentNode.parentNode;
if (target == null) continue;
if (target.nodeName != "DIV") return;
target.remove();
}
}
const shortcuts = document.getElementsByClassName("shortcuts").item("div");
const workTitle = createTitle("WORK RELATED");
const workContainer = document.createElement("div");
workContainer.classList.add("shortcuts");
const dataTitle = createTitle("IMPORTANT DATA");
const dataContainer = document.createElement("div");
dataContainer.classList.add("shortcuts");
for (const shortcut of shortcuts.childNodes) {
if (shortcut.nodeName !== "A") continue;
if (!shortcut.classList.contains("shortcut")) continue;
let title = "";
for (const child of shortcut.childNodes) {
if (child.nodeName !== "SPAN") continue;
if (!child.classList.contains("shortcut-label")) continue;
title = child.textContent.trim();
}
if (title == "") continue;
if (WORK_ITEM_TITLES.includes(title)) {
workContainer.appendChild(shortcuts.removeChild(shortcut));
} else if (DATA_ITEM_TITLES.includes(title)) {
dataContainer.appendChild(shortcuts.removeChild(shortcut));
}
}
if (workContainer.childNodes.length !== WORK_ITEM_TITLES.length) {
console.warn("FOCUS: Failed to find all the work items.");
}
if (dataContainer.childNodes.length !== DATA_ITEM_TITLES.length) {
console.warn("FOCUS: Failed to find all the data items.");
}
if (workContainer.childNodes.length > 0) {
shortcuts.before(workTitle);
workTitle.after(workContainer);
}
if (dataContainer.childNodes.length > 0) {
shortcuts.before(dataTitle);
dataTitle.after(dataContainer);
}
if (workContainer.childNodes.length > 0 || dataContainer.childNodes.length > 0) {
const uselessTitle = createTitle("USELESS FOR MOST OF THE TIME (click to expand)");
const details = document.createElement("details");
const summary = document.createElement("summary");
summary.appendChild(uselessTitle);
details.appendChild(summary);
details.appendChild(shortcuts.parentNode.removeChild(shortcuts));
const lastContainer = dataContainer.childNodes.length > 0 ? dataContainer : workContainer;
lastContainer.after(details);
}
console.log("Finished decluttering");
}
function createTitle(title) {
const element = document.createElement("center");
element.textContent = title;
element.style.padding = "10px";
element.style.fontWeight = "900";
element.style.fontSize = "large";
return element;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment