Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
33665c6
Create addon.json
VIGARPAST-777-2 Sep 9, 2025
2d76596
Create userscript.js
VIGARPAST-777-2 Sep 9, 2025
8dea897
Update addons.json
VIGARPAST-777-2 Sep 9, 2025
22fe3bd
Update addon.json
VIGARPAST-777-2 Sep 10, 2025
1645c79
Update userscript.js
VIGARPAST-777-2 Sep 10, 2025
1cd82b6
Create userstyles.css
VIGARPAST-777-2 Sep 10, 2025
2fa4341
Update addon.json
VIGARPAST-777-2 Sep 10, 2025
52110b8
Update userscript.js
VIGARPAST-777-2 Sep 10, 2025
7a4d418
Update userstyles.css
VIGARPAST-777-2 Sep 10, 2025
d8fbb4f
Update userscript.js
VIGARPAST-777-2 Sep 10, 2025
5b1c8ed
Update addon.json
VIGARPAST-777-2 Sep 15, 2025
605ac5a
Update userstyles.css
VIGARPAST-777-2 Sep 15, 2025
ea7cef2
Update addon.json
VIGARPAST-777-2 Sep 16, 2025
7f39b80
Update userscript.js
VIGARPAST-777-2 Sep 16, 2025
df44200
Update addon.json
VIGARPAST-777-2 Sep 16, 2025
732e82a
Update addon.json
VIGARPAST-777-2 Sep 16, 2025
3f8d2ac
Update addon.json
VIGARPAST-777-2 Sep 16, 2025
f9b5bf5
Update userstyles.css
VIGARPAST-777-2 Sep 16, 2025
5985186
Update userscript.js
VIGARPAST-777-2 Sep 16, 2025
be66e30
Update addon.json
VIGARPAST-777-2 Sep 16, 2025
6073dd8
Update userscript.js
VIGARPAST-777-2 Sep 16, 2025
7a3fca5
Update userstyles.css
VIGARPAST-777-2 Sep 16, 2025
0ac8210
Update userscript.js
VIGARPAST-777-2 Sep 16, 2025
13e5623
Update addon.json
VIGARPAST-777-2 Sep 16, 2025
5f8a874
Update addon.json
VIGARPAST-777-2 Sep 16, 2025
66fb1f1
Update userscript.js
VIGARPAST-777-2 Sep 16, 2025
82da879
Update userstyles.css
VIGARPAST-777-2 Sep 16, 2025
18956b8
Update userscript.js
VIGARPAST-777-2 Sep 16, 2025
28befad
Update userstyles.css
VIGARPAST-777-2 Sep 16, 2025
229f050
Update userstyles.css
VIGARPAST-777-2 Sep 16, 2025
6012a88
Update userstyles.css
VIGARPAST-777-2 Sep 16, 2025
452b779
Update addon.json
VIGARPAST-777-2 Sep 17, 2025
e334093
Format code
VIGARPAST-777-2 Sep 17, 2025
46040d2
Update addon.json
VIGARPAST-777-2 Sep 17, 2025
f3555ac
Format code
VIGARPAST-777-2 Sep 17, 2025
d10cb68
Update addon.json
VIGARPAST-777-2 Sep 18, 2025
0d8d406
Create c
VIGARPAST-777-2 Oct 21, 2025
fe892e0
Add files via upload
VIGARPAST-777-2 Oct 21, 2025
c667d9c
Delete addons/user-stats-in-profile/c
VIGARPAST-777-2 Oct 21, 2025
2f3fa10
Format code
VIGARPAST-777-2 Oct 21, 2025
7657e57
Update addons.json
VIGARPAST-777-2 Oct 21, 2025
1a2c898
Merge branch 'master' into master
VIGARPAST-777-2 Oct 21, 2025
a09f1ac
Update userscript.js
VIGARPAST-777-2 Oct 23, 2025
1bb044c
Format code
VIGARPAST-777-2 Oct 23, 2025
938b281
Update addons/user-stats-in-profile/addon.json
VIGARPAST-777-2 Oct 26, 2025
0a4ef2a
Update addons/user-stats-in-profile/addon.json
VIGARPAST-777-2 Oct 26, 2025
a769696
Update addons/user-stats-in-profile/addon.json
VIGARPAST-777-2 Oct 26, 2025
918740d
Update addons/user-stats-in-profile/addon.json
VIGARPAST-777-2 Oct 26, 2025
7decc0a
Update addons.json
VIGARPAST-777-2 Oct 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions addons/addons.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@
"live-read-topics",
"recolor-custom-blocks",
"totally-normal-modes",
"compact-profile",
"user-stats-in-profile",

"// NEW ADDONS ABOVE THIS ↑↑",
"// Note: these themes need this exact order to work properly,",
Expand Down
28 changes: 28 additions & 0 deletions addons/compact-profile/addon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"id": "compact-profile",
"name": "Compact Scratch Profile Sliders",
"description": "Rearranges the profile sections into a cleaner two-column layout by pairing sliders side by side, making profiles more compact and readable.",
"credits": [
{
"name": "VIGARPAST_777",
"link": "https://scratch.mit.edu/users/VIGARPAST_777/"
}
],
"userscripts": [
{
"url": "userscript.js",
"matches": ["https://scratch.mit.edu/users/*/"]
}
],
"userstyles": [
{
"url": "userstyles.css",
"matches": ["https://scratch.mit.edu/users/*/"]
}
],
"settings": [],
"enabledByDefault": false,
"targets": ["profiles"],
"versionAdded": "1.44.0",
"tags": ["profiles", "ui", "featured"]
}
45 changes: 45 additions & 0 deletions addons/compact-profile/userscript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export default async function ({ addon }) {
function groupSliders() {
const allSliders = Array.from(document.querySelectorAll(".box.slider-carousel-container"));
const parentContainer = allSliders[0]?.parentNode;
if (!allSliders.length || !parentContainer) return;

const order = [];
allSliders.forEach((slider) => {
const carousel = slider.querySelector(".slider-carousel");
if (!carousel) return;
const items = carousel.querySelectorAll("li");
if (!items.length) return;
order.push(slider);
});

for (let i = 0; i < order.length - 1; i += 2) {
const left = order[i];
const right = order[i + 1];

const flexWrapper = document.createElement("div");
flexWrapper.style.display = "flex";
flexWrapper.style.justifyContent = "space-between";
flexWrapper.style.marginBottom = "20px";

left.style.width = "48%";
right.style.width = "48%";
left.style.display = "block";
right.style.display = "block";

parentContainer.insertBefore(flexWrapper, left);
flexWrapper.appendChild(left);
flexWrapper.appendChild(right);

[left, right].forEach((box) => {
const carousel = box.querySelector(".slider-carousel");
if (carousel) {
carousel.style.overflowX = "auto";
carousel.style.scrollBehavior = "smooth";
}
});
}
}

groupSliders();
}
16 changes: 16 additions & 0 deletions addons/compact-profile/userstyles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.sa-compact-row {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class is not applied to any elements, so all the styles in this file are unused.

display: flex;
justify-content: space-between;
margin-bottom: 20px;
gap: 2%;
}

.sa-compact-row .box.slider-carousel-container {
width: 48%;
display: block;
}

.sa-compact-row .box.slider-carousel-container .slider-carousel {
overflow-x: auto;
scroll-behavior: smooth;
}
25 changes: 25 additions & 0 deletions addons/user-stats-in-profile/addon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "User Stats in Profile",
"description": "Displays project statistics inside user profiles using Scratch icons with real-time data.",
"credits": [
{
"name": "VIGARPAST_777",
"link": "https://scratch.mit.edu/users/VIGARPAST_777/"
}
],
"userscripts": [
{
"url": "userscript.js",
"matches": ["https://scratch.mit.edu/users/*"]
}
],
"userstyles": [
{
"url": "userstyles.css",
"matches": ["https://scratch.mit.edu/users/*"]
}
],
"enabledByDefault": false,
"versionAdded": "1.44.0",
"tags": ["community", "profiles"]
}
111 changes: 111 additions & 0 deletions addons/user-stats-in-profile/userscript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
export default async function ({ addon }) {
const username = location.pathname.split("/")[2];
if (!username) return;

const profileBox = document.querySelector("#profile-box .inner");
if (!profileBox) return;

if (document.querySelector(".scratch-stats-box")) return;

const statsDiv = document.createElement("div");
statsDiv.className = "scratch-stats-box";
statsDiv.style.display = "flex";
statsDiv.style.justifyContent = "space-between";
statsDiv.style.alignItems = "center";
statsDiv.style.padding = "10px";
statsDiv.style.marginTop = "15px";
statsDiv.style.fontSize = "14px";
statsDiv.style.backgroundColor = "#f9f9f9";
statsDiv.style.borderTop = "1px solid #ddd";

const statsElements = [
{ icon: "https://scratch.mit.edu/svgs/project/love-red.svg", count: "?", alt: "❤", key: "loves" },
{ icon: "https://scratch.mit.edu/svgs/project/fav-yellow.svg", count: "?", alt: "⭐", key: "faves" },
{
icon: "https://scratch.mit.edu/svgs/project/remix-gray.svg",
count: "?",
alt: "🔄",
className: "remix-icon",
key: "remixes",
},
{
icon: "https://scratch.mit.edu/svgs/project/views-gray.svg",
count: "?",
alt: "👁️",
className: "views-icon",
key: "views",
},
];

const domElements = {};

statsElements.forEach((stat) => {
const statDiv = document.createElement("div");
statDiv.style.display = "flex";
statDiv.style.alignItems = "center";
statDiv.style.gap = "6px";

const img = document.createElement("img");
img.src = stat.icon;
img.alt = stat.alt;
img.style.width = "20px";
img.style.height = "20px";
if (stat.className) img.classList.add(stat.className);

const span = document.createElement("span");
span.textContent = stat.count;

statDiv.appendChild(img);
statDiv.appendChild(span);
statsDiv.appendChild(statDiv);

domElements[stat.key] = span;
});

profileBox.appendChild(statsDiv);

const style = document.createElement("style");
style.textContent = `
img.views-icon { filter: invert(37%) sepia(95%) saturate(4000%) hue-rotate(200deg) brightness(95%) contrast(90%); }
img.remix-icon { filter: invert(55%) sepia(72%) saturate(500%) hue-rotate(90deg) brightness(95%) contrast(90%); }
`;
document.head.appendChild(style);

// Fetch views, loves, faves from ScratchInfo API
try {
const res = await fetch(`https://scratchinfo.quuq.dev/api/v1/users/${username}/projectStats`);
Copy link
Member

@Samq64 Samq64 Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know who runs this API?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know who runs this API?

Yes, https://scratch.mit.edu/users/redspacecat

const data = await res.json();
domElements.views.textContent = Number(data.totalViews).toLocaleString();
domElements.loves.textContent = Number(data.totalLoves).toLocaleString();
domElements.faves.textContent = Number(data.totalFaves).toLocaleString();
} catch (e) {
console.error("Failed to fetch ScratchInfo stats", e);
}

// Calculate remixes by fetching all user projects and then fetching each project individually
async function calculateRemixes() {
let totalRemixes = 0;
let offset = 0;
const limit = 40;
let projects;

do {
const res = await fetch(
`https://api.scratch.mit.edu/users/${username}/projects/?limit=${limit}&offset=${offset}`
);
projects = await res.json();
for (const project of projects) {
try {
const projRes = await fetch(`https://api.scratch.mit.edu/projects/${project.id}/`);
const projData = await projRes.json();
totalRemixes += projData.stats?.remixes || 0;
} catch {}
}
offset += limit;
} while (projects.length === limit);

domElements.remixes.textContent = totalRemixes.toLocaleString();
}

calculateRemixes();
}
18 changes: 18 additions & 0 deletions addons/user-stats-in-profile/userstyle.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.scratch-stats-box img.views-icon {
filter: invert(37%) sepia(95%) saturate(4000%) hue-rotate(200deg) brightness(95%) contrast(90%);
}

.scratch-stats-box img.remix-icon {
filter: invert(55%) sepia(72%) saturate(500%) hue-rotate(90deg) brightness(95%) contrast(90%);
}

.scratch-stats-box {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
margin-top: 15px;
font-size: 14px;
background-color: #f9f9f9;
border-top: 1px solid #ddd;
}
Loading