Skip to content

Commit f19a0ee

Browse files
authored
Merge branch 'main' into main
2 parents 4ebd112 + 1948a45 commit f19a0ee

File tree

12 files changed

+452
-35
lines changed

12 files changed

+452
-35
lines changed

extras/feature-locales/en.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

features/aviate.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

features/features.json

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@
44
"id": "webp-uploads",
55
"versionAdded": "v4.0.0"
66
},
7+
{
8+
"version": 2,
9+
"id": "remaining-replies",
10+
"versionAdded": "v4.0.0"
11+
},
12+
{
13+
"version": 2,
14+
"id": "video-recorder",
15+
"versionAdded": "v4.0.0"
16+
},
17+
{
18+
"version": 2,
19+
"id": "studio-creation-date",
20+
"versionAdded": "v4.0.0"
21+
},
722
{
823
"version": 2,
924
"id": "explore-filter",
@@ -1128,19 +1143,6 @@
11281143
"tags": [],
11291144
"type": ["Editor"]
11301145
},
1131-
{
1132-
"title": "Aviate Statuses",
1133-
"description": "Displays Aviate statuses on profile pages. You can set your status at aviate.scratchers.tech.",
1134-
"credits": ["MystPi", "rgantzos"],
1135-
"urls": [
1136-
"https://github.com/MystPi/",
1137-
"https://scratch.mit.edu/users/rgantzos/"
1138-
],
1139-
"file": "aviate",
1140-
"tags": [],
1141-
"type": ["Website"],
1142-
"dynamic": true
1143-
},
11441146
{
11451147
"title": "Project Idea Generator",
11461148
"description": "On the Scratch Ideas page, there will be a section where you can generate project ideas if you need some.",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"title": "Remaining Replies",
3+
"description": "Shows how many more replies are allowed in a thread of studio comments.",
4+
"credits": [
5+
{
6+
"url": "https://scratch.mit.edu/users/rgantzos/",
7+
"username": "rgantzos"
8+
}
9+
],
10+
"type": ["Website"],
11+
"dynamic": true,
12+
"scripts": [{ "file": "script.js", "runOn": "/studios/*" }]
13+
}
14+
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
export default async function ({ feature, console }) {
2+
window.feature = feature
3+
4+
ScratchTools.waitForElements(".flex-row.comment", function (comment) {
5+
let data = feature.redux
6+
.getState()
7+
.comments.comments.find(
8+
(c) => c.id.toString() === comment.id.split("-")[1]
9+
);
10+
11+
if (data) {
12+
let replyCount =
13+
feature.redux.getState().comments.replies[data.id]?.length || 0;
14+
let repliesLeft = 25 - replyCount;
15+
16+
updateReply(data.id, repliesLeft);
17+
} else {
18+
let parent = findParent(Number(comment.id.split("-")[1]));
19+
20+
if (parent) {
21+
let replyCount =
22+
feature.redux.getState().comments.replies[parent]?.length || 0;
23+
let repliesLeft = 25 - replyCount;
24+
updateReply(parent, repliesLeft);
25+
} else {
26+
console.log("nope")
27+
}
28+
}
29+
});
30+
31+
function findParent(replyId) {
32+
let replies = feature.redux.getState().comments.replies;
33+
let keys = Object.keys(replies);
34+
35+
let key = keys.find((k) => replies[k].find((r) => r.id === replyId));
36+
37+
return key ? Number(key) : null;
38+
}
39+
40+
function updateReply(commentId, count) {
41+
let div = document.querySelector(`.comment#comments-${commentId}`);
42+
if (!div) return;
43+
44+
let reply = div.querySelector(".comment-reply span");
45+
46+
if (reply.querySelector(".ste-reply-count")) {
47+
reply.querySelector(
48+
".ste-reply-count"
49+
).textContent = ` (${count.toString()} left)`;
50+
} else {
51+
let span = document.createElement("span");
52+
span.className = "ste-reply-count";
53+
feature.self.hideOnDisable(span)
54+
span.textContent = ` (${count.toString()} left)`;
55+
reply.appendChild(span);
56+
}
57+
58+
let data = feature.redux
59+
.getState()
60+
.comments.comments.find((c) => c.id.toString() === commentId.toString());
61+
62+
let replies = feature.redux.getState().comments.replies[commentId.toString()];
63+
64+
if (data && replies) {
65+
for (var i in replies) {
66+
updateReply(replies[i].id, count);
67+
}
68+
}
69+
}
70+
}
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"title": "Studio Creation Date",
3+
"description": "Adds the creation date of the studio to the studio footer.",
4+
"credits": [
5+
{
6+
"username": "MaterArc",
7+
"url": "https://scratch.mit.edu/users/MaterArc/"
8+
}
9+
],
10+
"type": ["Website"],
11+
"tags": ["New"],
12+
"dynamic": true,
13+
"scripts": [{ "file": "script.js", "runOn": "/studios/*" }],
14+
"resources": [{ "name": "calendar", "path": "/calendar.svg" }]
15+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
export default function ({ feature }) {
2+
ScratchTools.waitForElements(
3+
".studio-info-footer-stats",
4+
async function (footer) {
5+
if (document.querySelector(".ste-studio-created")) return;
6+
7+
const studioId = window.location.href.match(/studios\/(\d+)/)[1];
8+
const apiUrl = `https://api.scratch.mit.edu/studios/${studioId}`;
9+
10+
const response = await fetch(apiUrl);
11+
const data = await response.json();
12+
13+
const createdDate = new Date(data.history.created);
14+
const monthNames = [
15+
"Jan",
16+
"Feb",
17+
"Mar",
18+
"Apr",
19+
"May",
20+
"Jun",
21+
"Jul",
22+
"Aug",
23+
"Sep",
24+
"Oct",
25+
"Nov",
26+
"Dec",
27+
];
28+
const formattedDate = `Created ${
29+
monthNames[createdDate.getUTCMonth()]
30+
} ${createdDate.getUTCDate()}, ${createdDate.getUTCFullYear()}`;
31+
32+
const creationDateDiv = document.createElement("div");
33+
creationDateDiv.classList.add("studio-creation-date");
34+
creationDateDiv.classList.add("ste-studio-created")
35+
36+
const creationDateImg = document.createElement("img");
37+
creationDateImg.src = feature.self.getResource("calendar");
38+
39+
const creationDateSpan = document.createElement("span");
40+
creationDateSpan.textContent = formattedDate;
41+
42+
creationDateDiv.appendChild(creationDateImg);
43+
creationDateDiv.appendChild(creationDateSpan);
44+
45+
footer.insertBefore(creationDateDiv, footer.firstChild);
46+
}
47+
);
48+
}

features/video-recorder/data.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"title": "Record Stage",
3+
"description": "Allows you to record the stage for projects while in the editor or on the project page.",
4+
"credits": [
5+
{
6+
"username": "blob2763",
7+
"url": "https://blob2763.is-a.dev/"
8+
},
9+
{
10+
"username": "stio_studio",
11+
"url": "https://stio.studio/"
12+
}
13+
],
14+
"type": ["Editor"],
15+
"tags": ["New", "Featured"],
16+
"scripts": [
17+
{
18+
"file": "video-recorder.js",
19+
"runOn": "/projects/*"
20+
}
21+
],
22+
"styles": [
23+
{
24+
"file": "style.css",
25+
"runOn": "/projects/*"
26+
}
27+
],
28+
"resources": [
29+
{
30+
"name": "popup-html",
31+
"path": "/popup.html"
32+
}
33+
]
34+
}

features/video-recorder/popup.html

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<div class="ReactModalPortal STE-ReactModalPortal">
2+
<div class="ReactModal__Overlay ReactModal__Overlay--after-open modal_modal-overlay_1Lcbx">
3+
<div
4+
class="ReactModal__Content ReactModal__Content--after-open modal_modal-content_1h3ll prompt_modal-content_1BfWj"
5+
tabindex="-1" role="dialog" aria-label="Rename Variable">
6+
<div class="box_box_2jjDp" dir="ltr" style="flex-direction: column; flex-grow: 1">
7+
<div class="modal_header_1h7ps">
8+
<div class="modal_header-item_2zQTd modal_header-item-title_tLOU5">
9+
Video Recording
10+
</div>
11+
<div class="modal_header-item_2zQTd modal_header-item-close_2XDeL">
12+
<div aria-label="Close" class="close-button_close-button_lOp2G close-button_large_2oadS" role="button"
13+
tabindex="0">
14+
<img class="close-button_close-icon_HBCuO"
15+
src="data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3LjQ4IDcuNDgiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6MnB4O308L3N0eWxlPjwvZGVmcz48dGl0bGU+aWNvbi0tYWRkPC90aXRsZT48bGluZSBjbGFzcz0iY2xzLTEiIHgxPSIzLjc0IiB5MT0iNi40OCIgeDI9IjMuNzQiIHkyPSIxIi8+PGxpbmUgY2xhc3M9ImNscy0xIiB4MT0iMSIgeTE9IjMuNzQiIHgyPSI2LjQ4IiB5Mj0iMy43NCIvPjwvc3ZnPg==" />
16+
</div>
17+
</div>
18+
</div>
19+
<div class="prompt_body_18Z-I box_box_2jjDp">
20+
<!-- <div class="prompt_label_tWjYZ box_box_2jjDp"></div>
21+
<div class="box_box_2jjDp"><input class="prompt_variable-name-text-input_1iu8-"
22+
name="Rename all &quot;box size&quot; variables to:" value="box size"></div> -->
23+
<div class="prompt_button-row_3Wc5Z box_box_2jjDp STE-left-text">
24+
<button class="stopButton STE-hide-button">
25+
<span>Stop Recording</span>
26+
</button>
27+
<button class="prompt_ok-button_3QFdD startButton scratchtoolsTag">
28+
<span>Start Recording</span>
29+
</button>
30+
<br /><br />
31+
Microphone: <input type="checkbox" class="microphoneCheckbox">
32+
<br />
33+
Desktop sound: <input type="checkbox" class="desktopSoundCheckbox" checked>
34+
<br />
35+
<select class="video-format-select">
36+
<option value="mp4">mp4</option>
37+
<option value="webm">webm</option>
38+
</select>
39+
<br /><br />
40+
Preview: <br />
41+
<video class="STE-recorded-video"></video>
42+
<button class="prompt_ok-button_3QFdD downloadButton scratchtoolsTag">
43+
<span>Download Video</span>
44+
</button>
45+
</div>
46+
</div>
47+
</div>
48+
</div>
49+
</div>
50+
</div>

0 commit comments

Comments
 (0)