From 76a6718e4f0344b757b932f3d97b0ebab80cb204 Mon Sep 17 00:00:00 2001 From: rgantzos <86856959+rgantzos@users.noreply.github.com> Date: Sun, 30 Mar 2025 11:11:05 -0700 Subject: [PATCH] Prepare for v4.1.0 --- api/update/index.js | 5 +- extras/background.js | 38 +++- features/features.json | 5 + features/more-block-themes/script.js | 3 + features/random-block-colors/check.svg | 3 + features/random-block-colors/circle.svg | 17 ++ features/random-block-colors/colors.css | 40 ++++ features/random-block-colors/data.json | 28 +++ features/random-block-colors/script.js | 274 ++++++++++++++++++++++++ features/random-block-colors/style.css | 9 + manifest.json | 2 +- 11 files changed, 417 insertions(+), 7 deletions(-) create mode 100644 features/random-block-colors/check.svg create mode 100644 features/random-block-colors/circle.svg create mode 100644 features/random-block-colors/colors.css create mode 100644 features/random-block-colors/data.json create mode 100644 features/random-block-colors/script.js create mode 100644 features/random-block-colors/style.css diff --git a/api/update/index.js b/api/update/index.js index 7c235ca0..06da0a1a 100644 --- a/api/update/index.js +++ b/api/update/index.js @@ -40,12 +40,13 @@ async function checkUpdate() { forum: "0", }, }); - checkUpdate() + // checkUpdate() } } -checkUpdate(); +// checkUpdate(); function makeScreen(update) { + return console.log(update); if (document.querySelector(".ste-update-bg")) return; let background = Object.assign(document.createElement("div"), { diff --git a/extras/background.js b/extras/background.js index 1e404847..9c6a10d5 100644 --- a/extras/background.js +++ b/extras/background.js @@ -49,8 +49,7 @@ async function checkBetaUpdates() { ).json(); if ( data.version !== chrome.runtime.getManifest().version_name || - (await (await fetch("/changelog/beta.json")).json()).beta !== - data.beta + (await (await fetch("/changelog/beta.json")).json()).beta !== data.beta ) { // chrome.tabs.create({ // url: "/extras/beta/index.html", @@ -64,6 +63,7 @@ if (chrome.runtime.getManifest().version_name.endsWith("-beta")) { } chrome.runtime.onInstalled.addListener(async function (object) { + checkApril(); try { var featureData = await (await fetch("/features/features.json")).json(); } catch (err) { @@ -671,12 +671,17 @@ chrome.runtime.onMessageExternal.addListener(async function ( } if (msg.msg === "openPong") { await chrome.tabs.create({ - url: "/api/april/pong/index.html?username=" + msg.username + "&id=" + msg.id, + url: + "/api/april/pong/index.html?username=" + msg.username + "&id=" + msg.id, }); } if (msg.msg === "openDashboardPage") { await chrome.tabs.create({ - url: "/extras/dashboard/index.html?code=" + msg.token + "&username=" + msg.username, + url: + "/extras/dashboard/index.html?code=" + + msg.token + + "&username=" + + msg.username, }); chrome.tabs.remove(sender.tab.id, function () {}); } @@ -821,7 +826,32 @@ chrome.runtime.onMessage.addListener(async function ( } }); +async function checkApril() { + if (new Date().getMonth() === 3 && new Date().getDate() === 1) { + let features = (await chrome.storage.sync.get("features"))?.features || ""; + if (!features.includes("random-block-colors")) { + await chrome.storage.sync.set({ aprilAutomatic2025: true }); + features = features + ".random-block-colors"; + await chrome.storage.sync.set({ features }); + } + } else { + let aprilAutomatic = (await chrome.storage.sync.get("aprilAutomatic2025")) + ?.aprilAutomatic2025; + + if (aprilAutomatic) { + let features = + (await chrome.storage.sync.get("features"))?.features || ""; + if (features.includes("random-block-colors")) { + features = features.replaceAll("random-block-colors", ""); + await chrome.storage.sync.set({ features }); + await chrome.storage.sync.set({ aprilAutomatic2025: false }); + } + } + } +} + chrome.alarms.onAlarm.addListener(async function () { + checkApril(); chrome.alarms.clearAll(); chrome.alarms.create("test", { delayInMinutes: 0.5, diff --git a/features/features.json b/features/features.json index 779defe0..144b6446 100644 --- a/features/features.json +++ b/features/features.json @@ -1,4 +1,9 @@ [ + { + "version": 2, + "id": "random-block-colors", + "versionAdded": "v4.1.0" + }, { "version": 2, "id": "remove-confirmation", diff --git a/features/more-block-themes/script.js b/features/more-block-themes/script.js index 68ee6378..d89eb33e 100644 --- a/features/more-block-themes/script.js +++ b/features/more-block-themes/script.js @@ -1,4 +1,7 @@ export default async function ({ feature, console, scratchClass }) { + let randomBlockColorsEnabled = !!ScratchTools.modules.find((el) => el.feature.id === "random-block-colors") + if (randomBlockColorsEnabled) return; + let CIRCLE = await (await fetch(feature.self.getResource("circle"))).text(); let COLORS = document.createElement("link") diff --git a/features/random-block-colors/check.svg b/features/random-block-colors/check.svg new file mode 100644 index 00000000..241430a8 --- /dev/null +++ b/features/random-block-colors/check.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/features/random-block-colors/circle.svg b/features/random-block-colors/circle.svg new file mode 100644 index 00000000..88012ccd --- /dev/null +++ b/features/random-block-colors/circle.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/features/random-block-colors/colors.css b/features/random-block-colors/colors.css new file mode 100644 index 00000000..c4fff376 --- /dev/null +++ b/features/random-block-colors/colors.css @@ -0,0 +1,40 @@ +:root { + --motion-fill: transparent; + --motion-stroke: #3373CC; + + --looks-fill: transparent; + --looks-stroke: #774DCB; + + --sound-fill: transparent; + --sound-stroke: #BD42BD; + + --event-fill: transparent; + --event-stroke: #CC9900; + + --control-fill: transparent; + --control-stroke: #CF8B17; + + --sensing-fill: transparent; + --sensing-stroke: #2E8EB8; + + --operators-fill: transparent; + --operators-stroke: #389438; + + --data-fill: transparent; + --data-stroke: #DB6E00; + --data-lists-fill: transparent; + --data-lists-stroke: #E64D00; + + --custom-fill: transparent; + --custom-stroke: #FF3355; + + --other-fill: transparent; + --other-stroke: #0B8E69; + + --text-light: #000000; + --text-normal: #000000; + --text-light: var(--editorDarkMode-primary-text); + --text-normal: var(--editorDarkMode-primary-text); + + --arg-border: transparent; + } \ No newline at end of file diff --git a/features/random-block-colors/data.json b/features/random-block-colors/data.json new file mode 100644 index 00000000..844bb51d --- /dev/null +++ b/features/random-block-colors/data.json @@ -0,0 +1,28 @@ +{ + "title": "Random Block Colors", + "description": "Swaps around the colors of all the blocks each time you press the green flag!", + "credits": [ + { + "username": "Alan", + "url": "https://www.youtube.com/watch?v=z54AmH9Yi78&feature=youtu.be" + } + ], + "type": ["Editor", "Egg"], + "styles": [{ "file": "style.css", "runOn": "/projects/*" }], + "scripts": [{ "file": "script.js", "runOn": "/projects/*" }], + "resources": [ + { "name": "check", "path": "/check.svg" }, + { "name": "circle", "path": "/circle.svg" }, + { "name": "colors", "path": "/colors.css" } + ], + "components": [ + { + "type": "info", + "content": "This is an April Fool's Day feature. It was likely enabled automatically on April 1st, but you may disable it if you'd like." + }, + { + "type": "warning", + "content": "This feature is not compatible with the \"More Block Themes\" feature. You will not be able to use other block themes while this feature is enabled." + } + ] +} diff --git a/features/random-block-colors/script.js b/features/random-block-colors/script.js new file mode 100644 index 00000000..8c073d89 --- /dev/null +++ b/features/random-block-colors/script.js @@ -0,0 +1,274 @@ +export default async function ({ feature, console }) { + const COLORS = [ + { + name: "motion", + primary: "#4C97FF", + secondary: "#4280D7", + quaternary: "#3373CC", + tertiary: "#3373CC", + }, + { + name: "looks", + primary: "#9966FF", + secondary: "#855CD6", + quaternary: "#774DCB", + tertiary: "#774DCB", + }, + { + name: "sounds", + primary: "#CF63CF", + secondary: "#C94FC9", + quaternary: "#BD42BD", + tertiary: "#BD42BD", + }, + { + name: "control", + primary: "#FFAB19", + secondary: "#EC9C13", + quaternary: "#CF8B17", + tertiary: "#CF8B17", + }, + { + name: "event", + primary: "#FFBF00", + secondary: "#E6AC00", + quaternary: "#CC9900", + tertiary: "#CC9900", + }, + { + name: "sensing", + primary: "#5CB1D6", + secondary: "#47A8D1", + quaternary: "#2E8EB8", + tertiary: "#2E8EB8", + }, + { + name: "pen", + primary: "#0fBD8C", + secondary: "#0DA57A", + quaternary: "#0B8E69", + tertiary: "#0B8E69", + }, + { + name: "operators", + primary: "#59C059", + secondary: "#46B946", + quaternary: "#389438", + tertiary: "#389438", + }, + { + name: "data", + primary: "#FF8C1A", + secondary: "#FF8000", + quaternary: "#DB6E00", + tertiary: "#DB6E00", + }, + { + name: "data_lists", + primary: "#FF661A", + secondary: "#FF5500", + quaternary: "#E64D00", + tertiary: "#E64D00", + }, + { + name: "more", + primary: "#FF6680", + secondary: "#FF4D6A", + quaternary: "#FF3355", + tertiary: "#FF3355", + }, + ]; + + let activeColors = COLORS; + + function updateColors() { + let newBlockColors = JSON.parse(JSON.stringify(COLORS)); + randomizeArray(newBlockColors); + + for (var i in newBlockColors) { + delete newBlockColors[i].name; + } + + for (var i in COLORS) { + let newColors = newBlockColors[i]; + Object.keys(newColors).forEach(function (colorType) { + ScratchTools.traps.getScratchBlocks().Colours[COLORS[i].name][ + colorType + ] = newColors[colorType]; + }); + newBlockColors[i].name = COLORS[i].name; + } + + activeColors = newBlockColors; + + updateBlocks(); + updateToolbar(); + } + + ScratchTools.waitForElements( + "img[class^='green-flag_green-flag_']", + function (flag) { + flag.addEventListener("click", updateColors); + } + ); + + function updateToolbar() { + for (var i in activeColors) { + let newCategoryName = activeColors[i].name + .replaceAll("data", "variables") + .replaceAll("event", "events") + .replaceAll("sounds", "sound") + .replaceAll("more", "myBlocks"); + if ( + document.querySelector( + `div.scratchCategoryId-${newCategoryName} .scratchCategoryItemBubble` + ) + ) { + document.querySelector( + `div.scratchCategoryId-${newCategoryName} .scratchCategoryItemBubble` + ).style.backgroundColor = activeColors[i].primary; + document.querySelector( + `div.scratchCategoryId-${newCategoryName} .scratchCategoryItemBubble` + ).style.borderColor = activeColors[i].secondary; + } + } + } + + ScratchTools.waitForElements(".scratchCategoryMenuItem", function (item) { + let colorValues = activeColors.find( + (el) => + el.name === + item.className + .split("scratchCategoryId-")[1] + .split(" ")[0] + .replaceAll("variables", "data") + .replaceAll("events", "event") + .replaceAll("myBlocks", "more") + .replaceAll("sound", "sounds") + ); + if (colorValues && item.querySelector(".scratchCategoryItemBubble")) { + item.querySelector(".scratchCategoryItemBubble").style.backgroundColor = + colorValues.primary; + item.querySelector(".scratchCategoryItemBubble").style.borderColor = + colorValues.secondary; + } + }); + + window.updateColors = updateColors; + + function randomizeArray(array) { + let currentIndex = array.length; + + while (currentIndex != 0) { + let randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex--; + + [array[currentIndex], array[randomIndex]] = [ + array[randomIndex], + array[currentIndex], + ]; + } + } + + function updateBlocks() { + let blocks = feature.traps.blocks(); + let workspace = Blockly.getMainWorkspace(); + + let toolbox = workspace.getToolbox(); + let flyout = workspace.getFlyout(); + + blocks.Events.disable(); + blocks.Xml.clearWorkspaceAndLoadFromXml( + blocks.Xml.workspaceToDom(workspace), + workspace + ); + + if (flyout) { + let flyoutWorkspace = flyout.getWorkspace(); + blocks.Xml.clearWorkspaceAndLoadFromXml( + blocks.Xml.workspaceToDom(flyoutWorkspace), + flyoutWorkspace + ); + } + + let selectedItemId = toolbox.getSelectedItem().id_; + if (blocks.registry) { + toolbox.render(workspace.options.languageTree); + toolbox.selectItem_(null, toolbox.contents.get(selectedItemId)); + } else { + toolbox.categoryMenu_.populate(workspace.options.languageTree); + toolbox.selectCategoryById(selectedItemId, false); + } + toolbox.refreshSelection(); + workspace.toolboxRefreshEnabled_ = true; + + blocks.Events.enable(); + } + + ScratchTools.waitForElements( + "ul[class*='menu_menu_'][class*='menu_right_']", + async function (ul) { + if ( + ul.parentNode?.previousSibling?.previousSibling?.className.startsWith( + "settings-menu_dropdown-label_" + ) + ) { + let CIRCLE = await ( + await fetch(feature.self.getResource("circle")) + ).text(); + let css = await ( + await fetch(feature.self.getResource("colors")) + ).text(); + let list = ul.children[1].lastChild.firstChild; + + if (list.querySelector(".ste-custom-april")) return; + + let selected = list.querySelector( + "img[class*='settings-menu_selected_']" + ); + let SELECTED_CLASS = [...selected.classList].find((el) => + el.startsWith("settings-menu_selected_") + ); + + list.querySelectorAll("li:not(.ste-custom)").forEach(function (el) { + el.remove(); + }); + + let li = document.createElement("li"); + li.dataset.id = "ste-custom-april"; + li.className = `${scratchClass("menu_menu-item_")} ${scratchClass( + "menu_hoverable_" + )} ste-custom-april`; + + let div = document.createElement("div"); + div.className = scratchClass("settings-menu_option_"); + + let check = document.createElement("img"); + check.className = scratchClass("settings-menu_check_"); + check.src = feature.self.getResource("check"); + + let img = document.createElement("span"); + img.innerHTML = CIRCLE.replaceAll( + "-fill", + "-circle-fill" + "ste-custom-april" + ).replaceAll("-stroke", "-circle-stroke-" + "ste-custom-april"); + img.className = scratchClass("settings-menu_icon_"); + + let circleCSS = document.createElement("style"); + circleCSS.textContent = css + .replaceAll("-fill", "-circle-fill" + "ste-custom-april") + .replaceAll("-stroke", "-circle-stroke-" + "ste-custom-april"); + img.firstChild.prepend(circleCSS); + + check.classList.add(SELECTED_CLASS); + + let span = document.createElement("span"); + span.textContent = "Random Colors"; + + div.append(check, img, span); + li.appendChild(div); + list.appendChild(li); + } + } + ); +} diff --git a/features/random-block-colors/style.css b/features/random-block-colors/style.css new file mode 100644 index 00000000..0aedf492 --- /dev/null +++ b/features/random-block-colors/style.css @@ -0,0 +1,9 @@ +li.ste-custom-april svg { + height: 100%; + width: 100%; +} + +li.ste-custom-april span[class^='settings-menu_icon_'] { + height: 1.5rem; + width: 1.5rem; +} \ No newline at end of file diff --git a/manifest.json b/manifest.json index 7b3929eb..3fa7ac20 100644 --- a/manifest.json +++ b/manifest.json @@ -3,7 +3,7 @@ "short_name": "ScratchTools", "manifest_version": 3, "version": "4.1.0", - "version_name": "4.1.0-beta", + "version_name": "4.1.0", "default_locale": "en", "description": "__MSG_extDescription__", "author": "rgantzos",