Skip to content

Commit e51b8cc

Browse files
authored
Merge pull request #821 from rgantzos/main
Pin comments
2 parents 89f5c6d + cbe89fb commit e51b8cc

File tree

5 files changed

+252
-0
lines changed

5 files changed

+252
-0
lines changed

features/features.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
[
2+
{
3+
"version": 2,
4+
"id": "pin-comments",
5+
"versionAdded": "v3.8.0"
6+
},
27
{
38
"version": 2,
49
"id": "sidebar",

features/pin-comments/data.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"title": "Pin Project Comments",
3+
"description": "Allows you to pin comments on your own projects and see what comments are pinned on other projects.",
4+
"credits": [
5+
{
6+
"username": "NewYearsFan",
7+
"url": "https://scratch.mit.edu/users/NewYearsFan/"
8+
},
9+
{
10+
"username": "rgantzos",
11+
"url": "https://scratch.mit.edu/users/rgantzos/"
12+
}
13+
],
14+
"scripts": [
15+
{
16+
"file": "script.js",
17+
"runOn": "/projects/*"
18+
}
19+
],
20+
"styles": [
21+
{
22+
"file": "style.css",
23+
"runOn": "/projects/*"
24+
}
25+
],
26+
"tags": [
27+
"New"
28+
],
29+
"type": [
30+
"Website"
31+
],
32+
"dynamic": true,
33+
"resources": [{ "name": "pin", "path": "/pin.svg" }]
34+
}

features/pin-comments/pin.svg

Lines changed: 12 additions & 0 deletions
Loading

features/pin-comments/script.js

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
export default async function ({ feature, console }) {
2+
window.feature = feature
3+
4+
let pinned = await (await fetch(`https://data.scratchtools.app/pinned/${feature.redux.getState().preview.projectInfo.id}/`)).json()
5+
let { username: author } = feature.redux.getState().preview.projectInfo.author
6+
let { id } = feature.redux.getState().preview.projectInfo
7+
let { username } = feature.redux.getState().session?.session?.user
8+
9+
let AUTHOR = author
10+
11+
if (pinned.commentId) {
12+
ScratchTools.waitForElements(".comments-list", async function(list) {
13+
let data = await (await fetch(`https://api.scratch.mit.edu/users/${pinned.author}/`)).json()
14+
if (data) {
15+
let box = document.createElement("div")
16+
box.className = "ste-pinned-comment"
17+
18+
let h3 = document.createElement("h3")
19+
h3.textContent = "Pinned Comment"
20+
box.appendChild(h3)
21+
22+
let comment = document.createElement("div")
23+
comment.className = "flex-row comment-container"
24+
box.appendChild(comment)
25+
26+
let inner = document.createElement("div")
27+
inner.className = "flex-row comment"
28+
comment.appendChild(inner)
29+
30+
let a = document.createElement("a")
31+
a.href = `/users/${pinned.author}/`
32+
inner.appendChild(a)
33+
34+
let img = document.createElement("img")
35+
img.src = data.profile.images["90x90"]
36+
img.className = "avatar"
37+
a.appendChild(img)
38+
39+
let main = document.createElement("div")
40+
main.className = "flex-row comment-body column"
41+
inner.appendChild(main)
42+
43+
let topRow = document.createElement("div")
44+
topRow.className = "flex-row comment-top-row"
45+
main.appendChild(topRow)
46+
47+
let author = document.createElement("a")
48+
author.href = `/users/${pinned.author}/`
49+
author.className = "username"
50+
author.textContent = data.username
51+
topRow.appendChild(author)
52+
53+
let bubble = document.createElement("div")
54+
bubble.className = "comment-bubble"
55+
main.appendChild(bubble)
56+
57+
let content = document.createElement("span")
58+
content.textContent = pinned.content
59+
content.className = "comment-content"
60+
bubble.appendChild(content)
61+
62+
let bottomRow = document.createElement("div")
63+
bottomRow.className = "flex-row comment-bottom-row"
64+
bubble.appendChild(bottomRow)
65+
66+
let time = document.createElement("span")
67+
time.className = "comment-time"
68+
time.textContent = `Comment pinned by @${AUTHOR}.`
69+
bottomRow.appendChild(time)
70+
71+
let goTo = document.createElement("span")
72+
goTo.className = "comment-goto"
73+
bottomRow.appendChild(goTo)
74+
75+
let goToLink = document.createElement("a")
76+
goToLink.href = `https://scratch.mit.edu/projects/${pinned.projectId}/#comments-${pinned.commentId}`
77+
goToLink.textContent = "view full comment"
78+
goTo.appendChild(goToLink)
79+
80+
list.parentElement.insertBefore(box, list)
81+
}
82+
})
83+
}
84+
85+
if (author === username) {
86+
ScratchTools.waitForElements("div.flex-row.comments-list > div > div.flex-row.comment", function (comment) {
87+
let actions = comment.querySelector("div.action-list")
88+
if (!actions || actions.querySelector(".comment-pin")) return;
89+
90+
if (pinned.commentId?.toString() === comment.id.replace("comments-", "")) {
91+
let span = document.createElement("span")
92+
span.className = "comment-pin"
93+
let innerSpan = document.createElement("span")
94+
innerSpan.textContent = "Unpin"
95+
span.appendChild(innerSpan)
96+
actions.prepend(span)
97+
98+
span.addEventListener("click", async function () {
99+
ScratchTools.verifyUser(async function (token) {
100+
let data = await (
101+
await fetch("https://data.scratchtools.app/unpin/", {
102+
method: "POST",
103+
headers: {
104+
Accept: "application/json",
105+
"Content-Type": "application/json",
106+
},
107+
body: JSON.stringify({ token, project: id.toString() }),
108+
})
109+
).json();
110+
111+
if (data.error) {
112+
ScratchTools.modals.create({
113+
title: "Error",
114+
description:
115+
data.error,
116+
});
117+
} else {
118+
ScratchTools.modals.create({
119+
title: "Comment Unpinned",
120+
description:
121+
"This comment has been unpinned. You may reload the page to see the change.",
122+
});
123+
}
124+
})
125+
})
126+
} else {
127+
let span = document.createElement("span")
128+
span.className = "comment-pin"
129+
let innerSpan = document.createElement("span")
130+
innerSpan.textContent = "Pin"
131+
span.appendChild(innerSpan)
132+
actions.prepend(span)
133+
134+
span.addEventListener("click", async function () {
135+
ScratchTools.verifyUser(async function (token) {
136+
let data = await (
137+
await fetch("https://data.scratchtools.app/pin/", {
138+
method: "POST",
139+
headers: {
140+
Accept: "application/json",
141+
"Content-Type": "application/json",
142+
},
143+
body: JSON.stringify({ token, project: id.toString(), author: comment.querySelector("a").href.split("/")[4], id: comment.id.replace("comments-", ""), content: comment.querySelector(".comment-content").textContent }),
144+
})
145+
).json();
146+
147+
if (data.error) {
148+
ScratchTools.modals.create({
149+
title: "Error",
150+
description:
151+
data.error,
152+
});
153+
} else {
154+
ScratchTools.modals.create({
155+
title: "Comment Pinned",
156+
description:
157+
"This comment has been pinned and you may reload the page to see. Please only pin appropriate comments. If the comment you pinned is not appropriate, it may be removed and you may lose the ability to pin comments in the future.",
158+
});
159+
}
160+
})
161+
})
162+
}
163+
})
164+
}
165+
}

features/pin-comments/style.css

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
.comment-pin {
2+
opacity: .5;
3+
cursor: pointer;
4+
font-size: .75rem;
5+
font-weight: 500;
6+
margin-right: 1rem;
7+
}
8+
9+
.comment-pin:before {
10+
background-image: var(--scratchtoolsresource-pin);
11+
width: 1rem;
12+
height: 1rem;
13+
vertical-align: -0.25rem;
14+
display: inline-block;
15+
margin-right: .5rem;
16+
background-repeat: no-repeat;
17+
background-position: center center;
18+
background-size: contain;
19+
content: "";
20+
}
21+
22+
.ste-pinned-comment {
23+
padding: 1rem;
24+
width: 100%;
25+
position: relative;
26+
left: -1rem;
27+
border-radius: .5rem;
28+
margin-bottom: 2rem;
29+
background-color: #ff9f0020;
30+
}
31+
32+
.ste-pinned-comment h3 {
33+
width: 100%;
34+
text-align: center;
35+
display: block;
36+
}

0 commit comments

Comments
 (0)