diff --git a/extras/background.js b/extras/background.js
index 353ba692..d032e242 100644
--- a/extras/background.js
+++ b/extras/background.js
@@ -1,4 +1,4 @@
-var version = "2.20.0";
+var version = "2.21.0";
chrome.runtime.onInstalled.addListener(async function (object) {
chrome.alarms.clearAll();
diff --git a/extras/new.js b/extras/new.js
index b61b18eb..be9af4a4 100644
--- a/extras/new.js
+++ b/extras/new.js
@@ -1,6 +1,6 @@
update(
- "ScratchTools v2.20.0",
- "We are so happy to be releasing v2.20.0! This new version includes a lot of new features, including the ability to see if someone is following you, just by looking at their profile!"
+ "ScratchTools v2.21.0",
+ "This new version includes plenty of new features, including the ability to upload images directly to the forums without using other image hosting services. It also adds a user statistics box on profiles, as well as a button to leave studios."
);
function update(updateVersion, updateDescription) {
if (document.querySelector(".scratchtoolsUpdateInfo") === null) {
diff --git a/features/block-count-in-mystuff.js b/features/block-count-in-mystuff.js
index f6e894ca..ee7ebb72 100644
--- a/features/block-count-in-mystuff.js
+++ b/features/block-count-in-mystuff.js
@@ -21,7 +21,10 @@ if (window.location.href.startsWith("https://scratch.mit.edu/mystuff")) {
ScratchTools.waitForElements(
"ul.media-list > li",
async function (el) {
- if (stillLookingForBlockCount && !el.querySelector('.scratchtoolsBlockCount')) {
+ if (
+ stillLookingForBlockCount &&
+ !el.querySelector(".scratchtoolsBlockCount")
+ ) {
if (el.querySelector('a[href*="/projects/"]')) {
var blocks = await getBlockCount(
el
@@ -39,7 +42,7 @@ if (window.location.href.startsWith("https://scratch.mit.edu/mystuff")) {
el.querySelector(".media-info-item.date.shortDateFormat").appendChild(
span
);
- el.querySelector('a[data-control="edit"]').style.transition = 'none'
+ el.querySelector('a[data-control="edit"]').style.transition = "none";
el.querySelector('a[data-control="edit"]').style.marginTop = "1px";
}
}
diff --git a/features/custom-studio.js b/features/custom-studio.js
index 7acd8507..629fdb29 100644
--- a/features/custom-studio.js
+++ b/features/custom-studio.js
@@ -82,14 +82,14 @@ async function addStudioProjects(studioId) {
.querySelector(".inner.mod-splash")
.insertBefore(box, document.querySelector(".inner.mod-splash > .box"));
}
-let alreadyStarted = false
+let alreadyStarted = false;
ScratchTools.waitForElements(
".inner.mod-splash > .box",
function () {
let studioid = ScratchTools.Storage["Studio ID"];
if (/^\d+$/.test(studioid)) {
- if (!alreadyStarted && document.querySelector('.splash-header')) {
- alreadyStarted = true
+ if (!alreadyStarted && document.querySelector(".splash-header")) {
+ alreadyStarted = true;
addStudioProjects(studioid);
}
}
diff --git a/features/features.json b/features/features.json
index b3eae488..12774481 100644
--- a/features/features.json
+++ b/features/features.json
@@ -1,37 +1,16 @@
- [
- {
- "title": "Frontpage Curator Name as Link",
- "description": "Makes the name of the Frontpage Curator to a clickable link to his profile.",
- "credits": ["Dr_Lego"],
- "urls": [
- "https://scratch.mit.edu/users/Dr_Lego/"
- ],
- "file": "frontpage-curator",
- "type": ["Website"],
- "tags": ["New"]
- },
+[
{
- "title": "Show User Statistics",
- "description": "Replaces the 'What I've been doing' section on a profile page with the user's statistics.",
- "credits": ["Dr_Lego"],
+ "title": "Direct image uploads in the forums",
+ "description": "Allows you to easily upload images to the Scratch forums for posts and signatures without having to use third party image uploading services.",
+ "credits": ["ISTILLMAKESTUFF", "TheGlassPenguin", "StickFireGames"],
"urls": [
- "https://scratch.mit.edu/users/Dr_Lego/"
+ "https://scratch.mit.edu/users/ISTILLMAKESTUFF",
+ "https://scratch.mit.edu/users/TheGlassPenguin",
+ "https://scratch.mit.edu/users/stickfiregames"
],
- "file": "user-stats",
+ "file": "upload-img-directly",
"type": ["Website"],
- "tags": ["New"]
- },
- {
- "title": "Minimized Remix Credits",
- "description": "The remix credit boxes for projects take space from the project Instructions, so this makes the box smaller.",
- "credits": ["callumjt", "rgantzos"],
- "urls": [
- "https://scratch.mit.edu/users/callumjt/",
- "https://scratch.mit.edu/users/rgantzos/"
- ],
- "file": "minimized-remix-credits",
- "tags": ["New"],
- "type": ["Website"]
+ "tags": ["New", "Recommended"]
},
{
"title": "Leave Studio Button",
@@ -46,17 +25,34 @@
"type": ["Website"]
},
{
- "title": "Direct image uploads in the forums",
- "description": "Allows you to easily upload images to the Scratch forums for posts and signatures without having to use third party image uploading services.",
- "credits": ["ISTILLMAKESTUFF", "TheGlassPenguin", "StickFireGames"],
+ "title": "Show User Statistics",
+ "description": "Replaces the 'What I've been doing' section on a profile page with the user's statistics.",
+ "credits": ["Dr_Lego"],
+ "urls": ["https://scratch.mit.edu/users/Dr_Lego/"],
+ "file": "user-stats",
+ "type": ["Website"],
+ "tags": ["New"]
+ },
+ {
+ "title": "Frontpage Curator Name as Link",
+ "description": "Makes the name of the Frontpage Curator to a clickable link to his profile.",
+ "credits": ["Dr_Lego"],
+ "urls": ["https://scratch.mit.edu/users/Dr_Lego/"],
+ "file": "frontpage-curator",
+ "type": ["Website"],
+ "tags": ["New"]
+ },
+ {
+ "title": "Minimized Remix Credits",
+ "description": "The remix credit boxes for projects take space from the project Instructions, so this makes the box smaller.",
+ "credits": ["callumjt", "rgantzos"],
"urls": [
- "https://scratch.mit.edu/users/ISTILLMAKESTUFF",
- "https://scratch.mit.edu/users/TheGlassPenguin",
- "https://scratch.mit.edu/users/stickfiregames"
+ "https://scratch.mit.edu/users/callumjt/",
+ "https://scratch.mit.edu/users/rgantzos/"
],
- "file": "upload-img-directly",
- "type": ["Website"],
- "tags": ["New", "Recommended"]
+ "file": "minimized-remix-credits",
+ "tags": ["New"],
+ "type": ["Website"]
},
{
"title": "Show if Following on Profile",
@@ -68,7 +64,7 @@
],
"file": "follows-you",
"type": ["Website"],
- "tags": ["New", "Featured"],
+ "tags": ["Featured"],
"dynamic": true
},
{
diff --git a/features/follows-you.js b/features/follows-you.js
index 8b891ae3..76cca14b 100644
--- a/features/follows-you.js
+++ b/features/follows-you.js
@@ -1,39 +1,53 @@
async function getFollowing(user1, user2) {
- var notFound = true
- var isFollowing = false
- var offset = 0
+ var notFound = true;
+ var isFollowing = false;
+ var offset = 0;
while (notFound) {
- var response = await fetch(`https://api.scratch.mit.edu/users/${user2}/following/?limit=40&offset=${offset.toString()}`)
- var data = await response.json()
- if (data.length === 0) {
- notFound = false
- }
- data.forEach(function(el) {
- if (el.username.toLowerCase() === user1.toLowerCase()) {
- notFound = false
- isFollowing = true
- ScratchTools.waitForElements('.header-text', function(element) {
- if (!document.querySelector('.scratchtoolsFollowsYou')) {
- var span = element.insertBefore(document.createElement('span'), document.querySelector('.profile-details'))
- span.className = 'scratchtoolsFollowsYou'
- span.textContent = 'Follows You'
- span.style.opacity = '.5'
- span.style.fontSize = '.8rem'
- element.querySelector('h2').style.display = 'inline-block'
- }
- })
+ var response = await fetch(
+ `https://api.scratch.mit.edu/users/${user2}/following/?limit=40&offset=${offset.toString()}`
+ );
+ var data = await response.json();
+ if (data.length === 0) {
+ notFound = false;
+ }
+ data.forEach(function (el) {
+ if (el.username.toLowerCase() === user1.toLowerCase()) {
+ notFound = false;
+ isFollowing = true;
+ ScratchTools.waitForElements(".header-text", function (element) {
+ if (!document.querySelector(".scratchtoolsFollowsYou")) {
+ var span = element.insertBefore(
+ document.createElement("span"),
+ document.querySelector(".profile-details")
+ );
+ span.className = "scratchtoolsFollowsYou";
+ span.textContent = "Follows You";
+ span.style.opacity = ".5";
+ span.style.fontSize = ".8rem";
+ element.querySelector("h2").style.display = "inline-block";
}
- })
- offset = offset+40
+ });
+ }
+ });
+ offset = offset + 40;
}
-
}
-if (window.location.href.toLowerCase().startsWith('https://scratch.mit.edu/users/')) {
- getFollowing(Scratch.INIT_DATA.LOGGED_IN_USER.model.username, window.location.href.toLowerCase().split('https://scratch.mit.edu/users/')[1].split('/')[0])
+if (
+ window.location.href
+ .toLowerCase()
+ .startsWith("https://scratch.mit.edu/users/")
+) {
+ getFollowing(
+ Scratch.INIT_DATA.LOGGED_IN_USER.model.username,
+ window.location.href
+ .toLowerCase()
+ .split("https://scratch.mit.edu/users/")[1]
+ .split("/")[0]
+ );
}
-ScratchTools.setDisable('follows-you', function() {
- if (document.querySelector('.scratchtoolsFollowsYou')) {
- document.querySelector('.scratchtoolsFollowsYou').remove()
+ScratchTools.setDisable("follows-you", function () {
+ if (document.querySelector(".scratchtoolsFollowsYou")) {
+ document.querySelector(".scratchtoolsFollowsYou").remove();
}
-})
\ No newline at end of file
+});
diff --git a/features/frontpage-curator.js b/features/frontpage-curator.js
index 4b744282..b9ec7c4f 100644
--- a/features/frontpage-curator.js
+++ b/features/frontpage-curator.js
@@ -1,5 +1,7 @@
-if (window.location.href == "https://scratch.mit.edu/"){
- text = document.getElementsByClassName("inner mod-splash")[1].firstChild.firstChild.firstChild;
- Name = text.innerText.split(" ")[3]
- text.innerHTML = `Projects Curated by ${Name}`
-};
+if (window.location.href == "https://scratch.mit.edu/") {
+ text =
+ document.getElementsByClassName("inner mod-splash")[1].firstChild.firstChild
+ .firstChild;
+ Name = text.innerText.split(" ")[3];
+ text.innerHTML = `Projects Curated by ${Name}`;
+}
diff --git a/features/hide-block-category-names.js b/features/hide-block-category-names.js
index 91259b87..694a92fc 100644
--- a/features/hide-block-category-names.js
+++ b/features/hide-block-category-names.js
@@ -1,4 +1,4 @@
-var style = document.createElement('style')
+var style = document.createElement("style");
style.textContent = `
.scratchCategoryItemBubble {
border-radius: .2rem !important;
@@ -8,8 +8,8 @@ style.textContent = `
.scratchCategoryMenuItemLabel {
display: none !important;
}
-`
-document.body.appendChild(style)
-ScratchTools.setDisable('hide-block-category-names', function() {
- style.remove()
-})
\ No newline at end of file
+`;
+document.body.appendChild(style);
+ScratchTools.setDisable("hide-block-category-names", function () {
+ style.remove();
+});
diff --git a/features/highlight-unanswered.js b/features/highlight-unanswered.js
index debdc9f6..ec9b231f 100644
--- a/features/highlight-unanswered.js
+++ b/features/highlight-unanswered.js
@@ -16,4 +16,4 @@ ScratchTools.setDisable("highlight-unanswered", function () {
document.querySelectorAll("tbody > tr").forEach(function (el) {
el.style.backgroundColor = null;
});
-});
\ No newline at end of file
+});
diff --git a/features/leave-studio.js b/features/leave-studio.js
index 0dd4feb5..f8c73ace 100644
--- a/features/leave-studio.js
+++ b/features/leave-studio.js
@@ -1,66 +1,71 @@
if (
- window.location.href
- .toLowerCase()
- .startsWith("https://scratch.mit.edu/studios/") &&
- window.location.href.includes("/curators") &&
- !document.querySelector(".scratchtoolsLeaveStudio")
- ) {
- const studioId = window.location.href.replace("https://", "").split("/")[2];
-
- async function leaveStudio() {
- var auth = await ScratchTools.Session();
- await fetch(
- "https://scratch.mit.edu/site-api/users/curators-in/" +
- studioId +
- "/remove/?usernames=" +
- auth.user.username,
- {
- headers: {
- "x-csrftoken": ScratchTools.cookies.get("scratchcsrftoken"),
- },
- body: null,
- method: "PUT",
- }
- );
- window.location.href = window.location.href;
- }
-
- async function getCurating() {
- var auth = await ScratchTools.Session();
- var response = await fetch(
- "https://api.scratch.mit.edu/studios/" +
- studioId +
- "/users/" +
- auth.user.username,
- {
- headers: {
- "x-token": auth.user.token,
- },
- }
- );
- var data = await response.json();
- if ((data.curator || data.manager) & document.querySelector('.studio-member-name').textContent !== auth.user.username) {
- ScratchTools.waitForElements(
- ".studio-member-name",
- function (el) {
- var btn = document.createElement("button");
- btn.className = "scratchtoolsLeaveStudio button";
- btn.textContent = "Leave Studio";
- btn.style.backgroundColor = "#ff4c4c";
- btn.style.position = "absolute";
- btn.style.right = "0px";
- btn.onclick = function () {
- if (confirm("Are you sure you want to leave the studio?")) {
- leaveStudio();
- }
- };
- document.querySelector('.studio-header-container.studio-managers-header').appendChild(btn);
- },
- "scratchtoolsLeaveStudio",
- false
- );
+ window.location.href
+ .toLowerCase()
+ .startsWith("https://scratch.mit.edu/studios/") &&
+ window.location.href.includes("/curators") &&
+ !document.querySelector(".scratchtoolsLeaveStudio")
+) {
+ const studioId = window.location.href.replace("https://", "").split("/")[2];
+
+ async function leaveStudio() {
+ var auth = await ScratchTools.Session();
+ await fetch(
+ "https://scratch.mit.edu/site-api/users/curators-in/" +
+ studioId +
+ "/remove/?usernames=" +
+ auth.user.username,
+ {
+ headers: {
+ "x-csrftoken": ScratchTools.cookies.get("scratchcsrftoken"),
+ },
+ body: null,
+ method: "PUT",
}
+ );
+ window.location.href = window.location.href;
+ }
+
+ async function getCurating() {
+ var auth = await ScratchTools.Session();
+ var response = await fetch(
+ "https://api.scratch.mit.edu/studios/" +
+ studioId +
+ "/users/" +
+ auth.user.username,
+ {
+ headers: {
+ "x-token": auth.user.token,
+ },
+ }
+ );
+ var data = await response.json();
+ if (
+ (data.curator || data.manager) &
+ (document.querySelector(".studio-member-name").textContent !==
+ auth.user.username)
+ ) {
+ ScratchTools.waitForElements(
+ ".studio-member-name",
+ function (el) {
+ var btn = document.createElement("button");
+ btn.className = "scratchtoolsLeaveStudio button";
+ btn.textContent = "Leave Studio";
+ btn.style.backgroundColor = "#ff4c4c";
+ btn.style.position = "absolute";
+ btn.style.right = "0px";
+ btn.onclick = function () {
+ if (confirm("Are you sure you want to leave the studio?")) {
+ leaveStudio();
+ }
+ };
+ document
+ .querySelector(".studio-header-container.studio-managers-header")
+ .appendChild(btn);
+ },
+ "scratchtoolsLeaveStudio",
+ false
+ );
}
- getCurating();
}
-
\ No newline at end of file
+ getCurating();
+}
diff --git a/features/nfe-project-checker.js b/features/nfe-project-checker.js
index 8c665936..e27b16dc 100644
--- a/features/nfe-project-checker.js
+++ b/features/nfe-project-checker.js
@@ -3,7 +3,9 @@ function check() {
window.setTimeout(check, 50);
} else {
async function checkforNfe() {
- var data = await getStatus(window.location.href.split("/projects/")[1].split("/")[0])
+ var data = await getStatus(
+ window.location.href.split("/projects/")[1].split("/")[0]
+ );
var date = document.querySelector("div.share-date").lastChild;
if (!date.className.includes("scratchtools")) {
if (data === "notreviewed") {
@@ -26,7 +28,9 @@ function check() {
check();
async function getStatus(project) {
- var response = await fetch('https://scratch.mit.edu/projects/'+project+'/remixtree/bare/')
- var data = await response.json()
- return data[project].moderation_status
-}
\ No newline at end of file
+ var response = await fetch(
+ "https://scratch.mit.edu/projects/" + project + "/remixtree/bare/"
+ );
+ var data = await response.json();
+ return data[project].moderation_status;
+}
diff --git a/features/pause-audio.js b/features/pause-audio.js
index 8661c032..87232ede 100644
--- a/features/pause-audio.js
+++ b/features/pause-audio.js
@@ -6,8 +6,9 @@ if (window.location.href.startsWith("https://scratch.mit.edu/projects/")) {
var respond = true;
var currentStart = 0;
var currentlyActive = false;
- var btn =
- document.querySelector('[class^="sound-editor_round-button_"]')
+ var btn = document.querySelector(
+ '[class^="sound-editor_round-button_"]'
+ );
function addButton() {
window.btn2 = document.createElement("button");
btn2.className = btn.className + " scratchtoolsPause";
@@ -15,7 +16,8 @@ if (window.location.href.startsWith("https://scratch.mit.edu/projects/")) {
btn2.style.backgroundColor = "#ff9f00";
btn2.style.marginLeft = ".5rem";
var img = document.createElement("img");
- img.src = "https://raw.githubusercontent.com/STForScratch/data/main/pause.svg";
+ img.src =
+ "https://raw.githubusercontent.com/STForScratch/data/main/pause.svg";
img.draggable = false;
if (!ScratchTools.Scratch.scratchSound().state.playhead) {
btn2.style.opacity = "0.5";
@@ -36,7 +38,10 @@ if (window.location.href.startsWith("https://scratch.mit.edu/projects/")) {
btn3.appendChild(img2);
btn.parentNode.appendChild(btn3);
function callback() {
- if (btn.firstChild.src === "https://scratch.mit.edu/static/assets/b5257afbe4bcf7953029ddb8f18b24fe.svg") {
+ if (
+ btn.firstChild.src ===
+ "https://scratch.mit.edu/static/assets/b5257afbe4bcf7953029ddb8f18b24fe.svg"
+ ) {
btn2.style.opacity = "0.5";
} else {
btn2.style.opacity = "1";
diff --git a/features/search-assets.js b/features/search-assets.js
index 154e5e49..afd13cf4 100644
--- a/features/search-assets.js
+++ b/features/search-assets.js
@@ -3,7 +3,7 @@ var showSearchBar = true;
if (document.querySelector('[class^="asset-panel_wrapper_"]')) {
if (!document.querySelector(".scratchtoolsAssetSearch") && showSearchBar) {
var input = document.createElement("input");
- var assetBox = document.querySelector('[class^="asset-panel_wrapper_"]')
+ var assetBox = document.querySelector('[class^="asset-panel_wrapper_"]');
var assetRow = assetBox.firstChild.firstChild;
input.className = "scratchtoolsAssetSearch input_input-form_l9eYg";
input.placeholder = "Search";
diff --git a/features/user-stats.js b/features/user-stats.js
index d5c5ef3d..5a5b8f84 100644
--- a/features/user-stats.js
+++ b/features/user-stats.js
@@ -1,56 +1,116 @@
-async function getStats()
-{
+async function getStats() {
if (window.location.href.startsWith("https://scratch.mit.edu/users/")) {
- var response = await fetch(`https://scratchdb.lefty.one/v3/user/info/${window.location.href.replaceAll("https://scratch.mit.edu/users/","")}`)
- var data = await response.json()
- if(data.statistics != undefined){
- function image(url,alt){return(``)};
- function space(){return(" ")};
- function commafy(num){
- if(num == undefined){return("0")}else
- {return(parseInt(num).toLocaleString())}};
- var activity = document.getElementById("activity-feed")
- activity.style.display = "none" //remove();
- var box = document.getElementsByClassName("doing")[0];
- var table = `${"