-
Notifications
You must be signed in to change notification settings - Fork 0
/
wkSummary.js
550 lines (501 loc) · 31.4 KB
/
wkSummary.js
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
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
// ==UserScript==
// @name Wanikani Review Summary
// @namespace https://tampermonkey.net/
// @version 0.6.2
// @license MIT
// @description Show a popup with statistics about the review session when returning to the dashboard
// @author leohumnew
// @match https://www.wanikani.com/*
// @require https://greasyfork.org/scripts/489759-wk-custom-icons/code/CustomIcons.js?version=1417568
// @grant none
// ==/UserScript==
(function() {
'use strict';
if (window.location.href === "https://www.wanikani.com/subjects/review") {
runScript();
} else {
window.addEventListener("turbo:render", function(e) {
if (window.location.href === "https://www.wanikani.com/subjects/review") {
runScript();
}
});
}
async function runScript() {
// Variables to store the statistics
let questionsAnswered = 0;
let itemsCorrect = 0;
let itemsIncorrect = 0;
let meaningCorrect = 0;
let meaningIncorrect = 0;
let readingCorrect = 0;
let readingIncorrect = 0;
let correctHistory = [];
let incorrectEntered = new Map();
let itemsList = []; // Array to store the items reviewed
let currentQuestionType = "";
let currentCategory = "";
let currentWord = "";
let currentSRSLevel = -1;
let quizQueueSRS = [];
// Other Variables
let SRSLevelNames = ["Lesson", "Appr. I", "Appr. II", "Appr. III", "Appr. IV", "Guru I", "Guru II", "Master", "Enl.", "Burned", "Error"];
const GRAPH_HEIGHT = 120;
// Create style element with popup styles and append it to the document head
let style = document.createElement("style");
style.id = "summary-popup-styles";
style.textContent = ".summary-popup { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 9999; color: var(--color-text); background-color: var(--color-wk-panel-content-background, #eee); padding: 50px; overflow-y: auto; font-size: var(--font-size-large); }";
style.textContent += ".summary-popup .wk-icon { vertical-align: bottom; }";
style.textContent += ".summary-popup > a { background-color: transparent; text-decoration: none; text-align: center; margin: 30px 50px; position: absolute; top: 0px; right: 0px; cursor: pointer; padding: 10px; border-radius: 5px; outline: 1px solid var(--color-tertiary, black); color: var(--color-text) } .summary-popup > a:hover { color: var(--color-tertiary, #bbb); }";
style.textContent += ".summary-popup table { border-collapse: collapse; border-radius: 5px; width: 100%; background-color: var(--color-wk-panel-background, #000); } .summary-popup td { border: none; padding: 5px; text-align: center; }";
style.textContent += ".summary-popup h1 { margin-bottom: 10px; font-weight: bold; font-size: var(--font-size-xlarge); } .summary-popup h2 { font-weight: bold; margin-top: 20px; padding: 20px; color: #fff; font-size: var(--font-size-large); border-radius: 5px 5px 0 0; }";
style.textContent += ".summary-popup ul { background-color: var(--color-wk-panel-background, #fff); padding: 5px; border-radius: 0 0 5px 5px; } .summary-popup li { display: inline-block; } .summary-popup li a { display: block; margin: 10px 5px; padding: 10px; color: var(--color-text-dark, #fff); font-size: 1.5rem; height: 2.6rem; border-radius: 5px; text-decoration: none; position: relative; } .summary-popup li a img { height: 1em; vertical-align: middle; }";
style.textContent += ".summary-popup .summary-popup__popup { background-color: var(--color-menu, #ddd); color: var(--color-text, #fff); text-decoration: none; padding: 10px; border-radius: 5px; position: fixed; z-index: 9999; display: none; font-size: var(--font-size-medium); box-shadow: 0 2px 3px rgba(0, 0, 0, 0.5); width: max-content; line-height: 1.3; }";
style.textContent += ".summary-popup .summary-popup__popup:after { content: ''; position: absolute; top: -8px; margin-left: -10px; width: 0; height: 0; border-left: 10px solid transparent; border-right: 10px solid transparent; border-bottom: 10px solid var(--color-menu, #ddd); }";
style.textContent += ".summary-popup .summary-popup__popup--left:after { right: 15px; } .summary-popup .summary-popup__popup--right:after { left: 25px; }";
style.textContent += ".summary-popup .accuracy-graph { position: relative; height: " + (GRAPH_HEIGHT + 42) + "px; width: 100%; background-color: var(--color-wk-panel-background, #fff); padding: 25px 1% 15px 1%; border-radius: 0 0 5px 5px; }";
style.textContent += ".summary-popup .accuracy-graph span { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: var(--font-size-xlarge); color: var(--color-text); }";
style.textContent += ".summary-popup ul .wk-icon { position: absolute; top: -8px; right: -8px; text-align: center; color: white; background-color: var(--color-burned); padding: 3px; border-radius: 50%; border: white solid 1px }";
style.textContent += ".summary-popup ul .incorrect-text { color: var(--color-incorrect, #cc4343); font-size: var(--font-size-small); vertical-align: top; }";
if(window.matchMedia('(prefers-color-scheme: dark)').matches) style.textContent += ".summary-popup ul .incorrect-text { filter: brightness(2) }";
if(!document.getElementById("summary-popup-styles")) document.head.appendChild(style);
// Function to calculate the percentage
function percentage(numerator, denominator) {
if(denominator == 0) return "--";
return Math.round(numerator / denominator * 100) + "%";
}
// Function to get quiz queue SRS
async function getQuizQueueSRS() {
let elementArr = document.querySelector("#quiz-queue script[data-quiz-queue-target='subjectIdsWithSRS']");
if(elementArr) {
quizQueueSRS = JSON.parse(elementArr.innerHTML);
quizQueueSRS = quizQueueSRS.subject_ids_with_srs_info;
} else setTimeout(getQuizQueueSRS, 500);
}
getQuizQueueSRS();
function injectEndCode() {
// Clear the data-quiz-queue-done-url-value and data-quiz-queue-completion-url-value parameters on #quiz-queue
function get_controller(name) { // Thanks to @rfindley for this function
return Stimulus.getControllerForElementAndIdentifier(document.querySelector(`[data-controller~="${name}"]`),name);
}
let quizQueueController = get_controller("quiz-queue");
let quizOnDoneReplacement = function() { showStatistics(); };
quizQueueController.onDone = quizOnDoneReplacement.bind(quizQueueController);
quizQueueController.quizQueue.onDone = quizQueueController.onDone;
}
// Function to create a popup element
function createPopup(content) {
// Create a div element with some styles
let popup = document.createElement("div");
popup.className = "summary-popup";
// Create a close button with some styles and functionality
let closeButton = document.createElement("a");
closeButton.textContent = "Dashboard";
closeButton.href = "https://www.wanikani.com/dashboard";
closeButton.addEventListener('click', function() {
document.querySelector('.summary-popup')?.remove();
});
// Append the content and the close button to the popup
popup.append(content, closeButton);
return popup;
}
// Function to create a table element with some data
function createTable(data) {
// Create a table
let table = document.createElement("table");
let row = document.createElement("tr");
let row2 = document.createElement("tr");
let row3 = document.createElement("tr");
// Loop through the data array
for (let i = 0; i < data.length; i++) {
// Create table cell elements
let cell = document.createElement("td");
cell.textContent = data[i][0];
cell.style.fontSize = "var(--font-size-xxlarge)";
cell.style.fontWeight = "bold";
cell.style.padding = "25px 0 0 0";
row.appendChild(cell);
let cell2 = document.createElement("td");
cell2.textContent = data[i][1];
cell2.style.fontSize = "var(--font-size-small)";
cell2.style.fontStyle = "italic";
cell2.style.color = "var(--color-text-mid, #999)";
cell2.style.padding = "4px 0 10px 0";
row2.appendChild(cell2);
let cell3 = document.createElement("td");
cell3.textContent = data[i][2];
cell3.style.fontSize = "var(--font-size-medium)";
cell3.style.paddingBottom = "25px";
row3.appendChild(cell3);
}
// Append the rows to the table
table.append(row, row2, row3);
// Return the table element
return table;
}
// Function to create summary section
function createSummarySectionTitle(title, icon, bgColor) {
let sectionTitle = document.createElement("h2");
sectionTitle.appendChild(Icons.customIcon(icon));
sectionTitle.innerHTML += " " + title;
sectionTitle.style.backgroundColor = bgColor;
return sectionTitle;
}
// Function to create graph
function createGraph(data, canvas, congratulationMessageText) {
createGraph(data, canvas, congratulationMessageText, null);
}
function createGraph(data, canvas, congratulationMessageText, labels) {
let graphWidth = canvas.getBoundingClientRect().width;
canvas.height = GRAPH_HEIGHT + 2;
canvas.width = graphWidth;
let sidesOffset = parseFloat(window.getComputedStyle(document.documentElement).getPropertyValue('--font-size-small')); // Offset to apply to sides so that label text will fit - is applied to sides and bottom
let bottomOffset = sidesOffset * 1.3;
let graphStep = (graphWidth - (sidesOffset * 2)) / (data.length - 1);
let isAllPerfect = true;
let ctx = canvas.getContext("2d");
// Draw background horizontal lines
ctx.beginPath();
if(window.getComputedStyle(document.documentElement).getPropertyValue('--color-text-mid') == "") ctx.strokeStyle = "#aaa";
else ctx.strokeStyle = window.getComputedStyle(document.documentElement).getPropertyValue('--color-wk-panel-content-background');
ctx.lineWidth = 1;
for (let i = 0; i < 4; i++) {
let y = Math.round((GRAPH_HEIGHT - bottomOffset) / 3 * i) + 0.5;
ctx.moveTo(0, y);
ctx.lineTo(graphWidth, y);
}
ctx.stroke();
// Draw graph
ctx.beginPath();
ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--color-text');
ctx.lineWidth = 2;
for (let i = 0; i < data.length; i++) {
let x = graphStep * i + sidesOffset;
let y = (GRAPH_HEIGHT - bottomOffset) * (1 - data[i]) + 1;
if(data[i] != 1) isAllPerfect = false;
// Draw line
if(i == 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
// Draw labels
if(labels != null) {
let lastLabel = "";
let isDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].includes(labels[0]);
ctx.fillStyle = window.getComputedStyle(document.documentElement).getPropertyValue('--color-text');
ctx.font = window.getComputedStyle(document.documentElement).getPropertyValue('--font-size-small') + " sans-serif";
ctx.textAlign = "center";
for (let i = 0; i < data.length; i++) {
if(labels[i] != lastLabel) {
let x = graphStep * i + sidesOffset;
let y = GRAPH_HEIGHT - 1;
ctx.fillText(labels[i], x, y);
lastLabel = labels[i];
} else if(isDays && i == data.length - 1) {
let x = graphStep * i + sidesOffset;
let y = GRAPH_HEIGHT - 1;
ctx.fillText("Now", x, y);
}
}
}
// Show congratulation message if all perfect
if(isAllPerfect) {
let congratulationMessage = document.createElement("span");
congratulationMessage.textContent = congratulationMessageText;
canvas.parentNode.appendChild(congratulationMessage);
}
}
// Function to show the statistics when returning to the dashboard
function showStatistics() {
console.log(itemsList);
// Check if there are any items reviewed
if (itemsList.length > 0) {
// Create a heading element with some text and styles
let headingText = document.createElement("h1");
headingText.appendChild(Icons.customIcon("check-checked"));
headingText.innerHTML += " Review Summary";
let heading = document.createElement("div");
heading.append(headingText);
// Create an unordered list element
let listCorrect = document.createElement("ul");
let listIncorrect = document.createElement("ul");
// Loop through the items list array
let srsUpNum = 0;
let typeNum = [0, 0, 0];
for (let i = 0; i < itemsList.length; i++) {
// Create a list item element with the character or image
let listItem = document.createElement("li");
let listItemLink = document.createElement("a");
if(itemsList[i].characters.url == null) listItemLink.textContent = itemsList[i].characters;
else {
let listItemImage = document.createElement("img");
listItemImage.src = itemsList[i].characters.url;
listItemLink.appendChild(listItemImage);
}
if (itemsList[i].type === "Radical") {
listItemLink.style.backgroundColor = "var(--color-radical, #00aaff)";
listItemLink.href = "https://www.wanikani.com/radicals/" + itemsList[i].meanings[0];
} else if (itemsList[i].type === "Kanji") {
listItemLink.style.backgroundColor = "var(--color-kanji, #ff00aa)";
listItemLink.href = "https://www.wanikani.com/kanji/" + itemsList[i].characters;
}
else {
listItemLink.style.backgroundColor = "var(--color-vocabulary, #aa00ff)";
listItemLink.href = "https://www.wanikani.com/vocabulary/" + itemsList[i].characters;
}
// Make link open in new tab
listItemLink.target = "_blank";
// Badge if burned or if warning
if(itemsList[i].newSRS == 9) {
listItemLink.style.paddingRight = "15px";
listItemLink.appendChild(Icons.customIcon("fire"));
} else if(itemsList[i].isWarning) {
listItemLink.style.paddingRight = "15px";
listItemLink.appendChild(Icons.customIcon("warning"));
}
// Create popup with meaning and reading info on hover
let popup = document.createElement("div");
popup.className = "summary-popup__popup";
popup.innerHTML = "Meaning: <strong>" + itemsList[i].meanings.slice(0, 2).join(", ") + "</strong>";
if(itemsList[i].incorrectEntered != null && itemsList[i].incorrectEntered[0].length > 0) popup.innerHTML += '<br><span class="incorrect-text"> <strong>X</strong> ' + itemsList[i].incorrectEntered[0].join(", ") + "</span>";
if(itemsList[i].type == "Kanji") {
typeNum[1]++;
for (let k = 0; k < itemsList[i].readings.length; k++) { // Nanori, Onyomi, Kunyomi readings if kanji
if (itemsList[i].readings[k] != null) {
let label = "";
switch (k) {
case 0:
label = "Nanori";
break;
case 1:
label = "Onyomi";
break;
case 2:
label = "Kunyomi";
break;
}
popup.innerHTML += "<br>" + label + ": <strong>" + itemsList[i].readings[k].join(", ") + "</strong>";
}
}
}
else if(itemsList[i].type != "Radical" && itemsList[i].readings[0] != null) { // Reading if vocabulary
typeNum[2]++;
popup.innerHTML += "<br>Reading: <strong>" +
itemsList[i].readings.map(r => r.reading).join(", ") +
"</strong>";
} else { // No reading if radical
typeNum[0]++;
}
if(itemsList[i].incorrectEntered != null && itemsList[i].incorrectEntered[1].length > 0) popup.innerHTML += '<br><span class="incorrect-text"> <strong>X</strong> ' + itemsList[i].incorrectEntered[1].join(", ") + "</span>";
popup.innerHTML += "<br>SRS: " + SRSLevelNames[itemsList[i].oldSRS] + " -> " + SRSLevelNames[itemsList[i].newSRS];
popup.style.display = "block";
popup.style.visibility = "hidden";
listItemLink.addEventListener("mouseover", function(e) {
// Position the popup element relative to the parent item element: to the right of the parent unless that would cause the popup to go off the screen
let infoPos = listItemLink.getBoundingClientRect();
let popupPos = popup.getBoundingClientRect();
if (infoPos.left + popupPos.width + 5 > window.innerWidth) {
popup.style.right = window.innerWidth - infoPos.right + "px";
popup.style.removeProperty("left");
popup.className = "summary-popup__popup summary-popup__popup--left";
} else {
popup.style.left = infoPos.left + "px";
popup.style.removeProperty("right");
popup.className = "summary-popup__popup summary-popup__popup--right";
}
popup.style.top = infoPos.bottom + 5 + "px";
popup.style.visibility = "visible";
});
listItemLink.addEventListener("mouseout", function(e) {
popup.style.visibility = "hidden";
});
popup.style.visibility = "hidden";
// Append the list item to the list
listItemLink.appendChild(popup);
listItem.appendChild(listItemLink);
if (itemsList[i].SRSUp) {
listCorrect.appendChild(listItem);
srsUpNum++;
}
else listIncorrect.appendChild(listItem);
}
// Create a header table with main stats
let data = [
[itemsList.length, "R: " + typeNum[0] + " / K: " + typeNum[1] + " / V: " + typeNum[2], "Items Completed"],
[percentage(srsUpNum, itemsList.length), srsUpNum + " out of " + itemsList.length, "Items Correct"],
[percentage(itemsCorrect, questionsAnswered), itemsCorrect + " out of " + questionsAnswered , "Questions Correct"],
[percentage(meaningCorrect, meaningCorrect + meaningIncorrect), meaningCorrect + " out of " + (meaningCorrect + meaningIncorrect), "Meanings Correct"],
[percentage(readingCorrect, readingCorrect + readingIncorrect), readingCorrect + " out of " + (readingCorrect + readingIncorrect), "Readings Correct"]
];
let table = createTable(data);
// Create h2 titles for the lists
let correctTitle = createSummarySectionTitle(srsUpNum + " Items SRS Up", "srs-up", "var(--color-quiz-correct-background, #88cc00)");
let incorrectTitle = createSummarySectionTitle((itemsList.length - srsUpNum) + " Items SRS Down", "srs-down", "var(--color-quiz-incorrect-background, #ff0033)");
// Create a graph showing accuracy throughout the session using the correctHistory array, with an average of 3 elements
let graphTitle, graphDiv;
if(itemsList.length > 4) {
graphTitle = createSummarySectionTitle(" Session Accuracy", "chart-line", "var(--color-menu, #777)");
// Graph
graphDiv = document.createElement("div");
graphDiv.classList = "accuracy-graph";
let graph = document.createElement("canvas");
graph.style.width = "100%";
graph.style.height = "100%";
graphDiv.appendChild(graph);
}
// Get existing accuracy history array from local storage or create new one, then append the current accuracy to it and store it again
let accuracyArray = JSON.parse(localStorage.getItem("WKSummaryAccuracyHistory")) || [];
if(accuracyArray != [] && !Array.isArray(accuracyArray[0])) accuracyArray = [];
accuracyArray.push([Math.round(srsUpNum / itemsList.length * 100) / 100, new Date().toLocaleString("en-US", {weekday: "short"})]);
if(accuracyArray.length > 15) accuracyArray.shift(); // If the array is longer than 10 elements, remove the first one
localStorage.setItem("WKSummaryAccuracyHistory", JSON.stringify(accuracyArray));
// Create a graph showing accuracy throughout the last 10 (or less) sessions
let graphTitle2, graphDiv2;
if(accuracyArray.length > 3) {
graphTitle2 = createSummarySectionTitle(" Accuracy History", "chart-line", "var(--color-menu, #777)");
// Graph
graphDiv2 = document.createElement("div");
graphDiv2.classList = "accuracy-graph";
let graph = document.createElement("canvas");
graph.style.width = "100%";
graph.style.height = "100%";
graphDiv2.appendChild(graph);
}
// Create a div element to wrap everything
let content = document.createElement("div");
content.append(heading, table, incorrectTitle, listIncorrect, correctTitle, listCorrect, graphTitle ? graphTitle : "", graphDiv ? graphDiv : "", graphTitle2 ? graphTitle2 : "", graphDiv2 ? graphDiv2 : "");
// Create a popup element with all the summary content
let popup = createPopup(content);
document.body.appendChild(popup);
// If it exists, fill the graph with the correctHistory array
if(graphDiv) {
let graph = graphDiv.querySelector("canvas");
// Calculate graph data
let graphData = [];
for (let i = 1; i < correctHistory.length - 1; i++) {
graphData.push((correctHistory[i-1] + correctHistory[i] + correctHistory[i+1]) / 3);
}
createGraph(graphData, graph, "🎊 Perfect session! 🎊");
}
// If it exists, fill the second graph with the accuracyArray array
if(graphDiv2) {
let graph = graphDiv2.querySelector("canvas");
createGraph(accuracyArray.map(tuple => tuple[0]), graph, "🎊 Perfect history! 🎊", accuracyArray.map(tuple => tuple[1]));
}
// Reset the statistics variables
questionsAnswered = 0;
itemsCorrect = 0;
itemsIncorrect = 0;
meaningCorrect = 0;
meaningIncorrect = 0;
readingCorrect = 0;
readingIncorrect = 0;
itemsList = [];
} else {
window.location.href = "https://www.wanikani.com/dashboard";
}
}
let eventToObserve = window.doublecheck == null ? "didAnswerQuestion" : "didFinalAnswer";
// Add an event listener for the didAnswerQuestion event
window.addEventListener(eventToObserve, function(e) {
if(questionsAnswered == 0) {
injectEndCode();
}
// Check if the answer was correct or not by looking for the correct attribute
let correct = document.querySelector(".quiz-input__input-container[correct='true']") !== null;
correctHistory.push(correct);
// Record the answer entered if incorrect
if (!correct) {
if(!incorrectEntered.has(e.detail.subjectWithStats.subject.id)) incorrectEntered.set(e.detail.subjectWithStats.subject.id, [[], []]);
if(currentQuestionType === "meaning") incorrectEntered.get(e.detail.subjectWithStats.subject.id)[0].push(e.detail.answer);
else if(currentQuestionType === "reading") incorrectEntered.get(e.detail.subjectWithStats.subject.id)[1].push(e.detail.answer);
}
// Increment the questions answered and correct/incorrect counters
questionsAnswered++;
if (currentQuestionType === "meaning") {
correct ? meaningCorrect++ : meaningIncorrect++;
} else if (currentQuestionType === "reading") {
correct ? readingCorrect++ : readingIncorrect++;
}
if (correct) itemsCorrect++;
else itemsIncorrect++;
});
// Add an event listener for the didCompleteSubject event
window.addEventListener("didCompleteSubject", function(e) {
// Get the subject data from the event detail
let subject = e.detail.subjectWithStats.subject;
let didSRSUp = e.detail.subjectWithStats.stats.meaning.incorrect === 0 && e.detail.subjectWithStats.stats.reading.incorrect === 0;
let reading = null;
if(subject.type == "Vocabulary" || subject.type == "KanaVocabulary") {
reading = subject.readings;
} else if (subject.type == "Kanji") {
reading = [null, null, null];
if(subject.nanori.length > 0) {
reading[0] = subject.nanori;
}
if(subject.onyomi.length > 0) {
reading[1] = subject.onyomi;
}
if(subject.kunyomi.length > 0) {
reading[2] = subject.kunyomi;
}
}
let isWarning = e.detail.subjectWithStats.stats.meaning.incorrect + e.detail.subjectWithStats.stats.reading.incorrect > 2 || (e.detail.subjectWithStats.stats.meaning.incorrect > 0 && e.detail.subjectWithStats.stats.reading.incorrect > 0);
// Calculate the new SRS level
let newSRSLevel = didSRSUp ? currentSRSLevel + 1 : (currentSRSLevel < 2 ? currentSRSLevel : (currentSRSLevel < 5 ? currentSRSLevel - 1 : currentSRSLevel - 2));
console.log(subject.characters + " - Old SRS Level: " + SRSLevelNames[currentSRSLevel] + " New SRS Level: " + SRSLevelNames[newSRSLevel]);
// Push the subject data to the items list array
let subjectInfoToSave = { characters: subject.characters, type: subject.type, id: subject.id, SRSUp: didSRSUp, meanings: subject.meanings, readings: reading, oldSRS: currentSRSLevel, newSRS: newSRSLevel, isWarning: isWarning, incorrectEntered: incorrectEntered.get(subject.id) };
itemsList.push(subjectInfoToSave);
});
// Add an event listener for the willShowNextQuestion event
window.addEventListener("willShowNextQuestion", function(e) {
// Set current question variables with event info
currentQuestionType = e.detail.questionType;
currentCategory = e.detail.subject.type;
currentWord = e.detail.subject.characters;
currentSRSLevel = quizQueueSRS.find(function(element) { return element[0] == e.detail.subject.id; });
if(currentSRSLevel == undefined) {
getQuizQueueSRS();
currentSRSLevel = quizQueueSRS.find(function(element) { return element[0] == e.detail.subject.id; });
if(currentSRSLevel == undefined) currentSRSLevel = [e.detail.subject.id, 10];
}
currentSRSLevel = currentSRSLevel[1];
if(currentSRSLevel == null) {
getQuizQueueSRS();
currentSRSLevel = quizQueueSRS.find(function(element) { return element[0] == e.detail.subject.id; })[1];
if(currentSRSLevel == null) currentSRSLevel = 10;
}
});
// Add an event listener for the turbo before-visit event
window.addEventListener("turbo:before-visit", function(e) {
// Show stats if .summary-popup is not already visible and there are items reviewed
if (document.querySelector(".summary-popup") === null && questionsAnswered > 0) {
e.preventDefault();
showStatistics();
}
});
// Home button override
async function getHomeButton() {
let homeButton = document.querySelector(".summary-button");
if(!homeButton) setTimeout(getHomeButton, 500);
else {
homeButton.setAttribute("title", "Show statistics and return to dashboard");
homeButton.addEventListener("click", function(e) {
// Show stats if .summary-popup is not already visible and there are items reviewed
if (document.querySelector(".summary-popup") === null && questionsAnswered > 0) {
e.preventDefault();
showStatistics();
}
});
}
}
getHomeButton();
// If statistics screen is open, set the right arrow key and the escape key to go back to the dashboard
document.addEventListener("keydown", function(e) {
if (document.querySelector(".summary-popup") !== null && (e.key === "ArrowRight" || e.key === "Escape")) {
e.preventDefault();
window.location.href = "https://www.wanikani.com/dashboard";
}
});
}
})();