-
Notifications
You must be signed in to change notification settings - Fork 0
/
quickreply.html
381 lines (308 loc) · 17 KB
/
quickreply.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
<!DOCTYPE html>
<html>
<head>
<title>the post generation station</title>
<link href="/dark.css" rel="stylesheet" type="text/css" media="all">
</head>
<body>
<h1>Personal Scratch forums QuickReply</h1>
<h2 id="displayName">This webpage requires JavaScript.</h2>
<div id="dataView"></div>
<p style="display: none;" id="textDisplay"><textarea style='width: 50em; height: 10em;' id="copier" onclick='this.select()' readonly></textarea></p>
<p style="display: none;" id="textEditable">Replace "__EDITABLE__" with: <input type="text" id="editBox" placeholder="Replacement" onchange="replaceEditable(this.value)"></p>
<p style="display: none;" id="rejectedLoading">Fetching rejected suggestions...</p>
<p style="display: none;" id="rejectedChooser">
<a href="https://scratch.mit.edu/discuss/topic/343602/" target="blank">Open The Official List of Rejected Suggestions in a new tab</a>, find the relevant suggestion, then type its number here.
<br><br><input type="text" id="rejectedNumber" placeholder="X.Y"> <button onclick='quoteRejected(document.querySelector("#rejectedNumber").value.toString())'>Quote</button>
</p>
<small>This webpage contains some of my most common responses to <a href="https://scratch.mit.edu/discuss/">Scratch forum topics</a>.
<br>To view this webpage's source code, <a href='https://github.com/voxalice2/voxalice2.github.io/blob/main/quickreply.html'>click here!</a>
<br><br><details><summary>Updates</summary><hr>
Update 1 (2024-12-20) - Original version<hr>
Update 2 (2024-12-21) - Fixed textboxes<hr>
Update 3 (2024-12-22) - Added invisible items, <a onclick='displayView("test")'>test items</a>, and a JavaScript-disabled warning<hr>
Update 4 (2024-12-23) - Added editable items<hr>
Update 5 (2025-01-01) - Added function items, including a built-in quoter for The Official List of Rejected Suggestions<hr>
Update 6 (2025-01-05) - Fixed issues with scraping rejected suggestions, and cleaned up some code
</details></small>
<script>
'use strict';
// View data starts here
var viewData = {
// Root
0: {"name": "Choose a forum:",
"text": false,
"hidden": false,
"data": ["test", 6, 1, 2, 19, 20]},
6: {"name": "General (any forum)",
"text": false,
"hidden": false,
"data": [7, 8, 23]},
1: {"name": "Bugs and Glitches",
"text": false,
"hidden": false,
"data": [3, 4, 9, 12, 11, 24]},
2: {"name": "Suggestions",
"text": false,
"hidden": false,
"data": [5, 10]},
19: {"name": "Things I'm Making and Creating",
"text": false,
"hidden": false,
"data": [21]},
20: {"name": "Things I'm Reading and Playing",
"text": false,
"hidden": false,
"data": [22]},
// Bugs and Glitches
3: {"name": "Search Engine Down",
"text": true,
"hidden": false,
"editable": false,
"data": "[url=https://scratch.mit.edu/discuss/topic/790866/]Scratch's search engine is currently broken[/url], and all we can do is wait for it to be fixed.\n" +
"Unfortunately, no one seems to know what's causing issues or when they will be fixed.\n" +
"This affects everyone on Scratch, so the Scratch Team is aware of the situation.\n\n" +
'For now, you can type "site:scratch.mit.edu [i](query)[/i]" into an external search engine to work around this bug.'},
4: {"name": "Search Engine Down (+ User Searching)",
"text": true,
"hidden": false,
"editable": false,
"data": "[url=https://scratch.mit.edu/discuss/topic/790866/]Scratch's search engine is currently broken[/url], and all we can do is wait for it to be fixed.\n" +
"Unfortunately, no one seems to know what's causing issues or when they will be fixed.\n" +
"This affects everyone on Scratch, so the Scratch Team is aware of the situation.\n\n" +
'For now, you can type "site:scratch.mit.edu [i](query)[/i]" into an external search engine to work around this bug.\n\n' +
"If you want to [url=https://en.scratch-wiki.info/wiki/How_do_I_search_for_a_user%3F]search for a user[/url], use a link like this:\n" +
"[quote]https://scratch.mit.edu/users/USERNAME/[/quote]"},
9: {"name": "Cloud Variables Resetting",
"text": true,
"hidden": false,
"editable": false,
"data": "If you own the project with the broken cloud variables, try renaming those variables.\n\n" +
"If you don't own the project with the broken cloud variables, please ask the owner of that project to rename their cloud variables."},
12: {"name": "Cloud Variables Down",
"text": true,
"hidden": false,
"editable": false,
"data": "Cloud variables are currently broken, and all we can do is wait for them to be fixed.\n" +
"Unfortunately, no one seems to know what's causing issues or when they will be fixed.\n" +
"This affects everyone on Scratch, so the Scratch Team is aware of the situation."},
11: {"name": "Browser Information Instructions",
"text": true,
"hidden": false,
"editable": false,
"data": "When replying, could you click the globe icon (to the right of the emoji) to show what device and browser you're using?"},
24: {"name": "Can't Become a Scratcher (No Next Button)",
"text": true,
"hidden": false,
"editable": false,
"data": 'When you get to the Community Guidelines page, try selecting everything with the key combo Ctrl+A.\n\n' +
'That should make a blue box appear near the bottom-right corner of the screen, which you can then click to progress.\n\n' +
'Once you click "I Agree", you [i]will[/i] be a Scratcher, even if nothing seems to happen.'},
// Suggestions
5: {"name": "Duplicate Suggestion",
"text": true,
"hidden": false,
"editable": true,
"data": "This is a duplicate of [url=__EDITABLE__]an earlier suggestion[/url].\n" +
"Please use the linked topic to keep the discussion all in one place :)\n\n" +
"For future reference, you can use the [url=https://scratch.mit.edu/discuss/topic/657522/]Suggestions Directory[/url] or [url=https://ocular.jeffalo.net/]Ocular[/url] to check for duplicates."},
10: {"name": "Rejected Suggestion",
"text": false,
"hidden": false,
"editable": false,
"function": "rejected()"},
"rejectedOriginal": {"name": "Rejected Suggestion (Original)",
"text": true,
"hidden": false,
"editable": false,
"data": "Unfortunately, this suggestion is rejected.\n\n" +
"From [url=https://scratch.mit.edu/discuss/topic/343602/]The Official List of Rejected Suggestions[/url]:\n" +
"[quote=Za-Chary]View_source_then_find_the_rejected_suggestion_then_paste_it_here[/quote]"},
// General
7: {"name": "Duplicate Topic",
"text": true,
"hidden": false,
"editable": true,
"data": "This is a duplicate of [url=__EDITABLE__]an earlier topic[/url].\n" +
"Please use the linked topic to keep the discussion all in one place :)\n\n" +
"For future reference, you can use the third-party search engine [url=https://ocular.jeffalo.net/]Ocular[/url] to check for duplicates."},
8: {"name": "Topic Closing Instructions",
"text": true,
"hidden": false,
"editable": false,
"data": "If you don't see a Close Topic button anywhere, you can just report the original post and ask the Scratch Team to close it in the textbox.\n\n" +
"I'll do that for you right now. :)"},
23: {"name": "Welcome to the Forums",
"text": true,
"hidden": false,
"editable": false,
"data": "Welcome to the forums! Check out the Sticky topics in [url=https://scratch.mit.edu/discuss/6/]the New Scratchers forum[/url] for guidance."},
// Things I'm [...]
21: {"name": "Duplicate Topic (Things I'm Making and Creating)",
"text": true,
"hidden": false,
"editable": true,
"data": "This is a duplicate of [url=__EDITABLE__]an earlier topic[/url].\n" +
"Please use the linked topic to keep the discussion all in one place :)\n\n" +
"For future reference, you can use the [url=https://scratch.mit.edu/discuss/topic/776027/]Things I'm Making and Creating Directory[/url] or [url=https://ocular.jeffalo.net/]Ocular[/url] to check for duplicates."},
22: {"name": "Duplicate Topic (Things I'm Reading and Playing)",
"text": true,
"hidden": false,
"editable": true,
"data": "This is a duplicate of [url=__EDITABLE__]an earlier topic[/url].\n" +
"Please use the linked topic to keep the discussion all in one place :)\n\n" +
"For future reference, you can use the [url=https://scratch.mit.edu/discuss/topic/735680/]Things I'm Reading and Playing Topic Directory[/url] or [url=https://ocular.jeffalo.net/]Ocular[/url] to check for duplicates."},
// Testing
"test": {"name": "> TESTING <",
"text": false,
"hidden": true,
"data": ["this page doesn't exist", "test", 14, 15, Math.imul(3, 5) + 1, 17, 18, 0, "goTo"]},
14: {"name": "Hidden item 1",
"text": true,
"hidden": true,
"data": "HELLO WORLD"},
15: {"name": "Hidden item 2!",
"text": false,
"hidden": true,
"data": [1, 2, 3]},
16: {"name": "Invalid content 1",
"text": false,
"hidden": false,
"data": "Wow"},
17: {"name": "Invalid content 2",
"text": true,
"hidden": false,
"data": [1, 2, 3]},
18: {"name": "Invalid content 3!",
"text": false,
"hidden": false,
"data": true},
"goTo": {"name": "Go to any item",
"text": false,
"hidden": false,
"function": 'dataView.insertAdjacentHTML("beforeend",`<p><input type="text" placeholder="Item name" id="itemname"> <button onclick="displayView(document.querySelector(\'#itemname\').value)">Go</button></p>`)'},
}
// View data ends here
var dataView = document.querySelector("#dataView");
var textDisplay = document.querySelector("#textDisplay");
var textEditable = document.querySelector("#textEditable");
var copier = document.querySelector("#copier");
var rejectedLoading = document.querySelector("#rejectedLoading");
var rejectedChooser = document.querySelector("#rejectedChooser");
var rejectedData = "";
var viewHistory = [];
var viewing;
function show(element) { element.style.display = "block"; }
function hide(element) { element.style.display = "none"; }
function setCopier(copierText) { copier.value = copierText; }
function appendLink(id, name, back) {
if (!viewData[id].hidden) {
var linkContainer = document.createElement("p");
var linkElement = document.createElement("button");
linkElement.innerText = name ?? viewData[id].name;
if (back) {
linkElement.onclick = function() { displayLastItem(); };
} else {
linkElement.onclick = function() { displayView(id); };
}
linkContainer.append(linkElement);
dataView.append(linkContainer);
}
}
function displayLastItem() {
viewHistory.pop(); displayView(viewHistory.pop());
}
function displayView(id) {
if (id == undefined) { id = 0; }
viewing = id;
var data = viewData[id];
console.log("Displaying data at ID " + id, data);
if (data != undefined) {
document.querySelector("#displayName").innerText = data.name;
dataView.replaceChildren();
// Append "Back" link and hide everything (except for the name)
viewHistory.push(id);
if (viewHistory.length > 1) { appendLink(0, "<= Back to previous page <=", true); }
hide(textEditable);
hide(textDisplay);
hide(rejectedLoading);
hide(rejectedChooser);
document.querySelector("#editBox").value = "";
// Start handling data
if (data.text) {
show(textDisplay);
setCopier(data.data.toString());
if (data.editable) {
show(textEditable);
}
} else {
if (data.function) {
eval?.(`"use strict";${data.function}`);
} else {
if (typeof data.data == "object") {
data.data.forEach((element) => {
try { appendLink(element, null, false); }
catch (exception) { console.error(exception); }
});
}
}
}
}
}
function replaceEditable(edit) {
if (edit == "") { edit = "__EDITABLE__"; }
setCopier(viewData[viewing].data.toString().replace("__EDITABLE__", edit));
}
displayView(0, false);
// Rejected Suggestions code starts here
async function getRejected() {
if (rejectedData == "") { // If rejected suggestions data has not already been fetched
if (!window.navigator.onLine) { alert("Please connect to the Internet."); return false; }
try {
const response = await fetch("https://scratch.mit.edu/discuss/post/3466932/source/");
if (!response.ok) { throw new Error(`Response status: ${response.status}`); }
rejectedData = await response.text();
return true;
} catch (e) {
console.error(e);
alert("Something went wrong fetching rejected suggestions. Check this browser's console for more information.");
return false;
}
} else {return true}
}
function rejected() {
hide(rejectedLoading);
show(rejectedChooser);
document.querySelector("#rejectedNumber").value = "";
}
function quoteRejected(rejectedNumber) {
var requestConfirmed;
if (rejectedData == "") {requestConfirmed = confirm("This action will make a request to scratch.mit.edu.")} // If rejected suggestions data has not already been fetched
else {requestConfirmed = true}
if (requestConfirmed) {
show(rejectedLoading);
hide(rejectedChooser);
getRejected().then((good) => {
if (good) {
hide(rejectedLoading);
var rejectedQuote = "";
// Attempt to find rejected suggestion text, and alert if not found
var quoteDelimiter = (parseFloat(rejectedNumber) > 0) ? ("[b]" + rejectedNumber + " ") : null;
try { rejectedQuote = (quoteDelimiter + rejectedData.split(quoteDelimiter)[1].split("[b")[0]).trim(); } // Find text between "[b]X.Y " and "[b]"
catch (e) { console.error(e.message); show(rejectedChooser); alert("That doesn't seem to be a valid suggestion number. Check for typos."); }
if (rejectedQuote != "") {
hide(textEditable);
hide(rejectedChooser);
show(textDisplay);
setCopier("Unfortunately, this suggestion may be rejected.\n\n" +
"From [url=https://scratch.mit.edu/discuss/topic/343602/]The Official List of Rejected Suggestions[/url]:\n" +
"[quote=Za-Chary]" + rejectedQuote + "[/quote]");
}
} else { rejected(); }
})
}
}
</script>
<script src="/stable.js"></script>
</body>
</html>