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 = `${"
#" + commafy(data.statistics.ranks.followers) + " (#" + commafy(data.statistics.ranks.country.followers) + ")"+space()+"
"}${image('https://scratch.mit.edu/svgs/messages/follow.svg','Followers')}${commafy(data.statistics.followers)}${space()}
${image('https://scratch.mit.edu/svgs/messages/love.svg','Loves')}${commafy(data.statistics.loves)}${space()}
${image('https://scratch.mit.edu/svgs/messages/favorite.svg','Favorites')}${commafy(data.statistics.favorites)}${space()}
${image('https://scratch.mit.edu/svgs/project/views-gray.svg','Views')}${commafy(data.statistics.views)}${space()}
`; - var scratchstats = `View on Scratchstats` - var divText = `
${table}${scratchstats}
`.replaceAll("undefined","0") - var div = document.createElement("div"); - div.innerHTML = divText; - box.appendChild(div); - var statistics = document.getElementById("statistics"); + 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 = `${ + "
#" + + commafy(data.statistics.ranks.followers) + + " (#" + + commafy(data.statistics.ranks.country.followers) + + ")" + + space() + + "
" + }${image( + "https://scratch.mit.edu/svgs/messages/follow.svg", + "Followers" + )}${commafy(data.statistics.followers)}${space()}
${image( + "https://scratch.mit.edu/svgs/messages/love.svg", + "Loves" + )}${commafy(data.statistics.loves)}${space()}
${image( + "https://scratch.mit.edu/svgs/messages/favorite.svg", + "Favorites" + )}${commafy(data.statistics.favorites)}${space()}
${image( + "https://scratch.mit.edu/svgs/project/views-gray.svg", + "Views" + )}${commafy(data.statistics.views)}${space()}
`; + var scratchstats = `View on Scratchstats`; + var divText = + `
${table}${scratchstats}
`.replaceAll( + "undefined", + "0" + ); + var div = document.createElement("div"); + div.innerHTML = divText; + box.appendChild(div); + var statistics = document.getElementById("statistics"); - //=============Create spans============== - var children = box.childNodes; var h3 = children[1]; h3.innerText = ""; var spans = []; + //=============Create spans============== + var children = box.childNodes; + var h3 = children[1]; + h3.innerText = ""; + var spans = []; - // functions & variables - var boxStyle = "background-color: var(--darkWww-box, white);border-radius: 8px;border: 1px solid var(--darkWww-border-15, #d9d9d9);padding:2px;cursor:pointer" - function click(type){ - if(type){statistics.style.display = "block"; activity.style.display = "none";spans[1].style.fontSize="75%";spans[0].style.fontSize="90%"} - else{statistics.style.display = "none"; activity.style.display = "block";spans[0].style.fontSize="75%";spans[1].style.fontSize="90%"} - } + // functions & variables + var boxStyle = + "background-color: var(--darkWww-box, white);border-radius: 8px;border: 1px solid var(--darkWww-border-15, #d9d9d9);padding:2px;cursor:pointer"; + function click(type) { + if (type) { + statistics.style.display = "block"; + activity.style.display = "none"; + spans[1].style.fontSize = "75%"; + spans[0].style.fontSize = "90%"; + } else { + statistics.style.display = "none"; + activity.style.display = "block"; + spans[0].style.fontSize = "75%"; + spans[1].style.fontSize = "90%"; + } + } - // #1 - spans[0] = document.createElement("span"); - spans[0].id = "ST-STATS" - spans[0].innerText = "Statistics" - spans[0].style = boxStyle - h3.appendChild(spans[0]) - h3.appendChild(document.createTextNode(" ")) - // #2 - spans[1] = document.createElement("span"); - spans[1].id = "ST-WIBD" - spans[1].innerText = "Recent Activity" - spans[1].style = `${boxStyle};font-size:80%` - h3.appendChild(spans[1]) + // #1 + spans[0] = document.createElement("span"); + spans[0].id = "ST-STATS"; + spans[0].innerText = "Statistics"; + spans[0].style = boxStyle; + h3.appendChild(spans[0]); + h3.appendChild(document.createTextNode(" ")); + // #2 + spans[1] = document.createElement("span"); + spans[1].id = "ST-WIBD"; + spans[1].innerText = "Recent Activity"; + spans[1].style = `${boxStyle};font-size:80%`; + h3.appendChild(spans[1]); - // onclick - spans[0].onclick = function(){click(true)} - spans[1].onclick = function(){click(false)} - //=============================== - }; + // onclick + spans[0].onclick = function () { + click(true); + }; + spans[1].onclick = function () { + click(false); + }; + //=============================== + } } } -ScratchTools.waitForElements("#activity-feed", getStats, "getUserStatistics", false) - +ScratchTools.waitForElements( + "#activity-feed", + getStats, + "getUserStatistics", + false +);