Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name iready hack (only displays on your screen, not the teachers screen. use it only for substitutes)
- // @namespace http://tampermonkey.net/
- // @version 6.1
- // @description Menu to change minutes and update circular progress ring accurately + prevent iReady from resetting it
- // @match *://*.i-ready.com/*
- // @grant GM_xmlhttpRequest
- // @icon https://login.i-ready.com/favicon.ico
- // ==/UserScript==
- (function() {
- 'use strict';
- /* ---------------- MENU CREATION ---------------- */
- const menu = document.createElement("div");
- menu.style.position = "fixed";
- menu.style.top = "20px";
- menu.style.left = "20px";
- menu.style.padding = "15px 20px";
- menu.style.background = "rgba(20, 20, 30, 0.85)";
- menu.style.border = "1px solid #0ff";
- menu.style.borderRadius = "12px";
- menu.style.boxShadow = "0 0 15px #0ff, inset 0 0 10px #0ff";
- menu.style.backdropFilter = "blur(6px)";
- menu.style.zIndex = "999999";
- menu.style.fontFamily = "Arial";
- menu.style.cursor = "move";
- menu.style.color = "#0ff";
- menu.style.userSelect = "none";
- menu.style.transition = "0.2s ease-out";
- menu.classList.add("menu-animate");
- menu.innerHTML = `
- <div style="
- font-size: 16px;
- font-weight: bold;
- color: #0ff;
- text-shadow: 0 0 8px #0ff;
- margin-bottom: 10px;
- text-align: center;
- ">
- Made by Justalilbro
- </div>
- <button id="setMinsBtn"
- style="
- padding: 10px 18px;
- background: linear-gradient(135deg, #0ff, #09f);
- border: none;
- border-radius: 8px;
- color: black;
- font-weight: bold;
- cursor: pointer;
- box-shadow: 0 0 var(--glow) #0ff;
- "
- >Set Minutes</button>
- <button id="setPfpBtn"
- style="
- margin-top: 10px;
- padding: 10px 18px;
- background: linear-gradient(135deg, #0ff, #0af);
- border: none;
- border-radius: 8px;
- color: black;
- font-weight: bold;
- cursor: pointer;
- box-shadow: 0 0 var(--glow) #0ff;
- "
- >change Neon color of dashboard</button>
- <button id="openSiteBtn"
- style="
- margin-top: 10px;
- padding: 10px 18px;
- background: linear-gradient(135deg, #0ff, #0af);
- border: none;
- border-radius: 8px;
- color: black;
- font-weight: bold;
- cursor: pointer;
- box-shadow: 0 0 var(--glow) #0ff;
- "
- >Games</button>
- <button id="rainbowBtn"
- style="
- margin-top: 10px;
- padding: 10px 18px;
- background: linear-gradient(135deg, #0ff, #0af);
- border: none;
- border-radius: 8px;
- color: black;
- font-weight: bold;
- cursor: pointer;
- box-shadow: 0 0 var(--glow) #0ff;
- "
- >Rainbow Pulse</button>
- <button id="launcherBtn"
- style="
- margin-top: 10px;
- padding: 10px 18px;
- background: linear-gradient(135deg, #0ff, #0af);
- border: none;
- border-radius: 8px;
- color: black;
- font-weight: bold;
- cursor: pointer;
- box-shadow: 0 0 var(--glow) #0ff;
- "
- >Link Launcher</button>
- <label style="color:white; margin-top:10px;">Glow Intensity</label>
- <input id="glowSlider" type="range" min="0" max="30" value="10" style="width:100%;">
- <div id="launcherPopup" style="display:none;">
- <div id="launcherTopBar">
- <input id="launcherInput" placeholder="Enter URL" style="flex:1;">
- <button id="launchOpenBtn" class="neonBtn">Open</button>
- <button id="closeLauncherBtn" class="neonBtn">Close</button>
- </div>
- <iframe id="launcherFrame"></iframe>
- </div>
- <button id="bgBtn"
- style="
- margin-top: 10px;
- padding: 10px 18px;
- background: linear-gradient(135deg, #0ff, #0af);
- border: none;
- border-radius: 8px;
- color: black;
- font-weight: bold;
- cursor: pointer;
- box-shadow: 0 0 var(--glow) #0ff;
- "
- >Change Background</button>
- `;
- document.body.appendChild(menu);
- /* ---------------- LINK LAUNCHER (FIXED SITE + FULLSCREEN) ---------------- */
- document.getElementById("launcherBtn").onclick = () => {
- const fixedURL = "https://onehtmlpagechallenge.com/entries/tic-tac-toe.html"; // ← CHANGE THIS TO ANY SITE YOU WANT
- GM_xmlhttpRequest({
- method: "GET",
- url: fixedURL,
- onload: function(res) {
- const blob = new Blob([res.responseText], { type: "text/html" });
- const blobURL = URL.createObjectURL(blob);
- document.getElementById("launcherFrame").src = blobURL;
- document.getElementById("launcherPopup").style.display = "block";
- },
- onerror: function() {
- alert("Failed to load site.");
- }
- });
- };
- document.getElementById("closeLauncherBtn").onclick = () => {
- document.getElementById("launcherPopup").style.display = "none";
- };
- /* ---------------- GLOW SLIDER ---------------- */
- document.documentElement.style.setProperty("--glow", "10px");
- document.getElementById("glowSlider").oninput = (e) => {
- const value = e.target.value + "px";
- document.documentElement.style.setProperty("--glow", value);
- };
- /* ---------------- RAINBOW PULSE MODE ---------------- */
- let rainbowActive = false;
- let rainbowInterval = null;
- document.getElementById("rainbowBtn").onclick = () => {
- rainbowActive = !rainbowActive;
- if (rainbowActive) {
- let hue = 0;
- rainbowInterval = setInterval(() => {
- hue = (hue + 2) % 360;
- const color = `hsl(${hue}, 100%, 50%)`;
- document.querySelectorAll(`
- div.sc-lgpSej,
- div.kDLWDE,
- button[aria-label='Dashboard Navigation'],
- button[aria-label='Tour'],
- button[aria-label='Bookshelf'],
- button[aria-label='Math Tools'],
- button[aria-label='Learning Games'],
- div.sc-fNmvep,
- span.select-selected-text
- `).forEach(el => {
- el.style.background = color;
- el.style.border = `2px solid ${color}`;
- el.style.boxShadow = `0 0 15px ${color}`;
- });
- }, 50);
- } else {
- clearInterval(rainbowInterval);
- alert("Rainbow Mode OFF");
- }
- };
- // Trigger initial animation
- setTimeout(() => menu.classList.add("menu-visible"), 20);
- // --- THEME SWITCHER + RESET BUTTON ---
- const themeControls = document.createElement("div");
- themeControls.style.marginTop = "12px";
- themeControls.innerHTML = `
- <label style="font-size:14px;">Theme:</label>
- <select id="themeSelect" style="
- margin-left:6px;
- padding:4px;
- border-radius:6px;
- background:#111;
- color:#0ff;
- border:1px solid #0ff;
- ">
- <option value="neon">Neon</option>
- <option value="dark">Dark</option>
- <option value="light">Light</option>
- </select>
- <button id="resetBtn"
- style="
- margin-top:10px;
- width:100%;
- padding:8px;
- background:linear-gradient(135deg, #f00, #a00);
- border:none;
- border-radius:8px;
- color:white;
- font-weight:bold;
- cursor:pointer;
- box-shadow: 0 0 var(--glow) #0ff;
- "
- >Reset to Default</button>
- `;
- menu.appendChild(themeControls);
- // Top bar theming
- const topBar = document.querySelector(".sc-fNmvep.fgctbz");
- function applyTopBarTheme(theme) {
- if (!topBar) return;
- topBar.classList.remove("tb-neon", "tb-dark", "tb-light");
- topBar.classList.add(`tb-${theme}`);
- }
- // Apply theme
- const applyTheme = (theme) => {
- menu.classList.remove("theme-neon", "theme-dark", "theme-light");
- menu.classList.add(`theme-${theme}`);
- applyTopBarTheme(theme);
- localStorage.setItem("ireadyMenuTheme", theme);
- };
- // Load saved theme
- const savedTheme = localStorage.getItem("ireadyMenuTheme") || "neon";
- applyTheme(savedTheme);
- document.getElementById("themeSelect").value = savedTheme;
- // Theme change event
- document.getElementById("themeSelect").addEventListener("change", (e) => {
- applyTheme(e.target.value);
- });
- // Reset button logic
- document.getElementById("resetBtn").onclick = () => {
- applyTheme("neon");
- document.getElementById("themeSelect").value = "neon";
- window._ireadyForcedMins = null;
- updateMinutes(0);
- updateProgressRing(0);
- const pfpSpan = document.querySelector("button[aria-label='Profile'] span.sc-bmWQkG");
- if (pfpSpan) {
- pfpSpan.style.backgroundImage = "";
- pfpSpan.style.backgroundSize = "";
- pfpSpan.style.backgroundPosition = "";
- }
- menu.style.top = "20px";
- menu.style.left = "20px";
- alert("Menu reset to default.");
- };
- // --- Toggle menu visibility with "P" key (with animation) ---
- let menuVisible = true;
- document.addEventListener("keydown", (e) => {
- if (e.key.toLowerCase() === "p") {
- menuVisible = !menuVisible;
- if (menuVisible) {
- menu.style.display = "block";
- setTimeout(() => menu.classList.add("menu-visible"), 10);
- } else {
- menu.classList.remove("menu-visible");
- setTimeout(() => {
- if (!menuVisible) menu.style.display = "none";
- }, 250);
- }
- }
- });
- // --- Change profile picture from any PNG link ---
- document.getElementById("setPfpBtn").onclick = () => {
- let color = prompt("Enter a neon color (hex, rgb, or name):", "#00ffff");
- if (!color) return;
- // 1. Purple lesson card
- document.querySelectorAll("div.sc-lgpSej, div.kDLWDE").forEach(card => {
- card.style.background = color;
- card.style.border = `2px solid ${color}`;
- card.style.boxShadow = `0 0 15px ${color}`;
- card.style.transition = "0.25s ease-out";
- });
- // 2. Hamburger nav button
- const navBtn = document.querySelector("button[aria-label='Dashboard Navigation']");
- if (navBtn) {
- navBtn.style.background = color;
- navBtn.style.border = `2px solid ${color}`;
- navBtn.style.boxShadow = `0 0 12px ${color}`;
- navBtn.style.borderRadius = "10px";
- navBtn.style.transition = "0.25s ease-out";
- }
- // 3. Top bar
- const topBar = document.querySelector("div.sc-fNmvep, div.fgctbz");
- if (topBar) {
- topBar.style.background = color;
- topBar.style.borderBottom = `2px solid ${color}`;
- topBar.style.boxShadow = `0 0 12px ${color}`;
- topBar.style.transition = "0.25s ease-out";
- }
- // 4. Tour button
- const tourBtn = document.querySelector("button[aria-label='Tour']");
- if (tourBtn) {
- tourBtn.style.background = color;
- tourBtn.style.border = `2px solid ${color}`;
- tourBtn.style.boxShadow = `0 0 12px ${color}`;
- tourBtn.style.borderRadius = "10px";
- tourBtn.style.transition = "0.25s ease-out";
- }
- // 5. Bookshelf button
- const bookshelfBtn = document.querySelector("button[aria-label='Bookshelf']");
- if (bookshelfBtn) {
- bookshelfBtn.style.background = color;
- bookshelfBtn.style.border = `2px solid ${color}`;
- bookshelfBtn.style.boxShadow = `0 0 12px ${color}`;
- bookshelfBtn.style.borderRadius = "10px";
- bookshelfBtn.style.transition = "0.25s ease-out";
- }
- // 6. Math Tools button
- const mathToolsBtn = document.querySelector("button[aria-label='Math Tools']");
- if (mathToolsBtn) {
- mathToolsBtn.style.background = color;
- mathToolsBtn.style.border = `2px solid ${color}`;
- mathToolsBtn.style.boxShadow = `0 0 12px ${color}`;
- mathToolsBtn.style.borderRadius = "10px";
- mathToolsBtn.style.transition = "0.25s ease-out";
- }
- // 7. Learning Games button
- const learningGamesBtn = document.querySelector("button[aria-label='Learning Games']");
- if (learningGamesBtn) {
- learningGamesBtn.style.background = color;
- learningGamesBtn.style.border = `2px solid ${color}`;
- learningGamesBtn.style.boxShadow = `0 0 12px ${color}`;
- learningGamesBtn.style.borderRadius = "10px";
- learningGamesBtn.style.transition = "0.25s ease-out";
- }
- // 8. MATH span (custom cursor text)
- const mathSpan = document.querySelector("span.select-selected-text.sweezy-custom-cursor-hover");
- if (mathSpan) {
- mathSpan.style.color = color;
- mathSpan.style.textShadow = `0 0 10px ${color}`;
- mathSpan.style.transition = "0.25s ease-out";
- }
- };
- // --- Open Website button ---
- document.getElementById("openSiteBtn").onclick = () => {
- window.open("https://clever.pbseducation1914.org/", "_blank");
- };
- document.getElementById("bgBtn").onclick = () => {
- changeBackground();
- };
- // --- Make menu draggable ---
- let offsetX, offsetY, isDown = false;
- menu.addEventListener("mousedown", e => {
- isDown = true;
- offsetX = e.clientX - menu.offsetLeft;
- offsetY = e.clientY - menu.offsetTop;
- });
- document.addEventListener("mouseup", () => isDown = false);
- document.addEventListener("mousemove", e => {
- if (isDown) {
- menu.style.left = (e.clientX - offsetX) + "px";
- menu.style.top = (e.clientY - offsetY) + "px";
- }
- });
- // --- Button click handler ---
- document.getElementById("setMinsBtn").onclick = () => {
- let mins = prompt("How many mins? (both on math and reading)");
- if (mins === null) return;
- mins = mins.trim();
- if (!/^\d+$/.test(mins)) {
- alert("Please enter a valid number.");
- return;
- }
- mins = Number(mins);
- window._ireadyForcedMins = mins;
- updateMinutes(mins);
- updateProgressRing(mins);
- watchCircle(); // start locking the ring
- };
- // --- Replace minutes text ---
- function updateMinutes(value) {
- document.querySelectorAll("span.sc-eJoXEY.jyZGpj").forEach(span => {
- if (!isNaN(span.textContent.trim())) {
- span.textContent = value;
- }
- });
- document.querySelectorAll("span.sc-erPUmh.kLeQTe").forEach(span => {
- const match = span.textContent.trim().match(/^(\d+)\s*Minutes$/i);
- if (match) {
- span.textContent = `${value} Minutes`;
- }
- });
- }
- // --- Accurate SVG ring update ---
- function updateProgressRing(mins) {
- const clamped = Math.min(mins, 60);
- const progress = clamped / 60;
- // --- MATH RING ---
- const mathCircle = document.querySelector("#progress-circle");
- if (mathCircle) {
- const r = mathCircle.r.baseVal.value;
- const C = 2 * Math.PI * r;
- mathCircle.style.strokeDasharray = C;
- mathCircle.style.strokeDashoffset = C * (1 - progress);
- mathCircle.style.transition = "stroke-dashoffset 0.2s linear";
- }
- // --- READING RING ---
- const readingCircle = document.querySelector('svg#donut-chart circle.sc-hdBJTi.cgAQTl');
- if (readingCircle) {
- const r = readingCircle.r.baseVal.value;
- const C = 2 * Math.PI * r;
- readingCircle.style.strokeDasharray = C;
- readingCircle.style.strokeDashoffset = C * (1 - progress);
- readingCircle.style.transition = "stroke-dashoffset 0.2s linear";
- }
- }
- // --- MutationObserver to LOCK the ring so iReady can't reset it ---
- let circleObserver = null;
- function watchCircle() {
- const circle = document.querySelector("#progress-circle");
- if (!circle) return;
- if (circleObserver) circleObserver.disconnect();
- circleObserver = new MutationObserver(() => {
- if (window._ireadyForcedMins != null) {
- updateProgressRing(window._ireadyForcedMins);
- }
- });
- circleObserver.observe(circle, {
- attributes: true,
- attributeFilter: ["style"]
- });
- }
- // --- Debounced global observer for text updates ---
- let debounceTimer = null;
- const observer = new MutationObserver(() => {
- if (!window._ireadyForcedMins) return;
- clearTimeout(debounceTimer);
- debounceTimer = setTimeout(() => {
- updateMinutes(window._ireadyForcedMins);
- updateProgressRing(window._ireadyForcedMins);
- }, 50);
- });
- observer.observe(document.body, { childList: true, subtree: true });
- const style = document.createElement("style");
- style.textContent = `
- /* --- MENU THEMES --- */
- .theme-neon {
- background: rgba(20, 20, 30, 0.85) !important;
- border: 1px solid #0ff !important;
- color: #0ff !important;
- box-shadow: 0 0 15px #0ff, inset 0 0 10px #0ff !important;
- }
- .theme-dark {
- background: rgba(10, 10, 10, 0.9) !important;
- border: 1px solid #444 !important;
- color: #ddd !important;
- box-shadow: 0 0 10px #444 !important;
- }
- .theme-light {
- background: rgba(255, 255, 255, 0.9) !important;
- border: 1px solid #ccc !important;
- color: #222 !important;
- box-shadow: 0 0 10px #ccc !important;
- }
- /* --- TOP BAR THEMES --- */
- .tb-neon {
- background: rgba(0, 255, 255, 0.12) !important;
- border-bottom: 1px solid #0ff !important;
- box-shadow: 0 0 12px #0ff !important;
- }
- .tb-dark {
- background: rgba(10, 10, 10, 0.85) !important;
- border-bottom: 1px solid #444 !important;
- box-shadow: 0 0 8px #333 !important;
- }
- .tb-light {
- background: rgba(255, 255, 255, 0.9) !important;
- border-bottom: 1px solid #ccc !important;
- box-shadow: 0 0 8px #ccc !important;
- }
- /* Buttons inside the top bar */
- .tb-neon button,
- .tb-dark button,
- .tb-light button {
- transition: 0.2s ease-out !important;
- }
- /* Neon button glow */
- .tb-neon button {
- background: rgba(0, 255, 255, 0.15) !important;
- border-radius: 8px !important;
- box-shadow: 0 0 10px #0ff !important;
- }
- /* Dark mode buttons */
- .tb-dark button {
- background: rgba(40, 40, 40, 0.8) !important;
- border-radius: 8px !important;
- box-shadow: 0 0 6px #222 !important;
- }
- /* Light mode buttons */
- .tb-light button {
- background: rgba(240, 240, 240, 0.9) !important;
- border-radius: 8px !important;
- box-shadow: 0 0 6px #aaa !important;
- }
- /* Profile icon circle */
- .tb-neon .sc-bmWQkG {
- box-shadow: 0 0 10px #0ff !important;
- }
- .tb-dark .sc-bmWQkG {
- box-shadow: 0 0 6px #222 !important;
- }
- .tb-light .sc-bmWQkG {
- box-shadow: 0 0 6px #aaa !important;
- }
- /* --- MENU ANIMATION --- */
- .menu-animate {
- opacity: 0;
- transform: translateY(-10px);
- transition: opacity 0.25s ease-out, transform 0.25s ease-out;
- }
- .menu-visible {
- opacity: 1 !important;
- transform: translateY(0px) !important;
- }
- /* Neon card base style */
- .neon-card {
- border-radius: 14px !important;
- transition: 0.25s ease-out !important;
- }
- /* ---------------- FULLSCREEN LAUNCHER ---------------- */
- #launcherPopup {
- position: fixed !important;
- top: 0 !important;
- left: 0 !important;
- width: 100vw !important;
- height: 100vh !important;
- background: rgba(0, 0, 0, 0.85) !important;
- backdrop-filter: blur(6px);
- z-index: 999999 !important;
- padding: 0 !important;
- margin: 0 !important;
- display: none;
- }
- #launcherTopBar {
- width: 100%;
- height: 60px;
- background: rgba(0, 255, 255, 0.15);
- display: flex;
- align-items: center;
- gap: 10px;
- padding: 10px;
- box-sizing: border-box;
- border-bottom: 1px solid #0ff;
- }
- #launcherFrame {
- width: 100vw !important;
- height: calc(100vh - 60px) !important;
- border: none !important;
- outline: none !important;
- }
- `;
- document.head.appendChild(style);
- /* ---------------- CHANGE BACKGROUND (BLOB + TARGETED REMOVAL) ---------------- */
- function changeBackground() {
- const url = prompt("Enter wallpaper link (PNG/JPG/WebP):");
- if (!url) return;
- GM_xmlhttpRequest({
- method: "GET",
- url: url,
- responseType: "blob",
- onload: function(res) {
- const blobURL = URL.createObjectURL(res.response);
- // Apply your wallpaper ONLY to html/body
- const css = `
- html, body {
- background-image: url("${blobURL}") !important;
- background-size: cover !important;
- background-position: center !important;
- background-repeat: no-repeat !important;
- }
- `;
- const style = document.createElement("style");
- style.innerHTML = css;
- document.head.appendChild(style);
- // Remove ONLY the JoustBlue background
- const targetFragment = "Theme_JoustBlue_Background.svg";
- document.querySelectorAll("*").forEach(el => {
- const bg = getComputedStyle(el).backgroundImage;
- if (bg && bg.includes(targetFragment)) {
- el.style.backgroundImage = "none";
- el.style.background = "transparent";
- }
- });
- console.log("Wallpaper applied via blob:", blobURL);
- },
- onerror: function() {
- alert("Failed to load image. Try a different link.");
- }
- });
- }
- })();
Advertisement
Add Comment
Please, Sign In to add comment